Author: rminnich
Date: 2007-06-02 01:13:15 +0200 (Sat, 02 Jun 2007)
New Revision: 340
Modified:
LinuxBIOSv3/doc/design/newboot.lyx
Log:
More information, we are on the next step, which is smbus support for
dram. Per the discussion on v3 list, I am self-acking this one.
Signed-off-by: Ronald G. Minnich <rminnich(a)gmail.com>
Acked-by: Ronald G. Minnich <rminnich(a)gmail.com>
Modified: LinuxBIOSv3/doc/design/newboot.lyx
===================================================================
--- LinuxBIOSv3/doc/design/newboot.lyx 2007-06-01 04:41:42 UTC (rev 339)
+++ LinuxBIOSv3/doc/design/newboot.lyx 2007-06-01 23:13:15 UTC (rev 340)
@@ -2077,6 +2077,8 @@
\end_layout
\begin_layout LyX-Code
+
+\size tiny
/home/rminnich/src/bios/LinuxBIOSv3/mainboard/amd/norwich/initram.c: In function
'spd_read_byte': /home/rminnich/src/bios/LinuxBIOSv3/mainboard/amd/norwich/init
ram.c:30: error: implicit declaration of function 'smbus_read_byte' /home/rminnic
@@ -2122,5 +2124,320 @@
\end_layout
+\begin_layout Paragraph
+Hold on.
+ What are we doing here?
+\end_layout
+
+\begin_layout Standard
+We need to create an initram file for the LAR.
+ This initram file is going to set up DRAM.
+ LinuxBIOS supplies a skeleton function, which we show below, and the programmer
+ needs to supply some functions for their chipsets, so that this function
+ can work.
+
+\end_layout
+
+\begin_layout Standard
+What code is needed? A few things.
+ The northbridge code must supply register set functions.
+ The southbridge or superio must supply smbus read functions.
+ The basic sdram setup is found in lib/ram.c, and is dead simple:
+\end_layout
+
+\begin_layout LyX-Code
+
+\size tiny
+void ram_initialize(int controllers, void *ctrl) {
+\end_layout
+
+\begin_layout LyX-Code
+
+\size tiny
+ int i;
+\end_layout
+
+\begin_layout LyX-Code
+
+\size tiny
+ /* Set the registers we can set once to reasonable values.
+ */
+\end_layout
+
+\begin_layout LyX-Code
+
+\size tiny
+ for (i = 0; i < controllers; i++) {
+\end_layout
+
+\begin_layout LyX-Code
+
+\size tiny
+ printk(BIOS_INFO,
+\end_layout
+
+\begin_layout LyX-Code
+
+\size tiny
+ "Setting registers of RAM controller %d
+\backslash
+n", i);
+\end_layout
+
+\begin_layout LyX-Code
+
+\size tiny
+ ram_set_registers(ctrl, i);
+\end_layout
+
+\begin_layout LyX-Code
+
+\size tiny
+ }
+\end_layout
+
+\begin_layout LyX-Code
+
+\end_layout
+
+\begin_layout LyX-Code
+
+\size tiny
+ /* Now setup those things we can auto detect.
+ */
+\end_layout
+
+\begin_layout LyX-Code
+
+\size tiny
+ for (i = 0; i < controllers; i++) {
+\end_layout
+
+\begin_layout LyX-Code
+
+\size tiny
+ printk(BIOS_INFO,
+\end_layout
+
+\begin_layout LyX-Code
+
+\size tiny
+ "Setting SPD based registers of RAM controller %d
+\backslash
+n", i);
+\end_layout
+
+\begin_layout LyX-Code
+
+\size tiny
+ ram_set_spd_registers(ctrl, i);
+\end_layout
+
+\begin_layout LyX-Code
+
+\size tiny
+ }
+\end_layout
+
+\begin_layout LyX-Code
+
+\end_layout
+
+\begin_layout LyX-Code
+
+\size tiny
+ /* Now that everything is setup enable the RAM.
+ Some chipsets do
+\end_layout
+
+\begin_layout LyX-Code
+
+\size tiny
+ * the work for us while on others we need to it by hand.
+ */
+\end_layout
+
+\begin_layout LyX-Code
+
+\size tiny
+ printk(BIOS_DEBUG, "Enabling RAM
+\backslash
+n");
+\end_layout
+
+\begin_layout LyX-Code
+
+\size tiny
+ ram_enable(controllers, ctrl);
+\end_layout
+
+\begin_layout LyX-Code
+
+\end_layout
+
+\begin_layout LyX-Code
+
+\size tiny
+ /* RAM initialization is done.
+ */
+\end_layout
+
+\begin_layout LyX-Code
+
+\size tiny
+ printk(BIOS_DEBUG, "RAM enabled successfully
+\backslash
+n");
+\end_layout
+
+\begin_layout LyX-Code
+
+\size tiny
+}
+\end_layout
+
+\begin_layout Standard
+Ram_initialize is a core function of initram.
+ When it is called, RAM is not working; after it is called, RAM is working.
+ This function in turn calls functions in the northbridge code (or, in some
+ cases, CPU code; it depends on the part).
+ The basic idea is that this code is called with a pointer to an opaque
+ type (ctlr *), and an int indicating how many controllers, dram slots,
+ or whatever
+\begin_inset Quotes eld
+\end_inset
+
+things
+\begin_inset Quotes erd
+\end_inset
+
+ there are, where a
+\begin_inset Quotes eld
+\end_inset
+
+thing
+\begin_inset Quotes erd
+\end_inset
+
+ is totally chipset dependent.
+ The lib/ram.c code sets hardcoded settings, then sets dynamic settings by
+ querying the SPD bus, then enables the RAM.
+ This basic cycle has been refined now for eight years and has worked well
+ on many systems.
+
+\end_layout
+
+\begin_layout Standard
+The northbridge code has to provide three basic functions.
+ The first function, ram_set_registers, sets up basic parameters.
+ It will be called for each of the ram
+\begin_inset Quotes eld
+\end_inset
+
+things
+\begin_inset Quotes erd
+\end_inset
+
+, where, as described above,
+\begin_inset Quotes eld
+\end_inset
+
+thing
+\begin_inset Quotes erd
+\end_inset
+
+ can be just about anything, depending on the chipset.
+ The function will be called with the ctlr pointer, and in index in the
+ range 0..controllers-1.
+ The second function, ram_set_spd_registers, is called to tell the northbridge
+ code that it should do spd setup for
+\begin_inset Quotes eld
+\end_inset
+
+thing
+\begin_inset Quotes erd
+\end_inset
+
+ i.
+ Finally, the northbridge-provided enable function is called.
+
+\end_layout
+
+\begin_layout Standard
+Any or all of these functions may be empty.
+ In the common case, they all do something.
+ These functions, in turn, may require other functions from other chipset
+ parts.
+ The most important, and common, set of functions reads SPD values using
+ the SMBUS.
+ The mainboard must configure, as part of stage2, a file to be compiled
+ which provides these functions.
+ The simplest function is called smbus_read_byte(unsigned device, unsigned
+ address).
+ This function should do any needed initialization, to keep life simple
+ for the northbridge code, and then read from SMBUS device 'device' at address
+ 'address'.
+ Typically, the device address range is 0xa0 up to 0xa8.
+ The address depends on the DRAM technology.
+
+\end_layout
+
+\begin_layout Standard
+All of the LinuxBIOS code that is run after this point uses the device tree;
+ none of the initram code uses the device tree.
+ The reason is simple: the device tree lives in RAM.
+ This bootstrap code is intentionally simple and does not use the device
+ tree.
+
+\end_layout
+
+\begin_layout Standard
+We will start by providing SMBUS functions.
+ The SMBUS for this board is supported on the AMD CS5536 chip.
+ The file we create will be in southbridge/amd/cs5536/smbus_initram.c.
+
+\end_layout
+
+\begin_layout Standard
+The revision numbers skip a bit here, since others are also working on V3.
+ We start with revision 339.
+
+\end_layout
+
+\begin_layout Subsubsection
+R339
+\end_layout
+
+\begin_layout Standard
+Get the old code:
+\end_layout
+
+\begin_layout LyX-Code
+cp LinuxBIOSv2/src/southbridge/amd/cs5536/cs5536_early_smbus.c southbridge/amd/cs
+5536/smbus_initram.c
+\end_layout
+
+\begin_layout Standard
+Then we need to set up the mainboard Makefile to include this file in the
+ mainboard stage2.
+ This is pretty easy: add the .o for this file to the INITRAM_OBJ in the
+ mainboard Makefile:
+\end_layout
+
+\begin_layout LyX-Code
+
+\size tiny
+INITRAM_OBJ=$(obj)/stage0.init $(obj)/stage0.o $(obj)/mainboard/$(MAINBOARDDIR)/in
+itram.o $(obj)/southbridge/amd/cs5536/smbus_initram.o
+\end_layout
+
+\begin_layout Standard
+Now we get lots more errors, so off we go to fix them!
+\end_layout
+
+\begin_layout Standard
+
+\end_layout
+
\end_body
\end_document