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