[LinuxBIOS] Porting 440bx from v1, is this right?

Corey Osgood corey_osgood at verizon.net
Mon Apr 2 15:40:10 CEST 2007


I'm trying to port the sdram reading functions from LBv1 up to v2 (for
use with the raminit.c that Uwe just committed), but so far haven't
gotten it to work, so I'm hoping maybe someone can spot my problem (I
think this is where a problem is). For anyone not familiar with v1,
ASSERT_RAM_COMMAND() is called by generic_sdram_enable.inc, and is
supposed to read from an address on the dimms. Here's the code for just
reading:

from src/northbridge/intel/440bx/raminit.inc
#define RAM_READ 0x0400

#define DIMM0_BASE \
    xorl %eax, %eax

#define DIMM_BASE(n) \
    movl $(0x60 + ((n) -1)), %eax    ; \
    PCI_READ_CONFIG_BYTE        ; \
    andl $0xFF, %eax        ; \
    shll $23, %eax            ; \

#define DIMM_READ \
    addl %ebx, %eax            ; \
    movl (%eax), %edx        ; \ //%edx indicates a read, right?
    xorl $0xdff8, %eax        ; \
    movl (%eax), %edx

#define DIMM0_READ DIMM0_BASE   ; DIMM_READ
#define DIMM1_READ DIMM_BASE(1) ; DIMM_READ
#define DIMM2_READ DIMM_BASE(2) ; DIMM_READ
#define DIMM3_READ DIMM_BASE(3) ; DIMM_READ
#define DIMM4_READ DIMM_BASE(4) ; DIMM_READ
#define DIMM5_READ DIMM_BASE(5) ; DIMM_READ
#define DIMM6_READ DIMM_BASE(6) ; DIMM_READ
#define DIMM7_READ DIMM_BASE(7) ; DIMM_READ

#define DIMMS_READ_EBX_OFFSET \
    DIMM0_READ    ; \
    DIMM1_READ    ; \
    DIMM2_READ    ; \
    DIMM3_READ    ; \
    DIMM4_READ    ; \
    DIMM5_READ    ; \
    DIMM6_READ    ; \
    DIMM7_READ

#define DIMMS_READ(offset) \
    movl $offset, %ebx    ; \
    DIMMS_READ_EBX_OFFSET

#define ASSERT_RAM_COMMAND()        DIMMS_READ(RAM_READ)


And here's what I've ported it to. Anyone see anything that sticks out
as a problem?
(offset = 0x0400, except when setting MRS it's 0x01d0)

static void dimms_read(unsigned long offset)
{
    int slot;
    //DIMM0_READ
    unsigned long addr = 0;
    addr += offset;
    PRINT_DEBUG("addr = ");
    PRINT_DEBUG_HEX32(addr); // FIXME
    PRINT_DEBUG("\r\n");
    //DIMM_READ
    read32(addr);
    addr ^= 0xdff8; // xorl $0xdff8, %eax
    read32(addr);

    /* All this should be unnecessary for a single sided single dimm
               and may even screw things up a bit */
for(slot = 0; slot < 7; slot++)
    {
        //DIMM_BASE(n)
        /* Compute DIMM_BASE */
        addr = pci_read_config8(0, (0x60 + slot ));//count starts at 0,
so slot-1 not necessary
        /* NOTE: We should probably check if we already read this addr
        (ie if all dimm slots aren't populated), but easier not to */
        addr &= 0xFF;
        addr = (addr << 23);
        //DIMM_READ
        addr += offset;
        PRINT_DEBUG(" to 0x");
        PRINT_DEBUG_HEX32(addr); // FIXME
        read32(addr);
        /* This was pulled from v1, I think it's right */
        addr ^= 0xdff8;
        PRINT_DEBUG(" and 0x");
        PRINT_DEBUG_HEX32(addr); // FIXME
        PRINT_DEBUG("\r\n");
        read32(addr);
    }
}

Here's some of my minicom.cap, showing what addresses this comes up with:
<any non-MRS command>
 to 0x00000000 and
0x0000dff8
 to 0x04000000 and
0x0400dff8
 to 0x04000000 and
0x0400dff8
 to 0x04000000 and
0x0400dff8
 to 0x04000000 and
0x0400dff8
 to 0x04000000 and
0x0400dff8
 to 0x04000000 and
0x0400dff8
RAM Enable 4: Mode register
set
   Computed cas value =
0x01d0
   Sending RAM command 0x03addr =
000001d0
 to 0x000001d0 and
0x0000de28
 to 0x040001d0 and 0x0400de28
etc


Thanks,
Corey





More information about the coreboot mailing list