Chameleon

Chameleon Svn Source Tree

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

Archive Download this file

Revision: 1169