AMD Geode Porting Guide

From coreboot
Revision as of 05:11, 19 January 2008 by MJones (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Welcome! This is a collection on information to help you on your way to porting coreboot to an AMD Geode platform. Most of the information is about the Geode LX and CS5536 but may also be relevant to older version on Geode. (Note that this does not cover the Geode NX).

If you find something incorrect or other deficiencies in this information please fix them!




Documentation


Build coreboot for Geode

Use buildrom. It can handle the payload and VSA for you.

$ svn co svn://coreboot.org/buildrom

Checkout coreboot:

$ svn co svn://coreboot.org/repos/trunk/coreboot-v2

Build a db800 for starters and set buildrom to build your local svn directory in menuconfig.

$ make menuconfig
$ make

From this point you can customize the db800 and then make the target, mainboard, and buildrom customization patches later.


Manual build

If you really want to get your hands dirty. Roll up your sleeves....

Go get VSA lx_vsa.36k.bin here. It is already nrv2b'd. If you want the source it is here. Find a payload and build it.

$ cd coreboot-v2/targets
$ ./buildtarget amd/db800
$ cd amd/db800/db800
$ cp /from/someplace/payloadx ./payload.elf
$ make
$ cat lx_vsa.36k.bin db800.rom > amd-db800.rom


You should now have a 512KB ROM image. You should be able to use flashrom or a ROM programmer to get the image onto your system. (Be prepared to brick it....)


Porting

Now that you are building Geode core boot images you are ready to make customizations to your platform. Most customizations can be handled in the mainboard directory.

$ cd coreboot-v2/src/mainboard/amd/db800


Make yourself familiar with this directory. There are not too many files.


IRQ routing

Almost every platform will require customization of the PIR table in irq_table.c

Make yourself familiar with the PIR table specification.

If you have the motherboard schematics adjusting the table is fairly simple.

First check how many on board devices (including PCI slots) and update IRQ_SLOT_COUNT in Options.lb. Remember any time you change Options.lb or Config.lb you need to redo ./buildtarget.

Next check the INT lines (GPIOS) into the 5536.

CS5536
line 5536 signal/pin
PCI$INTA_X GPIO0 / INTA_L
PCI$INTB_X GPIO7 / INTB_X
PCI$INTC_X GPIO12 / INTR
PCI$INTD_X GPIO13 / 8MI_L

Based on this information you can setup you can setup the register "enable_gpio_int_route" = "0x0D0C0700" in Config.lb

For each motherboard device check the INT pins. For example a PCI slot would look something like this:

PCI slot
pin device line
pin A6 INTA_X PCI$INTB_X
pin A7 INTC_X PCI$INTD_X
pin B7 INTB_X PCI$INTC_X
pin B8 INTD_X PCI$INTA_X


Take a closer look at irq_tables.c. L_PIRQA is the chipset incoming IRQ line and M_PIRQA is the bitmap of IRQ numbers it can generate. These should not change. You can adjust the IRQs generated by changing PIRQA etc. Yes, it is fine if they all share 10 or 11 but it might be easier to debug if they all have a different IRQ.

The table entries are the slot/device IRQ lines. I will break one entry down.

/* bus, dev|fn,           {link, bitmap},      {link, bitmap},     {link, bitmap},     {link, bitmap},     slot, rfu */
{0x00, (0x01 << 3) | 0x0, {{L_PIRQA, M_PIRQA}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}}, 0x0, 0x0},   /* cpu */
{0x00, (0x0F << 3) | 0x0, {{L_PIRQA, M_PIRQA}, {L_PIRQB, M_PIRQB}, {L_PIRQC, M_PIRQC}, {L_PIRQD, M_PIRQD}}, 0x0, 0x0}, /* chipset */
{0x00, (0x0D << 3) | 0x0, {{L_PIRQB, M_PIRQB}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}}, 0x0, 0x0},   /* ethernet */
{0x00, (0x0E << 3) | 0x0, {{L_PIRQC, M_PIRQC}, {L_PIRQD, M_PIRQD}, {L_PIRQA, M_PIRQA}, {L_PIRQB, M_PIRQB}}, 0x1, 0x0}, /* slot1 */


I will break the last entry down.

{0x00, (0x0E << 3) | 0x0, - slot(device) address (IDSEL)
{{L_PIRQC, M_PIRQC}, - slot INT line A to chipset INT line C (L_PIRQC), it can generate IRQs (M_PIRQC)
{L_PIRQD, M_PIRQD},- slot INT line B to chipset INT line C (L_PIRQD), it can generate IRQs (M_PIRQD)
{L_PIRQA, M_PIRQA}, - slot INT line C to chipset INT line A....
{L_PIRQB, M_PIRQB}}, - slot INT lineD to chipset INT line B....
0x1, - arbitrary slot number
0x0}, - rfu always 0


If you don't have the schematics you will have to figure out the routing on your own. With lspci output and some trial and error you can figure it out. IRC or the email list is a good place to get help if you are stuck.

Here is a wiki entry on figuring out the routing table.


Memory

On some systems the memory is soldered down and there is no SPD which is required to properly setup DDR memory. In this case you will need to provide an SPD values in coreboot. This should be done by customizing spd_read_byte in cache_as_ram_auto.c to do a table lookup. A good example can be found in coreboot-v2/src/mainboard/pcengines/alix1c/cache_as_ram_auto.c.


Power button

By default the cs5536 code sets the power button up for the 4 second soft off setting. If your system is booting and shuts off after four seconds check for a power button enable jumper. If your system doesn't have a power button and comes on when plugged in you will need to adjust the power button MSR. This is best done in cache_as_ram_main() in cache_as_ram+auto.c after the call to cs5536_early_setup. The MSR name is PM Fail-Safe Delay and Enable (PM_FSD). Add the following line:

outl(0x00, PMS_IO_BASE + 0x40); // disable the power button


Other

What are we missing?