Chameleon

Chameleon Svn Source Tree

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

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

Archive Download this file

Revision: 24