Hello Tim and all those interested in i440bx,
the following function is fully functional code for implementing the activation of all detected SDRAM modules, and both sides. It has been tested with some combinations of 16 MB and 64 MB banks and works as expected. It will be included in the original import for mainboard/msi/ms6147, which I am about to post.
Best regards,
Mats Erik Andersson
------
static void do_ram_command(const struct mem_controller *ctrl, uint32_t command, uint32_t addr_offset) { char i, dram_known; uint16_t reg;
/* Support for multiple DIMMs. * This requires that one read32() is performed * for each RAM bank/row. */
/* Configure the RAM command. */ reg = pci_read_config16(ctrl->d0, SDRAMC); reg &= 0xff1f; /* Clear bits 7-5. */ reg |= (uint16_t) (command << 5); pci_write_config16(ctrl->d0, SDRAMC, reg);
/* RAM_COMMAND_NORMAL affects only the memory controller and doesn't need to be "sent" to the DIMMs. */ if (command == RAM_COMMAND_NORMAL) return;
/* RAM is populated from the bottom. This variable always * denotes the beginning of a newly populated block. */ dram_known = 0;
for (i = 0; i < (DIMM_SOCKETS * 2); i++) { /* Is this bank populated? */ if (pci_read_config8(ctrl->d0, DRB + i) > dram_known) { /* The DRB# registers count in 8 MB blocks. * 'dram_known contains the known lower bound of * the present block. Activate it. */ read32( (dram_known * 8 * 1024 * 1024) + addr_offset); PRINT_DEBUG("RAM strobe 0x"); PRINT_DEBUG_HEX32(dram_known * 8 * 1024 * 1024 + addr_offset); PRINT_DEBUG("\r\n"); /* DRB registers are cumulative, so grab the current value. */ dram_known = pci_read_config8(ctrl->d0, DRB + i); };
} }