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