Chameleon

Chameleon Svn Source Tree

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

  • Property svn:executable set to
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 "efi_tables.h"
10#include "fake_efi.h"
11#include "platform.h"
12#include "smbios_patcher.h"
13#include "pci.h"
14
15#ifndef DEBUG_SMBIOS
16#define DEBUG_SMBIOS 0
17#endif
18
19#if DEBUG_SMBIOS
20#define DBG(x...)printf(x)
21#else
22#define DBG(x...)
23#endif
24
25typedef struct {
26 const char* key;
27 const char* value;
28} SMStrEntryPair;
29
30// defaults for a MacBook
31static const SMStrEntryPair const sm_macbook_defaults[]={
32{"SMbiosvendor","Apple Inc."},
33{"SMbiosversion","MB41.88Z.00C1.B00.0802091535"},
34{"SMbiosdate","02/09/08"},
35{"SMmanufacter","Apple Inc."},
36{"SMproductname","MacBook4,1"},
37{"SMsystemversion","1.0"},
38{"SMserial","SOMESRLNMBR"},
39{"SMfamily","MacBook"},
40{"SMboardmanufacter","Apple Inc."},
41{"SMboardproduct","Mac-F22788A9"},
42{"SMboardversion","PVT"},
43{"SMchassismanufacter","Apple Inc."},
44{"SMchassisversion","Mac-F22788A9"},
45{"SMchassisserial","SOMESRLNMBR"},
46/*{"SMSKU","System SKU#"},*/
47{"SMboardserial","1"},
48{ "",""}
49};
50
51// defaults for a MacBook Pro
52static const SMStrEntryPair const sm_macbookpro_defaults[]={
53{"SMbiosvendor","Apple Inc."},
54{"SMbiosversion","MBP41.88Z.00C1.B03.0802271651"},
55{"SMbiosdate","02/27/08"},
56{"SMmanufacter","Apple Inc."},
57{"SMproductname","MacBookPro4,1"},
58{"SMsystemversion","1.0"},
59{"SMserial","SOMESRLNMBR"},
60{"SMfamily","MacBook Pro"},
61{"SMboardmanufacter","Apple Inc."},
62{"SMboardproduct","Mac-F42D89C8"},
63{"SMboardversion","PVT"},
64{"SMchassismanufacter","Apple Inc."},
65{"SMchassisversion","Mac-F42D89C8"},
66{"SMchassisserial","SOMESRLNMBR"},
67/*{"SMSKU","System SKU#"},*/
68{"SMboardserial","1"},
69{ "",""}
70};
71
72// defaults for a MacBook Pro core i5/i7
73static const SMStrEntryPair const sm_macbookpro_core_defaults[]={
74{"SMbiosvendor","Apple Inc."},
75{"SMbiosversion","MBP61.88Z.0057.B09.1004161215"},
76{"SMbiosdate","04/16/2010"},
77{"SMmanufacter","Apple Inc."},
78{"SMproductname","MacBookPro6,2"},
79{"SMsystemversion","1.0"},
80{"SMserial","SOMESERIAL"},
81{"SMfamily","MacBook Pro"},
82{"SMboardmanufacter","Apple Inc."},
83{"SMboardproduct","Mac-F22686C8"},
84{"SMboardversion","MacBookPro6,2"},
85{"SMchassismanufacter","Apple Inc."},
86{"SMchassisversion","Mac-F22686C8"},
87{"SMchassisserial","SOMESRLNMBR"},
88/*{"SMSKU","System SKU#"},*/
89{"SMboardserial","Base Board Serial#"},
90{ "",""}
91};
92
93// defaults for a Mac mini
94static const SMStrEntryPair const sm_macmini_defaults[]={
95{"SMbiosvendor","Apple Inc."},
96{"SMbiosversion","MM21.88Z.009A.B00.0706281359"},
97{"SMbiosdate","06/28/08"},
98{"SMmanufacter","Apple Inc."},
99{"SMproductname","Macmini2,1"},
100{"SMsystemversion","1.0"},
101{"SMserial","SOMESRLNMBR"},
102{"SMfamily","Napa Mac"},
103{"SMboardmanufacter","Apple Inc."},
104{"SMboardproduct","Mac-F4208EAA"},
105{"SMboardversion","PVT"},
106{"SMchassismanufacter","Apple Inc."},
107{"SMchassisversion","Mac-F4208EAA"},
108{"SMchassisserial","SOMESRLNMBR"},
109/*{"SMSKU","System SKU#"},*/
110{"SMboardserial","1"},
111{ "",""}
112};
113
114// defaults for an iMac
115static const SMStrEntryPair const sm_imac_defaults[]={
116{"SMbiosvendor","Apple Inc."},
117{"SMbiosversion","IM81.88Z.00C1.B00.0802091538"},
118{"SMbiosdate","04/01/2008"},
119{"SMmanufacter","Apple Inc."},
120{"SMproductname","iMac8,1"},
121{"SMsystemversion","1.0"},
122{"SMserial","SOMESRLNMBR"},
123{"SMfamily","Mac"},
124{"SMboardmanufacter","Apple Inc."},
125{"SMboardproduct","Mac-F227BEC8"},
126{"SMboardversion","iMac8,1"},
127{"SMchassismanufacter","Apple Inc."},
128{"SMchassisversion","Mac-F227BEC8"},
129{"SMchassisserial","SOMESRLNMBR"},
130/*{"SMSKU","System SKU#"},*/
131{"SMboardserial","Base Board Serial#"},
132{ "",""}
133};
134
135// defaults for a Mac Pro
136static const SMStrEntryPair const sm_macpro_defaults[]={
137{"SMbiosvendor","Apple Inc."},
138{"SMbiosversion","MP31.88Z.006C.B02.0801021250"},
139{"SMbiosdate","01/02/08"},
140{"SMmanufacter","Apple Inc."},
141{"SMproductname","MacPro3,1"},
142{"SMsystemversion","1.0"},
143{"SMserial","SOMESRLNMBR"},
144{"SMfamily","MacPro"},
145{"SMboardmanufacter","Apple Computer, Inc."},
146{"SMboardproduct","Mac-F42C88C8"},
147{"SMboardversion","Proto1"},
148{"SMchassismanufacter","Apple Inc."},
149{"SMchassisversion","Mac-F42C88C8"},
150{"SMchassisserial","SOMESRLNMBR"},
151/*{"SMSKU","System SKU#"},*/
152{"SMboardserial","Base Board Serial#"},
153{ "",""}
154};
155
156// defaults for an iMac11,1 core i3/i5/i7
157static const SMStrEntryPair const sm_imac_core_defaults[]={
158{"SMbiosvendor","Apple Inc."},
159{"SMbiosversion","IM111.88Z.0034.B00.0910301727"},
160{"SMbiosdate","10/30/09"},
161{"SMmanufacter","Apple Inc."},
162{"SMproductname","iMac11,1"},
163{"SMsystemversion","1.0"},
164{"SMserial","SOMESRLNMBR"},
165{"SMfamily","iMac"},
166{"SMboardmanufacter","Apple Inc."},
167{"SMboardproduct","Mac-F2268DAE"},
168{"SMboardversion","Not Specified"},
169{"SMchassismanufacter","Apple Inc."},
170{"SMchassisversion","Mac-F2268DAE"},
171{"SMchassisserial","SOMESRLNMBR"},
172/*{"SMSKU","System SKU#"},*/
173{"SMboardserial","Base Board Serial#"},
174{ "",""}
175};
176
177// defaults for a Mac Pro 4,1 core i7/Xeon
178static const SMStrEntryPair const sm_macpro_core_defaults[]={
179{"SMbiosvendor","Apple Computer, Inc."},
180{"SMbiosversion","MP41.88Z.0081.B04.0903051113"},
181{"SMbiosdate","11/06/2009"},
182{"SMmanufacter","Apple Computer, Inc."},
183{"SMproductname","MacPro4,1"},
184{"SMsystemversion","1.0"},
185{"SMserial","SOMESRLNMBR"},
186{"SMfamily","MacPro"},
187{"SMboardmanufacter","Apple Computer, Inc."},
188{"SMboardproduct","Mac-F4208DC8"},
189{"SMboardversion","MacPro4,1"},
190{"SMchassismanufacter","Apple Computer, Inc."},
191{"SMchassisversion","Mac-F4208DC8"},
192{"SMchassisserial","SOMESRLNMBR"},
193/*{"SMSKU","System SKU#"},*/
194{"SMboardserial","Base Board Serial#"},
195{ "",""}
196};
197
198static const char* sm_get_defstr(const char * key, int table_num)
199{
200inti;
201const SMStrEntryPair*sm_defaults;
202
203if (Platform.CPU.Vendor == 0x756E6547)
204{
205switch (Platform.CPU.Family)
206{
207case 0x06:
208{
209switch (Platform.CPU.Model)
210{
211case 0x19: // Core i5 650
212case 0x1e: // Core i7, i5 LGA1156, "Lynnfield", "Jasper", 45nm
213case 0x1f: // Core i7, i5, Nehalem
214case 0x25: // Core i7, i5, i3 LGA1156, "Westmere", 32nm
215if(platformCPUFeature(CPU_FEATURE_MOBILE)) sm_defaults = sm_macbookpro_core_defaults;
216else sm_defaults=sm_imac_core_defaults;
217break;
218case 0x1a: // Core i7 LGA1366, Xeon 550, 45nm
219case 0x2a: // Sandy Bridge, 32nm
220case 0x2c: // Core i7 LGA1366, "Westmere", 32nm, Hexa-Core
221case 0x2e: // Core i7, Nehalem-Ex, Xeon
222case 0x2f: // Core i7, "Westmere-Ex", 45nm, Hexa-Core
223if(platformCPUFeature(CPU_FEATURE_MOBILE)) sm_defaults = sm_macbookpro_core_defaults;
224else sm_defaults = sm_macpro_core_defaults;
225break;
226default:
227goto coldcase;
228break;
229}
230}
231default:
232goto coldcase;
233break;
234}
235}
236else
237{
238coldcase:
239if (platformCPUFeature(CPU_FEATURE_MOBILE))
240{
241if(Platform.CPU.NoCores > 1) sm_defaults = sm_macbookpro_defaults;
242else sm_defaults = sm_macbook_defaults;
243}
244else
245{
246switch (Platform.CPU.NoCores)
247{
248case 1:
249sm_defaults = sm_macmini_defaults;
250break;
251case 2:
252sm_defaults = sm_imac_defaults;
253break;
254default:
255sm_defaults = sm_macpro_defaults;
256break;
257}
258}
259}
260
261for (i=0; sm_defaults[i].key[0]; i++)
262{
263if(!strcmp (sm_defaults[i].key, key)) return sm_defaults[i].value;
264}
265
266// Shouldn't happen
267printf ("Error: no default for '%s' known\n", key);
268sleep (2);
269return "";
270}
271
272static int sm_get_fsb(const char *name, int table_num)
273{
274return Platform.CPU.FSBFrequency/1000000;
275}
276
277static int sm_get_cpu (const char *name, int table_num)
278{
279return Platform.CPU.CPUFrequency/1000000;
280}
281
282/*static int sm_rom_armed(const char *name, int table_num)
283{
284static intret[4];
285struct SMBEntryPoint*smbios;
286SMBByte*p;
287
288smbios = getSmbios(SMBIOS_ORIGINAL);
289if(smbios==NULL) return 0;
290
291p = (SMBByte*) FindFirstDmiTableOfType(0, 0x18);
292if (p==NULL) return 0;
293p += 10;
294
295memcpy(ret, p, 4);
296verbose("ROM Characteristics: default= 0x%x/%s\t", ret);
297int result = *ret;
298verbose("result= 0x%x/%s\n", result);
299return result;
300}*/
301
302/*static int sm_get_rom (const char *name, int table_num)
303{
304int *romchar = sm_rom_armed();
305verbose("\trom_char: 0x%x, 0x%x\n", romchar, *romchar);
306return *romchar;
307}*/
308
309static int sm_get_bus_speed (const char *name, int table_num)
310{
311if (Platform.CPU.Vendor == 0x756E6547) // Intel
312{
313switch (Platform.CPU.Family)
314{
315case 0x06:
316{
317switch (Platform.CPU.Model)
318{
319case 0x0d:// Pentium M, "Dothan", 90nm
320case 0x0e:// Core Solo/Duo, "Yonah", 65nm
321case 0x0f:// Pentium 4, Core 2, Xeon, "Merom", "Conroe", 65nm
322case 0x17:// Core 2 Extreme, Xeon, "Penryn", "Wolfdale", 45nm
323case 0x1c:// Intel Atom
324case 0x27:// Intel Atom, "Lincroft", 45nm
325return 0; // TODO: populate bus speed for these processors
326break;
327case 0x2f:// Core i7, "Westmere-Ex", 45nm, Hexa-Core
328return 0; // TODO: populate bus speed for these processors
329break;
330case 0x0c:// Core i7 & Atom
331if(strstr(Platform.CPU.BrandString, "Atom")) return 0;
332case 0x19:// Core i5 650
333case 0x1a:// Core i7 LGA1366, Xeon 550, 45nm
334case 0x1e:// Core i7, i5 LGA1156, "Lynnfield", "Jasper", 45nm
335case 0x1f:// Core i7, i5, Nehalem
336case 0x25:// Core i7, i5, i3 LGA1156, "Westmere", 32nm
337case 0x2a:// Sandy Bridge, 32nm
338case 0x2c:// Core i7 LGA1366, "Westmere", 32nm, Hexa-Core
339case 0x2e:// Core i7, Nehalem-Ex, Xeon
340{
341// thanks to dgobe for i3/i5/i7 bus speed detection
342int nhm_bus = 0x3F;
343static long possible_nhm_bus[] = {0xFF, 0x7F, 0x3F};
344unsigned long did, vid;
345int i;
346
347// Nehalem supports Scrubbing
348// First, locate the PCI bus where the MCH is located
349for(i = 0; i < sizeof(possible_nhm_bus); i++)
350{
351vid = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), 0x00);
352did = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), 0x02);
353vid &= 0xFFFF;
354did &= 0xFF00;
355
356if(vid == 0x8086 && did >= 0x2C00)
357nhm_bus = possible_nhm_bus[i];
358}
359
360unsigned long qpimult, qpibusspeed;
361qpimult = pci_config_read32(PCIADDR(nhm_bus, 2, 1), 0x50);
362qpimult &= 0x7F;
363DBG("qpimult %d\n", qpimult);
364qpibusspeed = (qpimult * 2 * (Platform.CPU.FSBFrequency/1000000));
365// Rek: rounding decimals to match original mac profile info
366if (qpibusspeed%100 != 0)qpibusspeed = ((qpibusspeed+50)/100)*100;
367DBG("qpibusspeed %d\n", qpibusspeed);
368return qpibusspeed;
369break;
370}
371}
372}
373}
374}
375return 0;
376}
377
378static int sm_get_cores()
379{
380int cores = Platform.CPU.NoCores;
381
382switch (cores)
383{
384case 1:// Core Solo
385return 0x0201;
386break;
387case 4:// Quad Core, Xeon
388return 0x0501;
389break;
390default:// Core 2, 65nm
391return 0x0301;
392break;
393}
394}
395
396static int sm_get_cputype (const char *name, int table_num)
397{
398static bool done = false;
399
400if (Platform.CPU.Vendor == 0x756E6547) // Intel
401{
402if(!done) done = true;
403int intelPM = Platform.CPU.Model;
404
405switch (intelPM)
406{
407case 0xc:// Core i7 & Atom
408if(strstr(Platform.CPU.BrandString, "Atom")) return sm_get_cores();
409else return 0x0701;
410break;
411case 0x0d:// Pentium M model D
412return 0x0101;
413break;
414case 0x0e:// Core Solo/Duo, "Yonah", 65nm
415case 0x16:// Core 2 Solo, "Merom-L", "Conroe-L", 45nm
416return 0x0201;
417break;
418case 0x15:// EP80579 integrated processor
419return 0x0301;// ???
420break;
421case 0x1d:// Six-Core Xeon 7400, "Dunnington", 45nm
422return 0x0401;
423break;
424case 0x19:// Core i5 650
425case 0x13:// Core i5, Xeon MP, "Havendale", "Auburndale", 45nm
426return 0x0601;
427break;
428case 0x1e:// Nehalem, Xeon, "Lynnfield", "Clarksfield", "Jasper", 45nm
429case 0x1f:// Core i7, i5, Nehalem
430if(strstr(Platform.CPU.BrandString, "Core(TM) i5"))
431return 0x0601;
432if(strstr(Platform.CPU.BrandString, "Xeon(R)")) // Lynnfiled Quad-Core Xeon
433return 0x0501;// Lynnfiled Quad-Core Xeon
434else
435return 0x0701;
436break;
437case 0x1a:// Nehalem, Xeon 5500, "Bloomfield", 45nm
438case 0x2e:// Nehalem-ex, "Beckton", 45nm
439return 0x0701;
440break;
441case 0x2c:// Nehalem, "Gulftown", 32nm, Hexa-Core
442case 0x2f:// Core i7, "Westmere-Ex", 45nm, Hexa-Core
443return 0x0501;
444break;
445case 0x2a:// Sandy Bridge, 32nm; valv: probably not here
446case 0x25:// Nehalem, "Clarkdale", 32nm
447if(strstr(Platform.CPU.BrandString, "Core(TM) i3"))
448return 0x0901;
449if(strstr(Platform.CPU.BrandString, "Core(TM) i5"))
450return 0x0601;
451if(strstr(Platform.CPU.BrandString, "Core(TM) i5 CPU M 540"))
452return 0x0602;
453else
454return 0x0701;
455break;
456case 0x0f:// Pentium 4, Core 2, Xeon, "Merom", "Conroe", 65nm
457case 0x17:// Core 2 Extreme, Xeon, "Penryn", "Wolfdale", 45nm
458case 0x1c:// Intel Atom
459case 0x27:// Intel Atom, "Lincroft", 45nm
460default:
461return sm_get_cores();
462}
463}
464return sm_get_cores();
465}
466
467static int sm_get_memtype (const char *name, int table_num)
468{
469intmap;
470
471if (table_num < MAX_RAM_SLOTS)
472{
473map = Platform.DMI.DIMM[table_num];
474if (Platform.RAM.DIMM[map].InUse && Platform.RAM.DIMM[map].Type != 0)
475{
476DBG("RAM Detected Type = %d\n", Platform.RAM.DIMM[map].Type);
477return Platform.RAM.DIMM[map].Type;
478}
479}
480return SMB_MEM_TYPE_DDR2;
481}
482
483static int sm_get_memspeed (const char *name, int table_num)
484{
485intmap;
486
487if (table_num < MAX_RAM_SLOTS)
488{
489map = Platform.DMI.DIMM[table_num];
490if (Platform.RAM.DIMM[map].InUse && Platform.RAM.DIMM[map].Frequency != 0)
491{
492DBG("RAM Detected Freq = %d Mhz\n", Platform.RAM.DIMM[map].Frequency);
493return Platform.RAM.DIMM[map].Frequency;
494}
495}
496
497return 800;
498}
499
500static const char *sm_get_memvendor (const char *name, int table_num)
501{
502intmap;
503
504if (table_num < MAX_RAM_SLOTS)
505{
506map = Platform.DMI.DIMM[table_num];
507if (Platform.RAM.DIMM[map].InUse && strlen(Platform.RAM.DIMM[map].Vendor) > 0)
508{
509DBG("RAM Detected Vendor[%d]='%s'\n", table_num, Platform.RAM.DIMM[map].Vendor);
510return Platform.RAM.DIMM[map].Vendor;
511}
512}
513return "N/A";
514}
515
516static const char *sm_get_memserial (const char *name, int table_num)
517{
518intmap;
519
520if (table_num < MAX_RAM_SLOTS) {
521map = Platform.DMI.DIMM[table_num];
522if (Platform.RAM.DIMM[map].InUse && strlen(Platform.RAM.DIMM[map].SerialNo) > 0)
523{
524DBG("name = %s, map=%d, RAM Detected SerialNo[%d]='%s'\n", name ? name : "",
525map, table_num, Platform.RAM.DIMM[map].SerialNo);
526return Platform.RAM.DIMM[map].SerialNo;
527}
528}
529return "N/A";
530}
531
532static const char *sm_get_mempartno (const char *name, int table_num)
533{
534intmap;
535
536if (table_num < MAX_RAM_SLOTS)
537{
538map = Platform.DMI.DIMM[table_num];
539if (Platform.RAM.DIMM[map].InUse && strlen(Platform.RAM.DIMM[map].PartNo) > 0)
540{
541DBG("Ram Detected PartNo[%d]='%s'\n", table_num, Platform.RAM.DIMM[map].PartNo);
542return Platform.RAM.DIMM[map].PartNo;
543}
544}
545return "N/A";
546}
547
548static int sm_one (int tablen)
549{
550return 1;
551}
552
553struct smbios_property smbios_properties[]=
554{
555{.name="SMbiosvendor",.table_type= 0,.value_type=SMSTRING,.offset=0x04,.auto_str=sm_get_defstr},
556{.name="SMbiosversion",.table_type= 0,.value_type=SMSTRING,.offset=0x05,.auto_str=sm_get_defstr},
557{.name="SMbiosdate",.table_type= 0,.value_type=SMSTRING,.offset=0x08,.auto_str=sm_get_defstr},
558/*{.name="SMrom-size",.table_type= 0,.value_type=SMBYTE,.offset=0x09,.auto_int=0},*/
559/*{.name="SMcharacteristics",.table_type= 0,.value_type=SMOWORD,.offset=0x0a,.auto_int=sm_rom_armed},*/
560{.name="SMmanufacter",.table_type= 1,.value_type=SMSTRING,.offset=0x04,.auto_str=sm_get_defstr},
561{.name="SMproductname",.table_type= 1,.value_type=SMSTRING,.offset=0x05,.auto_str=sm_get_defstr},
562{.name="SMsystemversion",.table_type= 1,.value_type=SMSTRING,.offset=0x06,.auto_str=sm_get_defstr},
563{.name="SMserial",.table_type= 1,.value_type=SMSTRING,.offset=0x07,.auto_str=sm_get_defstr},
564{.name="SMUUID",.table_type= 1, .value_type=SMOWORD,.offset=0x08,.auto_oword=0},
565/*{.name="SMSKU",.table_type= 1,.value_type=SMSTRING,.offset=0x13,.auto_str=sm_get_defstr},*/
566{.name="SMfamily",.table_type= 1,.value_type=SMSTRING,.offset=0x1a,.auto_str=sm_get_defstr},
567{.name="SMboardmanufacter",.table_type= 2, .value_type=SMSTRING,.offset=0x04,.auto_str=sm_get_defstr},
568{.name="SMboardproduct",.table_type= 2, .value_type=SMSTRING,.offset=0x05,.auto_str=sm_get_defstr},
569{.name="SMboardversion",.table_type= 2,.value_type=SMSTRING,.offset=0x06,.auto_str=sm_get_defstr},
570{.name="SMboardserial",.table_type= 2,.value_type=SMSTRING,.offset=0x07,.auto_str=sm_get_defstr},
571{.name="SMchassismanufacter",.table_type= 3,.value_type=SMSTRING,.offset=0x04,.auto_str=sm_get_defstr},
572{.name="SMchassisversion",.table_type= 3,.value_type=SMSTRING,.offset=0x06,.auto_str=sm_get_defstr},
573{.name="SMchassisserial",.table_type= 3,.value_type=SMSTRING,.offset=0x07,.auto_str=sm_get_defstr},
574{.name="SMProcessorfamily",.table_type= 4,.value_type=SMBYTE,.offset=0x06,.auto_int=0},
575{.name="SMexternalclock",.table_type= 4,.value_type=SMWORD,.offset=0x12,.auto_int=sm_get_fsb},
576{.name="SMmaximalclock",.table_type= 4,.value_type=SMWORD,.offset=0x14,.auto_int=sm_get_cpu},
577{.name="SMmemdevloc",.table_type= 17,.value_type=SMSTRING,.offset=0x10,.auto_str=0},
578{.name="SMmembankloc",.table_type= 17,.value_type=SMSTRING,.offset=0x11,.auto_str=0},
579{.name="SMmemtype",.table_type= 17,.value_type=SMBYTE,.offset=0x12,.auto_int=sm_get_memtype},
580{.name="SMmemspeed",.table_type= 17,.value_type=SMWORD,.offset=0x15,.auto_int=sm_get_memspeed},
581{.name="SMmemmanufacter",.table_type= 17,.value_type=SMSTRING,.offset=0x17,.auto_str=sm_get_memvendor},
582{.name="SMmemserial",.table_type= 17,.value_type=SMSTRING,.offset=0x18,.auto_str=sm_get_memserial},
583{.name="SMmempart",.table_type= 17,.value_type=SMSTRING,.offset=0x1A,.auto_str=sm_get_mempartno},
584{.name="SMoemcpu",.table_type= 131,.value_type=SMWORD,.offset=0x02,.auto_int=0},
585{.name="SMcputype",.table_type= 131,.value_type=SMWORD,.offset=0x04,.auto_int=sm_get_cputype},
586{.name="SMbusspeed",.table_type= 132,.value_type=SMWORD,.offset=0x04,.auto_int=sm_get_bus_speed}
587};
588
589struct smbios_table_description smbios_table_descriptions[]=
590{
591{.type=0,.len=0x18,.numfunc=sm_one},
592{.type=1,.len=0x1b,.numfunc=sm_one},
593{.type=2,.len=0x0f,.numfunc=sm_one},
594{.type=4,.len=0x2a,.numfunc=sm_one},
595{.type=17,.len=0x1c,.numfunc=0},
596{.type=131,.len=0x06,.numfunc=sm_one},
597{.type=132,.len=0x06,.numfunc=sm_one}
598};
599
600// getting smbios addr with fast compare ops, late checksum testing ...
601#define COMPARE_DWORD(a,b) ( *((u_int32_t *) a) == *((u_int32_t *) b) )
602static const char * const SMTAG = "_SM_";
603static const char* const DMITAG= "_DMI_";
604
605static struct SMBEntryPoint *getAddressOfSmbiosTable(void)
606{
607struct SMBEntryPoint*smbios;
608/*
609 * The logic is to start at 0xf0000 and end at 0xfffff iterating 16 bytes at a time looking
610 * for the SMBIOS entry-point structure anchor (literal ASCII "_SM_").
611 */
612smbios = (struct SMBEntryPoint*) SMBIOS_RANGE_START;
613while (smbios <= (struct SMBEntryPoint *)SMBIOS_RANGE_END) {
614 if (COMPARE_DWORD(smbios->anchor, SMTAG) &&
615 COMPARE_DWORD(smbios->dmi.anchor, DMITAG) &&
616 smbios->dmi.anchor[4]==DMITAG[4] &&
617 checksum8(smbios, sizeof(struct SMBEntryPoint)) == 0)
618 {
619 return smbios;
620 }
621 smbios = (struct SMBEntryPoint*) ( ((char*) smbios) + 16 );
622}
623printf("ERROR: Unable to find SMBIOS!\n");
624pause();
625return NULL;
626}
627
628/** Compute necessary space requirements for new smbios */
629static struct SMBEntryPoint *smbios_dry_run(struct SMBEntryPoint *origsmbios)
630{
631struct SMBEntryPoint*ret;
632char*smbiostables;
633char*tablesptr;
634intorigsmbiosnum;
635inti, j;
636inttablespresent[256];
637booldo_auto=true;
638
639bzero(tablespresent, sizeof(tablespresent));
640
641getBoolForKey(kSMBIOSdefaults, &do_auto, &bootInfo->bootConfig);
642
643ret = (struct SMBEntryPoint *)AllocateKernelMemory(sizeof(struct SMBEntryPoint));
644if (origsmbios) {
645smbiostables = (char *)origsmbios->dmi.tableAddress;
646origsmbiosnum = origsmbios->dmi.structureCount;
647} else {
648smbiostables = NULL;
649origsmbiosnum = 0;
650}
651
652// _SM_
653ret->anchor[0] = 0x5f;
654ret->anchor[1] = 0x53;
655ret->anchor[2] = 0x4d;
656ret->anchor[3] = 0x5f;
657ret->entryPointLength = sizeof(*ret);
658ret->majorVersion = 2;
659ret->minorVersion = 1;
660ret->maxStructureSize = 0; // will be calculated later in this function
661ret->entryPointRevision = 0;
662for (i=0;i<5;i++) {
663ret->formattedArea[i] = 0;
664}
665//_DMI_
666ret->dmi.anchor[0] = 0x5f;
667ret->dmi.anchor[1] = 0x44;
668ret->dmi.anchor[2] = 0x4d;
669ret->dmi.anchor[3] = 0x49;
670ret->dmi.anchor[4] = 0x5f;
671ret->dmi.tableLength = 0; // will be calculated later in this function
672ret->dmi.tableAddress = 0; // will be initialized in smbios_real_run()
673ret->dmi.structureCount = 0; // will be calculated later in this function
674ret->dmi.bcdRevision = 0x21;
675tablesptr = smbiostables;
676
677 // add stringlen of overrides to original stringlen, update maxStructure size adequately,
678 // update structure count and tablepresent[type] with count of type.
679if (smbiostables) {
680for (i=0; i<origsmbiosnum; i++) {
681struct smbios_table_header*cur = (struct smbios_table_header *)tablesptr;
682char*stringsptr;
683intstringlen;
684
685tablesptr += cur->length;
686stringsptr = tablesptr;
687for (; tablesptr[0]!=0 || tablesptr[1]!=0; tablesptr++);
688tablesptr += 2;
689stringlen = tablesptr - stringsptr - 1;
690if (stringlen == 1) {
691stringlen = 0;
692}
693for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
694const char*str;
695intsize;
696charaltname[40];
697
698sprintf(altname, "%s_%d",smbios_properties[j].name, tablespresent[cur->type] + 1);
699if (smbios_properties[j].table_type == cur->type &&
700 smbios_properties[j].value_type == SMSTRING &&
701 (getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig) ||
702 getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)))
703{
704stringlen += size + 1;
705} else if (smbios_properties[j].table_type == cur->type &&
706 smbios_properties[j].value_type == SMSTRING &&
707 do_auto && smbios_properties[j].auto_str)
708{
709stringlen += strlen(smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[cur->type])) + 1;
710}
711}
712if (stringlen == 0) {
713stringlen = 1;
714}
715stringlen++;
716if (ret->maxStructureSize < cur->length+stringlen) {
717ret->maxStructureSize=cur->length+stringlen;
718}
719ret->dmi.tableLength += cur->length+stringlen;
720ret->dmi.structureCount++;
721tablespresent[cur->type]++;
722}
723}
724 // Add eventually table types whose detected count would be < required count, and update ret header with:
725 // new stringlen addons, structure count, and tablepresent[type] count adequately
726for (i=0; i<sizeof(smbios_table_descriptions)/sizeof(smbios_table_descriptions[0]); i++) {
727intnumnec=-1;
728charbuffer[40];
729
730sprintf(buffer, "SMtable%d", i);
731if (!getIntForKey(buffer, &numnec, &bootInfo->smbiosConfig)) {
732numnec = -1;
733}
734if (numnec==-1 && do_auto && smbios_table_descriptions[i].numfunc) {
735numnec = smbios_table_descriptions[i].numfunc(smbios_table_descriptions[i].type);
736}
737while (tablespresent[smbios_table_descriptions[i].type] < numnec) {
738intstringlen = 0;
739for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
740const char*str;
741intsize;
742charaltname[40];
743
744sprintf(altname, "%s_%d",smbios_properties[j].name, tablespresent[smbios_table_descriptions[i].type] + 1);
745if (smbios_properties[j].table_type == smbios_table_descriptions[i].type &&
746 smbios_properties[j].value_type == SMSTRING &&
747 (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
748 getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig)))
749{
750stringlen += size + 1;
751} else if (smbios_properties[j].table_type == smbios_table_descriptions[i].type &&
752 smbios_properties[j].value_type==SMSTRING &&
753 do_auto && smbios_properties[j].auto_str)
754{
755stringlen += strlen(smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[smbios_table_descriptions[i].type])) + 1;
756}
757}
758if (stringlen == 0) {
759stringlen = 1;
760}
761stringlen++;
762if (ret->maxStructureSize < smbios_table_descriptions[i].len+stringlen) {
763ret->maxStructureSize = smbios_table_descriptions[i].len + stringlen;
764}
765ret->dmi.tableLength += smbios_table_descriptions[i].len + stringlen;
766ret->dmi.structureCount++;
767tablespresent[smbios_table_descriptions[i].type]++;
768}
769}
770return ret;
771}
772
773/** From the origsmbios detected by getAddressOfSmbiosTable() to newsmbios whose entrypoint
774 * struct has been created by smbios_dry_run, update each table struct content of new smbios
775 * int the new allocated table address of size newsmbios->tablelength.
776 */
777static void smbios_real_run(struct SMBEntryPoint * origsmbios, struct SMBEntryPoint * newsmbios)
778{
779char *smbiostables;
780char *tablesptr, *newtablesptr;
781int origsmbiosnum;
782// bitmask of used handles
783uint8_t handles[8192];
784uint16_t nexthandle=0;
785int i, j;
786int tablespresent[256];
787bool do_auto=true;
788
789 static bool done = false; // IMPROVEME: called twice via getSmbios(), but only the second call can get all necessary info !
790
791extern void dumpPhysAddr(const char * title, void * a, int len);
792
793bzero(tablespresent, sizeof(tablespresent));
794bzero(handles, sizeof(handles));
795
796getBoolForKey(kSMBIOSdefaults, &do_auto, &bootInfo->bootConfig);
797
798newsmbios->dmi.tableAddress = (uint32_t)AllocateKernelMemory(newsmbios->dmi.tableLength);
799if (origsmbios) {
800smbiostables = (char *)origsmbios->dmi.tableAddress;
801origsmbiosnum = origsmbios->dmi.structureCount;
802} else {
803smbiostables = NULL;
804origsmbiosnum = 0;
805}
806tablesptr = smbiostables;
807newtablesptr = (char *)newsmbios->dmi.tableAddress;
808
809 // if old smbios exists then update new smbios with old smbios original content first
810if (smbiostables) {
811for (i=0; i<origsmbiosnum; i++) {
812struct smbios_table_header*oldcur = (struct smbios_table_header *) tablesptr;
813struct smbios_table_header*newcur = (struct smbios_table_header *) newtablesptr;
814char*stringsptr;
815intnstrings = 0;
816
817handles[(oldcur->handle) / 8] |= 1 << ((oldcur->handle) % 8);
818
819 // copy table length from old table to new table but not the old strings
820memcpy(newcur,oldcur, oldcur->length);
821
822tablesptr += oldcur->length;
823stringsptr = tablesptr;
824newtablesptr += oldcur->length;
825
826 // calculate the number of strings in the old content
827for (;tablesptr[0]!=0 || tablesptr[1]!=0; tablesptr++) {
828if (tablesptr[0] == 0) {
829nstrings++;
830}
831}
832if (tablesptr != stringsptr) {
833nstrings++;
834}
835tablesptr += 2;
836
837 // copy the old strings to new table
838memcpy(newtablesptr, stringsptr, tablesptr-stringsptr);
839
840 // point to next possible space for a string (deducting the second 0 char at the end)
841newtablesptr += tablesptr - stringsptr - 1;
842 if (nstrings == 0) { // if no string was found rewind to the first 0 char of the 0,0 terminator
843newtablesptr--;
844}
845
846 // now for each property in the table update the overrides if any (auto or user)
847for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
848const char*str;
849intsize;
850intnum;
851charaltname[40];
852
853sprintf(altname, "%s_%d", smbios_properties[j].name, tablespresent[newcur->type] + 1);
854if (smbios_properties[j].table_type == newcur->type) {
855switch (smbios_properties[j].value_type) {
856case SMSTRING:
857if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
858 getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
859{
860memcpy(newtablesptr, str, size);
861newtablesptr[size] = 0;
862newtablesptr += size + 1;
863*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
864} else if (do_auto && smbios_properties[j].auto_str) {
865str = smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]);
866size = strlen(str);
867memcpy(newtablesptr, str, size);
868newtablesptr[size] = 0;
869newtablesptr += size + 1;
870*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
871}
872break;
873
874case SMOWORD:
875if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
876 getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
877{
878intk=0, t=0, kk=0;
879const char*ptr = str;
880memset(((char*)newcur) + smbios_properties[j].offset, 0, 16);
881while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n')) {
882ptr++;
883}
884if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X')) {
885ptr += 2;
886}
887for (;ptr-str<size && *ptr && k<16;ptr++) {
888if (*ptr>='0' && *ptr<='9') {
889(t=(t<<4)|(*ptr-'0')),kk++;
890}
891if (*ptr>='a' && *ptr<='f') {
892(t=(t<<4)|(*ptr-'a'+10)),kk++;
893}
894if (*ptr>='A' && *ptr<='F') {
895(t=(t<<4)|(*ptr-'A'+10)),kk++;
896}
897if (kk == 2) {
898*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset + k)) = t;
899k++;
900kk = 0;
901t = 0;
902}
903}
904}
905break;
906
907case SMBYTE:
908if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
909 getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
910{
911*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
912} else if (do_auto && smbios_properties[j].auto_int) {
913*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
914}
915break;
916
917case SMWORD:
918if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
919 getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
920{
921*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
922} else if (do_auto && smbios_properties[j].auto_int) {
923*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
924}
925break;
926}
927}
928}
929if (nstrings == 0) {
930newtablesptr[0] = 0;
931newtablesptr++;
932}
933newtablesptr[0] = 0;
934newtablesptr++;
935tablespresent[newcur->type]++;
936}
937}
938
939 // for each eventual complementary table not present in the original smbios, do the overrides
940for (i=0; i<sizeof(smbios_table_descriptions)/sizeof(smbios_table_descriptions[0]); i++) {
941intnumnec = -1;
942charbuffer[40];
943
944sprintf(buffer, "SMtable%d", i);
945if (!getIntForKey(buffer, &numnec, &bootInfo->smbiosConfig)) {
946numnec = -1;
947}
948if (numnec == -1 && do_auto && smbios_table_descriptions[i].numfunc) {
949numnec = smbios_table_descriptions[i].numfunc(smbios_table_descriptions[i].type);
950}
951while (tablespresent[smbios_table_descriptions[i].type] < numnec) {
952struct smbios_table_header*newcur = (struct smbios_table_header *) newtablesptr;
953intnstrings = 0;
954
955memset(newcur,0, smbios_table_descriptions[i].len);
956while (handles[(nexthandle)/8] & (1 << ((nexthandle) % 8))) {
957nexthandle++;
958}
959newcur->handle = nexthandle;
960handles[nexthandle / 8] |= 1 << (nexthandle % 8);
961newcur->type = smbios_table_descriptions[i].type;
962newcur->length = smbios_table_descriptions[i].len;
963newtablesptr += smbios_table_descriptions[i].len;
964for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
965const char*str;
966intsize;
967intnum;
968charaltname[40];
969
970sprintf(altname, "%s_%d", smbios_properties[j].name, tablespresent[newcur->type] + 1);
971if (smbios_properties[j].table_type == newcur->type) {
972switch (smbios_properties[j].value_type) {
973case SMSTRING:
974if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
975 getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
976{
977memcpy(newtablesptr, str, size);
978newtablesptr[size] = 0;
979newtablesptr += size + 1;
980*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
981} else if (do_auto && smbios_properties[j].auto_str) {
982str = smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]);
983size = strlen(str);
984memcpy(newtablesptr, str, size);
985newtablesptr[size] = 0;
986newtablesptr += size + 1;
987*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
988}
989break;
990
991case SMOWORD:
992if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
993 getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
994{
995intk=0, t=0, kk=0;
996const char*ptr = str;
997
998memset(((char*)newcur) + smbios_properties[j].offset, 0, 16);
999while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n')) {
1000ptr++;
1001}
1002if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X')) {
1003ptr += 2;
1004}
1005for (;ptr-str<size && *ptr && k<16;ptr++) {
1006if (*ptr>='0' && *ptr<='9') {
1007(t=(t<<4)|(*ptr-'0')),kk++;
1008}
1009if (*ptr>='a' && *ptr<='f') {
1010(t=(t<<4)|(*ptr-'a'+10)),kk++;
1011}
1012if (*ptr>='A' && *ptr<='F') {
1013(t=(t<<4)|(*ptr-'A'+10)),kk++;
1014}
1015if (kk == 2) {
1016*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset + k)) = t;
1017k++;
1018kk = 0;
1019t = 0;
1020}
1021}
1022}
1023break;
1024
1025case SMBYTE:
1026if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
1027 getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
1028{
1029*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
1030} else if (do_auto && smbios_properties[j].auto_int) {
1031*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
1032}
1033break;
1034
1035case SMWORD:
1036if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
1037 getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
1038{
1039*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
1040} else if (do_auto && smbios_properties[j].auto_int) {
1041*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
1042}
1043break;
1044}
1045}
1046}
1047if (nstrings == 0) {
1048newtablesptr[0] = 0;
1049newtablesptr++;
1050}
1051newtablesptr[0] = 0;
1052newtablesptr++;
1053tablespresent[smbios_table_descriptions[i].type]++;
1054}
1055}
1056
1057 // calculate new checksums
1058newsmbios->dmi.checksum = 0;
1059newsmbios->dmi.checksum = 256 - checksum8(&newsmbios->dmi, sizeof(newsmbios->dmi));
1060newsmbios->checksum = 0;
1061newsmbios->checksum = 256 - checksum8(newsmbios, sizeof(*newsmbios));
1062
1063if (!done) {
1064verbose("Patched DMI Table\n");
1065done=true;
1066}
1067}
1068
1069#define MAX_DMI_TABLES 96
1070typedef struct DmiNumAssocTag {
1071 struct DMIHeader * dmi;
1072 uint8_t type;
1073} DmiNumAssoc;
1074
1075static DmiNumAssoc DmiTablePair[MAX_DMI_TABLES];
1076static int DmiTablePairCount = 0;
1077static int current_pos=0;
1078static bool ftTablePairInit = true;
1079
1080/**
1081 * Get a table structure entry from a type specification and a smbios address
1082 * return NULL if table is not found
1083 */
1084static void getSmbiosTableStructure(struct SMBEntryPoint *smbios)
1085{
1086 struct DMIHeader * dmihdr=NULL;
1087 SMBByte* p;
1088 int i;
1089
1090 if (ftTablePairInit && smbios!=NULL) {
1091 ftTablePairInit = false;
1092#if DEBUG_SMBIOS
1093 printf(">>> SMBIOSAddr=0x%08x\n", smbios);
1094 printf(">>> DMI: addr=0x%08x, len=%d, count=%d\n", smbios->dmi.tableAddress,
1095 smbios->dmi.tableLength, smbios->dmi.structureCount);
1096#endif
1097 p = (SMBByte *) smbios->dmi.tableAddress;
1098 for (i=0;
1099 i < smbios->dmi.structureCount &&
1100 p + 4 <= (SMBByte *)smbios->dmi.tableAddress + smbios->dmi.tableLength;
1101 i++) {
1102 dmihdr = (struct DMIHeader *) p;
1103
1104/*#if DEBUG_SMBIOS
1105 verbose(">>>>>> DMI(%d): type=0x%02x, len=0x%d\n",i,dmihdr->type,dmihdr->length);
1106#endif*/
1107 if (dmihdr->length < 4 || dmihdr->type == 127 /* EOT */) break;
1108 if (DmiTablePairCount < MAX_DMI_TABLES) {
1109 DmiTablePair[DmiTablePairCount].dmi = dmihdr;
1110 DmiTablePair[DmiTablePairCount].type = dmihdr->type;
1111 DmiTablePairCount++;
1112 }
1113 else {
1114 printf("DMI table entries list is full! Next entries won't be stored.\n");
1115 }
1116#if DEBUG_SMBIOS
1117 printf("DMI header found for table type %d, length = %d\n", dmihdr->type, dmihdr->length);
1118#endif
1119 p = p + dmihdr->length;
1120 while ((p - (SMBByte *)smbios->dmi.tableAddress + 1 < smbios->dmi.tableLength) && (p[0] != 0x00 || p[1] != 0x00)) {
1121 p++;
1122 }
1123 p += 2;
1124}
1125
1126 }
1127}
1128
1129/** Get original or new smbios entry point, if sucessful, the adresses are cached for next time */
1130struct SMBEntryPoint *getSmbios(int which)
1131{
1132 static struct SMBEntryPoint *orig = NULL; // cached
1133 static struct SMBEntryPoint *patched = NULL; // cached
1134
1135 // whatever we are called with orig or new flag, initialize asap both structures
1136 switch (which) {
1137 case SMBIOS_ORIGINAL:
1138 if (orig==NULL) {
1139 orig = getAddressOfSmbiosTable();
1140 getSmbiosTableStructure(orig); // generate tables entry list for fast table finding
1141 }
1142 return orig;
1143 case SMBIOS_PATCHED:
1144 if (orig==NULL && (orig = getAddressOfSmbiosTable())==NULL ) {
1145 printf("Could not find original SMBIOS !!\n");
1146 pause();
1147 } else {
1148 patched = smbios_dry_run(orig);
1149 if(patched==NULL) {
1150 printf("Could not create new SMBIOS !!\n");
1151 pause();
1152 }
1153 else {
1154 smbios_real_run(orig, patched);
1155 }
1156 }
1157
1158 return patched;
1159 default:
1160 printf("ERROR: invalid option for getSmbios() !!\n");
1161 break;
1162 }
1163
1164 return NULL;
1165}
1166
1167/** Find first original dmi Table with a particular type */
1168struct DMIHeader* FindFirstDmiTableOfType(int type, int minlength)
1169{
1170 current_pos = 0;
1171
1172 return FindNextDmiTableOfType(type, minlength);
1173};
1174
1175/** Find next original dmi Table with a particular type */
1176struct DMIHeader* FindNextDmiTableOfType(int type, int minlength)
1177{
1178 int i;
1179
1180 if (ftTablePairInit) getSmbios(SMBIOS_ORIGINAL);
1181
1182 for (i=current_pos; i < DmiTablePairCount; i++) {
1183 if (type == DmiTablePair[i].type &&
1184 DmiTablePair[i].dmi &&
1185 DmiTablePair[i].dmi->length >= minlength ) {
1186 current_pos = i+1;
1187 return DmiTablePair[i].dmi;
1188 }
1189 }
1190 return NULL; // not found
1191};
1192

Archive Download this file

Revision: 705