Chameleon

Chameleon Commit Details

Date:2010-09-26 08:07:23 (13 years 6 months ago)
Author:Evan Lojewski
Commit:555
Parents: 554
Message:Removed recursion, already taken care of in the pci setup function.
Changes:
M/branches/meklort/i386/modules/Memory/spd.c
M/branches/meklort/i386/modules/Memory/Memory.c
M/branches/meklort/i386/modules/Memory/dram_controllers.c
M/branches/meklort/i386/modules/Memory/spd.h
M/branches/meklort/i386/modules/Memory/mem.c

File differences

branches/meklort/i386/modules/Memory/mem.c
1212
1313
1414
15
15
1616
1717
1818
#include "smbios_patcher.h"
#ifndef DEBUG_MEM
#define DEBUG_MEM 0
#define DEBUG_MEM 1
#endif
#if DEBUG_MEM
branches/meklort/i386/modules/Memory/spd.c
1515
1616
1717
18
18
1919
2020
2121
......
129129
130130
131131
132
132
133133
134134
135135
136136
137137
138138
139
139
140140
141141
142142
......
147147
148148
149149
150
151
150
151
152152
153153
154154
......
171171
172172
173173
174
175
176
177
178
179
180
181
182
174
175
176
177
178
179
180
181
182
183183
184184
185185
186186
187
188
189
190
191
192
193
194
195
187
188
189
190
191
192
193
194
195
196196
197197
198198
......
208208
209209
210210
211
211
212212
213213
214214
215
215
216216
217
217
218218
219219
220220
......
223223
224224
225225
226
226
227227
228228
229229
......
258258
259259
260260
261
261
262262
263263
264
264
265265
266266
267
268
267
268
269269
270
270
271271
272272
273273
......
276276
277277
278278
279
279
280280
281281
282282
......
285285
286286
287287
288
289
290
291
292
293
294
295
296
297
298
299
300
288
289
290
291
292
293
294
295
296
297
298
299
300
301301
302302
303303
......
305305
306306
307307
308
308
309309
310310
311311
......
326326
327327
328328
329
330
331
332
333
334
335
336
329
330
331
332
333
334
335
336
337337
338
339
338
339
340340
341341
342342
343343
344
345
344
345
346346
347347
348
348
349349
350350
351351
352352
353
353
354354
355355
356356
......
363363
364364
365365
366
366
367367
368368
369
370
371
369
370
372371
373
374
372
373
374
375
376
377
378
379
380
381
382
375383
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
384
399385
400
386
387
388
389
390
391
392
393
394
401395
#include "memvendors.h"
#ifndef DEBUG_SPD
#define DEBUG_SPD 0
#define DEBUG_SPD 1
#endif
#if DEBUG_SPD
}
/** Get Vendor Name from spd, 2 cases handled DDR3 and DDR2,
have different formats, always return a valid ptr.*/
have different formats, always return a valid ptr.*/
const char * getVendorName(RamSlotInfo_t* slot, uint32_t base, int slot_num)
{
uint8_t bank = 0;
uint8_t code = 0;
int i = 0;
uint8_t * spd = (uint8_t *) slot->spd;
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) { // DDR3
bank = (spd[SPD_DDR3_MEMORY_BANK] & 0x07f); // constructors like Patriot use b7=1
code = spd[SPD_DDR3_MEMORY_CODE];
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2) {
if(spd[64]==0x7f) {
for (i=64; i<72 && spd[i]==0x7f;i++) {
bank++;
READ_SPD(spd, base, slot_num,i+1); // prefetch next spd byte to read for next loop
bank++;
READ_SPD(spd, base, slot_num,i+1); // prefetch next spd byte to read for next loop
}
READ_SPD(spd, base, slot_num,i);
code = spd[i];
{
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) {
switch(spd[12]) {
case 0x0f:
return 1066;
case 0x0c:
return 1333;
case 0x0a:
return 1600;
case 0x14:
default:
return 800;
case 0x0f:
return 1066;
case 0x0c:
return 1333;
case 0x0a:
return 1600;
case 0x14:
default:
return 800;
}
}
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2) {
switch(spd[9]) {
case 0x50:
return 400;
case 0x3d:
return 533;
case 0x30:
return 667;
case 0x25:
default:
return 800;
case 0x50:
return 400;
case 0x3d:
return 533;
case 0x30:
return 667;
case 0x25:
default:
return 800;
}
}
return 800; // default freq for unknown types
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) // DDR3
{
sprintf(asciiSerial, "%X%X%X%X%X%X%X%X", SMST(122) /*& 0x7*/, SLST(122), SMST(123), SLST(123), SMST(124), SLST(124), SMST(125), SLST(125));
sprintf(asciiSerial, "%X%X%X%X%X%X%X%X", SMST(122) /*& 0x7*/, SLST(122), SMST(123), SLST(123), SMST(124), SLST(124), SMST(125), SLST(125));
}
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2) // DDR2 or DDR
{
sprintf(asciiSerial, "%X%X%X%X%X%X%X%X", SMST(95) /*& 0x7*/, SLST(95), SMST(96), SLST(96), SMST(97), SLST(97), SMST(98), SLST(98));
sprintf(asciiSerial, "%X%X%X%X%X%X%X%X", SMST(95) /*& 0x7*/, SLST(95), SMST(96), SLST(96), SMST(97), SLST(97), SMST(98), SLST(98));
}
return strdup(asciiSerial);
}
const char * getDDRPartNum(char* spd, uint32_t base, int slot)
{
int i, start=0, index = 0;
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) {
start = 128;
}
uint32_t base;
bool dump = false;
RamSlotInfo_t* slot;
base = pci_config_read16(smbus_dev->dev.addr, 0x20) & 0xFFFE;
DBG("Scanning smbus_dev <%04x, %04x> ...\n",smbus_dev->vendor_id, smbus_dev->device_id);
getBoolForKey("DumpSPD", &dump, &bootInfo->bootConfig);
bool fullBanks = // needed at least for laptops
Platform->DMI.MemoryModules == Platform->DMI.MaxMemorySlots;
// Search MAX_RAM_SLOTS slots
Platform->DMI.MemoryModules == Platform->DMI.MaxMemorySlots;
// Search MAX_RAM_SLOTS slots
char spdbuf[256];
for (i = 0; i < MAX_RAM_SLOTS; i++){
DBG("Scanning slot %d\n", i);
slot = &Platform->RAM.DIMM[i];
if (spd_size && (spd_size != 0xff) ) {
slot->spd = spdbuf;
slot->InUse = true;
bzero(slot->spd, spd_size);
// Copy spd data into buffer
init_spd(slot->spd, base, i);
switch (slot->spd[SPD_MEMORY_TYPE]) {
case SPD_MEMORY_TYPE_SDRAM_DDR2:
slot->ModuleSize = ((1 << (slot->spd[SPD_NUM_ROWS] & 0x0f) + (slot->spd[SPD_NUM_COLUMNS] & 0x0f) - 17) *
((slot->spd[SPD_NUM_DIMM_BANKS] & 0x7) + 1) * slot->spd[SPD_NUM_BANKS_PER_SDRAM]);
break;
case SPD_MEMORY_TYPE_SDRAM_DDR3:
slot->ModuleSize = ((slot->spd[4] & 0x0f) + 28 ) + ((slot->spd[8] & 0x7) + 3 );
slot->ModuleSize -= (slot->spd[7] & 0x7) + 25;
slot->ModuleSize = ((1 << slot->ModuleSize) * (((slot->spd[7] >> 3) & 0x1f) + 1));
break;
case SPD_MEMORY_TYPE_SDRAM_DDR2:
slot->ModuleSize = ((1 << (slot->spd[SPD_NUM_ROWS] & 0x0f) + (slot->spd[SPD_NUM_COLUMNS] & 0x0f) - 17) *
((slot->spd[SPD_NUM_DIMM_BANKS] & 0x7) + 1) * slot->spd[SPD_NUM_BANKS_PER_SDRAM]);
break;
case SPD_MEMORY_TYPE_SDRAM_DDR3:
slot->ModuleSize = ((slot->spd[4] & 0x0f) + 28 ) + ((slot->spd[8] & 0x7) + 3 );
slot->ModuleSize -= (slot->spd[7] & 0x7) + 25;
slot->ModuleSize = ((1 << slot->ModuleSize) * (((slot->spd[7] >> 3) & 0x1f) + 1));
break;
}
spd_type = (slot->spd[SPD_MEMORY_TYPE] < ((char) 12) ? slot->spd[SPD_MEMORY_TYPE] : 0);
slot->PartNo = getDDRPartNum(slot->spd, base, i);
slot->Vendor = getVendorName(slot, base, i);
slot->SerialNo = getDDRSerial(slot->spd);
// determine spd speed
speed = getDDRspeedMhz(slot->spd);
if (slot->Frequency<speed) slot->Frequency = speed;
}
verbose("Slot: %d Type %d %dMB (%s) %dMHz Vendor=%s\n PartNo=%s SerialNo=%s\n",
i,
(int)slot->Type,
slot->ModuleSize,
spd_memory_types[spd_type],
slot->Frequency,
slot->Vendor,
slot->PartNo,
slot->SerialNo);
i,
(int)slot->Type,
slot->ModuleSize,
spd_memory_types[spd_type],
slot->Frequency,
slot->Vendor,
slot->PartNo,
slot->SerialNo);
if(DEBUG_SPD) {
dumpPhysAddr("spd content: ",slot->spd, spd_size);
getc();
dumpPhysAddr("spd content: ",slot->spd, spd_size);
getc();
}
}
// laptops sometimes show slot 0 and 2 with slot 1 empty when only 2 slots are presents so:
Platform->DMI.DIMM[i]=
i>0 && Platform->RAM.DIMM[1].InUse==false && fullBanks && Platform->DMI.MaxMemorySlots==2 ?
mapping[i] : i; // for laptops case, mapping setup would need to be more generic than this
i>0 && Platform->RAM.DIMM[1].InUse==false && fullBanks && Platform->DMI.MaxMemorySlots==2 ?
mapping[i] : i; // for laptops case, mapping setup would need to be more generic than this
slot->spd = NULL;
} // for
}
struct smbus_controllers_t smbus_controllers[] = {
{0x8086, 0x269B, "ESB2", read_smb_intel },
{0x8086, 0x25A4, "6300ESB", read_smb_intel },
{0x8086, 0x24C3, "ICH4", read_smb_intel },
{0x8086, 0x3A60, "ICH10B", read_smb_intel },
{0x8086, 0x3B30, "P55", read_smb_intel },
{0x8086, 0x5032, "EP80579", read_smb_intel }
};
// initial call : pci_dt = root_pci_dev;
// find_and_read_smbus_controller(root_pci_dev);
bool find_and_read_smbus_controller(pci_dt_t* pci_dt)
bool is_smbus_controller(pci_dt_t* pci_dt)
{
pci_dt_t*current = pci_dt;
int i;
int i = 0;
for ( ; i < sizeof(smbus_controllers) / sizeof(smbus_controllers[0]); i++ )
{
if (pci_dt->vendor_id == smbus_controllers[i].vendor &&
pci_dt->device_id == smbus_controllers[i].device)
{
return true;
}
}
return false;
}
while (current) {
#if DEBUG_SPD
printf("%02x:%02x.%x [%04x] [%04x:%04x] :: %s\n",
current->dev.bits.bus, current->dev.bits.dev, current->dev.bits.func,
current->class_id, current->vendor_id, current->device_id,
get_pci_dev_path(current));
#endif
for ( i = 0; i < sizeof(smbus_controllers) / sizeof(smbus_controllers[0]); i++ )
{
if (current->vendor_id == smbus_controllers[i].vendor &&
current->device_id == smbus_controllers[i].device)
{
smbus_controllers[i].read_smb(current); // read smb
return true;
}
}
find_and_read_smbus_controller(current->children);
current = current->next;
}
return false; // not found
}
void scan_spd(PlatformInfo_t *p)
void scan_spd(PlatformInfo_t *p, pci_dt_t* smbus_controller_dev)
{
find_and_read_smbus_controller(root_pci_dev);
int i = 0;
for ( ; i < sizeof(smbus_controllers) / sizeof(smbus_controllers[0]); i++ )
{
if (smbus_controller_dev->vendor_id == smbus_controllers[i].vendor &&
smbus_controller_dev->device_id == smbus_controllers[i].device)
{
smbus_controllers[i].read_smb(smbus_controller_dev); // read smb
}
}
}
branches/meklort/i386/modules/Memory/Memory.c
1515
1616
1717
18
1819
1920
2021
......
3536
3637
3738
39
40
41
42
43
3844
3945
4046
4147
42
43
4448
4549
4650
......
5155
5256
5357
54
55
58
59
60
61
62
5663
5764
5865
#include "modules.h"
pci_dt_t * dram_controller_dev = NULL;
pci_dt_t * smbus_controller_dev = NULL;
void Memory_hook(void* arg1, void* arg2, void* arg3, void* arg4);
{
dram_controller_dev = current;
}
else if(is_smbus_controller(current))
{
smbus_controller_dev = current;
}
}
void Memory_hook(void* arg1, void* arg2, void* arg3, void* arg4)
{
bool useAutodetection = true;
getBoolForKey(kUseMemDetect, &useAutodetection, &bootInfo->bootConfig);
scan_dram_controller(dram_controller_dev); // Rek: pci dev ram controller direct and fully informative scan ...
}
scan_memory(Platform); // unfortunately still necesary for some comp where spd cant read correct speed
scan_spd(Platform);
//getc();
if(smbus_controller_dev)
{
scan_spd(Platform, smbus_controller_dev);
}
}
}
branches/meklort/i386/modules/Memory/dram_controllers.c
2020
2121
2222
23
23
2424
2525
2626
#include "dram_controllers.h"
#ifndef DEBUG_DRAM
#define DEBUG_DRAM 0
#define DEBUG_DRAM 1
#endif
#if DEBUG_DRAM
branches/meklort/i386/modules/Memory/spd.h
1010
1111
1212
13
13
14
1415
1516
1617
#include "platform.h"
#include "libsaio.h"
void scan_spd(PlatformInfo_t *p);
bool is_smbus_controller(pci_dt_t* pci_dt);
void scan_spd(PlatformInfo_t *p, pci_dt_t* smbus_controller_dev);
struct smbus_controllers_t {
uint32_tvendor;

Archive Download the corresponding diff file

Revision: 555