Chameleon

Chameleon Svn Source Tree

Root/branches/slice/i386/libsaio/smbios_patcher.c

1/*
2 * Copyright 2008 mackerintel
3 */
4
5#include "libsaio.h"
6#include "boot.h"
7#include "bootstruct.h"
8#include "acpi.h"
9#include "convert.h"
10#include "efi_tables.h"
11#include "fake_efi.h"
12#include "platform.h"
13#include "smbios_patcher.h"
14#include "SMBIOS.h"
15#include "pci.h"
16
17#ifndef DEBUG_SMBIOS
18#define DEBUG_SMBIOS 0
19#endif
20
21#if DEBUG_SMBIOS
22#define DBG(x...)printf(x)
23#else
24#define DBG(x...)
25#endif
26//Slice - for ACPI patcher templates
27intModelLength = 0;
28charMacModel[8] = "MacBook";
29unsigned int ModelRev = 0x00010001;
30uint64_t smbios_p;
31
32char* gSMBIOSBoardModel;
33
34typedef struct {
35 const char* key;
36 const char* value;
37} SMStrEntryPair;
38//Slice - TODO must be unique UUID for each model?
39/* Random values
4019422392-C343-4A3A-92A3-AB1F0A6C3E52
41E3314823-659D-42B6-B42C-147E4E3484D4
42C3D73A74-809A-4804-A747-DDB934A737D0
43*/
44// defaults for a MacBook
45static const SMStrEntryPair const sm_macbook_defaults[]={
46{"SMbiosvendor","Apple Inc."},
47{"SMbiosversion","MB41.88Z.0073.B00.0809221748"},
48{"SMbiosdate","04/01/2008"},
49{"SMmanufacter","Apple Inc."},
50{"SMproductname","MacBook4,1"},
51{"SMsystemversion","1.0"},
52{"SMserial","SOMESRLNMBR"},
53{"SMfamily","MacBook"},
54{"SMboardmanufacter","Apple Inc."},
55{"SMboardproduct","Mac-F42D89C8"},
56{"SMUUID", "19422392-C343-106B-80A3-001F0A6C3E52"},
57{ "",""}
58};
59
60// defaults for a MacBook Pro
61static const SMStrEntryPair const sm_macbookpro_defaults[]={
62{"SMbiosvendor","Apple Inc."},
63{"SMbiosversion","MBP41.88Z.0073.B00.0809221748"},
64{"SMbiosdate","04/01/2008"},
65{"SMmanufacter","Apple Inc."},
66{"SMproductname","MacBookPro4,1"},
67{"SMsystemversion","1.0"},
68{"SMserial","SOMESRLNMBR"},
69{"SMfamily","MacBookPro"},
70{"SMboardmanufacter","Apple Inc."},
71{"SMboardproduct","Mac-F42D89C8"},
72{"SMUUID", "862F78AF-9B36-106B-807A-00BA8C14A528"},
73{ "",""}
74};
75
76// defaults for a Mac mini
77static const SMStrEntryPair const sm_macmini_defaults[]={
78{"SMbiosvendor","Apple Inc."},
79{"SMbiosversion","MM21.88Z.009A.B00.0706281359"},
80{"SMbiosdate","04/01/2008"},
81{"SMmanufacter","Apple Inc."},
82{"SMproductname","Macmini2,1"},
83{"SMsystemversion","1.0"},
84{"SMserial","SOMESRLNMBR"},
85{"SMfamily","Napa Mac"},
86{"SMboardmanufacter","Apple Inc."},
87{"SMboardproduct","Mac-F4208EAA"},
88{"SMUUID", "862F78AF-9B36-40AF-B67A-ABBA8C14A528"},
89{ "",""}
90};
91
92// defaults for an iMac
93static const SMStrEntryPair const sm_imac_defaults[]={
94{"SMbiosvendor","Apple Inc."},
95{"SMbiosversion","IM91.88Z.00C1.B00.0802091538"},
96{"SMbiosdate","04/01/2008"},
97{"SMmanufacter","Apple Inc."},
98{"SMproductname","iMac9,1"},
99{"SMsystemversion","1.0"},
100{"SMserial","SOMESRLNMBR"},
101{"SMfamily","Mac"},
102{"SMboardmanufacter","Apple Inc."},
103{"SMboardproduct","Mac-F227BEC8"},
104{"SMUUID", "862F78AF-9B36-40AF-B67A-ABBA8C14A528"},
105{ "",""}
106};
107
108// defaults for a Mac Pro
109static const SMStrEntryPair const sm_macpro_defaults[]={
110{"SMbiosvendor","Apple Computer, Inc."},
111{"SMbiosversion","MP31.88Z.006C.B05.0802291410"},
112{"SMbiosdate","04/01/2008"},
113{"SMmanufacter","Apple Computer, Inc."},
114{"SMproductname","MacPro3,1"},
115{"SMsystemversion","1.0"},
116{"SMserial","SOMESRLNMBR"},
117{"SMfamily","MacPro"},
118{"SMboardmanufacter","Apple Computer, Inc."},
119{"SMboardproduct","Mac-F4208DC8"},
120{"SMUUID", "862F78AF-9B36-40AF-B67A-ABBA8C14A528"},
121{ "",""}
122};
123
124// defaults for an iMac11,1 core i3/i5/i7
125static const SMStrEntryPair const sm_imac_core_defaults[]={
126{"SMbiosvendor","Apple Inc."},
127{"SMbiosversion","IM111.88Z.0034.B00.0802091538"},
128{"SMbiosdate","06/01/2009"},
129{"SMmanufacter","Apple Inc."},
130{"SMproductname","iMac11,1"},
131{"SMsystemversion","1.0"},
132{"SMserial","SOMESRLNMBR"},
133{"SMfamily","iMac"},
134{"SMboardmanufacter","Apple Computer, Inc."},
135{"SMboardproduct","Mac-F2268DAE"},
136{"SMUUID", "862F78AF-9B36-40AF-B67A-ABBA8C14A528"},
137{ "",""}
138};
139#if NEVER_USE_MACPRO41
140// defaults for a Mac Pro 4,1 Xeon
141static const SMStrEntryPair const sm_macpro_core_defaults[]={
142{"SMbiosvendor","Apple Computer, Inc."},
143{"SMbiosversion","MP41.88Z.0081.B04.0903051113"},
144{"SMbiosdate","11/06/2009"},
145{"SMmanufacter","Apple Computer, Inc."},
146{"SMproductname","MacPro4,1"},
147{"SMsystemversion","1.0"},
148{"SMserial","SOMESRLNMBR"},
149{"SMfamily","MacPro"},
150{"SMboardmanufacter","Apple Computer, Inc."},
151{"SMboardproduct","Mac-F4208DC8"},
152{"SMUUID", "862F78AF-9B36-40AF-B67A-ABBA8C14A528"},
153{ "",""}
154};
155#endif
156static const char* sm_get_defstr(const char * key, int table_num)
157{
158inti;
159const SMStrEntryPair*sm_defaults;
160
161//if (platformCPUFeature(CPU_FEATURE_MOBILE)) {
162if (Platform->CPU.Mobile) {
163if (Platform->CPU.NoCores > 1) {
164//TODO if NVidia - MBP else MB
165sm_defaults=sm_macbookpro_defaults;
166} else {
167sm_defaults=sm_macbook_defaults;
168}
169} else {
170switch (Platform->CPU.NoCores)
171{
172case 1:
173sm_defaults=sm_macmini_defaults;
174break;
175case 2:
176sm_defaults=sm_imac_defaults;
177break;
178default:
179{
180switch (Platform->CPU.Family)
181{
182case 0x06:
183{
184switch (Platform->CPU.Model)
185{
186case CPU_MODEL_FIELDS: // Intel Core i5, i7 LGA1156 (45nm)
187case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) ???
188case CPU_MODEL_DALES_32NM: // Intel Core i3, i5, i7 LGA1156 (32nm) (Clarkdale, Arrandale)
189case 0x19: // Intel Core i5 650 @3.20 Ghz
190//sm_defaults=sm_imac_defaults;
191//break;
192case CPU_MODEL_NEHALEM:
193case CPU_MODEL_NEHALEM_EX:
194case CPU_MODEL_WESTMERE:
195case CPU_MODEL_WESTMERE_EX:
196sm_defaults=sm_imac_core_defaults;
197break;
198default:
199sm_defaults=sm_imac_core_defaults;
200break;
201}
202break;
203}
204default:
205sm_defaults=sm_macpro_defaults;
206break;
207}
208break;
209}
210}
211}
212
213for (i=0; sm_defaults[i].key[0]; i++) {
214if (!strcmp (sm_defaults[i].key, key)) {
215return sm_defaults[i].value;
216}
217}
218
219// Shouldn't happen
220printf ("Error: no default for '%s' known\n", key);
221sleep (2);
222return "";
223}
224
225static int sm_get_fsb(const char *name, int table_num)
226{
227return Platform->CPU.FSBFrequency/1000000;
228}
229
230static int sm_get_cpu (const char *name, int table_num)
231{
232return Platform->CPU.CPUFrequency/1000000;
233}
234
235static int sm_get_bus_speed (const char *name, int table_num)
236{
237if (Platform->CPU.Vendor == 0x756E6547) // Intel
238{
239switch (Platform->CPU.Family)
240{
241case 0x06:
242{
243switch (Platform->CPU.Model)
244{
245case CPU_MODEL_PENTIUM_M: // Pentium M 0x0D
246case CPU_MODEL_YONAH:// Yonah0x0E
247case CPU_MODEL_MEROM:// Merom0x0F
248case CPU_MODEL_PENRYN:// Penryn0x17
249case CPU_MODEL_ATOM:// Atom 45nm0x1C
250return 0; // TODO: populate bus speed for these processors
251
252//case CPU_MODEL_FIELDS: // Intel Core i5, i7 LGA1156 (45nm)
253//if (strstr(Platform->CPU.BrandString, "Core(TM) i5"))
254//return 2500; // Core i5
255//return 4800; // Core i7
256
257//case CPU_MODEL_NEHALEM: // Intel Core i7 LGA1366 (45nm)
258//case CPU_MODEL_NEHALEM_EX:
259//case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) ???
260//return 4800; // GT/s / 1000
261//
262case CPU_MODEL_WESTMERE_EX: // Intel Core i7 LGA1366 (45nm) 6 Core ???
263return 0; // TODO: populate bus speed for these processors
264
265//case 0x19: // Intel Core i5 650 @3.20 Ghz
266//return 2500; // why? Intel spec says 2.5GT/s
267
268case 0x19: // Intel Core i5 650 @3.20 Ghz
269case CPU_MODEL_NEHALEM: // Intel Core i7 LGA1366 (45nm)
270case CPU_MODEL_FIELDS: // Intel Core i5, i7 LGA1156 (45nm)
271case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) ???
272case CPU_MODEL_DALES_32NM: // Intel Core i3, i5, i7 LGA1156 (32nm)
273case CPU_MODEL_WESTMERE: // Intel Core i7 LGA1366 (32nm) 6 Core
274case CPU_MODEL_NEHALEM_EX: // Intel Core i7 LGA1366 (45nm) 6 Core ???
275{ // thanks to dgobe for i3/i5/i7 bus speed detection
276int nhm_bus = 0x3F;
277static long possible_nhm_bus[] = {0xFF, 0x7F, 0x3F};
278unsigned long did, vid;
279int i;
280
281// Nehalem supports Scrubbing
282// First, locate the PCI bus where the MCH is located
283for(i = 0; i < sizeof(possible_nhm_bus); i++)
284{
285vid = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), 0x00);
286did = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), 0x02);
287vid &= 0xFFFF;
288did &= 0xFF00;
289
290if(vid == 0x8086 && did >= 0x2C00)
291nhm_bus = possible_nhm_bus[i];
292}
293
294unsigned long qpimult, qpibusspeed;
295qpimult = pci_config_read32(PCIADDR(nhm_bus, 2, 1), 0x50);
296qpimult &= 0x7F;
297DBG("qpimult %d\n", qpimult);
298qpibusspeed = (qpimult * 2 * (Platform->CPU.FSBFrequency/1000000));
299// Rek: rounding decimals to match original mac profile info
300if (qpibusspeed%100 != 0)qpibusspeed = ((qpibusspeed+50)/100)*100;
301DBG("qpibusspeed %d\n", qpibusspeed);
302return qpibusspeed;
303}
304}
305}
306}
307}
308return 0;
309}
310
311static int sm_get_simplecputype()
312{
313if (Platform->CPU.NoCores >= 4)
314{
315return 0x0501; // Quad-Core Xeon
316}
317else if (Platform->CPU.NoCores == 1)
318{
319return 0x0201; // Core Solo
320};
321
322return 0x0301; // Core 2 Duo
323}
324
325static int sm_get_cputype (const char *name, int table_num)
326{
327static bool done = false;
328
329if (Platform->CPU.Vendor == 0x756E6547) // Intel
330{
331if (!done) {
332verbose("CPU is %s, family 0x%x, model 0x%x\n", Platform->CPU.BrandString, Platform->CPU.Family, Platform->CPU.Model);
333done = true;
334}
335
336switch (Platform->CPU.Family)
337{
338case 0x06:
339{
340switch (Platform->CPU.Model)
341{
342case CPU_MODEL_PENTIUM_M: // Pentium M = 0x0D
343return 0x0101;
344case CPU_MODEL_YONAH: // Yonah
345case CPU_MODEL_MEROM: // Merom
346case CPU_MODEL_PENRYN: // Penryn
347case CPU_MODEL_ATOM: // Intel Atom (45nm)
348return sm_get_simplecputype();
349
350case CPU_MODEL_NEHALEM: // Intel Core i7 LGA1366 (45nm)
351return 0x0701; // Core i7
352
353case CPU_MODEL_FIELDS: // Lynnfield, Clarksfield, Jasper
354if (strstr(Platform->CPU.BrandString, "Core(TM) i5"))
355return 0x601; // Core i5
356return 0x701; // Core i7
357
358case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) (Havendale, Auburndale)
359if (strstr(Platform->CPU.BrandString, "Core(TM) i5"))
360return 0x601; // Core i5
361return 0x0701; // Core i7
362
363case CPU_MODEL_DALES_32NM: // Intel Core i3, i5, i7 LGA1156 (32nm) (Clarkdale, Arrandale)
364if (strstr(Platform->CPU.BrandString, "Core(TM) i3"))
365return 0x901; // Core i3
366if (strstr(Platform->CPU.BrandString, "Core(TM) i5"))
367return 0x601; // Core i5
368return 0x0701; // Core i7
369
370case CPU_MODEL_WESTMERE: // Intel Core i7 LGA1366 (32nm) 6 Core (Gulftown, Westmere-EP, Westmere-WS)
371case CPU_MODEL_WESTMERE_EX: // Intel Core i7 LGA1366 (45nm) 6 Core ???
372return 0x0701; // Core i7
373
374case 0x19: // Intel Core i5 650 @3.20 Ghz
375return 0x601; // Core i5
376}
377}
378}
379}
380
381return sm_get_simplecputype();
382}
383
384static int sm_get_memtype (const char *name, int table_num)
385{
386intmap;
387
388if (table_num < MAX_RAM_SLOTS) {
389map = Platform->DMI.DIMM[table_num];
390if (Platform->RAM.DIMM[map].InUse && Platform->RAM.DIMM[map].Type != 0) {
391 DBG("RAM Detected Type = %d\n", Platform->RAM.DIMM[map].Type);
392 return Platform->RAM.DIMM[map].Type;
393}
394}
395
396return SMB_MEM_TYPE_DDR2;
397}
398
399static int sm_get_memspeed (const char *name, int table_num)
400{
401intmap;
402
403if (table_num < MAX_RAM_SLOTS) {
404map = Platform->DMI.DIMM[table_num];
405if (Platform->RAM.DIMM[map].InUse && Platform->RAM.DIMM[map].Frequency != 0) {
406 DBG("RAM Detected Freq = %d Mhz\n", Platform->RAM.DIMM[map].Frequency);
407 return Platform->RAM.DIMM[map].Frequency;
408}
409}
410
411return 800;
412}
413
414static const char *sm_get_memvendor (const char *name, int table_num)
415{
416intmap;
417
418if (table_num < MAX_RAM_SLOTS) {
419map = Platform->DMI.DIMM[table_num];
420if (Platform->RAM.DIMM[map].InUse && strlen(Platform->RAM.DIMM[map].Vendor) > 0) {
421DBG("RAM Detected Vendor[%d]='%s'\n", table_num, Platform->RAM.DIMM[map].Vendor);
422return Platform->RAM.DIMM[map].Vendor;
423}
424}
425return "N/A";
426}
427
428static const char *sm_get_memserial (const char *name, int table_num)
429{
430intmap;
431
432if (table_num < MAX_RAM_SLOTS) {
433map = Platform->DMI.DIMM[table_num];
434if (Platform->RAM.DIMM[map].InUse && strlen(Platform->RAM.DIMM[map].SerialNo) > 0) {
435 DBG("name = %s, map=%d, RAM Detected SerialNo[%d]='%s'\n", name ? name : "",
436 map, table_num, Platform->RAM.DIMM[map].SerialNo);
437 return Platform->RAM.DIMM[map].SerialNo;
438}
439}
440return "N/A";
441}
442
443static const char *sm_get_mempartno (const char *name, int table_num)
444{
445intmap;
446
447if (table_num < MAX_RAM_SLOTS) {
448map = Platform->DMI.DIMM[table_num];
449if (Platform->RAM.DIMM[map].InUse && strlen(Platform->RAM.DIMM[map].PartNo) > 0) {
450DBG("Ram Detected PartNo[%d]='%s'\n", table_num, Platform->RAM.DIMM[map].PartNo);
451return Platform->RAM.DIMM[map].PartNo;
452}
453}
454return "N/A";
455}
456
457static int sm_one (int tablen)
458{
459return 1;
460}
461
462struct smbios_property smbios_properties[]=
463{
464{.name="SMbiosvendor",.table_type= 0,.value_type=SMSTRING,.offset=0x04,.auto_str=sm_get_defstr},
465{.name="SMbiosversion",.table_type= 0,.value_type=SMSTRING,.offset=0x05,.auto_str=sm_get_defstr},
466{.name="SMbiosdate",.table_type= 0,.value_type=SMSTRING,.offset=0x08,.auto_str=sm_get_defstr},
467{.name="SMmanufacter",.table_type= 1,.value_type=SMSTRING,.offset=0x04,.auto_str=sm_get_defstr},
468{.name="SMproductname",.table_type= 1,.value_type=SMSTRING,.offset=0x05,.auto_str=sm_get_defstr},
469{.name="SMsystemversion",.table_type= 1,.value_type=SMSTRING,.offset=0x06,.auto_str=sm_get_defstr},
470{.name="SMserial",.table_type= 1,.value_type=SMSTRING,.offset=0x07,.auto_str=sm_get_defstr},
471{.name="SMUUID",.table_type= 1, .value_type=SMOWORD,.offset=0x08,.auto_oword=sm_get_defstr},
472{.name="SMfamily",.table_type= 1,.value_type=SMSTRING,.offset=0x1a,.auto_str=sm_get_defstr},
473{.name="SMboardmanufacter",.table_type= 2, .value_type=SMSTRING,.offset=0x04,.auto_str=sm_get_defstr},
474{.name="SMboardproduct",.table_type= 2, .value_type=SMSTRING,.offset=0x05,.auto_str=sm_get_defstr},
475{.name="SMexternalclock",.table_type= 4,.value_type=SMWORD,.offset=0x12,.auto_int=sm_get_fsb},
476{.name="SMmaximalclock",.table_type= 4,.value_type=SMWORD,.offset=0x14,.auto_int=sm_get_cpu},
477{.name="SMmemdevloc",.table_type=17,.value_type=SMSTRING,.offset=0x10,.auto_str=0},
478{.name="SMmembankloc",.table_type=17,.value_type=SMSTRING,.offset=0x11,.auto_str=0},
479{.name="SMmemtype",.table_type=17,.value_type=SMBYTE,.offset=0x12,.auto_int=sm_get_memtype},
480{.name="SMmemspeed",.table_type=17,.value_type=SMWORD,.offset=0x15,.auto_int=sm_get_memspeed},
481{.name="SMmemmanufacter",.table_type=17,.value_type=SMSTRING,.offset=0x17,.auto_str=sm_get_memvendor},
482{.name="SMmemserial",.table_type=17,.value_type=SMSTRING,.offset=0x18,.auto_str=sm_get_memserial},
483{.name="SMmempart",.table_type=17,.value_type=SMSTRING,.offset=0x1A,.auto_str=sm_get_mempartno},
484{.name="SMcputype",.table_type=131,.value_type=SMWORD,.offset=0x04,.auto_int=sm_get_cputype},
485{.name="SMbusspeed",.table_type=132,.value_type=SMWORD,.offset=0x04,.auto_int=sm_get_bus_speed}
486};
487
488struct smbios_table_description smbios_table_descriptions[]=
489{
490{.type=kSMBTypeBIOSInformation,.len=0x18,.numfunc=sm_one},
491{.type=kSMBTypeSystemInformation,.len=0x1b,.numfunc=sm_one},
492{.type=kSMBTypeBaseBoard,.len=0x0f,.numfunc=sm_one}, //except kSMBBaseBoardProcessorMemoryModule
493{.type=kSMBTypeProcessorInformation,.len=0x2a,.numfunc=sm_one},
494//kSMBTypeMemoryModule len=12 obsolete but Used by AppleSMBIOS
495//kSMBTypeSystemSlot len=13 Used by AppleSMBIOS
496//kSMBTypePhysicalMemoryArray len=15 Used by AppleSMBIOS
497{.type=kSMBTypeMemoryDevice,.len=0x24,.numfunc=0},
498//Slice - we are not ready to fill the data
499//{.type=kSMBTypeFirmwareVolume,.len=0x56,.numfunc=0},
500//{.type=kSMBTypeMemorySPD,.len=0x0c,.numfunc=0},
501{.type=kSMBTypeOemProcessorType,.len=0x06,.numfunc=sm_one},
502{.type=kSMBTypeOemProcessorBusSpeed,.len=0x06,.numfunc=sm_one}
503};
504/* Apple known types
505 enum {
506 kSMBTypeBIOSInformation = 0,
507 kSMBTypeSystemInformation = 1,
508 kSMBTypeBaseBoard = 2,
509 kSMBTypeSystemEnclosure = 3,
510 kSMBTypeProcessorInformation = 4,
511 kSMBTypeMemoryModule = 6,
512 kSMBTypeCacheInformation = 7,
513 kSMBTypeSystemSlot = 9,
514 kSMBTypePhysicalMemoryArray = 16,
515 kSMBTypeMemoryDevice = 17,
516 kSMBType32BitMemoryErrorInfo = 18,
517 kSMBType64BitMemoryErrorInfo = 33,
518
519 // Apple Specific Structures
520kSMBTypeFirmwareVolume = 128,
521kSMBTypeMemorySPD = 130,
522kSMBTypeOemProcessorType = 131,
523kSMBTypeOemProcessorBusSpeed = 132
524};
525
526 */
527
528// getting smbios addr with fast compare ops, late checksum testing ...
529#define COMPARE_DWORD(a,b) ( *((u_int32_t *) a) == *((u_int32_t *) b) )
530static const char * const SMTAG = "_SM_";
531static const char* const DMITAG= "_DMI_";
532
533static struct SMBEntryPoint *getAddressOfSmbiosTable(void)
534{
535struct SMBEntryPoint*smbios;
536/*
537 * The logic is to start at 0xf0000 and end at 0xfffff iterating 16 bytes at a time looking
538 * for the SMBIOS entry-point structure anchor (literal ASCII "_SM_").
539 */
540smbios = (struct SMBEntryPoint*) SMBIOS_RANGE_START;
541while (smbios <= (struct SMBEntryPoint *)SMBIOS_RANGE_END) {
542 if (COMPARE_DWORD(smbios->anchor, SMTAG) &&
543 COMPARE_DWORD(smbios->dmi.anchor, DMITAG) &&
544 smbios->dmi.anchor[4]==DMITAG[4] &&
545 checksum8(smbios, sizeof(struct SMBEntryPoint)) == 0)
546 {
547 return smbios;
548 }
549 smbios = (struct SMBEntryPoint*) ( ((char*) smbios) + 16 );
550}
551printf("ERROR: Unable to find SMBIOS!\n");
552pause();
553return NULL;
554}
555
556/** Compute necessary space requirements for new smbios */
557static struct SMBEntryPoint *smbios_dry_run(struct SMBEntryPoint *origsmbios)
558{
559struct SMBEntryPoint*ret;
560char*smbiostables;
561char*tablesptr;
562intorigsmbiosnum;
563inti, j;
564inttablespresent[256];
565booldo_auto=true;
566
567bzero(tablespresent, sizeof(tablespresent));
568
569getBoolForKey(kSMBIOSdefaults, &do_auto, &bootInfo->bootConfig);
570
571ret = (struct SMBEntryPoint *)AllocateKernelMemory(sizeof(struct SMBEntryPoint));
572if (origsmbios) {
573smbiostables = (char *)origsmbios->dmi.tableAddress;
574origsmbiosnum = origsmbios->dmi.structureCount;
575} else {
576smbiostables = NULL;
577origsmbiosnum = 0;
578}
579
580// _SM_
581ret->anchor[0] = 0x5f;
582ret->anchor[1] = 0x53;
583ret->anchor[2] = 0x4d;
584ret->anchor[3] = 0x5f;
585ret->entryPointLength = sizeof(*ret);
586ret->majorVersion = 2;
587ret->minorVersion = 1;
588ret->maxStructureSize = 0; // will be calculated later in this function
589ret->entryPointRevision = 0;
590for (i=0;i<5;i++) {
591ret->formattedArea[i] = 0;
592}
593//_DMI_
594ret->dmi.anchor[0] = 0x5f;
595ret->dmi.anchor[1] = 0x44;
596ret->dmi.anchor[2] = 0x4d;
597ret->dmi.anchor[3] = 0x49;
598ret->dmi.anchor[4] = 0x5f;
599ret->dmi.tableLength = 0; // will be calculated later in this function
600ret->dmi.tableAddress = 0; // will be initialized in smbios_real_run()
601ret->dmi.structureCount = 0; // will be calculated later in this function
602ret->dmi.bcdRevision = 0x21;
603tablesptr = smbiostables;
604
605 // add stringlen of overrides to original stringlen, update maxStructure size adequately,
606 // update structure count and tablepresent[type] with count of type.
607if (smbiostables) {
608for (i=0; i<origsmbiosnum; i++) {
609struct smbios_table_header*cur = (struct smbios_table_header *)tablesptr;
610char*stringsptr;
611intstringlen;
612
613tablesptr += cur->length;
614stringsptr = tablesptr;
615for (; tablesptr[0]!=0 || tablesptr[1]!=0; tablesptr++);
616tablesptr += 2;
617stringlen = tablesptr - stringsptr - 1;
618if (stringlen == 1) {
619stringlen = 0;
620}
621for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
622const char*str;
623intsize;
624charaltname[40];
625
626sprintf(altname, "%s_%d",smbios_properties[j].name, tablespresent[cur->type] + 1);
627if (smbios_properties[j].table_type == cur->type &&
628 smbios_properties[j].value_type == SMSTRING &&
629 (getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig) ||
630 getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)))
631{
632stringlen += size + 1;
633} else if (smbios_properties[j].table_type == cur->type &&
634 smbios_properties[j].value_type == SMSTRING &&
635 do_auto && smbios_properties[j].auto_str)
636{
637stringlen += strlen(smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[cur->type])) + 1;
638}
639}
640if (stringlen == 0) {
641stringlen = 1;
642}
643stringlen++;
644if (ret->maxStructureSize < cur->length+stringlen) {
645ret->maxStructureSize=cur->length+stringlen;
646}
647ret->dmi.tableLength += cur->length+stringlen;
648ret->dmi.structureCount++;
649tablespresent[cur->type]++;
650}
651}
652 // Add eventually table types whose detected count would be < required count, and update ret header with:
653 // new stringlen addons, structure count, and tablepresent[type] count adequately
654for (i=0; i<sizeof(smbios_table_descriptions)/sizeof(smbios_table_descriptions[0]); i++) {
655intnumnec=-1;
656charbuffer[40];
657
658sprintf(buffer, "SMtable%d", i);
659if (!getIntForKey(buffer, &numnec, &bootInfo->smbiosConfig)) {
660numnec = -1;
661}
662if (numnec==-1 && do_auto && smbios_table_descriptions[i].numfunc) {
663numnec = smbios_table_descriptions[i].numfunc(smbios_table_descriptions[i].type);
664}
665while (tablespresent[smbios_table_descriptions[i].type] < numnec) {
666intstringlen = 0;
667for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
668const char*str;
669intsize;
670charaltname[40];
671
672sprintf(altname, "%s_%d",smbios_properties[j].name, tablespresent[smbios_table_descriptions[i].type] + 1);
673if (smbios_properties[j].table_type == smbios_table_descriptions[i].type &&
674 smbios_properties[j].value_type == SMSTRING &&
675 (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
676 getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig)))
677{
678stringlen += size + 1;
679} else if (smbios_properties[j].table_type == smbios_table_descriptions[i].type &&
680 smbios_properties[j].value_type==SMSTRING &&
681 do_auto && smbios_properties[j].auto_str)
682{
683stringlen += strlen(smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[smbios_table_descriptions[i].type])) + 1;
684}
685}
686if (stringlen == 0) {
687stringlen = 1;
688}
689stringlen++;
690if (ret->maxStructureSize < smbios_table_descriptions[i].len+stringlen) {
691ret->maxStructureSize = smbios_table_descriptions[i].len + stringlen;
692}
693ret->dmi.tableLength += smbios_table_descriptions[i].len + stringlen;
694ret->dmi.structureCount++;
695tablespresent[smbios_table_descriptions[i].type]++;
696}
697}
698return ret;
699}
700
701/** From the origsmbios detected by getAddressOfSmbiosTable() to newsmbios whose entrypoint
702 * struct has been created by smbios_dry_run, update each table struct content of new smbios
703 * int the new allocated table address of size newsmbios->tablelength.
704 */
705static void smbios_real_run(struct SMBEntryPoint * origsmbios, struct SMBEntryPoint * newsmbios)
706{
707char *smbiostables;
708char *tablesptr, *newtablesptr;
709int origsmbiosnum=0;
710// bitmask of used handles
711uint8_t handles[8192];
712uint16_t nexthandle=0;
713int i, j;
714int tablespresent[256];
715bool do_auto=true;
716
717 static bool done = false; // IMPROVEME: called twice via getSmbios(), but only the second call can get all necessary info !
718
719extern void dumpPhysAddr(const char * title, void * a, int len);
720
721bzero(tablespresent, sizeof(tablespresent));
722bzero(handles, sizeof(handles));
723
724getBoolForKey(kSMBIOSdefaults, &do_auto, &bootInfo->bootConfig);
725
726newsmbios->dmi.tableAddress = (uint32_t)AllocateKernelMemory(newsmbios->dmi.tableLength);
727if (origsmbios) {
728smbiostables = (char *)origsmbios->dmi.tableAddress;
729origsmbiosnum = origsmbios->dmi.structureCount;
730} else {
731smbiostables = NULL;
732origsmbiosnum = 0;
733}
734tablesptr = smbiostables;
735newtablesptr = (char *)newsmbios->dmi.tableAddress;
736
737 // if old smbios exists then update new smbios with old smbios original content first
738if (smbiostables) {
739for (i=0; i<origsmbiosnum; i++) {
740struct smbios_table_header*oldcur = (struct smbios_table_header *) tablesptr;
741struct smbios_table_header*newcur = (struct smbios_table_header *) newtablesptr;
742char*stringsptr;
743intnstrings = 0;
744
745handles[(oldcur->handle) / 8] |= 1 << ((oldcur->handle) % 8);
746
747 // copy table length from old table to new table but not the old strings
748memcpy(newcur,oldcur, oldcur->length);
749
750tablesptr += oldcur->length;
751stringsptr = tablesptr;
752newtablesptr += oldcur->length;
753
754 // calculate the number of strings in the old content
755for (;tablesptr[0]!=0 || tablesptr[1]!=0; tablesptr++) {
756if (tablesptr[0] == 0) {
757nstrings++;
758}
759}
760if (tablesptr != stringsptr) {
761nstrings++;
762}
763tablesptr += 2;
764
765 // copy the old strings to new table
766memcpy(newtablesptr, stringsptr, tablesptr-stringsptr);
767
768 // point to next possible space for a string (deducting the second 0 char at the end)
769newtablesptr += tablesptr - stringsptr - 1;
770 if (nstrings == 0) { // if no string was found rewind to the first 0 char of the 0,0 terminator
771newtablesptr--;
772}
773
774 // now for each property in the table update the overrides if any (auto or user)
775for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
776const char*str;
777intsize;
778intnum;
779charaltname[40];
780
781sprintf(altname, "%s_%d", smbios_properties[j].name, tablespresent[newcur->type] + 1);
782if (smbios_properties[j].table_type == newcur->type) {
783switch (smbios_properties[j].value_type) {
784case SMSTRING:
785if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
786 getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
787{
788memcpy(newtablesptr, str, size);
789newtablesptr[size] = 0;
790newtablesptr += size + 1;
791*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
792} else if (do_auto && smbios_properties[j].auto_str) {
793str = smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]);
794size = strlen(str);
795memcpy(newtablesptr, str, size);
796newtablesptr[size] = 0;
797newtablesptr += size + 1;
798*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
799}
800break;
801
802case SMOWORD:
803if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
804 getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
805{
806//intk=0, t=0, kk=0;
807//const char*ptr = str;
808verbose("Set SMUUID to %s\n", str);
809//memset(((char*)newcur) + smbios_properties[j].offset, 0, 16);
810EFI_GUID* p = getUUIDFromString(str);
811memcpy(((char*)newcur) + smbios_properties[j].offset, p, 16);
812/*
813while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n')) {
814ptr++;
815}
816if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X')) {
817ptr += 2;
818}
819for (;ptr-str<size && *ptr && k<16;ptr++) {
820if (*ptr=='-') {
821continue; //Slice - ignore "-" inside UUID string
822}
823if (*ptr>='0' && *ptr<='9') {
824(t=(t<<4)|(*ptr-'0')),kk++;
825}
826if (*ptr>='a' && *ptr<='f') {
827(t=(t<<4)|(*ptr-'a'+10)),kk++;
828}
829if (*ptr>='A' && *ptr<='F') {
830(t=(t<<4)|(*ptr-'A'+10)),kk++;
831}
832if (kk == 2) {
833*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset + k)) = t;
834k++;
835kk = 0;
836t = 0;
837}
838}
839 */
840}
841break;
842
843case SMBYTE:
844if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
845 getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
846{
847*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
848} else if (do_auto && smbios_properties[j].auto_int) {
849*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
850}
851break;
852
853case SMWORD:
854if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
855 getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
856{
857*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
858} else if (do_auto && smbios_properties[j].auto_int) {
859*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
860}
861break;
862}
863}
864}
865if (nstrings == 0) {
866newtablesptr[0] = 0;
867newtablesptr++;
868}
869newtablesptr[0] = 0;
870newtablesptr++;
871tablespresent[newcur->type]++;
872}
873}
874
875 // for each eventual complementary table not present in the original smbios, do the overrides
876for (i=0; i<sizeof(smbios_table_descriptions)/sizeof(smbios_table_descriptions[0]); i++) {
877intnumnec = -1;
878charbuffer[40];
879
880sprintf(buffer, "SMtable%d", i);
881if (!getIntForKey(buffer, &numnec, &bootInfo->smbiosConfig)) {
882numnec = -1;
883}
884if (numnec == -1 && do_auto && smbios_table_descriptions[i].numfunc) {
885numnec = smbios_table_descriptions[i].numfunc(smbios_table_descriptions[i].type);
886}
887while (tablespresent[smbios_table_descriptions[i].type] < numnec) {
888struct smbios_table_header*newcur = (struct smbios_table_header *) newtablesptr;
889intnstrings = 0;
890
891memset(newcur,0, smbios_table_descriptions[i].len);
892while (handles[(nexthandle)/8] & (1 << ((nexthandle) % 8))) {
893nexthandle++;
894}
895newcur->handle = nexthandle;
896handles[nexthandle / 8] |= 1 << (nexthandle % 8);
897newcur->type = smbios_table_descriptions[i].type;
898newcur->length = smbios_table_descriptions[i].len;
899newtablesptr += smbios_table_descriptions[i].len;
900for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
901const char*str;
902intsize;
903intnum;
904charaltname[40];
905
906sprintf(altname, "%s_%d", smbios_properties[j].name, tablespresent[newcur->type] + 1);
907if (smbios_properties[j].table_type == newcur->type) {
908switch (smbios_properties[j].value_type) {
909case SMSTRING:
910if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
911 getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
912{
913memcpy(newtablesptr, str, size);
914newtablesptr[size] = 0;
915newtablesptr += size + 1;
916*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
917} else if (do_auto && smbios_properties[j].auto_str) {
918str = smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]);
919size = strlen(str);
920memcpy(newtablesptr, str, size);
921newtablesptr[size] = 0;
922newtablesptr += size + 1;
923*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
924}
925break;
926
927case SMOWORD:
928if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
929 getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
930{
931EFI_GUID* p = getUUIDFromString(str);
932memcpy(((char*)newcur) + smbios_properties[j].offset, p, 16);
933/*
934intk=0, t=0, kk=0;
935const char*ptr = str;
936verbose("Set SMUUID to %s\n", str);
937
938memset(((char*)newcur) + smbios_properties[j].offset, 0, 16);
939while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n')) {
940ptr++;
941}
942if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X')) {
943ptr += 2;
944}
945for (;ptr-str<size && *ptr && k<16;ptr++) {
946if (*ptr=='-') {
947continue; //Slice - ignore "-" inside UUID string
948}
949if (*ptr>='0' && *ptr<='9') {
950(t=(t<<4)|(*ptr-'0')),kk++;
951}
952if (*ptr>='a' && *ptr<='f') {
953(t=(t<<4)|(*ptr-'a'+10)),kk++;
954}
955if (*ptr>='A' && *ptr<='F') {
956(t=(t<<4)|(*ptr-'A'+10)),kk++;
957}
958if (kk == 2) {
959*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset + k)) = t;
960k++;
961kk = 0;
962t = 0;
963}
964}
965 */
966}
967break;
968
969case SMBYTE:
970if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
971 getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
972{
973*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
974} else if (do_auto && smbios_properties[j].auto_int) {
975*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
976}
977break;
978
979case SMWORD:
980if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
981 getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
982{
983*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
984} else if (do_auto && smbios_properties[j].auto_int) {
985*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
986}
987break;
988}
989}
990}
991if (nstrings == 0) {
992newtablesptr[0] = 0;
993newtablesptr++;
994}
995newtablesptr[0] = 0;
996newtablesptr++;
997tablespresent[smbios_table_descriptions[i].type]++;
998}
999}
1000
1001 // calculate new checksums
1002newsmbios->dmi.checksum = 0;
1003newsmbios->dmi.checksum = 256 - checksum8(&newsmbios->dmi, sizeof(newsmbios->dmi));
1004newsmbios->checksum = 0;
1005newsmbios->checksum = 256 - checksum8(newsmbios, sizeof(*newsmbios));
1006
1007if (!done) {
1008verbose("Patched DMI Table\n");
1009done=true;
1010}
1011}
1012
1013#define MAX_DMI_TABLES 96
1014typedef struct DmiNumAssocTag {
1015 struct DMIHeader * dmi;
1016 uint8_t type;
1017} DmiNumAssoc;
1018
1019static DmiNumAssoc DmiTablePair[MAX_DMI_TABLES];
1020static int DmiTablePairCount = 0;
1021static int current_pos=0;
1022static bool ftTablePairInit = true; //use twice first run and after
1023
1024/**
1025 * Get a table structure entry from a type specification and a smbios address
1026 * return NULL if table is not found
1027 */
1028static void getSmbiosTableStructure(struct SMBEntryPoint *smbios)
1029{
1030 struct DMIHeader * dmihdr=NULL;
1031 SMBByte* p;
1032 int i;
1033
1034 if (ftTablePairInit && smbios!=NULL) {
1035 ftTablePairInit = false;
1036#if DEBUG_SMBIOS
1037 printf(">>> SMBIOSAddr=0x%08x\n", smbios);
1038 printf(">>> DMI: addr=0x%08x, len=%d, count=%d\n", smbios->dmi.tableAddress,
1039 smbios->dmi.tableLength, smbios->dmi.structureCount);
1040#endif
1041 p = (SMBByte *) smbios->dmi.tableAddress;
1042 for (i=0;
1043 i < smbios->dmi.structureCount &&
1044 p + 4 <= (SMBByte *)smbios->dmi.tableAddress + smbios->dmi.tableLength;
1045 i++) {
1046 dmihdr = (struct DMIHeader *) p;
1047
1048#if DEBUG_SMBIOS
1049 // verbose(">>>>>> DMI(%d): type=0x%02x, len=0x%d\n",i,dmihdr->type,dmihdr->length);
1050#endif
1051 if (dmihdr->length < 4 || dmihdr->type == 127 /* EOT */) break;
1052 if (DmiTablePairCount < MAX_DMI_TABLES) {
1053 DmiTablePair[DmiTablePairCount].dmi = dmihdr;
1054 DmiTablePair[DmiTablePairCount].type = dmihdr->type;
1055 DmiTablePairCount++;
1056 }
1057 else {
1058 printf("DMI table entries list is full! Next entries won't be stored.\n");
1059 }
1060#if DEBUG_SMBIOS
1061 printf("DMI header found for table type %d, length = %d\n", dmihdr->type, dmihdr->length);
1062#endif
1063 p = p + dmihdr->length;
1064 while ((p - (SMBByte *)smbios->dmi.tableAddress + 1 < smbios->dmi.tableLength) && (p[0] != 0x00 || p[1] != 0x00)) {
1065 p++;
1066 }
1067 p += 2;
1068}
1069
1070 }
1071}
1072
1073void getSmbiosMacModel(void)
1074{
1075#define MAX_MODEL_LEN32
1076
1077//Slice - I want to use MacModel for ACPITables so I need char* representation
1078const char*value = getStringForKey("SMproductname", &bootInfo->smbiosConfig);
1079int i, n=0, first=0, rev1=0, rev2=0;
1080for (i=0; i<8; i++)
1081{
1082char c = value[i];
1083if (isalpha(c))
1084{
1085MacModel[i]=c;
1086n++;
1087} else
1088if ((c) >= '0' && (c) <= '9')
1089{
1090if (first)
1091{
1092rev1 = rev1 * 10 + (int)(c) & 0xf;
1093} else
1094rev2 = rev2 * 10 + (int)(c) & 0xf;
1095} else
1096first = 1;
1097//printf("char=%c first=%d rev1=%d rev2=%d\n", c, first, rev1, rev2);
1098}
1099for (i=n; i<8; i++) {
1100MacModel[i] = 0x20;
1101}
1102ModelRev = (rev2 << 16) + rev1;
1103//ModelLength = (len + 1) * 2;
1104//printf("Model=%s %08x\n", MacModel, ModelRev);
1105//getc();
1106
1107}
1108
1109 static struct SMBEntryPoint *orig = NULL; // cached
1110 static struct SMBEntryPoint *patched = NULL; // cached
1111
1112/** Get original or new smbios entry point, if successful, the addresses are cached for next time */
1113struct SMBEntryPoint *getSmbios(int which)
1114{
1115
1116 // whatever we are called with orig or new flag, initialize asap both structures
1117 switch (which) {
1118 case SMBIOS_ORIGINAL:
1119 if (orig==NULL) {
1120 orig = getAddressOfSmbiosTable();
1121 getSmbiosTableStructure(orig); // generate tables entry list for fast table finding
1122 }
1123 return orig;
1124 case SMBIOS_PATCHED:
1125 if (orig==NULL && (orig = getAddressOfSmbiosTable())==NULL ) {
1126 printf("Could not find original SMBIOS !!\n");
1127 pause();
1128 } else {
1129 patched = smbios_dry_run(orig);
1130 if(patched==NULL) {
1131 printf("Could not create new SMBIOS !!\n");
1132 pause();
1133 }
1134 else {
1135 smbios_real_run(orig, patched);
1136 }
1137 }
1138getSmbiosMacModel();//Dunno if it is a right place to do that
1139 return patched;
1140 default:
1141 printf("ERROR: invalid option for getSmbios() !!\n");
1142 break;
1143 }
1144
1145 return NULL;
1146}
1147
1148/** Find first original dmi Table with a particular type */
1149struct DMIHeader* FindFirstDmiTableOfType(int type, int minlength)
1150{
1151 current_pos = 0; //static variable
1152
1153 return FindNextDmiTableOfType(type, minlength);
1154};
1155
1156/** Find next original dmi Table with a particular type */
1157struct DMIHeader* FindNextDmiTableOfType(int type, int minlength)
1158{
1159 int i;
1160
1161 if (ftTablePairInit) getSmbios(SMBIOS_ORIGINAL);
1162
1163 for (i=current_pos; i < DmiTablePairCount; i++) {
1164 if (type == DmiTablePair[i].type &&
1165 DmiTablePair[i].dmi &&
1166 DmiTablePair[i].dmi->length >= minlength ) {
1167 current_pos = i+1;
1168 return DmiTablePair[i].dmi;
1169 }
1170 }
1171 return NULL; // not found
1172};
1173
1174#if 1 //NOTUSED //Slice -- it is used?
1175const char * smbiosStringAtIndex(DMIHeader* smHeader, int index, int* length )
1176{
1177 const char * last = 0;
1178 const char * next = (const char *) smHeader + smHeader->length;
1179
1180 if ( length ) *length = 0;
1181 while ( index-- )
1182 {
1183 last = 0;
1184const char * cp = 0;
1185for ( cp = next; *cp || cp[1]; cp++ )
1186 {
1187 if ( *cp == '\0' )
1188 {
1189 last = next;
1190 next = cp + 1;
1191 break;
1192 }
1193 }
1194 if ( last == 0 ) break;
1195 }
1196
1197 if ( last )
1198 {
1199 while (*last == ' ') last++;
1200 if (length)
1201 {
1202 UInt8 len;
1203 for ( len = next - last - 1; len && last[len - 1] == ' '; len-- )
1204 ;
1205 *length = len; // number of chars not counting the terminating NULL
1206 }
1207 }
1208
1209 return last ? last : "";
1210}
1211
1212
1213void getSmbiosProductName()
1214{
1215//struct SMBEntryPoint*smbios;
1216DMISystemInformation*p;
1217char*tempString;
1218inttmpLen;
1219
1220//smbios = getSmbios(SMBIOS_ORIGINAL);
1221//if (smbios==NULL) return 0;
1222
1223p = (DMISystemInformation*) FindFirstDmiTableOfType(1, 0x19); // Type 1: (3.3.2) System Information
1224if (p==NULL) return; // NULL;
1225
1226
1227tempString = (char*)smbiosStringAtIndex((DMIHeader*)p, p->productName, &tmpLen);
1228tempString[tmpLen] = 0;
1229
1230gSMBIOSBoardModel = malloc(tmpLen + 1);
1231if(gSMBIOSBoardModel)
1232{
1233strncpy(gSMBIOSBoardModel, tempString, tmpLen);
1234Node* node = DT__FindNode("/", false);
1235DT__AddProperty(node, "orig-model", tmpLen, gSMBIOSBoardModel);
1236}
1237verbose("Actual model name is '%s'\n", tempString);
1238}
1239#endif
1240
1241//Slice
1242//#define MEGA 1000000LL - now in mem.h
1243void scan_cpu_DMI(void) //PlatformInfo_t *p)
1244{
1245// int i=0;
1246int maxClock = 0;
1247 struct DMIHeader * dmihdr = NULL;
1248 struct DMIProcessorInformation* cpuInfo; // Type 4
1249
1250for (dmihdr = FindFirstDmiTableOfType(4, 30); dmihdr; dmihdr = FindNextDmiTableOfType(4, 30))
1251{
1252cpuInfo = (struct DMIProcessorInformation*)dmihdr;
1253if (cpuInfo->processorType != 3) { // CPU
1254continue;
1255}
1256//TODO validate
1257#if 1 //NOTYET
1258msglog("Platform CPU Info:\n FSB=%d\n MaxSpeed=%d\n CurrentSpeed=%d\n", Platform->CPU.FSBFrequency/MEGA, Platform->CPU.TSCFrequency/MEGA, Platform->CPU.CPUFrequency/MEGA);
1259
1260if ((cpuInfo->externalClock) && (cpuInfo->externalClock < 400)) { //<400MHz
1261Platform->CPU.FSBFrequency = (cpuInfo->externalClock) * MEGA;
1262}
1263maxClock = cpuInfo->maximumClock;
1264if (cpuInfo->maximumClock < cpuInfo->currentClock) {
1265maxClock = cpuInfo->currentClock;
1266}
1267if ((maxClock) && (maxClock < 10000)) { //<10GHz
1268Platform->CPU.TSCFrequency = maxClock * MEGA;
1269}
1270if ((cpuInfo->currentClock) && (cpuInfo->currentClock < 10000)) { //<10GHz
1271Platform->CPU.CPUFrequency = cpuInfo->currentClock * MEGA;
1272}
1273#endif
1274msglog("DMI CPU Info:\n FSB=%d\n MaxSpeed=%d\n CurrentSpeed=%d\n", cpuInfo->externalClock, cpuInfo->maximumClock, cpuInfo->currentClock);
1275msglog("DMI CPU Info 2:\n Family=%x\n Socket=%x\n Cores=%d Enabled=%d Threads=%d\n", cpuInfo->processorFamily, cpuInfo->processorUpgrade, cpuInfo->coreCount, cpuInfo->coreEnabled, cpuInfo->Threads);
1276#if 1 //NOTYET
1277if ((cpuInfo->coreCount) && (cpuInfo->coreCount<Platform->CPU.NoCores)) {
1278if (cpuInfo->coreEnabled < cpuInfo->coreCount) {
1279cpuInfo->coreCount = cpuInfo->coreEnabled;
1280}
1281Platform->CPU.NoCores = cpuInfo->coreCount;
1282}
1283if ((cpuInfo->Threads) && (cpuInfo->Threads<Platform->CPU.NoThreads)) {
1284Platform->CPU.NoThreads = cpuInfo->Threads;
1285}
1286#endif
1287
1288return;
1289}
1290
1291return;
1292}
1293//Slice - check other DMI info
1294bool scanDMI(void)
1295{
1296struct DMIHeader * dmihdr = NULL;
1297 struct DMISystemEnclosure* encInfo; // Type 3
1298
1299for (dmihdr = FindFirstDmiTableOfType(3, 13); dmihdr; dmihdr = FindNextDmiTableOfType(3, 13))
1300{
1301encInfo = (struct DMISystemEnclosure*)dmihdr;
1302msglog("DMI Chassis Info:\n Type=%x\n Boot-up State=%x\n Power Supply=%x Thermal State=%x\n", encInfo->type, encInfo->bootupState, encInfo->powerSupplyState, encInfo->thermalState);
1303switch (encInfo->type) {
1304case 1:
1305case 2:
1306return FALSE;
1307case 3:
1308case 4:
1309case 6:
1310case 7:
1311Platform->CPU.Mobile = FALSE;
1312break;
1313case 8:
1314case 9:
1315case 0x0A:
1316case 0x0B:
1317case 0x0E:
1318Platform->CPU.Mobile = TRUE;
1319break;
1320
1321default:
1322break;
1323}
1324return TRUE;
1325}
1326return FALSE;
1327}
1328

Archive Download this file

Revision: 676