Chameleon

Chameleon Svn Source Tree

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

Source at commit 106 created 14 years 2 months ago.
By diebuche, Adding 915patch and edid
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 "SMBIOS.h"
14
15#ifndef DEBUG_SMBIOS
16#define DEBUG_SMBIOS 1
17#endif
18
19#if DEBUG_SMBIOS
20#define DBG(x...)printf(x)
21#else
22#define DBG(x...)
23#endif
24
25
26// defaults for a MacBook
27static char sm_macbook_defaults[][2][40]={
28{"SMbiosvendor","Apple Inc."},
29{"SMbiosversion","MB41.88Z.0073.B00.0809221748"},
30{"SMbiosdate","04/01/2008"},
31{"SMmanufacter","Apple Inc."},
32{"SMproductname","MacBook4,1"},
33{"SMsystemversion","1.0"},
34{"SMserial","SOMESRLNMBR"},
35{"SMfamily","MacBook"},
36{"SMboardmanufacter","Apple Inc."},
37{"SMboardproduct","Mac-F42D89C8"},
38{ "",""}
39};
40
41// defaults for a MacBook Pro
42static char sm_macbookpro_defaults[][2][40]={
43{"SMbiosvendor","Apple Inc."},
44{"SMbiosversion","MBP41.88Z.0073.B00.0809221748"},
45{"SMbiosdate","04/01/2008"},
46{"SMmanufacter","Apple Inc."},
47{"SMproductname","MacBookPro4,1"},
48{"SMsystemversion","1.0"},
49{"SMserial","SOMESRLNMBR"},
50{"SMfamily","MacBookPro"},
51{"SMboardmanufacter","Apple Inc."},
52{"SMboardproduct","Mac-F42D89C8"},
53{ "",""}
54};
55
56// defaults for a Mac mini
57static char sm_macmini_defaults[][2][40]={
58{"SMbiosvendor","Apple Inc."},
59{"SMbiosversion","MM21.88Z.009A.B00.0706281359"},
60{"SMbiosdate","04/01/2008"},
61{"SMmanufacter","Apple Inc."},
62{"SMproductname","Macmini2,1"},
63{"SMsystemversion","1.0"},
64{"SMserial","SOMESRLNMBR"},
65{"SMfamily","Napa Mac"},
66{"SMboardmanufacter","Apple Inc."},
67{"SMboardproduct","Mac-F4208EAA"},
68{ "",""}
69};
70
71// defaults for an iMac
72static char sm_imac_defaults[][2][40]={
73{"SMbiosvendor","Apple Inc."},
74{"SMbiosversion","IM81.88Z.00C1.B00.0802091538"},
75{"SMbiosdate","04/01/2008"},
76{"SMmanufacter","Apple Inc."},
77{"SMproductname","iMac8,1"},
78{"SMsystemversion","1.0"},
79{"SMserial","SOMESRLNMBR"},
80{"SMfamily","Mac"},
81{"SMboardmanufacter","Apple Inc."},
82{"SMboardproduct","Mac-F227BEC8"},
83{ "",""}
84};
85
86// defaults for a Mac Pro
87static char sm_macpro_defaults[][2][40]={
88{"SMbiosvendor","Apple Computer, Inc."},
89{"SMbiosversion","MP31.88Z.006C.B05.0802291410"},
90{"SMbiosdate","04/01/2008"},
91{"SMmanufacter","Apple Computer, Inc."},
92{"SMproductname","MacPro3,1"},
93{"SMsystemversion","1.0"},
94{"SMserial","SOMESRLNMBR"},
95{"SMfamily","MacPro"},
96{"SMboardmanufacter","Apple Computer, Inc."},
97{"SMboardproduct","Mac-F4208DC8"},
98{ "",""}
99};
100
101static char *sm_get_defstr(char *name, int table_num)
102{
103inti;
104char(*sm_defaults)[2][40];
105
106if (platformCPUFeature(CPU_FEATURE_MOBILE)) {
107if (Platform.CPU.NoCores > 1) {
108sm_defaults=sm_macbookpro_defaults;
109} else {
110sm_defaults=sm_macbook_defaults;
111}
112} else {
113switch (Platform.CPU.NoCores) {
114case 1: sm_defaults=sm_macmini_defaults; break;
115case 2: sm_defaults=sm_imac_defaults; break;
116default: sm_defaults=sm_macpro_defaults; break;
117}
118}
119
120for (i=0;sm_defaults[i][0][0];i++) {
121if (!strcmp (sm_defaults[i][0],name)) {
122return sm_defaults[i][1];
123}
124}
125
126// Shouldn't happen
127printf ("Error: no default for '%s' known\n", name);
128sleep (2);
129return "";
130}
131
132static int sm_get_fsb(char *name, int table_num)
133{
134return Platform.CPU.FSBFrequency/1000000;
135}
136
137static int sm_get_cpu (char *name, int table_num)
138{
139return Platform.CPU.CPUFrequency/1000000;
140}
141
142static int sm_get_cputype (char *name, int table_num)
143{
144if (Platform.CPU.NoCores == 1) {
145return 0x0101; // <01 01> Intel Core Solo?
146} else if (Platform.CPU.NoCores == 2) {
147return 0x0301; // <01 03> Intel Core 2 Duo
148} else if (Platform.CPU.NoCores >= 4) {
149return 0x0501; // <01 05> Quad-Core Intel Xeon
150} else {
151return 0x0301; // Default to Core 2 Duo
152}
153}
154
155static int sm_get_memtype (char *name, int table_num)
156{
157intmap;
158
159if (table_num < MAX_RAM_SLOTS) {
160map = Platform.DMI.DIMM[table_num];
161if (Platform.RAM.DIMM[map].InUse && Platform.RAM.DIMM[map].Type != 0) {
162 DBG("RAM Detected Type = %d\n", Platform.RAM.DIMM[map].Type);
163 return Platform.RAM.DIMM[map].Type;
164}
165}
166return SMB_MEM_TYPE_DDR2;
167}
168
169static int sm_get_memspeed (char *name, int table_num)
170{
171if (Platform.RAM.Frequency != 0) {
172 DBG("RAM Detected Freq = %d\n", Platform.RAM.Frequency/1000000);
173 return Platform.RAM.Frequency/1000000;
174}
175return 800;
176}
177
178static char *sm_get_memvendor (char *name, int table_num)
179{
180intmap;
181
182if (table_num < MAX_RAM_SLOTS) {
183map = Platform.DMI.DIMM[table_num];
184if (Platform.RAM.DIMM[map].InUse && strlen(Platform.RAM.DIMM[map].Vendor) > 0) {
185DBG("RAM Detected Vendor[%d]='%s'\n", table_num, Platform.RAM.DIMM[map].Vendor);
186return Platform.RAM.DIMM[map].Vendor;
187}
188}
189return "N/A";
190}
191
192static char *sm_get_memserial (char *name, int table_num)
193{
194intmap;
195
196if (table_num < MAX_RAM_SLOTS) {
197map = Platform.DMI.DIMM[table_num];
198if (Platform.RAM.DIMM[map].InUse && strlen(Platform.RAM.DIMM[map].SerialNo) > 0) {
199DBG("RAM Detected SerialNo[%d]='%s'\n", table_num, Platform.RAM.DIMM[map].SerialNo);
200return Platform.RAM.DIMM[map].SerialNo;
201}
202}
203return "N/A";
204}
205
206static char *sm_get_mempartno (char *name, int table_num)
207{
208intmap;
209
210if (table_num < MAX_RAM_SLOTS) {
211map = Platform.DMI.DIMM[table_num];
212if (Platform.RAM.DIMM[map].InUse && strlen(Platform.RAM.DIMM[map].PartNo) > 0) {
213DBG("Ram Detected PartNo[%d]='%s'\n", table_num, Platform.RAM.DIMM[map].PartNo);
214return Platform.RAM.DIMM[map].PartNo;
215}
216}
217return "N/A";
218}
219
220static int sm_one (int tablen)
221{
222return 1;
223}
224
225struct smbios_property smbios_properties[]=
226{
227{.name="SMbiosvendor",.table_type= 0,.value_type=SMSTRING,.offset=0x04,.auto_str=sm_get_defstr},
228{.name="SMbiosversion",.table_type= 0,.value_type=SMSTRING,.offset=0x05,.auto_str=sm_get_defstr},
229{.name="SMbiosdate",.table_type= 0,.value_type=SMSTRING,.offset=0x08,.auto_str=sm_get_defstr},
230{.name="SMmanufacter",.table_type= 1,.value_type=SMSTRING,.offset=0x04,.auto_str=sm_get_defstr},
231{.name="SMproductname",.table_type= 1,.value_type=SMSTRING,.offset=0x05,.auto_str=sm_get_defstr},
232{.name="SMsystemversion",.table_type= 1,.value_type=SMSTRING,.offset=0x06,.auto_str=sm_get_defstr},
233{.name="SMserial",.table_type= 1,.value_type=SMSTRING,.offset=0x07,.auto_str=sm_get_defstr},
234{.name="SMUUID",.table_type= 1, .value_type=SMOWORD,.offset=0x08,.auto_oword=0},
235{.name="SMfamily",.table_type= 1,.value_type=SMSTRING,.offset=0x1a,.auto_str=sm_get_defstr},
236{.name="SMboardmanufacter",.table_type= 2, .value_type=SMSTRING,.offset=0x04,.auto_str=sm_get_defstr},
237{.name="SMboardproduct",.table_type= 2, .value_type=SMSTRING,.offset=0x05,.auto_str=sm_get_defstr},
238{.name="SMexternalclock",.table_type= 4,.value_type=SMWORD,.offset=0x12,.auto_int=sm_get_fsb},
239{.name="SMmaximalclock",.table_type= 4,.value_type=SMWORD,.offset=0x14,.auto_int=sm_get_cpu},
240{.name="SMmemdevloc",.table_type=17,.value_type=SMSTRING,.offset=0x10,.auto_str=0},
241{.name="SMmembankloc",.table_type=17,.value_type=SMSTRING,.offset=0x11,.auto_str=0},
242{.name="SMmemtype",.table_type=17,.value_type=SMBYTE,.offset=0x12,.auto_int=sm_get_memtype},
243{.name="SMmemspeed",.table_type=17,.value_type=SMWORD,.offset=0x15,.auto_int=sm_get_memspeed},
244{.name="SMmemmanufacter",.table_type=17,.value_type=SMSTRING,.offset=0x17,.auto_str=sm_get_memvendor},
245{.name="SMmemserial",.table_type=17,.value_type=SMSTRING,.offset=0x18,.auto_str=sm_get_memserial},
246{.name="SMmempart",.table_type=17,.value_type=SMSTRING,.offset=0x1A,.auto_str=sm_get_mempartno},
247{.name="SMcputype",.table_type=131,.value_type=SMWORD,.offset=0x04,.auto_int=sm_get_cputype},
248{.name="SMbusspeed",.table_type=132,.value_type=SMWORD,.offset=0x04,.auto_str=0}
249};
250
251struct smbios_table_description smbios_table_descriptions[]=
252{
253{.type=0,.len=0x18,.numfunc=sm_one},
254{.type=1,.len=0x1b,.numfunc=sm_one},
255{.type=2,.len=0x0f,.numfunc=sm_one},
256{.type=4,.len=0x2a,.numfunc=sm_one},
257{.type=17,.len=0x1c,.numfunc=0},
258{.type=131,.len=0x06,.numfunc=sm_one},
259{.type=132,.len=0x06,.numfunc=sm_one}
260};
261
262// getting smbios addr with fast compare ops, late checksum testing ...
263#define COMPARE_DWORD(a,b) ( *((u_int32_t *) a) == *((u_int32_t *) b) )
264static const char * const SMTAG = "_SM_";
265static const char* const DMITAG= "_DMI_";
266
267static struct SMBEntryPoint *getAddressOfSmbiosTable(void)
268{
269struct SMBEntryPoint*smbios;
270
271/*
272 * The logic is to start at 0xf0000 and end at 0xfffff iterating 16 bytes at a time looking
273 * for the SMBIOS entry-point structure anchor (literal ASCII "_SM_").
274 */
275smbios = (struct SMBEntryPoint*) SMBIOS_RANGE_START;
276while (smbios <= (struct SMBEntryPoint *)SMBIOS_RANGE_END) {
277 if (COMPARE_DWORD(smbios->anchor, SMTAG) && COMPARE_DWORD(smbios->dmi.anchor, DMITAG) &&
278 checksum8(smbios, sizeof(struct SMBEntryPoint)) == 0)
279{
280return smbios;
281}
282 smbios = (((void*) smbios) + 16);
283}
284printf("ERROR: Unable to find SMBIOS!\n");
285sleep(5);
286return NULL;
287}
288
289/* Compute necessary space requirements for new smbios */
290struct SMBEntryPoint *smbios_dry_run(struct SMBEntryPoint *origsmbios)
291{
292struct SMBEntryPoint*ret;
293char*smbiostables;
294char*tablesptr;
295intorigsmbiosnum;
296inti, j;
297inttablespresent[256];
298booldo_auto=true;
299
300bzero(tablespresent, sizeof(tablespresent));
301
302getBoolForKey(kSMBIOSdefaults, &do_auto, &bootInfo->bootConfig);
303
304ret = (struct SMBEntryPoint *)AllocateKernelMemory(sizeof(struct SMBEntryPoint));
305if (origsmbios) {
306smbiostables = (char *)origsmbios->dmi.tableAddress;
307origsmbiosnum = origsmbios->dmi.structureCount;
308} else {
309smbiostables = NULL;
310origsmbiosnum = 0;
311}
312
313// _SM_
314ret->anchor[0] = 0x5f;
315ret->anchor[1] = 0x53;
316ret->anchor[2] = 0x4d;
317ret->anchor[3] = 0x5f;
318ret->entryPointLength = sizeof(*ret);
319ret->majorVersion = 2;
320ret->minorVersion = 1;
321ret->maxStructureSize = 0;
322ret->entryPointRevision = 0;
323for (i=0;i<5;i++) {
324ret->formattedArea[i] = 0;
325}
326//_DMI_
327ret->dmi.anchor[0] = 0x5f;
328ret->dmi.anchor[1] = 0x44;
329ret->dmi.anchor[2] = 0x4d;
330ret->dmi.anchor[3] = 0x49;
331ret->dmi.anchor[4] = 0x5f;
332ret->dmi.tableLength = 0;
333ret->dmi.tableAddress = 0;
334ret->dmi.structureCount = 0;
335ret->dmi.bcdRevision = 0x21;
336tablesptr = smbiostables;
337if (smbiostables) {
338for (i=0; i<origsmbiosnum; i++) {
339struct smbios_table_header*cur = (struct smbios_table_header *)tablesptr;
340char*stringsptr;
341intstringlen;
342
343tablesptr += cur->length;
344stringsptr = tablesptr;
345for (; tablesptr[0]!=0 || tablesptr[1]!=0; tablesptr++);
346tablesptr += 2;
347stringlen = tablesptr - stringsptr - 1;
348if (stringlen == 1) {
349stringlen = 0;
350}
351for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
352const char*str;
353intsize;
354charaltname[40];
355
356sprintf(altname, "%s_%d",smbios_properties[j].name, tablespresent[cur->type] + 1);
357if (smbios_properties[j].table_type == cur->type &&
358 smbios_properties[j].value_type == SMSTRING &&
359 (getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig) ||
360 getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)))
361{
362stringlen += size + 1;
363} else if (smbios_properties[j].table_type == cur->type &&
364 smbios_properties[j].value_type == SMSTRING &&
365 do_auto && smbios_properties[j].auto_str)
366{
367stringlen += strlen(smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[cur->type])) + 1;
368}
369}
370if (stringlen == 0) {
371stringlen = 1;
372}
373stringlen++;
374if (ret->maxStructureSize < cur->length+stringlen) {
375ret->maxStructureSize=cur->length+stringlen;
376}
377ret->dmi.tableLength += cur->length+stringlen;
378ret->dmi.structureCount++;
379tablespresent[cur->type]++;
380}
381}
382for (i=0; i<sizeof(smbios_table_descriptions)/sizeof(smbios_table_descriptions[0]); i++) {
383intnumnec=-1;
384charbuffer[40];
385
386sprintf(buffer, "SMtable%d", i);
387if (!getIntForKey(buffer, &numnec, &bootInfo->smbiosConfig)) {
388numnec = -1;
389}
390if (numnec==-1 && do_auto && smbios_table_descriptions[i].numfunc) {
391numnec = smbios_table_descriptions[i].numfunc(smbios_table_descriptions[i].type);
392}
393while (tablespresent[smbios_table_descriptions[i].type] < numnec) {
394intstringlen = 0;
395for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
396const char*str;
397intsize;
398charaltname[40];
399
400sprintf(altname, "%s_%d",smbios_properties[j].name, tablespresent[smbios_table_descriptions[i].type] + 1);
401if (smbios_properties[j].table_type == smbios_table_descriptions[i].type &&
402 smbios_properties[j].value_type == SMSTRING &&
403 (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
404 getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig)))
405{
406stringlen += size + 1;
407} else if (smbios_properties[j].table_type == smbios_table_descriptions[i].type &&
408 smbios_properties[j].value_type==SMSTRING &&
409 do_auto && smbios_properties[j].auto_str)
410{
411stringlen += strlen(smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[smbios_table_descriptions[i].type])) + 1;
412}
413}
414if (stringlen == 0) {
415stringlen = 1;
416}
417stringlen++;
418if (ret->maxStructureSize < smbios_table_descriptions[i].len+stringlen) {
419ret->maxStructureSize = smbios_table_descriptions[i].len + stringlen;
420}
421ret->dmi.tableLength += smbios_table_descriptions[i].len + stringlen;
422ret->dmi.structureCount++;
423tablespresent[smbios_table_descriptions[i].type]++;
424}
425}
426return ret;
427}
428
429void smbios_real_run(struct SMBEntryPoint * origsmbios, struct SMBEntryPoint * newsmbios)
430{
431char *smbiostables;
432char *tablesptr, *newtablesptr;
433int origsmbiosnum;
434// bitmask of used handles
435uint8_t handles[8192];
436uint16_t nexthandle=0;
437int i, j;
438int tablespresent[256];
439bool do_auto=true;
440
441bzero(tablespresent, sizeof(tablespresent));
442bzero(handles, sizeof(handles));
443
444getBoolForKey(kSMBIOSdefaults, &do_auto, &bootInfo->bootConfig);
445
446newsmbios->dmi.tableAddress = (uint32_t)AllocateKernelMemory(newsmbios->dmi.tableLength);
447if (origsmbios) {
448smbiostables = (char *)origsmbios->dmi.tableAddress;
449origsmbiosnum = origsmbios->dmi.structureCount;
450} else {
451smbiostables = NULL;
452origsmbiosnum = 0;
453}
454tablesptr = smbiostables;
455newtablesptr = (char *)newsmbios->dmi.tableAddress;
456if (smbiostables) {
457for (i=0; i<origsmbiosnum; i++) {
458struct smbios_table_header*oldcur = (struct smbios_table_header *) tablesptr;
459struct smbios_table_header*newcur = (struct smbios_table_header *) newtablesptr;
460char*stringsptr;
461intnstrings = 0;
462
463handles[(oldcur->handle) / 8] |= 1 << ((oldcur->handle) % 8);
464memcpy(newcur,oldcur, oldcur->length);
465
466tablesptr += oldcur->length;
467stringsptr = tablesptr;
468newtablesptr += oldcur->length;
469for (;tablesptr[0]!=0 || tablesptr[1]!=0; tablesptr++) {
470if (tablesptr[0] == 0) {
471nstrings++;
472}
473}
474if (tablesptr != stringsptr) {
475nstrings++;
476}
477tablesptr += 2;
478memcpy(newtablesptr, stringsptr, tablesptr-stringsptr);
479//point to next possible space for a string
480newtablesptr += tablesptr - stringsptr - 1;
481if (nstrings == 0) {
482newtablesptr--;
483}
484for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
485const char*str;
486intsize;
487intnum;
488charaltname[40];
489
490sprintf(altname, "%s_%d", smbios_properties[j].name, tablespresent[newcur->type] + 1);
491if (smbios_properties[j].table_type == newcur->type) {
492switch (smbios_properties[j].value_type) {
493case SMSTRING:
494if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
495 getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
496{
497memcpy(newtablesptr, str, size);
498newtablesptr[size] = 0;
499newtablesptr += size + 1;
500*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
501} else if (do_auto && smbios_properties[j].auto_str) {
502str = smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]);
503size = strlen(str);
504memcpy(newtablesptr, str, size);
505newtablesptr[size] = 0;
506newtablesptr += size + 1;
507*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
508}
509break;
510
511case SMOWORD:
512if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
513 getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
514{
515intk=0, t=0, kk=0;
516const char*ptr = str;
517memset(((char*)newcur) + smbios_properties[j].offset, 0, 16);
518while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n')) {
519ptr++;
520}
521if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X')) {
522ptr += 2;
523}
524for (;ptr-str<size && *ptr && k<16;ptr++) {
525if (*ptr>='0' && *ptr<='9') {
526(t=(t<<4)|(*ptr-'0')),kk++;
527}
528if (*ptr>='a' && *ptr<='f') {
529(t=(t<<4)|(*ptr-'a'+10)),kk++;
530}
531if (*ptr>='A' && *ptr<='F') {
532(t=(t<<4)|(*ptr-'A'+10)),kk++;
533}
534if (kk == 2) {
535*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset + k)) = t;
536k++;
537kk = 0;
538t = 0;
539}
540}
541}
542break;
543
544case SMBYTE:
545if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
546 getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
547{
548*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
549} else if (do_auto && smbios_properties[j].auto_int) {
550*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
551}
552break;
553
554case SMWORD:
555if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
556 getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
557{
558*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
559} else if (do_auto && smbios_properties[j].auto_int) {
560*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
561}
562break;
563}
564}
565}
566if (nstrings == 0) {
567newtablesptr[0] = 0;
568newtablesptr++;
569}
570newtablesptr[0] = 0;
571newtablesptr++;
572tablespresent[newcur->type]++;
573}
574}
575for (i=0; i<sizeof(smbios_table_descriptions)/sizeof(smbios_table_descriptions[0]); i++) {
576intnumnec = -1;
577charbuffer[40];
578
579sprintf(buffer, "SMtable%d", i);
580if (!getIntForKey(buffer, &numnec, &bootInfo->smbiosConfig)) {
581numnec = -1;
582}
583if (numnec == -1 && do_auto && smbios_table_descriptions[i].numfunc) {
584numnec = smbios_table_descriptions[i].numfunc(smbios_table_descriptions[i].type);
585}
586while (tablespresent[smbios_table_descriptions[i].type] < numnec) {
587struct smbios_table_header*newcur = (struct smbios_table_header *) newtablesptr;
588intnstrings = 0;
589
590memset(newcur,0, smbios_table_descriptions[i].len);
591while (handles[(nexthandle)/8] & (1 << ((nexthandle) % 8))) {
592nexthandle++;
593}
594newcur->handle = nexthandle;
595handles[nexthandle / 8] |= 1 << (nexthandle % 8);
596newcur->type = smbios_table_descriptions[i].type;
597newcur->length = smbios_table_descriptions[i].len;
598newtablesptr += smbios_table_descriptions[i].len;
599for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
600const char*str;
601intsize;
602intnum;
603charaltname[40];
604
605sprintf(altname, "%s_%d", smbios_properties[j].name, tablespresent[newcur->type] + 1);
606if (smbios_properties[j].table_type == newcur->type) {
607switch (smbios_properties[j].value_type) {
608case SMSTRING:
609if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
610 getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
611{
612memcpy(newtablesptr, str, size);
613newtablesptr[size] = 0;
614newtablesptr += size + 1;
615*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
616} else if (do_auto && smbios_properties[j].auto_str) {
617str = smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]);
618size = strlen(str);
619memcpy(newtablesptr, str, size);
620newtablesptr[size] = 0;
621newtablesptr += size + 1;
622*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
623}
624break;
625
626case SMOWORD:
627if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
628 getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
629{
630intk=0, t=0, kk=0;
631const char*ptr = str;
632
633memset(((char*)newcur) + smbios_properties[j].offset, 0, 16);
634while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n')) {
635ptr++;
636}
637if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X')) {
638ptr += 2;
639}
640for (;ptr-str<size && *ptr && k<16;ptr++) {
641if (*ptr>='0' && *ptr<='9') {
642(t=(t<<4)|(*ptr-'0')),kk++;
643}
644if (*ptr>='a' && *ptr<='f') {
645(t=(t<<4)|(*ptr-'a'+10)),kk++;
646}
647if (*ptr>='A' && *ptr<='F') {
648(t=(t<<4)|(*ptr-'A'+10)),kk++;
649}
650if (kk == 2) {
651*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset + k)) = t;
652k++;
653kk = 0;
654t = 0;
655}
656}
657}
658break;
659
660case SMBYTE:
661if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
662 getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
663{
664*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
665} else if (do_auto && smbios_properties[j].auto_int) {
666*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
667}
668break;
669
670case SMWORD:
671if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
672 getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
673{
674*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
675} else if (do_auto && smbios_properties[j].auto_int) {
676*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
677}
678break;
679}
680}
681}
682if (nstrings == 0) {
683newtablesptr[0] = 0;
684newtablesptr++;
685}
686newtablesptr[0] = 0;
687newtablesptr++;
688tablespresent[smbios_table_descriptions[i].type]++;
689}
690}
691newsmbios->dmi.checksum = 0;
692newsmbios->dmi.checksum = 256 - checksum8(&newsmbios->dmi, sizeof(newsmbios->dmi));
693newsmbios->checksum = 0;
694newsmbios->checksum = 256 - checksum8(newsmbios, sizeof(*newsmbios));
695verbose("Patched DMI Table\n");
696}
697
698struct SMBEntryPoint *getSmbios(int which)
699{
700 static struct SMBEntryPoint *orig = NULL; // cached
701 static struct SMBEntryPoint *patched = NULL; // cached
702
703if (orig == NULL) orig = getAddressOfSmbiosTable();
704
705switch (which) {
706case SMBIOS_ORIGINAL:
707 return orig;
708case SMBIOS_PATCHED:
709 if (patched == NULL) {
710 patched = smbios_dry_run(orig);
711 smbios_real_run(orig, patched);
712 }
713 return patched;
714default:
715 printf("ERROR: invalid option for getSmbios() !!\n");
716 return NULL;
717}
718}
719
720/**
721 * Get a table structure entry from a type specification and a smbios address
722 * return NULL if table is not found
723 */
724struct DMIHeader *getSmbiosTableStructure(struct SMBEntryPoint*smbios, int type, int min_length)
725{
726 struct DMIHeader * dmihdr=NULL;
727 bool found = false;
728 SMBByte* p;
729 int i;
730
731 if (smbios == NULL || type < 0 ) return NULL;
732#if DEBUG_SMBIOS
733printf(">>> SMBIOSAddr=0x%08x\n", smbios);
734printf(">>> DMI: addr=0x%08x, len=0x%d, count=%d\n", smbios->dmi.tableAddress,
735smbios->dmi.tableLength, smbios->dmi.structureCount);
736#endif
737p = (SMBByte *) smbios->dmi.tableAddress;
738for (i=0; i < smbios->dmi.structureCount && p + 4 <= (SMBByte *)smbios->dmi.tableAddress + smbios->dmi.tableLength; i++)
739{
740 dmihdr = (struct DMIHeader *) p;
741#if DEBUG_SMBIOS
742 verbose(">>>>>> DMI(%d): type=0x%02x, len=0x%d\n",i,dmihdr->type,dmihdr->length);
743#endif
744 if (dmihdr->length < 4 || dmihdr->type == 127 /* EOT */) break;
745 if (dmihdr->type == type) /* 3.3.2 System Information */
746{
747 if (dmihdr->length >= min_length) found = true;
748 break;
749}
750 p = p + dmihdr->length;
751 while ((p - (SMBByte *)smbios->dmi.tableAddress + 1 < smbios->dmi.tableLength) && (p[0] != 0x00 || p[1] != 0x00))
752{
753 p++;
754}
755 p += 2;
756}
757
758#if DEBUG_SMBIOS
759 printf("DMI header found for table type %d, length = %d\n", type, dmihdr->type, dmihdr->length);
760#endif
761return found ? dmihdr : NULL;
762 }
763

Archive Download this file

Revision: 106