Chameleon

Chameleon Svn Source Tree

Root/branches/slice/trunkM/i386/libsaio/smbios.c

1/*
2 * SMBIOS Table Patcher, part of the Chameleon Boot Loader Project
3 *
4 * Copyright 2010 by Islam M. Ahmed Zaid. All rights reserved.
5 *
6 */
7
8
9#include "boot.h"
10#include "bootstruct.h"
11#include "smbios_getters.h"
12
13#ifndef DEBUG_SMBIOS
14#define DEBUG_SMBIOS 0
15#endif
16
17#if DEBUG_SMBIOS
18#define DBG(x...)verbose(x)
19#else
20#define DBG(x...)
21#endif
22
23#define SMBPlist&bootInfo->smbiosConfig
24/* ASSUMPTION: 16KB should be enough for the whole thing */
25#define SMB_ALLOC_SIZE16384
26
27
28//-------------------------------------------------------------------------------------------------------------------------
29// SMBIOS Plist Keys
30//-------------------------------------------------------------------------------------------------------------------------
31/* BIOS Information */
32#define kSMBBIOSInformationVendorKey"SMbiosvendor"
33#define kSMBBIOSInformationVersionKey"SMbiosversion"
34#define kSMBBIOSInformationReleaseDateKey"SMbiosdate"
35
36/* System Information */
37#define kSMBSystemInformationManufacturerKey"SMmanufacturer"
38#define kSMBSystemInformationProductNameKey"SMproductname"
39#define kSMBSystemInformationVersionKey"SMsystemversion"
40#define kSMBSystemInformationSerialNumberKey"SMserial"
41#define kSMBSystemInformationFamilyKey"SMfamily"
42
43/* Base Board */
44#define kSMBBaseBoardManufacturerKey"SMboardmanufacturer"
45#define kSMBBaseBoardProductKey"SMboardproduct"
46
47/* Processor Information */
48#define kSMBProcessorInformationExternalClockKey"SMexternalclock"
49#define kSMBProcessorInformationMaximumClockKey"SMmaximalclock"
50
51/* Memory Device */
52#define kSMBMemoryDeviceDeviceLocatorKey"SMmemdevloc"
53#define kSMBMemoryDeviceBankLocatorKey"SMmembankloc"
54#define kSMBMemoryDeviceMemoryTypeKey"SMmemtype"
55#define kSMBMemoryDeviceMemorySpeedKey"SMmemspeed"
56#define kSMBMemoryDeviceManufacturerKey"SMmemmanufacturer"
57#define kSMBMemoryDeviceSerialNumberKey"SMmemserial"
58#define kSMBMemoryDevicePartNumberKey"SMmempart"
59
60/* Apple Specific */
61#define kSMBOemProcessorTypeKey"SMcputype"
62#define kSMBOemProcessorBusSpeedKey"SMbusspeed"
63
64//-------------------------------------------------------------------------------------------------------------------------
65// Default SMBIOS Data
66//-------------------------------------------------------------------------------------------------------------------------
67/* Rewrite: use a struct */
68
69#define kDefaultVendorManufacturer"Apple Inc."
70#define kDefaultBIOSReleaseDate"11/06/2009"
71#define kDefaultSerialNumber"SOMESRLNMBR"
72#define kDefaultBoardProduct"Mac-F4208DC8"
73#define kDefaultSystemVersion"1.0"
74
75// defaults for a Mac mini
76#define kDefaultMacminiFamily"Macmini"
77#define kDefaultMacmini"Macmini1,1"
78#define kDefaultMacminiBIOSVersion" MM11.88Z.009A.B00.0903051113"
79
80// defaults for a MacBook
81#define kDefaultMacBookFamily"MacBook"
82#define kDefaultMacBook"MacBook4,1"
83#define kDefaultMacBookBIOSVersion" MB41.88Z.0073.B00.0809221748"
84
85// defaults for a MacBook Pro
86#define kDefaultMacBookProFamily"MacBookPro"
87#define kDefaultMacBookPro"MacBookPro5,1"
88#define kDefaultMacBookProBIOSVersion" MBP51.88Z.007E.B05.0906151647"
89
90// defaults for an iMac
91#define kDefaultiMacFamily"iMac"
92#define kDefaultiMac"iMac8,1"
93#define kDefaultiMacBIOSVersion" IM81.88Z.00C1.B00.0903051113"
94// defaults for an iMac11,1 core i3/i5/i7
95#define kDefaultiMacNehalem"iMac11,1"
96#define kDefaultiMacNehalemBIOSVersion" IM111.88Z.0034.B00.0802091538"
97// defaults for an iMac12,1
98#define kDefaultiMacSandy"iMac12,1"
99#define kDefaultiMacSandyBIOSVersion" IM121.88Z.0047.B00.1102091756"
100
101// defaults for a Mac Pro
102#define kDefaultMacProFamily"MacPro"
103#define kDefaultMacPro"MacPro3,1"
104#define kDefaultMacProBIOSVersion" MP31.88Z.006C.B05.0903051113"
105// defaults for a Mac Pro 4,1 core i7/Xeon
106#define kDefaultMacProNehalem"MacPro4,1"
107#define kDefaultMacProNehalemBIOSVersion" MP41.88Z.0081.B04.0903051113"
108// defaults for a Mac Pro 5,1 core i7/Xeon
109#define kDefaultMacProWestmere"MacPro5,1"
110#define kDefaultMacProWestmereBIOSVersion" MP51.88Z.007F.B00.1008031144"
111#define kDefaulMacProWestmereBIOSReleaseDate"08/03/10"
112//-------------------------------------------------------------------------------------------------------------------------
113#define MAX_DMI_TABLES 255
114typedef struct DmiNumAssocTag {
115 SMBStructHeader* dmi;
116 uint8_t type;
117} DmiNumAssoc;
118
119static DmiNumAssoc DmiTablePair[MAX_DMI_TABLES];
120static int DmiTablePairCount = 0;
121static int current_pos=0;
122static bool ftTablePairInit = true; //use twice first run and after
123
124#define getFieldOffset(struct, field)((uint8_t)(uint32_t)&(((struct *)0)->field))
125
126/**
127 * Get a table structure entry from a type specification and a smbios address
128 * return NULL if table is not found
129 */
130void getSmbiosTableStructure(struct SMBEntryPoint *smbios)
131{
132 SMBStructHeader* dmihdr=NULL;
133 SMBByte* p;
134 int i;
135
136 if (ftTablePairInit && smbios!=NULL) {
137 ftTablePairInit = false;
138#if DEBUG_SMBIOS
139 verbose(">>> SMBIOSAddr=0x%08x\n", smbios);
140 verbose(">>> DMI: addr=0x%08x, len=%d, count=%d\n", smbios->dmi.tableAddress,
141smbios->dmi.tableLength, smbios->dmi.structureCount);
142#endif
143 p = (SMBByte *) smbios->dmi.tableAddress;
144 for (i=0;
145 i < smbios->dmi.structureCount &&
146 p + 4 <= (SMBByte *)smbios->dmi.tableAddress + smbios->dmi.tableLength;
147 i++) {
148 dmihdr = (SMBStructHeader *) p;
149
150#if DEBUG_SMBIOS
151 // verbose(">>>>>> DMI(%d): type=0x%02x, len=0x%d\n",i,dmihdr->type,dmihdr->length);
152#endif
153 if (dmihdr->length < 4 || dmihdr->type == 127 /* EOT */) break;
154 if (DmiTablePairCount < MAX_DMI_TABLES) {
155 DmiTablePair[DmiTablePairCount].dmi = dmihdr;
156 DmiTablePair[DmiTablePairCount].type = dmihdr->type;
157 DmiTablePairCount++;
158 }
159 else {
160 verbose("DMI table entries list is full! Next entries won't be stored.\n");
161 }
162#if DEBUG_SMBIOS
163 verbose("DMI header found for table type %d, length = %d\n", dmihdr->type, dmihdr->length);
164#endif
165 p = p + dmihdr->length;
166 while ((p - (SMBByte *)smbios->dmi.tableAddress + 1 < smbios->dmi.tableLength) && (p[0] != 0x00 || p[1] != 0x00)) {
167 p++;
168}
169 p += 2;
170}
171
172 }
173}
174
175typedef struct {
176SMBStructHeader *orig;
177SMBStructHeader *new;
178} SMBStructPtrs;
179
180struct {
181char *vendor;
182char *version;
183char *releaseDate;
184} defaultBIOSInfo;
185
186struct {
187char *manufacturer;
188char *productName;
189char *version;
190char *serialNumber;
191char *family;
192} defaultSystemInfo;
193
194struct {
195char *manufacturer;
196char *product;
197} defaultBaseBoard;
198
199
200typedef struct {
201uint8_ttype;
202SMBValueTypevalueType;
203uint8_tfieldOffset;
204char*keyString;
205bool(*getSMBValue)(returnType *);
206char**defaultValue;
207} SMBValueSetter;
208
209SMBValueSetter SMBSetters[] =
210{
211//-------------------------------------------------------------------------------------------------------------------------
212// BIOSInformation
213//-------------------------------------------------------------------------------------------------------------------------
214{kSMBTypeBIOSInformation,kSMBString,getFieldOffset(SMBBIOSInformation, vendor),kSMBBIOSInformationVendorKey,
215NULL,&defaultBIOSInfo.vendor},
216
217{kSMBTypeBIOSInformation,kSMBString,getFieldOffset(SMBBIOSInformation, version),kSMBBIOSInformationVersionKey,
218NULL,&defaultBIOSInfo.version},
219
220{kSMBTypeBIOSInformation,kSMBString,getFieldOffset(SMBBIOSInformation, releaseDate),kSMBBIOSInformationReleaseDateKey,
221NULL,&defaultBIOSInfo.releaseDate},
222
223//-------------------------------------------------------------------------------------------------------------------------
224// SystemInformation
225//-------------------------------------------------------------------------------------------------------------------------
226{kSMBTypeSystemInformation,kSMBString,getFieldOffset(SMBSystemInformation, manufacturer),kSMBSystemInformationManufacturerKey,
227NULL,&defaultSystemInfo.manufacturer},
228
229{kSMBTypeSystemInformation,kSMBString,getFieldOffset(SMBSystemInformation, productName),kSMBSystemInformationProductNameKey,
230NULL,&defaultSystemInfo.productName},
231
232{kSMBTypeSystemInformation,kSMBString,getFieldOffset(SMBSystemInformation, version),kSMBSystemInformationVersionKey,
233NULL,&defaultSystemInfo.version},
234
235{kSMBTypeSystemInformation,kSMBString,getFieldOffset(SMBSystemInformation, serialNumber),kSMBSystemInformationSerialNumberKey,
236NULL,&defaultSystemInfo.serialNumber},
237
238{kSMBTypeSystemInformation,kSMBString,getFieldOffset(SMBSystemInformation, skuNumber),NULL,
239NULL,NULL},
240
241{kSMBTypeSystemInformation,kSMBString,getFieldOffset(SMBSystemInformation, family),kSMBSystemInformationFamilyKey,
242NULL,&defaultSystemInfo.family},
243
244
245//-------------------------------------------------------------------------------------------------------------------------
246// BaseBoard
247//-------------------------------------------------------------------------------------------------------------------------
248{kSMBTypeBaseBoard,kSMBString,getFieldOffset(SMBBaseBoard, manufacturer),kSMBBaseBoardManufacturerKey,
249NULL,&defaultBaseBoard.manufacturer},
250
251{kSMBTypeBaseBoard,kSMBString,getFieldOffset(SMBBaseBoard, product),kSMBBaseBoardProductKey,
252NULL,&defaultBaseBoard.product},
253
254{kSMBTypeBaseBoard,kSMBString,getFieldOffset(SMBBaseBoard, version),NULL,NULL,NULL},
255
256{kSMBTypeBaseBoard,kSMBString,getFieldOffset(SMBBaseBoard, serialNumber),NULL,NULL,NULL},
257
258{kSMBTypeBaseBoard,kSMBString,getFieldOffset(SMBBaseBoard, assetTagNumber),NULL,NULL,NULL},
259
260{kSMBTypeBaseBoard,kSMBString,getFieldOffset(SMBBaseBoard, locationInChassis),NULL,NULL,NULL},
261//-------------------------------------------------------------------------------------------------------------------------
262// SystemEnclosure
263//-------------------------------------------------------------------------------------------------------------------------
264{kSMBTypeSystemEnclosure,kSMBString,getFieldOffset(SMBSystemEnclosure, manufacturer),
265kSMBBaseBoardManufacturerKey,NULL,&defaultBaseBoard.manufacturer},
266
267//-------------------------------------------------------------------------------------------------------------------------
268// ProcessorInformation
269//-------------------------------------------------------------------------------------------------------------------------
270{kSMBTypeProcessorInformation,kSMBString,getFieldOffset(SMBProcessorInformation, socketDesignation),NULL,NULL,NULL},
271
272{kSMBTypeProcessorInformation,kSMBString,getFieldOffset(SMBProcessorInformation, manufacturer),NULL,NULL,NULL},
273
274{kSMBTypeProcessorInformation,kSMBString,getFieldOffset(SMBProcessorInformation, processorVersion),NULL,NULL,NULL},
275
276{kSMBTypeProcessorInformation,kSMBWord,getFieldOffset(SMBProcessorInformation, externalClock),kSMBProcessorInformationExternalClockKey,
277getProcessorInformationExternalClock,NULL},
278
279{kSMBTypeProcessorInformation,kSMBWord,getFieldOffset(SMBProcessorInformation, maximumClock),kSMBProcessorInformationMaximumClockKey,
280getProcessorInformationMaximumClock,NULL},
281
282{kSMBTypeProcessorInformation,kSMBString,getFieldOffset(SMBProcessorInformation, serialNumber),NULL,NULL,NULL},
283
284{kSMBTypeProcessorInformation,kSMBString,getFieldOffset(SMBProcessorInformation, assetTag),NULL,NULL,NULL},
285
286{kSMBTypeProcessorInformation,kSMBString,getFieldOffset(SMBProcessorInformation, partNumber),NULL,NULL,NULL},
287
288//-------------------------------------------------------------------------------------------------------------------------
289// Memory Device
290//-------------------------------------------------------------------------------------------------------------------------
291{kSMBTypeMemoryDevice,kSMBString,getFieldOffset(SMBMemoryDevice, deviceLocator),kSMBMemoryDeviceDeviceLocatorKey,
292NULL,NULL},
293
294{kSMBTypeMemoryDevice,kSMBString,getFieldOffset(SMBMemoryDevice, bankLocator),kSMBMemoryDeviceBankLocatorKey,
295NULL,NULL},
296
297{kSMBTypeMemoryDevice,kSMBByte,getFieldOffset(SMBMemoryDevice, memoryType),kSMBMemoryDeviceMemoryTypeKey,
298getSMBMemoryDeviceMemoryType,NULL},
299
300{kSMBTypeMemoryDevice,kSMBWord,getFieldOffset(SMBMemoryDevice, memorySpeed),kSMBMemoryDeviceMemorySpeedKey,
301getSMBMemoryDeviceMemorySpeed,NULL},
302
303{kSMBTypeMemoryDevice,kSMBString,getFieldOffset(SMBMemoryDevice, manufacturer),kSMBMemoryDeviceManufacturerKey,
304getSMBMemoryDeviceManufacturer,NULL},
305
306{kSMBTypeMemoryDevice,kSMBString,getFieldOffset(SMBMemoryDevice, serialNumber),kSMBMemoryDeviceSerialNumberKey,
307getSMBMemoryDeviceSerialNumber,NULL},
308
309{kSMBTypeMemoryDevice,kSMBString,getFieldOffset(SMBMemoryDevice, assetTag),NULL,NULL,NULL},
310
311{kSMBTypeMemoryDevice,kSMBString,getFieldOffset(SMBMemoryDevice, partNumber),kSMBMemoryDevicePartNumberKey,
312getSMBMemoryDevicePartNumber,NULL},
313
314
315//-------------------------------------------------------------------------------------------------------------------------
316// Apple Specific
317//-------------------------------------------------------------------------------------------------------------------------
318{kSMBTypeOemProcessorType,kSMBWord,getFieldOffset(SMBOemProcessorType, ProcessorType),kSMBOemProcessorTypeKey,
319getSMBOemProcessorType,NULL},
320
321{kSMBTypeOemProcessorBusSpeed,kSMBWord,getFieldOffset(SMBOemProcessorBusSpeed, ProcessorBusSpeed),kSMBOemProcessorBusSpeedKey,
322getSMBOemProcessorBusSpeed,NULL}
323};
324
325int numOfSetters = sizeof(SMBSetters) / sizeof(SMBValueSetter);
326
327
328SMBEntryPoint *origeps= 0;
329SMBEntryPoint *neweps= 0;
330
331static uint8_t stringIndex;// increament when a string is added and set the field value accordingly
332static uint8_t stringsSize;// add string size
333
334static SMBWord tableLength= 0;
335static SMBWord handle= 0;
336static SMBWord maxStructSize= 0;
337static SMBWord structureCount= 0;
338
339/* Rewrite this function */
340void setDefaultSMBData(void)
341{
342defaultBIOSInfo.vendor= kDefaultVendorManufacturer;
343defaultBIOSInfo.releaseDate= kDefaultBIOSReleaseDate;
344
345defaultSystemInfo.manufacturer= kDefaultVendorManufacturer;
346defaultSystemInfo.version= kDefaultSystemVersion;
347defaultSystemInfo.serialNumber= kDefaultSerialNumber;
348
349defaultBaseBoard.manufacturer= kDefaultVendorManufacturer;
350defaultBaseBoard.product= kDefaultBoardProduct;
351
352if (Platform->Type == 2)//platformCPUFeature(CPU_FEATURE_MOBILE))
353{
354if (vgaVendor != PCI_VENDOR_ID_INTEL) //Slice
355{
356defaultBIOSInfo.version= kDefaultMacBookProBIOSVersion;
357defaultSystemInfo.productName= kDefaultMacBookPro;
358defaultSystemInfo.family= kDefaultMacBookProFamily;
359}
360else
361{
362defaultBIOSInfo.version= kDefaultMacBookBIOSVersion;
363defaultSystemInfo.productName= kDefaultMacBook;
364defaultSystemInfo.family= kDefaultMacBookFamily;
365}
366}
367else
368{
369switch (Platform->CPU.NoCores)
370{
371case 1:
372defaultBIOSInfo.version= kDefaultMacminiBIOSVersion;
373defaultSystemInfo.productName= kDefaultMacmini;
374defaultSystemInfo.family= kDefaultMacminiFamily;
375break;
376
377case 2:
378defaultBIOSInfo.version= kDefaultiMacBIOSVersion;
379defaultSystemInfo.productName= kDefaultiMac;
380defaultSystemInfo.family= kDefaultiMacFamily;
381break;
382default:
383{
384switch (Platform->CPU.Family)
385{
386case 0x06:
387{
388switch (Platform->CPU.Model)
389{
390case CPU_MODEL_FIELDS:// Intel Core i5, i7, Xeon X34xx LGA1156 (45nm)
391case CPU_MODEL_DALES:
392case CPU_MODEL_DALES_32NM:// Intel Core i3, i5 LGA1156 (32nm)
393case 0x19:// ??? Intel Core i5 650 @3.20 GHz
394defaultBIOSInfo.version= kDefaultiMacNehalemBIOSVersion;
395defaultSystemInfo.productName= kDefaultiMacNehalem;
396defaultSystemInfo.family= kDefaultiMacFamily;
397break;
398
399case CPU_MODEL_SANDY:// Intel Core i3, i5, i7 LGA1155 (32nm)
400case CPU_MODEL_SANDY_XEON:// Intel Xeon E3
401defaultBIOSInfo.version= kDefaultiMacSandyBIOSVersion;
402defaultSystemInfo.productName= kDefaultiMacSandy;
403defaultSystemInfo.family= kDefaultiMacFamily;
404break;
405case CPU_MODEL_NEHALEM:// Intel Core i7, Xeon W35xx, Xeon X55xx, Xeon E55xx LGA1366 (45nm)
406case CPU_MODEL_NEHALEM_EX:// Intel Xeon X75xx, Xeon X65xx, Xeon E75xx, Xeon E65x
407defaultBIOSInfo.version= kDefaultMacProNehalemBIOSVersion;
408defaultSystemInfo.productName= kDefaultMacProNehalem;
409defaultSystemInfo.family= kDefaultMacProFamily;
410break;
411
412case CPU_MODEL_WESTMERE:// Intel Core i7, Xeon X56xx, Xeon E56xx, Xeon W36xx LGA1366 (32nm) 6 Core
413case CPU_MODEL_WESTMERE_EX:// Intel Xeon E7
414defaultBIOSInfo.version= kDefaultMacProWestmereBIOSVersion;
415defaultBIOSInfo.releaseDate= kDefaulMacProWestmereBIOSReleaseDate;
416defaultSystemInfo.productName= kDefaultMacProWestmere;
417defaultSystemInfo.family= kDefaultMacProFamily;
418break;
419
420default:
421defaultBIOSInfo.version= kDefaultMacProBIOSVersion;
422defaultSystemInfo.productName= kDefaultMacPro;
423defaultSystemInfo.family= kDefaultMacProFamily;
424break;
425}
426break;
427}
428default:
429defaultBIOSInfo.version= kDefaultMacProBIOSVersion;
430defaultSystemInfo.productName= kDefaultMacPro;
431defaultSystemInfo.family= kDefaultMacProFamily;
432break;
433}
434break;
435}
436}
437}
438}
439
440/* Used for SM*n smbios.plist keys */
441bool getSMBValueForKey(SMBStructHeader *structHeader, const char *keyString, const char **string, returnType *value)
442{
443static int idx = -1;
444static int current = -1;
445int len;
446char key[24];
447
448if (current != structHeader->handle)
449{
450idx++;
451current = structHeader->handle;
452}
453
454sprintf(key, "%s%d", keyString, idx);
455
456if (value)
457if (getIntForKey(key, (int *)&(value->dword), SMBPlist))
458return true;
459else
460if (getValueForKey(key, string, &len, SMBPlist))
461return true;
462return false;
463}
464
465char *getSMBStringForField(SMBStructHeader *structHeader, uint8_t field)
466{
467uint8_t *stringPtr = (uint8_t *)structHeader + structHeader->length;
468
469if (!field)
470return NULL;
471
472for (field--; field != 0 && strlen((char *)stringPtr) > 0;
473field--, stringPtr = (uint8_t *)((uint32_t)stringPtr + strlen((char *)stringPtr) + 1));
474
475return (char *)stringPtr;
476}
477
478void setSMBStringForField(SMBStructHeader *structHeader, const char *string, uint8_t *field)
479{
480int strSize;
481
482if (!field)
483return;
484if (!string)
485{
486*field = 0;
487return;
488}
489
490strSize = strlen(string);
491
492// remove any spaces found at the end
493while ((strSize != 0) && (string[strSize - 1] == ' '))
494strSize--;
495
496if (strSize == 0)
497{
498*field = 0;
499return;
500}
501
502memcpy((uint8_t *)structHeader + structHeader->length + stringsSize, string, strSize);
503*field = stringIndex;
504
505stringIndex++;
506stringsSize += strSize + 1;
507}
508
509bool setSMBValue(SMBStructPtrs *structPtr, int idx, returnType *value)
510{
511const char *string = 0;
512int len;
513bool parsed;
514int val;
515
516if (numOfSetters <= idx)
517return false;
518
519switch (SMBSetters[idx].valueType)
520{
521case kSMBString:
522if (SMBSetters[idx].keyString)
523{
524if (getValueForKey(SMBSetters[idx].keyString, &string, &len, SMBPlist))
525break;
526else
527if (structPtr->orig->type == kSMBTypeMemoryDevice)// MemoryDevice only
528if (getSMBValueForKey(structPtr->orig, SMBSetters[idx].keyString, &string, NULL))
529break;
530}
531if (SMBSetters[idx].getSMBValue)
532if (SMBSetters[idx].getSMBValue((returnType *)&string))
533break;
534if ((SMBSetters[idx].defaultValue) && *(SMBSetters[idx].defaultValue))
535{
536string = *(SMBSetters[idx].defaultValue);
537break;
538}
539string = getSMBStringForField(structPtr->orig, *(uint8_t *)value);
540break;
541
542case kSMBByte:
543case kSMBWord:
544case kSMBDWord:
545//case kSMBQWord:
546if (SMBSetters[idx].keyString)
547{
548parsed = getIntForKey(SMBSetters[idx].keyString, &val, SMBPlist);
549if (!parsed)
550if (structPtr->orig->type == kSMBTypeMemoryDevice)// MemoryDevice only
551parsed = getSMBValueForKey(structPtr->orig, SMBSetters[idx].keyString, NULL, (returnType *)&val);
552if (parsed)
553{
554switch (SMBSetters[idx].valueType)
555{
556case kSMBByte:
557value->byte = (uint8_t)val;
558break;
559case kSMBWord:
560value->word = (uint16_t)val;
561break;
562case kSMBDWord:
563default:
564value->dword = (uint32_t)val;
565break;
566}
567return true;
568}
569}
570
571if (SMBSetters[idx].getSMBValue)
572if (SMBSetters[idx].getSMBValue(value))
573return true;
574#if 0
575if (*(SMBSetters[idx].defaultValue))
576{
577value->dword = *(uint32_t *)(SMBSetters[idx].defaultValue);
578return true;
579}
580#endif
581break;
582}
583
584if (SMBSetters[idx].valueType == kSMBString && string)
585setSMBStringForField(structPtr->new, string, &value->byte);
586
587return true;
588}
589
590//-------------------------------------------------------------------------------------------------------------------------
591// Apple Specific
592//-------------------------------------------------------------------------------------------------------------------------
593void addSMBFirmwareVolume(SMBStructPtrs *structPtr)
594{
595return;
596}
597
598void addSMBMemorySPD(SMBStructPtrs *structPtr)
599{
600/* SPD data from Platform->RAM.spd */
601return;
602}
603
604void addSMBOemProcessorType(SMBStructPtrs *structPtr)
605{
606SMBOemProcessorType *p = (SMBOemProcessorType *)structPtr->new;
607
608p->header.type= kSMBTypeOemProcessorType;
609p->header.length= sizeof(SMBOemProcessorType);
610p->header.handle= handle++;
611
612setSMBValue(structPtr, numOfSetters - 2 , (returnType *)&(p->ProcessorType));
613
614structPtr->new = (SMBStructHeader *)((uint8_t *)structPtr->new + sizeof(SMBOemProcessorType) + 2);
615tableLength += sizeof(SMBOemProcessorType) + 2;
616structureCount++;
617}
618
619void addSMBOemProcessorBusSpeed(SMBStructPtrs *structPtr)
620{
621SMBOemProcessorBusSpeed *p = (SMBOemProcessorBusSpeed *)structPtr->new;
622SMBWord tmp = 0;
623switch (Platform->CPU.Family)
624{
625case 0x06:
626{
627switch (Platform->CPU.Model)
628{
629case 0x19:// ??? Intel Core i5 650 @3.20 GHz
630case CPU_MODEL_FIELDS:// Intel Core i5, i7, Xeon X34xx LGA1156 (45nm)
631case CPU_MODEL_DALES:
632case CPU_MODEL_DALES_32NM:// Intel Core i3, i5 LGA1156 (32nm)
633case CPU_MODEL_NEHALEM:// Intel Core i7, Xeon W35xx, Xeon X55xx, Xeon E55xx LGA1366 (45nm)
634case CPU_MODEL_NEHALEM_EX:// Intel Xeon X75xx, Xeon X65xx, Xeon E75xx, Xeon E65x
635case CPU_MODEL_WESTMERE:// Intel Core i7, Xeon X56xx, Xeon E56xx, Xeon W36xx LGA1366 (32nm) 6 Core
636case CPU_MODEL_WESTMERE_EX:// Intel Xeon E7
637case CPU_MODEL_SANDY:
638case CPU_MODEL_SANDY_XEON:
639tmp = p->ProcessorBusSpeed;
640break;
641
642default:
643tmp = (Platform->CPU.FSBFrequency * 4) / MEGA;
644break;
645//return;
646}
647}
648}
649
650p->header.type= kSMBTypeOemProcessorBusSpeed;
651p->header.length= sizeof(SMBOemProcessorBusSpeed);
652p->header.handle= handle++;
653
654if(!setSMBValue(structPtr, numOfSetters -1, (returnType *)&(p->ProcessorBusSpeed)))
655p->ProcessorBusSpeed = tmp;
656
657structPtr->new = (SMBStructHeader *)((uint8_t *)structPtr->new + sizeof(SMBOemProcessorBusSpeed) + 2);
658tableLength += sizeof(SMBOemProcessorBusSpeed) + 2;
659structureCount++;
660}
661
662//-------------------------------------------------------------------------------------------------------------------------
663// EndOfTable
664//-------------------------------------------------------------------------------------------------------------------------
665void addSMBEndOfTable(SMBStructPtrs *structPtr)
666{
667structPtr->new->type= kSMBTypeEndOfTable;
668structPtr->new->length= sizeof(SMBStructHeader);
669structPtr->new->handle= handle++;
670
671structPtr->new = (SMBStructHeader *)((uint8_t *)structPtr->new + sizeof(SMBStructHeader) + 2);
672tableLength += sizeof(SMBStructHeader) + 2;
673structureCount++;
674}
675
676void setSMBStruct(SMBStructPtrs *structPtr)
677{
678bool setterFound = false;
679
680uint8_t *ptr;
681SMBWord structSize;
682int i;
683
684stringIndex = 1;
685stringsSize = 0;
686
687if (handle < structPtr->orig->handle)
688handle = structPtr->orig->handle;
689
690memcpy((void *)structPtr->new, structPtr->orig, structPtr->orig->length);
691
692for (i = 0; i < numOfSetters; i++)
693if ((structPtr->orig->type == SMBSetters[i].type) && (SMBSetters[i].fieldOffset < structPtr->orig->length))
694{
695setterFound = true;
696setSMBValue(structPtr, i, (returnType *)((uint8_t *)structPtr->new + SMBSetters[i].fieldOffset));
697}
698
699if (setterFound)
700{
701ptr = (uint8_t *)structPtr->new + structPtr->orig->length;
702for (; ((uint16_t *)ptr)[0] != 0; ptr++);
703
704if (((uint16_t *)ptr)[0] == 0)
705ptr += 2;
706
707structSize = ptr - (uint8_t *)structPtr->new;
708}
709else
710{
711ptr = (uint8_t *)structPtr->orig + structPtr->orig->length;
712for (; ((uint16_t *)ptr)[0] != 0; ptr++);
713
714if (((uint16_t *)ptr)[0] == 0)
715ptr += 2;
716
717structSize = ptr - (uint8_t *)structPtr->orig;
718memcpy((void *)structPtr->new, structPtr->orig, structSize);
719}
720
721structPtr->new = (SMBStructHeader *)((uint8_t *)structPtr->new + structSize);
722
723tableLength += structSize;
724
725if (structSize > maxStructSize)
726maxStructSize = structSize;
727
728structureCount++;
729}
730
731void setupNewSMBIOSTable(SMBEntryPoint *eps, SMBStructPtrs *structPtr)
732{
733uint8_t *ptr = (uint8_t *)eps->dmi.tableAddress;
734structPtr->orig = (SMBStructHeader *)ptr;
735
736for (;((eps->dmi.tableAddress + eps->dmi.tableLength) > ((uint32_t)(uint8_t *)structPtr->orig + sizeof(SMBStructHeader)));)
737{
738switch (structPtr->orig->type)
739{
740/* Skip all Apple Specific Structures */
741case kSMBTypeFirmwareVolume:
742case kSMBTypeMemorySPD:
743case kSMBTypeOemProcessorType:
744case kSMBTypeOemProcessorBusSpeed:
745/* And this one too, to be added at the end */
746case kSMBTypeEndOfTable:
747break;
748
749default:
750/* Add */
751setSMBStruct(structPtr);
752break;
753}
754
755ptr = (uint8_t *)((uint32_t)structPtr->orig + structPtr->orig->length);
756for (; ((uint16_t *)ptr)[0] != 0; ptr++);
757
758if (((uint16_t *)ptr)[0] == 0)
759ptr += 2;
760
761structPtr->orig = (SMBStructHeader *)ptr;
762}
763
764addSMBFirmwareVolume(structPtr);
765addSMBMemorySPD(structPtr);
766addSMBOemProcessorType(structPtr);
767addSMBOemProcessorBusSpeed(structPtr);
768
769addSMBEndOfTable(structPtr);
770}
771
772void setupSMBIOSTable(void)
773{
774SMBStructPtrs *structPtr;
775uint8_t *buffer;
776bool setSMB = true;
777
778if (!origeps)
779return;
780
781neweps = origeps;
782
783structPtr = (SMBStructPtrs *)malloc(sizeof(SMBStructPtrs));
784if (!structPtr)
785return;
786
787buffer = malloc(SMB_ALLOC_SIZE);
788if (!buffer)
789return;
790
791bzero(buffer, SMB_ALLOC_SIZE);
792structPtr->new = (SMBStructHeader *)buffer;
793
794getBoolForKey(kSMBIOSdefaults, &setSMB, &bootInfo->chameleonConfig);
795if (setSMB)
796setDefaultSMBData();
797
798setupNewSMBIOSTable(origeps, structPtr);
799
800neweps = (SMBEntryPoint *)AllocateKernelMemory(sizeof(SMBEntryPoint));
801if (!neweps)
802return;
803bzero(neweps, sizeof(SMBEntryPoint));
804
805neweps->anchor[0]= '_';
806neweps->anchor[1]= 'S';
807neweps->anchor[2]= 'M';
808neweps->anchor[3]= '_';
809neweps->entryPointLength= sizeof(SMBEntryPoint);
810neweps->majorVersion= 2;
811neweps->minorVersion= 4;
812neweps->maxStructureSize= maxStructSize;
813neweps->entryPointRevision= 0;
814
815neweps->dmi.anchor[0]= '_';
816neweps->dmi.anchor[1]= 'D';
817neweps->dmi.anchor[2]= 'M';
818neweps->dmi.anchor[3]= 'I';
819neweps->dmi.anchor[4]= '_';
820neweps->dmi.tableLength= tableLength;
821neweps->dmi.tableAddress= AllocateKernelMemory(tableLength);
822neweps->dmi.structureCount= structureCount;
823neweps->dmi.bcdRevision= 0x24;
824
825if (!neweps->dmi.tableAddress)
826return;
827
828memcpy((void *)neweps->dmi.tableAddress, buffer, tableLength);
829
830neweps->dmi.checksum= 0;
831neweps->dmi.checksum= 0x100 - checksum8(&neweps->dmi, sizeof(DMIEntryPoint));
832
833neweps->checksum= 0;
834neweps->checksum= 0x100 - checksum8(neweps, sizeof(SMBEntryPoint));
835
836free(buffer);
837decodeSMBIOSTable(neweps);
838DBG("SMBIOS orig=%x new=%x\n", origeps, neweps);
839}
840
841void *getSmbios(int which)
842{
843switch (which)
844{
845case SMBIOS_ORIGINAL:
846if (!origeps)
847origeps = getAddressOfSmbiosTable();
848return origeps;
849case SMBIOS_PATCHED:
850return neweps;
851}
852
853return 0;
854}
855
856/** Find first original dmi Table with a particular type */
857SMBStructHeader* FindFirstDmiTableOfType(int type, int minlength)
858{
859 current_pos = 0; //static variable
860
861 return FindNextDmiTableOfType(type, minlength);
862};
863
864/** Find next original dmi Table with a particular type */
865SMBStructHeader* FindNextDmiTableOfType(int type, int minlength)
866{
867 int i;
868
869// if (ftTablePairInit) getSmbios(SMBIOS_ORIGINAL);
870
871 for (i=current_pos; i < DmiTablePairCount; i++) {
872 if (type == DmiTablePair[i].type &&
873 DmiTablePair[i].dmi &&
874 DmiTablePair[i].dmi->length >= minlength ) {
875 current_pos = i+1;
876#if DEBUG_SMBIOS
877DBG("SMBIOS table type %d found\n", type);
878printf("Press a key to continue... (DEBUG)\n");
879getchar();
880#endif
881
882 return DmiTablePair[i].dmi;
883 }
884 }
885DBG("SMBIOS table type %d not found\n", type);
886#if DEBUG_ACPI
887printf("Press a key to continue... (DEBUG)\n");
888getchar();
889#endif
890 return NULL; // not found
891};
892
893
894/* Collect any information needed later */
895void readSMBIOSInfo(SMBEntryPoint *eps)
896{
897uint8_t *structPtr = (uint8_t *)eps->dmi.tableAddress;
898SMBStructHeader *structHeader = (SMBStructHeader *)structPtr;
899SMBByte tmp = 0;
900SMBWord tmpW = 0;
901
902//int dimmnbr = 0;
903Platform->DMI.MaxMemorySlots= 0;
904Platform->DMI.CntMemorySlots= 0;
905Platform->DMI.MemoryModules= 0;
906
907for (;((eps->dmi.tableAddress + eps->dmi.tableLength) > ((uint32_t)(uint8_t *)structHeader + sizeof(SMBStructHeader)));)
908{
909switch (structHeader->type)
910{
911case kSMBTypeSystemInformation:
912Platform->UUID = ((SMBSystemInformation *)structHeader)->uuid;
913break;
914//Slice - platform mobility should based on Enclosure but not on CPU type
915case kSMBTypeSystemEnclosure:
916tmp = ((SMBSystemEnclosure *)structHeader)->type;
917Platform->Type = (tmp >=8)?2:1;
918break;
919//Slice - values from DMI/SMBIOS are defined correct if overclocked
920// do not need in complex MSR calculation
921case kSMBTypeProcessorInformation:
922tmpW = ((SMBProcessorInformation *)structHeader)->externalClock;
923Platform->CPU.FSBFrequency = (uint64_t)tmpW * MEGA + (uint64_t)(tmpW % 10) * 110000; //According to Intel 133->133.33MHz
924tmpW = ((SMBProcessorInformation *)structHeader)->currentClock;
925Platform->CPU.CPUFrequency = (uint64_t)tmpW * MEGA + (uint64_t)(tmpW % 10) * 110000;
926msglog("From SMBIOS: FSB=%d CPU=%d\n", Platform->CPU.FSBFrequency, Platform->CPU.CPUFrequency);
927break;
928
929case kSMBTypePhysicalMemoryArray:
930Platform->DMI.MaxMemorySlots += ((SMBPhysicalMemoryArray *)structHeader)->numMemoryDevices;
931break;
932
933/*case kSMBTypeMemoryDevice:
934Platform->DMI.CntMemorySlots++;
935if (((SMBMemoryDevice *)structHeader)->memorySize != 0)
936Platform->DMI.MemoryModules++;
937if (((SMBMemoryDevice *)structHeader)->memorySpeed > 0)
938Platform->RAM.DIMM[dimmnbr].Frequency = ((SMBMemoryDevice *)structHeader)->memorySpeed;
939dimmnbr++;
940break;
941 */
942}
943
944structPtr = (uint8_t *)((uint32_t)structHeader + structHeader->length);
945for (; ((uint16_t *)structPtr)[0] != 0; structPtr++);
946
947if (((uint16_t *)structPtr)[0] == 0)
948structPtr += 2;
949
950structHeader = (SMBStructHeader *)structPtr;
951}
952}
953

Archive Download this file

Revision: 1291