Chameleon

Chameleon Svn Source Tree

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

1/*
2 * Copyright 2008 mackerintel
3 */
4
5#include "libsaio.h"
6#include "boot.h"
7#include "bootstruct.h"
8#include "acpi.h"
9#include "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 0
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{
157if (table_num < MAX_RAM_SLOTS &&
158 Platform.RAM.DIMM[table_num].InUse &&
159 Platform.RAM.DIMM[table_num].Type != 0)
160{
161return Platform.RAM.DIMM[table_num].Type;
162}
163return SMB_MEM_TYPE_DDR2;
164}
165
166static int sm_get_memspeed (char *name, int table_num)
167{
168if (Platform.RAM.Frequency != 0) {
169return Platform.RAM.Frequency/1000000;
170}
171return 667;
172}
173
174static char *sm_get_memvendor (char *name, int table_num)
175{
176if (table_num < MAX_RAM_SLOTS &&
177 Platform.RAM.DIMM[table_num].InUse &&
178 strlen(Platform.RAM.DIMM[table_num].Vendor) > 0)
179{
180DBG("Vendor[%d]='%s'\n", table_num, Platform.RAM.DIMM[table_num].Vendor);
181return Platform.RAM.DIMM[table_num].Vendor;
182}
183return "N/A";
184}
185
186static char *sm_get_memserial (char *name, int table_num)
187{
188if (table_num < MAX_RAM_SLOTS &&
189 Platform.RAM.DIMM[table_num].InUse &&
190 strlen(Platform.RAM.DIMM[table_num].SerialNo) > 0)
191{
192DBG("SerialNo[%d]='%s'\n", table_num, Platform.RAM.DIMM[table_num].SerialNo);
193return Platform.RAM.DIMM[table_num].SerialNo;
194}
195return "N/A";
196}
197
198static char *sm_get_mempartno (char *name, int table_num)
199{
200if (table_num < MAX_RAM_SLOTS &&
201 Platform.RAM.DIMM[table_num].InUse &&
202 strlen(Platform.RAM.DIMM[table_num].PartNo) > 0)
203{
204DBG("PartNo[%d]='%s'\n", table_num, Platform.RAM.DIMM[table_num].PartNo);
205return Platform.RAM.DIMM[table_num].PartNo;
206}
207return "N/A";
208}
209
210static int sm_one (int tablen)
211{
212return 1;
213}
214
215struct smbios_property smbios_properties[]=
216{
217{.name="SMbiosvendor",.table_type= 0,.value_type=SMSTRING,.offset=0x04,.auto_str=sm_get_defstr},
218{.name="SMbiosversion",.table_type= 0,.value_type=SMSTRING,.offset=0x05,.auto_str=sm_get_defstr},
219{.name="SMbiosdate",.table_type= 0,.value_type=SMSTRING,.offset=0x08,.auto_str=sm_get_defstr},
220{.name="SMmanufacter",.table_type= 1,.value_type=SMSTRING,.offset=0x04,.auto_str=sm_get_defstr},
221{.name="SMproductname",.table_type= 1,.value_type=SMSTRING,.offset=0x05,.auto_str=sm_get_defstr},
222{.name="SMsystemversion",.table_type= 1,.value_type=SMSTRING,.offset=0x06,.auto_str=sm_get_defstr},
223{.name="SMserial",.table_type= 1,.value_type=SMSTRING,.offset=0x07,.auto_str=sm_get_defstr},
224{.name="SMUUID",.table_type= 1, .value_type=SMOWORD,.offset=0x08,.auto_oword=0},
225{.name="SMfamily",.table_type= 1,.value_type=SMSTRING,.offset=0x1a,.auto_str=sm_get_defstr},
226{.name="SMboardmanufacter",.table_type= 2, .value_type=SMSTRING,.offset=0x04,.auto_str=sm_get_defstr},
227{.name="SMboardproduct",.table_type= 2, .value_type=SMSTRING,.offset=0x05,.auto_str=sm_get_defstr},
228{.name="SMexternalclock",.table_type= 4,.value_type=SMWORD,.offset=0x12,.auto_int=sm_get_fsb},
229{.name="SMmaximalclock",.table_type= 4,.value_type=SMWORD,.offset=0x14,.auto_int=sm_get_cpu},
230{.name="SMmemdevloc",.table_type=17,.value_type=SMSTRING,.offset=0x10,.auto_str=0},
231{.name="SMmembankloc",.table_type=17,.value_type=SMSTRING,.offset=0x11,.auto_str=0},
232{.name="SMmemtype",.table_type=17,.value_type=SMBYTE,.offset=0x12,.auto_int=sm_get_memtype},
233{.name="SMmemspeed",.table_type=17,.value_type=SMWORD,.offset=0x15,.auto_int=sm_get_memspeed},
234{.name="SMmemmanufacter",.table_type=17,.value_type=SMSTRING,.offset=0x17,.auto_str=sm_get_memvendor},
235{.name="SMmemserial",.table_type=17,.value_type=SMSTRING,.offset=0x18,.auto_str=sm_get_memserial},
236{.name="SMmempart",.table_type=17,.value_type=SMSTRING,.offset=0x1A,.auto_str=sm_get_mempartno},
237{.name="SMcputype",.table_type=131,.value_type=SMWORD,.offset=0x04,.auto_int=sm_get_cputype},
238{.name="SMbusspeed",.table_type=132,.value_type=SMWORD,.offset=0x04,.auto_str=0}
239};
240
241struct smbios_table_description smbios_table_descriptions[]=
242{
243{.type=0,.len=0x18,.numfunc=sm_one},
244{.type=1,.len=0x1b,.numfunc=sm_one},
245{.type=2,.len=0x0f,.numfunc=sm_one},
246{.type=4,.len=0x2a,.numfunc=sm_one},
247{.type=17,.len=0x1c,.numfunc=0},
248{.type=131,.len=0x06,.numfunc=sm_one},
249{.type=132,.len=0x06,.numfunc=sm_one}
250};
251
252struct SMBEntryPoint *getAddressOfSmbiosTable(void)
253{
254/* First see if we can even find the damn SMBIOS table
255 * The logic here is to start at 0xf0000 and end at 0xfffff iterating 16 bytes at a time looking
256 * for the SMBIOS entry-point structure anchor (literal ASCII "_SM_").
257 */
258void *smbios_addr = (void*)SMBIOS_RANGE_START;
259
260for (; (smbios_addr<=(void*)SMBIOS_RANGE_END) && (*(uint32_t*)smbios_addr!=SMBIOS_ANCHOR_UINT32_LE); smbios_addr+=16) ;
261if (smbios_addr <= (void*)SMBIOS_RANGE_END) {
262/* NOTE: The specification does not specifically state what to do in the event of finding an
263 * SMBIOS anchor on an invalid table. It might be better to move this code into the for loop
264 * so that searching can continue.
265 */
266uint8_t csum = checksum8(smbios_addr, sizeof(struct SMBEntryPoint));
267/* The table already contains the checksum so we merely need to see if its checksum is now zero. */
268if (csum != 0) {
269printf("Found SMBIOS anchor but bad table checksum. Assuming no SMBIOS.\n");
270sleep(5);
271smbios_addr = 0;
272}
273} else {
274/* If this happens, it's possible that a PnP BIOS call can be done to retrieve the address of the table.
275 * The latest versions of the spec state that modern programs should not even attempt to do this.
276 */
277printf("Unable to find SMBIOS table.\n");
278sleep(5);
279smbios_addr = 0;
280}
281return smbios_addr;
282}
283
284/* Compute necessary space requirements for new smbios */
285struct SMBEntryPoint *smbios_dry_run(struct SMBEntryPoint *origsmbios)
286{
287struct SMBEntryPoint*ret;
288char*smbiostables;
289char*tablesptr;
290intorigsmbiosnum;
291inti, j;
292inttablespresent[256];
293booldo_auto=true;
294
295bzero(tablespresent, sizeof(tablespresent));
296
297getBoolForKey(kSMBIOSdefaults, &do_auto, &bootInfo->bootConfig);
298
299ret = (struct SMBEntryPoint *)AllocateKernelMemory(sizeof(struct SMBEntryPoint));
300if (origsmbios) {
301smbiostables = (char *)origsmbios->dmi.tableAddress;
302origsmbiosnum = origsmbios->dmi.structureCount;
303} else {
304smbiostables = NULL;
305origsmbiosnum = 0;
306}
307
308// _SM_
309ret->anchor[0] = 0x5f;
310ret->anchor[1] = 0x53;
311ret->anchor[2] = 0x4d;
312ret->anchor[3] = 0x5f;
313ret->entryPointLength = sizeof(*ret);
314ret->majorVersion = 2;
315ret->minorVersion = 1;
316ret->maxStructureSize = 0;
317ret->entryPointRevision = 0;
318for (i=0;i<5;i++) {
319ret->formattedArea[i] = 0;
320}
321//_DMI_
322ret->dmi.anchor[0] = 0x5f;
323ret->dmi.anchor[1] = 0x44;
324ret->dmi.anchor[2] = 0x4d;
325ret->dmi.anchor[3] = 0x49;
326ret->dmi.anchor[4] = 0x5f;
327ret->dmi.tableLength = 0;
328ret->dmi.tableAddress = 0;
329ret->dmi.structureCount = 0;
330ret->dmi.bcdRevision = 0x21;
331tablesptr = smbiostables;
332if (smbiostables) {
333for (i=0; i<origsmbiosnum; i++) {
334struct smbios_table_header*cur = (struct smbios_table_header *)tablesptr;
335char*stringsptr;
336intstringlen;
337
338tablesptr += cur->length;
339stringsptr = tablesptr;
340for (; tablesptr[0]!=0 || tablesptr[1]!=0; tablesptr++);
341tablesptr += 2;
342stringlen = tablesptr - stringsptr - 1;
343if (stringlen == 1) {
344stringlen = 0;
345}
346for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
347const char*str;
348intsize;
349charaltname[40];
350
351sprintf(altname, "%s_%d",smbios_properties[j].name, tablespresent[cur->type] + 1);
352if (smbios_properties[j].table_type == cur->type &&
353 smbios_properties[j].value_type == SMSTRING &&
354 (getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig) ||
355 getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)))
356{
357stringlen += size + 1;
358} else if (smbios_properties[j].table_type == cur->type &&
359 smbios_properties[j].value_type == SMSTRING &&
360 do_auto && smbios_properties[j].auto_str)
361{
362stringlen += strlen(smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[cur->type])) + 1;
363}
364}
365if (stringlen == 0) {
366stringlen = 1;
367}
368stringlen++;
369if (ret->maxStructureSize < cur->length+stringlen) {
370ret->maxStructureSize=cur->length+stringlen;
371}
372ret->dmi.tableLength += cur->length+stringlen;
373ret->dmi.structureCount++;
374tablespresent[cur->type]++;
375}
376}
377for (i=0; i<sizeof(smbios_table_descriptions)/sizeof(smbios_table_descriptions[0]); i++) {
378intnumnec=-1;
379charbuffer[40];
380
381sprintf(buffer, "SMtable%d", i);
382if (!getIntForKey(buffer, &numnec, &bootInfo->smbiosConfig)) {
383numnec = -1;
384}
385if (numnec==-1 && do_auto && smbios_table_descriptions[i].numfunc) {
386numnec = smbios_table_descriptions[i].numfunc(smbios_table_descriptions[i].type);
387}
388while (tablespresent[smbios_table_descriptions[i].type] < numnec) {
389intstringlen = 0;
390for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
391const char*str;
392intsize;
393charaltname[40];
394
395sprintf(altname, "%s_%d",smbios_properties[j].name, tablespresent[smbios_table_descriptions[i].type] + 1);
396if (smbios_properties[j].table_type == smbios_table_descriptions[i].type &&
397 smbios_properties[j].value_type == SMSTRING &&
398 (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
399 getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig)))
400{
401stringlen += size + 1;
402} else if (smbios_properties[j].table_type == smbios_table_descriptions[i].type &&
403 smbios_properties[j].value_type==SMSTRING &&
404 do_auto && smbios_properties[j].auto_str)
405{
406stringlen += strlen(smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[smbios_table_descriptions[i].type])) + 1;
407}
408}
409if (stringlen == 0) {
410stringlen = 1;
411}
412stringlen++;
413if (ret->maxStructureSize < smbios_table_descriptions[i].len+stringlen) {
414ret->maxStructureSize = smbios_table_descriptions[i].len + stringlen;
415}
416ret->dmi.tableLength += smbios_table_descriptions[i].len + stringlen;
417ret->dmi.structureCount++;
418tablespresent[smbios_table_descriptions[i].type]++;
419}
420}
421return ret;
422}
423
424void smbios_real_run(struct SMBEntryPoint * origsmbios, struct SMBEntryPoint * newsmbios)
425{
426char *smbiostables;
427char *tablesptr, *newtablesptr;
428int origsmbiosnum;
429// bitmask of used handles
430uint8_t handles[8192];
431uint16_t nexthandle=0;
432int i, j;
433int tablespresent[256];
434bool do_auto=true;
435
436bzero(tablespresent, sizeof(tablespresent));
437bzero(handles, sizeof(handles));
438
439getBoolForKey(kSMBIOSdefaults, &do_auto, &bootInfo->bootConfig);
440
441newsmbios->dmi.tableAddress = (uint32_t)AllocateKernelMemory(newsmbios->dmi.tableLength);
442if (origsmbios) {
443smbiostables = (char *)origsmbios->dmi.tableAddress;
444origsmbiosnum = origsmbios->dmi.structureCount;
445} else {
446smbiostables = NULL;
447origsmbiosnum = 0;
448}
449tablesptr = smbiostables;
450newtablesptr = (char *)newsmbios->dmi.tableAddress;
451if (smbiostables) {
452for (i=0; i<origsmbiosnum; i++) {
453struct smbios_table_header*oldcur = (struct smbios_table_header *) tablesptr;
454struct smbios_table_header*newcur = (struct smbios_table_header *) newtablesptr;
455char*stringsptr;
456intnstrings = 0;
457
458handles[(oldcur->handle) / 8] |= 1 << ((oldcur->handle) % 8);
459memcpy(newcur,oldcur, oldcur->length);
460
461tablesptr += oldcur->length;
462stringsptr = tablesptr;
463newtablesptr += oldcur->length;
464for (;tablesptr[0]!=0 || tablesptr[1]!=0; tablesptr++) {
465if (tablesptr[0] == 0) {
466nstrings++;
467}
468}
469if (tablesptr != stringsptr) {
470nstrings++;
471}
472tablesptr += 2;
473memcpy(newtablesptr, stringsptr, tablesptr-stringsptr);
474//point to next possible space for a string
475newtablesptr += tablesptr - stringsptr - 1;
476if (nstrings == 0) {
477newtablesptr--;
478}
479for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
480const char*str;
481intsize;
482intnum;
483charaltname[40];
484
485sprintf(altname, "%s_%d", smbios_properties[j].name, tablespresent[newcur->type] + 1);
486if (smbios_properties[j].table_type == newcur->type) {
487switch (smbios_properties[j].value_type) {
488case SMSTRING:
489if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
490 getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
491{
492memcpy(newtablesptr, str, size);
493newtablesptr[size] = 0;
494newtablesptr += size + 1;
495*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
496} else if (do_auto && smbios_properties[j].auto_str) {
497str = smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]);
498size = strlen(str);
499memcpy(newtablesptr, str, size);
500newtablesptr[size] = 0;
501newtablesptr += size + 1;
502*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
503}
504break;
505
506case SMOWORD:
507if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
508 getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
509{
510intk=0, t=0, kk=0;
511const char*ptr = str;
512memset(((char*)newcur) + smbios_properties[j].offset, 0, 16);
513while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n')) {
514ptr++;
515}
516if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X')) {
517ptr += 2;
518}
519for (;ptr-str<size && *ptr && k<16;ptr++) {
520if (*ptr>='0' && *ptr<='9') {
521(t=(t<<4)|(*ptr-'0')),kk++;
522}
523if (*ptr>='a' && *ptr<='f') {
524(t=(t<<4)|(*ptr-'a'+10)),kk++;
525}
526if (*ptr>='A' && *ptr<='F') {
527(t=(t<<4)|(*ptr-'A'+10)),kk++;
528}
529if (kk == 2) {
530*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset + k)) = t;
531k++;
532kk = 0;
533t = 0;
534}
535}
536}
537break;
538
539case SMBYTE:
540if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
541 getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
542{
543*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
544} else if (do_auto && smbios_properties[j].auto_int) {
545*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
546}
547break;
548
549case SMWORD:
550if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
551 getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
552{
553*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
554} else if (do_auto && smbios_properties[j].auto_int) {
555*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
556}
557break;
558}
559}
560}
561if (nstrings == 0) {
562newtablesptr[0] = 0;
563newtablesptr++;
564}
565newtablesptr[0] = 0;
566newtablesptr++;
567tablespresent[newcur->type]++;
568}
569}
570for (i=0; i<sizeof(smbios_table_descriptions)/sizeof(smbios_table_descriptions[0]); i++) {
571intnumnec = -1;
572charbuffer[40];
573
574sprintf(buffer, "SMtable%d", i);
575if (!getIntForKey(buffer, &numnec, &bootInfo->smbiosConfig)) {
576numnec = -1;
577}
578if (numnec == -1 && do_auto && smbios_table_descriptions[i].numfunc) {
579numnec = smbios_table_descriptions[i].numfunc(smbios_table_descriptions[i].type);
580}
581while (tablespresent[smbios_table_descriptions[i].type] < numnec) {
582struct smbios_table_header*newcur = (struct smbios_table_header *) newtablesptr;
583intnstrings = 0;
584
585memset(newcur,0, smbios_table_descriptions[i].len);
586while (handles[(nexthandle)/8] & (1 << ((nexthandle) % 8))) {
587nexthandle++;
588}
589newcur->handle = nexthandle;
590handles[nexthandle / 8] |= 1 << (nexthandle % 8);
591newcur->type = smbios_table_descriptions[i].type;
592newcur->length = smbios_table_descriptions[i].len;
593newtablesptr += smbios_table_descriptions[i].len;
594for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
595const char*str;
596intsize;
597intnum;
598charaltname[40];
599
600sprintf(altname, "%s_%d", smbios_properties[j].name, tablespresent[newcur->type] + 1);
601if (smbios_properties[j].table_type == newcur->type) {
602switch (smbios_properties[j].value_type) {
603case SMSTRING:
604if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
605 getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
606{
607memcpy(newtablesptr, str, size);
608newtablesptr[size] = 0;
609newtablesptr += size + 1;
610*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
611} else if (do_auto && smbios_properties[j].auto_str) {
612str = smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]);
613size = strlen(str);
614memcpy(newtablesptr, str, size);
615newtablesptr[size] = 0;
616newtablesptr += size + 1;
617*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
618}
619break;
620
621case SMOWORD:
622if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
623 getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
624{
625intk=0, t=0, kk=0;
626const char*ptr = str;
627
628memset(((char*)newcur) + smbios_properties[j].offset, 0, 16);
629while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n')) {
630ptr++;
631}
632if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X')) {
633ptr += 2;
634}
635for (;ptr-str<size && *ptr && k<16;ptr++) {
636if (*ptr>='0' && *ptr<='9') {
637(t=(t<<4)|(*ptr-'0')),kk++;
638}
639if (*ptr>='a' && *ptr<='f') {
640(t=(t<<4)|(*ptr-'a'+10)),kk++;
641}
642if (*ptr>='A' && *ptr<='F') {
643(t=(t<<4)|(*ptr-'A'+10)),kk++;
644}
645if (kk == 2) {
646*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset + k)) = t;
647k++;
648kk = 0;
649t = 0;
650}
651}
652}
653break;
654
655case SMBYTE:
656if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
657 getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
658{
659*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
660} else if (do_auto && smbios_properties[j].auto_int) {
661*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
662}
663break;
664
665case SMWORD:
666if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
667 getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
668{
669*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
670} else if (do_auto && smbios_properties[j].auto_int) {
671*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
672}
673break;
674}
675}
676}
677if (nstrings == 0) {
678newtablesptr[0] = 0;
679newtablesptr++;
680}
681newtablesptr[0] = 0;
682newtablesptr++;
683tablespresent[smbios_table_descriptions[i].type]++;
684}
685}
686newsmbios->dmi.checksum = 0;
687newsmbios->dmi.checksum = 256 - checksum8(&newsmbios->dmi, sizeof(newsmbios->dmi));
688newsmbios->checksum = 0;
689newsmbios->checksum = 256 - checksum8(newsmbios, sizeof(*newsmbios));
690verbose("Patched DMI Table\n");
691}
692
693struct SMBEntryPoint *getSmbios(void)
694{
695struct SMBEntryPoint *orig_address;
696struct SMBEntryPoint *new_address;
697
698orig_address=getAddressOfSmbiosTable();
699new_address = smbios_dry_run(orig_address);
700smbios_real_run(orig_address, new_address);
701return new_address;
702}
703

Archive Download this file

Revision: 141