[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