Chameleon

Chameleon Svn Source Tree

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

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

Archive Download this file

Revision: 20