[LinuxBIOS] RAM detection for Intel 430FX and memory sizing
popkonserve
popkonserve at gmx.de
Sat Aug 11 15:49:28 CEST 2007
i tried another approach, looks way nicer now. any comments? let me know :)
Holger
/* IN RAMINIT.H */
enum E_DRAM_TYPE {
DRT_SYMMETRIC = 0,
DRT_ASYMMETRIC = 1
};
struct S_DRAMTechnology {
uint8_t row_address;
uint8_t column_address;
uint16_t row_size;
enum E_DRAM_TYPE type;
};
static const struct S_DRAMTechnology dram_technology[] = {
{ 0, 24, 32, DRT_SYMMETRIC},
{24, 22, 32, DRT_ASYMMETRIC},
{23, 22, 16, DRT_ASYMMETRIC},
{ 0, 22, 8, DRT_SYMMETRIC},
{21, 11, 4, DRT_ASYMMETRIC},
{ 0, 0, 0, DRT_SYMMETRIC}
};
/* IN RAMINIT.C */
static void detect_size(const struct mem_controller* ctrl,
uint8_t* dram_size,
const uint8_t row)
{
uint32_t address0 = 0x0;
uint32_t address8 = 1;
uint32_t data1 = 0x55555555UL;
uint32_t data2 = 0xAAAAAAAAUL;
uint32_t data3 = 0xFEDCBA98UL;
uint32_t data4 = 0;
uint8_t detected = 0;
uint8_t index = 0;
do {
/* FIXME: Not sure if this is really needed */
pci_write_config8(ctrl->d0,
CR_DRAM_ROW_BOUNDARY_BASE + row,
dram_technology[index].row_size / SIMM_GRANULARITY);
/* Write some data */
dimm_write32(address0, data1);
/* Prepare the first address */
address8 = (1 << dram_technology[index].column_address);
/* Write some more data */
dimm_write32(address8, data2);
/* Write even more data to yet another address for asymmetric DRAM */
if(dram_technology[index].type == DRT_ASYMMETRIC) {
/* Prepare the second address */
address8 = (1 << dram_technology[index].row_address);
/* Write even more data */
dimm_write32(address8, data3);
}
/* Read data back */
dimm_read32(address0, data4);
if(data1 == data4) {
/* Found DRAM with correct size and technology */
dram_size[row] = dram_technology[index].row_address /
SIMM_GRANULARITY;
detected = 1;
break;
}
else {
/* No RAM found yet. Try next addressing scheme. */
index++;
}
} while(detected == 0 || dram_technology[index].row_size != 0);
if(detected == 0) {
dram_size[row] = DRAM_EMPTY;
}
}
More information about the coreboot
mailing list