Root/
Source at commit 214 created 13 years 5 months ago. By ifabio, update to chameleon trunk 630, and now the pakage folder is the same as blackosx branch, also add Icon "building" into buildpkg script, and add mint theme info into the English localizable.strings. | |
---|---|
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 "pci.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 | typedef struct {␊ |
26 | const char* key;␊ |
27 | const char* value;␊ |
28 | } SMStrEntryPair;␊ |
29 | ␊ |
30 | // defaults for a MacBook␊ |
31 | static const SMStrEntryPair const sm_macbook_defaults[]={␊ |
32 | ␉{"SMbiosvendor",␉"Apple Inc."␉␉␉},␊ |
33 | ␉{"SMbiosversion",␉"MB41.88Z.0073.B00.0809221748"␉},␊ |
34 | ␉{"SMbiosdate",␉␉"04/01/2008"␉␉␉},␊ |
35 | ␉{"SMmanufacter",␉"Apple Inc."␉␉␉},␊ |
36 | ␉{"SMproductname",␉"MacBook4,1"␉␉␉},␊ |
37 | ␉{"SMsystemversion",␉"1.0"␉␉␉␉},␊ |
38 | ␉{"SMserial",␉␉"W8826DJD0P1"␉␉␉},␊ |
39 | ␉{"SMfamily",␉␉"MacBook"␉␉␉},␊ |
40 | ␉{"SMboardmanufacter",␉"Apple Inc."␉␉␉},␊ |
41 | ␉{"SMboardproduct",␉"Mac-F42D89C8"␉␉␉},␊ |
42 | ␉{ "",""␉}␊ |
43 | };␊ |
44 | ␊ |
45 | // defaults for a MacBook Pro␊ |
46 | static const SMStrEntryPair const sm_macbookpro_defaults[]={␊ |
47 | ␉{"SMbiosvendor",␉"Apple Inc."␉␉␉},␊ |
48 | ␉{"SMbiosversion",␉"MBP41.88Z.0073.B00.0809221748"␉},␊ |
49 | ␉{"SMbiosdate",␉␉"04/01/2008"␉␉␉},␊ |
50 | ␉{"SMmanufacter",␉"Apple Inc."␉␉␉},␊ |
51 | ␉{"SMproductname",␉"MacBookPro4,1"␉␉␉},␊ |
52 | ␉{"SMsystemversion",␉"1.0"␉␉␉␉},␊ |
53 | ␉{"SMserial",␉␉"W88261E7YP4"␉␉␉},␊ |
54 | ␉{"SMfamily",␉␉"MacBookPro"␉␉␉},␊ |
55 | ␉{"SMboardmanufacter",␉"Apple Inc."␉␉␉},␊ |
56 | ␉{"SMboardproduct",␉"Mac-F42D89C8"␉␉␉},␊ |
57 | ␉{ "",""␉}␊ |
58 | };␊ |
59 | ␊ |
60 | // defaults for a Mac mini ␊ |
61 | static const SMStrEntryPair const sm_macmini_defaults[]={␊ |
62 | ␉{"SMbiosvendor",␉"Apple Inc."␉␉␉},␊ |
63 | ␉{"SMbiosversion",␉"MM21.88Z.009A.B00.0706281359"␉},␊ |
64 | ␉{"SMbiosdate",␉␉"04/01/2008"␉␉␉},␊ |
65 | ␉{"SMmanufacter",␉"Apple Inc."␉␉␉},␊ |
66 | ␉{"SMproductname",␉"Macmini2,1"␉␉␉},␊ |
67 | ␉{"SMsystemversion",␉"1.0"␉␉␉␉},␊ |
68 | ␉{"SMserial",␉␉"G8830338YL3"␉␉␉},␊ |
69 | ␉{"SMfamily",␉␉"Napa Mac"␉␉␉},␊ |
70 | ␉{"SMboardmanufacter",␉"Apple Inc."␉␉␉},␊ |
71 | ␉{"SMboardproduct",␉"Mac-F4208EAA"␉␉␉},␊ |
72 | ␉{ "",""␉}␊ |
73 | };␊ |
74 | ␊ |
75 | // defaults for an iMac␊ |
76 | static const SMStrEntryPair const sm_imac_defaults[]={␊ |
77 | ␉{"SMbiosvendor",␉"Apple Inc."␉␉␉},␊ |
78 | ␉{"SMbiosversion",␉"IM81.88Z.00C1.B00.0802091538"␉},␊ |
79 | ␉{"SMbiosdate",␉␉"04/01/2008"␉␉␉},␊ |
80 | ␉{"SMmanufacter",␉"Apple Inc."␉␉␉},␊ |
81 | ␉{"SMproductname",␉"iMac8,1"␉␉␉},␉␊ |
82 | ␉{"SMsystemversion",␉"1.0"␉␉␉␉},␊ |
83 | ␉{"SMserial",␉␉"YM84915LZE2"␉␉␉},␊ |
84 | ␉{"SMfamily",␉␉"Mac"␉␉␉␉},␊ |
85 | ␉{"SMboardmanufacter",␉"Apple Inc."␉␉␉},␊ |
86 | ␉{"SMboardproduct",␉"Mac-F227BEC8"␉␉␉},␊ |
87 | ␉{ "",""␉}␊ |
88 | };␊ |
89 | ␊ |
90 | // defaults for a Mac Pro␊ |
91 | static const SMStrEntryPair const sm_macpro_defaults[]={␊ |
92 | ␉{"SMbiosvendor",␉␉"Apple Computer, Inc."␉␉␉},␊ |
93 | ␉{"SMbiosversion",␉␉"MP31.88Z.006C.B05.0802291410"␉},␊ |
94 | ␉{"SMbiosdate",␉␉␉"04/01/2008"␉␉␉␉␉},␊ |
95 | ␉{"SMmanufacter",␉␉"Apple Computer, Inc."␉␉␉},␊ |
96 | ␉{"SMproductname",␉␉"MacPro3,1"␉␉␉␉␉␉},␊ |
97 | ␉{"SMsystemversion",␉␉"1.0"␉␉␉␉␉␉␉},␊ |
98 | ␉{"SMserial",␉␉␉"W87234JHYA4"␉␉␉␉␉},␊ |
99 | ␉{"SMfamily",␉␉␉"MacPro"␉␉␉␉␉␉},␊ |
100 | ␉{"SMboardmanufacter",␉"Apple Computer, Inc."␉␉␉},␊ |
101 | ␉{"SMboardproduct",␉␉"Mac-F4208DC8"␉␉␉␉␉},␊ |
102 | ␉{ "",""␉}␊ |
103 | };␊ |
104 | ␊ |
105 | // defaults for an iMac11,1 core i3/i5/i7␊ |
106 | static const SMStrEntryPair const sm_imac_core_defaults[]={␊ |
107 | ␉{"SMbiosvendor",␉␉"Apple Inc."␉␉␉␉␉},␊ |
108 | ␉{"SMbiosversion",␉␉"IM111.88Z.0034.B00.0802091538"␉},␊ |
109 | ␉{"SMbiosdate",␉␉␉"06/01/2009"␉␉␉␉␉},␊ |
110 | ␉{"SMmanufacter",␉␉"Apple Inc."␉␉␉␉␉},␊ |
111 | ␉{"SMproductname",␉␉"iMac11,1"␉␉␉␉␉␉},␉␊ |
112 | ␉{"SMsystemversion",␉␉"1.0"␉␉␉␉␉␉␉},␊ |
113 | ␉{"SMserial",␉␉␉"W895154Z5RU"␉␉␉␉␉},␊ |
114 | ␉{"SMfamily",␉␉␉"iMac"␉␉␉␉␉␉␉},␊ |
115 | ␉{"SMboardmanufacter",␉"Apple Computer, Inc."␉␉␉},␊ |
116 | ␉{"SMboardproduct",␉␉"Mac-F2268DAE"␉␉␉␉␉},␊ |
117 | ␉{ "",""␉}␊ |
118 | };␊ |
119 | ␊ |
120 | // defaults for a Mac Pro 4,1 core i7/Xeon␊ |
121 | static const SMStrEntryPair const sm_macpro_core_defaults[]={␊ |
122 | ␉{"SMbiosvendor",␉␉"Apple Computer, Inc."␉␉␉},␊ |
123 | ␉{"SMbiosversion",␉␉"MP41.88Z.0081.B04.0903051113"␉},␊ |
124 | ␉{"SMbiosdate",␉␉␉"11/06/2009"␉␉␉␉␉},␊ |
125 | ␉{"SMmanufacter",␉␉"Apple Computer, Inc."␉␉␉},␊ |
126 | ␉{"SMproductname",␉␉"MacPro4,1"␉␉␉␉␉␉},␊ |
127 | ␉{"SMsystemversion",␉␉"1.0"␉␉␉␉␉␉␉},␊ |
128 | ␉{"SMserial",␉␉␉"H09222GU4PD"␉␉␉␉␉},␊ |
129 | ␉{"SMfamily",␉␉␉"MacPro"␉␉␉␉␉␉},␊ |
130 | ␉{"SMboardmanufacter",␉"Apple Computer, Inc."␉␉␉},␊ |
131 | ␉{"SMboardproduct",␉␉"Mac-F4208DC8"␉␉␉␉␉},␊ |
132 | ␉{ "",""␉}␊ |
133 | };␊ |
134 | ␊ |
135 | static const char* sm_get_defstr(const char * key, int table_num)␊ |
136 | {␊ |
137 | ␉int␉i;␊ |
138 | ␉const SMStrEntryPair*␉sm_defaults;␊ |
139 | ␊ |
140 | ␉if (platformCPUFeature(CPU_FEATURE_MOBILE)) {␊ |
141 | ␉␉if (Platform.CPU.NoCores > 1) {␊ |
142 | ␉␉␉sm_defaults=sm_macbookpro_defaults;␊ |
143 | ␉␉} else {␊ |
144 | ␉␉␉sm_defaults=sm_macbook_defaults;␊ |
145 | ␉␉}␊ |
146 | ␉} else {␊ |
147 | ␉␉switch (Platform.CPU.NoCores) ␊ |
148 | ␉␉{␊ |
149 | ␉␉␉case 1: ␊ |
150 | ␉␉␉␉sm_defaults=sm_macmini_defaults; ␊ |
151 | ␉␉␉␉break;␊ |
152 | ␉␉␉case 2:␊ |
153 | ␉␉␉␉sm_defaults=sm_imac_defaults;␊ |
154 | ␉␉␉␉break;␊ |
155 | ␉␉␉default:␊ |
156 | ␉␉␉{␊ |
157 | ␉␉␉␉switch (Platform.CPU.Family) ␊ |
158 | ␉␉␉␉{␊ |
159 | ␉␉␉␉␉case 0x06:␊ |
160 | ␉␉␉␉␉{␊ |
161 | ␉␉␉␉␉␉switch (Platform.CPU.Model)␊ |
162 | ␉␉␉␉␉␉{␊ |
163 | ␉␉␉␉␉␉␉case CPU_MODEL_FIELDS: // Intel Core i5, i7 LGA1156 (45nm)␊ |
164 | ␉␉␉␉␉␉␉case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) ???␊ |
165 | ␉␉␉␉␉␉␉case CPU_MODEL_DALES_32NM: // Intel Core i3, i5, i7 LGA1156 (32nm) (Clarkdale, Arrandale)␊ |
166 | ␉␉␉␉␉␉␉case 0x19: // Intel Core i5 650 @3.20 Ghz ␊ |
167 | ␉␉␉␉␉␉␉␉sm_defaults=sm_imac_core_defaults; ␊ |
168 | ␉␉␉␉␉␉␉␉break;␊ |
169 | ␉␉␉␉␉␉␉case CPU_MODEL_NEHALEM: ␊ |
170 | ␉␉␉␉␉␉␉case CPU_MODEL_NEHALEM_EX:␊ |
171 | ␉␉␉␉␉␉␉case CPU_MODEL_WESTMERE: ␊ |
172 | ␉␉␉␉␉␉␉case CPU_MODEL_WESTMERE_EX:␊ |
173 | ␉␉␉␉␉␉␉␉sm_defaults=sm_macpro_core_defaults; ␊ |
174 | ␉␉␉␉␉␉␉␉break;␊ |
175 | ␉␉␉␉␉␉␉default:␊ |
176 | ␉␉␉␉␉␉␉␉sm_defaults=sm_macpro_defaults; ␊ |
177 | ␉␉␉␉␉␉␉␉break;␊ |
178 | ␉␉␉␉␉␉}␊ |
179 | ␉␉␉␉␉␉break;␊ |
180 | ␉␉␉␉␉}␊ |
181 | ␉␉␉␉␉default:␊ |
182 | ␉␉␉␉␉␉sm_defaults=sm_macpro_defaults; ␊ |
183 | ␉␉␉␉␉␉break;␊ |
184 | ␉␉␉␉}␊ |
185 | ␉␉␉␉break;␊ |
186 | ␉␉␉}␊ |
187 | ␉␉}␊ |
188 | ␉}␊ |
189 | ␉␊ |
190 | ␉for (i=0; sm_defaults[i].key[0]; i++) {␊ |
191 | ␉␉if (!strcmp (sm_defaults[i].key, key)) {␊ |
192 | ␉␉␉return sm_defaults[i].value;␊ |
193 | ␉␉}␊ |
194 | ␉}␊ |
195 | ␊ |
196 | ␉// Shouldn't happen␊ |
197 | ␉printf ("Error: no default for '%s' known\n", key);␊ |
198 | ␉sleep (2);␊ |
199 | ␉return "";␊ |
200 | }␊ |
201 | ␊ |
202 | static int sm_get_fsb(const char *name, int table_num)␊ |
203 | {␊ |
204 | ␉return Platform.CPU.FSBFrequency/1000000;␊ |
205 | }␊ |
206 | ␊ |
207 | static int sm_get_cpu (const char *name, int table_num)␊ |
208 | {␊ |
209 | ␉return Platform.CPU.CPUFrequency/1000000;␊ |
210 | }␊ |
211 | ␊ |
212 | static int sm_get_bus_speed (const char *name, int table_num)␊ |
213 | {␊ |
214 | ␉if (Platform.CPU.Vendor == 0x756E6547) // Intel␊ |
215 | ␉{␉␉␊ |
216 | ␉␉switch (Platform.CPU.Family) ␊ |
217 | ␉␉{␊ |
218 | ␉␉␉case 0x06:␊ |
219 | ␉␉␉{␊ |
220 | ␉␉␉␉switch (Platform.CPU.Model)␊ |
221 | ␉␉␉␉{␊ |
222 | ␉␉␉␉␉case 0x0D: // ?␊ |
223 | ␉␉␉␉␉case CPU_MODEL_YONAH:␉// Yonah␉␉0x0E␊ |
224 | ␉␉␉␉␉case CPU_MODEL_MEROM:␉// Merom␉␉0x0F␊ |
225 | ␉␉␉␉␉case CPU_MODEL_PENRYN:␉// Penryn␉␉0x17␊ |
226 | ␉␉␉␉␉case CPU_MODEL_ATOM:␉// Atom 45nm␉0x1C␊ |
227 | ␉␉␉␉␉␉return 0; // TODO: populate bus speed for these processors␊ |
228 | ␉␉␉␉␉␉␊ |
229 | //␉␉␉␉␉case CPU_MODEL_FIELDS: // Intel Core i5, i7 LGA1156 (45nm)␊ |
230 | //␉␉␉␉␉␉if (strstr(Platform.CPU.BrandString, "Core(TM) i5"))␊ |
231 | //␉␉␉␉␉␉␉return 2500; // Core i5␊ |
232 | //␉␉␉␉␉␉return 4800; // Core i7␊ |
233 | ␉␉␉␉␉␉␊ |
234 | //␉␉␉␉␉case CPU_MODEL_NEHALEM: // Intel Core i7 LGA1366 (45nm)␊ |
235 | //␉␉␉␉␉case CPU_MODEL_NEHALEM_EX:␊ |
236 | //␉␉␉␉␉case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) ???␊ |
237 | //␉␉␉␉␉␉return 4800; // GT/s / 1000␊ |
238 | //␉␉␉␉␉␉␊ |
239 | ␉␉␉␉␉case CPU_MODEL_WESTMERE_EX: // Intel Core i7 LGA1366 (45nm) 6 Core ???␊ |
240 | ␉␉␉␉␉␉return 0; // TODO: populate bus speed for these processors␊ |
241 | ␉␉␉␉␉␉␊ |
242 | //␉␉␉␉␉case 0x19: // Intel Core i5 650 @3.20 Ghz␊ |
243 | //␉␉␉␉␉␉return 2500; // why? Intel spec says 2.5GT/s ␊ |
244 | ␊ |
245 | ␉␉␉␉␉case 0x19: // Intel Core i5 650 @3.20 Ghz␊ |
246 | ␉␉␉␉␉case CPU_MODEL_NEHALEM: // Intel Core i7 LGA1366 (45nm)␊ |
247 | ␉␉␉␉␉case CPU_MODEL_FIELDS: // Intel Core i5, i7 LGA1156 (45nm)␊ |
248 | ␉␉␉␉␉case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) ???␊ |
249 | ␉␉␉␉␉case CPU_MODEL_DALES_32NM: // Intel Core i3, i5, i7 LGA1156 (32nm)␊ |
250 | ␉␉␉␉␉case CPU_MODEL_WESTMERE: // Intel Core i7 LGA1366 (32nm) 6 Core␊ |
251 | ␉␉␉␉␉case CPU_MODEL_NEHALEM_EX: // Intel Core i7 LGA1366 (45nm) 6 Core ???␊ |
252 | ␉␉␉␉␉{ // thanks to dgobe for i3/i5/i7 bus speed detection␊ |
253 | ␉␉␉␉␉␉int nhm_bus = 0x3F;␊ |
254 | ␉␉␉␉␉␉static long possible_nhm_bus[] = {0xFF, 0x7F, 0x3F};␊ |
255 | ␉␉␉␉␉␉unsigned long did, vid;␊ |
256 | ␉␉␉␉␉␉int i;␊ |
257 | ␉␉␉␉␉␉␊ |
258 | ␉␉␉␉␉␉// Nehalem supports Scrubbing␊ |
259 | ␉␉␉␉␉␉// First, locate the PCI bus where the MCH is located␊ |
260 | ␉␉␉␉␉␉for(i = 0; i < sizeof(possible_nhm_bus); i++)␊ |
261 | ␉␉␉␉␉␉{␊ |
262 | ␉␉␉␉␉␉␉vid = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), 0x00);␊ |
263 | ␉␉␉␉␉␉␉did = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), 0x02);␊ |
264 | ␉␉␉␉␉␉␉vid &= 0xFFFF;␊ |
265 | ␉␉␉␉␉␉␉did &= 0xFF00;␊ |
266 | ␉␉␉␉␉␉␉␊ |
267 | ␉␉␉␉␉␉␉if(vid == 0x8086 && did >= 0x2C00)␊ |
268 | ␉␉␉␉␉␉␉␉nhm_bus = possible_nhm_bus[i]; ␊ |
269 | ␉␉␉␉␉␉}␊ |
270 | ␉␉␉␉␉␉␊ |
271 | ␉␉␉␉␉␉unsigned long qpimult, qpibusspeed;␊ |
272 | ␉␉␉␉␉␉qpimult = pci_config_read32(PCIADDR(nhm_bus, 2, 1), 0x50);␊ |
273 | ␉␉␉␉␉␉qpimult &= 0x7F;␊ |
274 | ␉␉␉␉␉␉DBG("qpimult %d\n", qpimult);␊ |
275 | ␉␉␉␉␉␉qpibusspeed = (qpimult * 2 * (Platform.CPU.FSBFrequency/1000000));␊ |
276 | ␉␉␉␉␉␉// Rek: rounding decimals to match original mac profile info␊ |
277 | ␉␉␉␉␉␉if (qpibusspeed%100 != 0)qpibusspeed = ((qpibusspeed+50)/100)*100;␊ |
278 | ␉␉␉␉␉␉DBG("qpibusspeed %d\n", qpibusspeed);␊ |
279 | ␉␉␉␉␉␉return qpibusspeed;␊ |
280 | ␉␉␉␉␉}␊ |
281 | ␉␉␉␉}␊ |
282 | ␉␉␉}␊ |
283 | ␉␉}␊ |
284 | ␉}␊ |
285 | ␉return 0;␊ |
286 | }␊ |
287 | ␊ |
288 | static int sm_get_simplecputype()␊ |
289 | {␊ |
290 | ␉if (Platform.CPU.NoCores >= 4) ␊ |
291 | ␉{␊ |
292 | ␉␉return 0x0501; // Quad-Core Xeon␊ |
293 | ␉}␊ |
294 | ␉else if (Platform.CPU.NoCores == 1) ␊ |
295 | ␉{␊ |
296 | ␉␉return 0x0201; // Core Solo␊ |
297 | ␉};␊ |
298 | ␉␊ |
299 | ␉return 0x0301; // Core 2 Duo␊ |
300 | }␊ |
301 | ␊ |
302 | static int sm_get_cputype (const char *name, int table_num)␊ |
303 | {␊ |
304 | ␉static bool done = false;␉␉␊ |
305 | ␉␉␊ |
306 | ␉if (Platform.CPU.Vendor == 0x756E6547) // Intel␊ |
307 | ␉{␊ |
308 | ␉␉if (!done) {␊ |
309 | ␉␉␉verbose("CPU is %s, family 0x%x, model 0x%x\n", Platform.CPU.BrandString, Platform.CPU.Family, Platform.CPU.Model);␊ |
310 | ␉␉␉done = true;␊ |
311 | ␉␉}␊ |
312 | ␉␉␊ |
313 | ␉␉switch (Platform.CPU.Family) ␊ |
314 | ␉␉{␊ |
315 | ␉␉␉case 0x06:␊ |
316 | ␉␉␉{␊ |
317 | ␉␉␉␉switch (Platform.CPU.Model)␊ |
318 | ␉␉␉␉{␊ |
319 | ␉␉␉␉␉case 0x0D: // ?␊ |
320 | ␉␉␉␉␉case CPU_MODEL_YONAH: // Yonah␊ |
321 | ␉␉␉␉␉case CPU_MODEL_MEROM: // Merom␊ |
322 | ␉␉␉␉␉case CPU_MODEL_PENRYN: // Penryn␊ |
323 | ␉␉␉␉␉case CPU_MODEL_ATOM: // Intel Atom (45nm)␊ |
324 | ␉␉␉␉␉␉return sm_get_simplecputype();␊ |
325 | ␉␉␉␉␉␉␊ |
326 | ␉␉␉␉␉case CPU_MODEL_NEHALEM: // Intel Core i7 LGA1366 (45nm)␊ |
327 | ␉␉␉␉␉␉return 0x0701; // Core i7␊ |
328 | ␉␉␉␉␉␉␊ |
329 | ␉␉␉␉␉case CPU_MODEL_FIELDS: // Lynnfield, Clarksfield, Jasper␊ |
330 | ␉␉␉␉␉␉if (strstr(Platform.CPU.BrandString, "Core(TM) i5"))␊ |
331 | ␉␉␉␉␉␉␉return 0x601; // Core i5␊ |
332 | ␉␉␉␉␉␉return 0x701; // Core i7␊ |
333 | ␉␉␉␉␉␉␊ |
334 | ␉␉␉␉␉case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) (Havendale, Auburndale)␊ |
335 | ␉␉␉␉␉␉if (strstr(Platform.CPU.BrandString, "Core(TM) i5"))␊ |
336 | ␉␉␉␉␉␉␉return 0x601; // Core i5␊ |
337 | ␉␉␉␉␉␉return 0x0701; // Core i7␊ |
338 | ␉␉␉␉␉␉␊ |
339 | ␉␉␉␉␉case CPU_MODEL_DALES_32NM: // Intel Core i3, i5, i7 LGA1156 (32nm) (Clarkdale, Arrandale)␊ |
340 | ␉␉␉␉␉␉if (strstr(Platform.CPU.BrandString, "Core(TM) i3"))␊ |
341 | ␉␉␉␉␉␉␉return 0x901; // Core i3␊ |
342 | ␉␉␉␉␉␉if (strstr(Platform.CPU.BrandString, "Core(TM) i5"))␊ |
343 | ␉␉␉␉␉␉␉return 0x601; // Core i5␊ |
344 | ␉␉␉␉␉␉return 0x0701; // Core i7␊ |
345 | ␉␉␉␉␉␉␊ |
346 | ␉␉␉␉␉case CPU_MODEL_WESTMERE: // Intel Core i7 LGA1366 (32nm) 6 Core (Gulftown, Westmere-EP, Westmere-WS)␊ |
347 | ␉␉␉␉␉case CPU_MODEL_WESTMERE_EX: // Intel Core i7 LGA1366 (45nm) 6 Core ???␊ |
348 | ␉␉␉␉␉␉return 0x0701; // Core i7␊ |
349 | ␉␉␉␉␉␉␊ |
350 | ␉␉␉␉␉case 0x19: // Intel Core i5 650 @3.20 Ghz␊ |
351 | ␉␉␉␉␉␉return 0x601; // Core i5␊ |
352 | ␉␉␉␉}␊ |
353 | ␉␉␉}␊ |
354 | ␉␉}␊ |
355 | ␉}␊ |
356 | ␉␊ |
357 | ␉return sm_get_simplecputype();␊ |
358 | }␊ |
359 | ␊ |
360 | static int sm_get_memtype (const char *name, int table_num)␊ |
361 | {␊ |
362 | ␉int␉map;␊ |
363 | ␊ |
364 | ␉if (table_num < MAX_RAM_SLOTS) {␊ |
365 | ␉␉map = Platform.DMI.DIMM[table_num];␊ |
366 | ␉␉if (Platform.RAM.DIMM[map].InUse && Platform.RAM.DIMM[map].Type != 0) {␊ |
367 | DBG("RAM Detected Type = %d\n", Platform.RAM.DIMM[map].Type);␊ |
368 | return Platform.RAM.DIMM[map].Type;␊ |
369 | ␉␉}␊ |
370 | ␉}␊ |
371 | ␉␊ |
372 | ␉return SMB_MEM_TYPE_DDR2;␊ |
373 | }␊ |
374 | ␊ |
375 | static int sm_get_memspeed (const char *name, int table_num)␊ |
376 | {␊ |
377 | ␉int␉map;␊ |
378 | ␊ |
379 | ␉if (table_num < MAX_RAM_SLOTS) {␊ |
380 | ␉␉map = Platform.DMI.DIMM[table_num];␊ |
381 | ␉␉if (Platform.RAM.DIMM[map].InUse && Platform.RAM.DIMM[map].Frequency != 0) {␊ |
382 | DBG("RAM Detected Freq = %d Mhz\n", Platform.RAM.DIMM[map].Frequency);␊ |
383 | return Platform.RAM.DIMM[map].Frequency;␊ |
384 | ␉␉}␊ |
385 | ␉}␊ |
386 | ␊ |
387 | ␉return 800;␊ |
388 | }␊ |
389 | ␊ |
390 | static const char *sm_get_memvendor (const char *name, int table_num)␊ |
391 | {␊ |
392 | ␉int␉map;␊ |
393 | ␊ |
394 | ␉if (table_num < MAX_RAM_SLOTS) {␊ |
395 | ␉␉map = Platform.DMI.DIMM[table_num];␊ |
396 | ␉␉if (Platform.RAM.DIMM[map].InUse && strlen(Platform.RAM.DIMM[map].Vendor) > 0) {␊ |
397 | ␉␉␉DBG("RAM Detected Vendor[%d]='%s'\n", table_num, Platform.RAM.DIMM[map].Vendor);␊ |
398 | ␉␉␉return Platform.RAM.DIMM[map].Vendor;␊ |
399 | ␉␉}␊ |
400 | ␉}␊ |
401 | ␉return "N/A";␊ |
402 | }␊ |
403 | ␉␊ |
404 | static const char *sm_get_memserial (const char *name, int table_num)␊ |
405 | {␊ |
406 | ␉int␉map;␊ |
407 | ␊ |
408 | ␉if (table_num < MAX_RAM_SLOTS) {␊ |
409 | ␉␉map = Platform.DMI.DIMM[table_num];␊ |
410 | ␉␉if (Platform.RAM.DIMM[map].InUse && strlen(Platform.RAM.DIMM[map].SerialNo) > 0) {␊ |
411 | DBG("name = %s, map=%d, RAM Detected SerialNo[%d]='%s'\n", name ? name : "", ␊ |
412 | map, table_num, Platform.RAM.DIMM[map].SerialNo);␊ |
413 | return Platform.RAM.DIMM[map].SerialNo;␊ |
414 | ␉␉}␊ |
415 | ␉}␊ |
416 | ␉return "N/A";␊ |
417 | }␊ |
418 | ␊ |
419 | static const char *sm_get_mempartno (const char *name, int table_num)␊ |
420 | {␊ |
421 | ␉int␉map;␊ |
422 | ␊ |
423 | ␉if (table_num < MAX_RAM_SLOTS) {␊ |
424 | ␉␉map = Platform.DMI.DIMM[table_num];␊ |
425 | ␉␉if (Platform.RAM.DIMM[map].InUse && strlen(Platform.RAM.DIMM[map].PartNo) > 0) {␊ |
426 | ␉␉␉DBG("Ram Detected PartNo[%d]='%s'\n", table_num, Platform.RAM.DIMM[map].PartNo);␊ |
427 | ␉␉␉return Platform.RAM.DIMM[map].PartNo;␊ |
428 | ␉␉}␊ |
429 | ␉}␊ |
430 | ␉return "N/A";␊ |
431 | }␊ |
432 | ␊ |
433 | static int sm_one (int tablen)␊ |
434 | {␊ |
435 | ␉return 1;␊ |
436 | }␊ |
437 | ␊ |
438 | struct smbios_property smbios_properties[]=␊ |
439 | {␊ |
440 | ␉{.name="SMbiosvendor",␉␉.table_type= 0,␉.value_type=SMSTRING,␉.offset=0x04,␉.auto_str=sm_get_defstr␉},␊ |
441 | ␉{.name="SMbiosversion",␉␉.table_type= 0,␉.value_type=SMSTRING,␉.offset=0x05,␉.auto_str=sm_get_defstr␉},␊ |
442 | ␉{.name="SMbiosdate",␉␉.table_type= 0,␉.value_type=SMSTRING,␉.offset=0x08,␉.auto_str=sm_get_defstr␉},␊ |
443 | ␉{.name="SMmanufacter",␉␉.table_type= 1,␉.value_type=SMSTRING,␉.offset=0x04,␉.auto_str=sm_get_defstr␉},␊ |
444 | ␉{.name="SMproductname",␉␉.table_type= 1,␉.value_type=SMSTRING,␉.offset=0x05,␉.auto_str=sm_get_defstr␉},␊ |
445 | ␉{.name="SMsystemversion",␉.table_type= 1,␉.value_type=SMSTRING,␉.offset=0x06,␉.auto_str=sm_get_defstr␉},␊ |
446 | ␉{.name="SMserial",␉␉.table_type= 1,␉.value_type=SMSTRING,␉.offset=0x07,␉.auto_str=sm_get_defstr␉},␊ |
447 | ␉{.name="SMUUID",␉␉.table_type= 1, .value_type=SMOWORD,␉.offset=0x08,␉.auto_oword=0␉␉},␊ |
448 | ␉{.name="SMfamily",␉␉.table_type= 1,␉.value_type=SMSTRING,␉.offset=0x1a,␉.auto_str=sm_get_defstr␉},␊ |
449 | ␉{.name="SMboardmanufacter",␉.table_type= 2, .value_type=SMSTRING,␉.offset=0x04,␉.auto_str=sm_get_defstr␉},␊ |
450 | ␉{.name="SMboardproduct",␉.table_type= 2, .value_type=SMSTRING,␉.offset=0x05,␉.auto_str=sm_get_defstr␉},␊ |
451 | ␉{.name="SMexternalclock",␉.table_type= 4,␉.value_type=SMWORD,␉.offset=0x12,␉.auto_int=sm_get_fsb␉},␊ |
452 | ␉{.name="SMmaximalclock",␉.table_type= 4,␉.value_type=SMWORD,␉.offset=0x14,␉.auto_int=sm_get_cpu␉},␊ |
453 | ␉{.name="SMmemdevloc",␉␉.table_type=17,␉.value_type=SMSTRING,␉.offset=0x10,␉.auto_str=0␉␉},␊ |
454 | ␉{.name="SMmembankloc",␉␉.table_type=17,␉.value_type=SMSTRING,␉.offset=0x11,␉.auto_str=0␉␉},␊ |
455 | ␉{.name="SMmemtype",␉␉.table_type=17,␉.value_type=SMBYTE,␉.offset=0x12,␉.auto_int=sm_get_memtype},␊ |
456 | ␉{.name="SMmemspeed",␉␉.table_type=17,␉.value_type=SMWORD,␉.offset=0x15,␉.auto_int=sm_get_memspeed},␊ |
457 | ␉{.name="SMmemmanufacter",␉.table_type=17,␉.value_type=SMSTRING,␉.offset=0x17,␉.auto_str=sm_get_memvendor},␊ |
458 | ␉{.name="SMmemserial",␉␉.table_type=17,␉.value_type=SMSTRING,␉.offset=0x18,␉.auto_str=sm_get_memserial},␊ |
459 | ␉{.name="SMmempart",␉␉.table_type=17,␉.value_type=SMSTRING,␉.offset=0x1A,␉.auto_str=sm_get_mempartno},␊ |
460 | ␉{.name="SMcputype",␉␉.table_type=131,.value_type=SMWORD,␉.offset=0x04,␉.auto_int=sm_get_cputype},␊ |
461 | ␉{.name="SMbusspeed",␉␉.table_type=132,.value_type=SMWORD,␉.offset=0x04,␉.auto_int=sm_get_bus_speed}␊ |
462 | };␊ |
463 | ␊ |
464 | struct smbios_table_description smbios_table_descriptions[]=␊ |
465 | {␊ |
466 | ␉{.type=0,␉.len=0x18,␉.numfunc=sm_one},␊ |
467 | ␉{.type=1,␉.len=0x1b,␉.numfunc=sm_one},␊ |
468 | ␉{.type=2,␉.len=0x0f,␉.numfunc=sm_one},␊ |
469 | ␉{.type=4,␉.len=0x2a,␉.numfunc=sm_one},␊ |
470 | ␉{.type=17,␉.len=0x1c,␉.numfunc=0},␊ |
471 | ␉{.type=131,␉.len=0x06,␉.numfunc=sm_one},␊ |
472 | ␉{.type=132,␉.len=0x06,␉.numfunc=sm_one}␊ |
473 | };␊ |
474 | ␊ |
475 | // getting smbios addr with fast compare ops, late checksum testing ...␊ |
476 | #define COMPARE_DWORD(a,b) ( *((u_int32_t *) a) == *((u_int32_t *) b) )␊ |
477 | static const char * const SMTAG = "_SM_";␊ |
478 | static const char* const DMITAG= "_DMI_";␊ |
479 | ␊ |
480 | static struct SMBEntryPoint *getAddressOfSmbiosTable(void)␊ |
481 | {␊ |
482 | ␉struct SMBEntryPoint␉*smbios;␊ |
483 | ␉/* ␊ |
484 | ␉ * The logic is to start at 0xf0000 and end at 0xfffff iterating 16 bytes at a time looking␊ |
485 | ␉ * for the SMBIOS entry-point structure anchor (literal ASCII "_SM_").␊ |
486 | ␉ */␊ |
487 | ␉smbios = (struct SMBEntryPoint*) SMBIOS_RANGE_START;␊ |
488 | ␉while (smbios <= (struct SMBEntryPoint *)SMBIOS_RANGE_END) {␊ |
489 | if (COMPARE_DWORD(smbios->anchor, SMTAG) && ␊ |
490 | COMPARE_DWORD(smbios->dmi.anchor, DMITAG) &&␊ |
491 | smbios->dmi.anchor[4]==DMITAG[4] &&␊ |
492 | checksum8(smbios, sizeof(struct SMBEntryPoint)) == 0)␊ |
493 | ␉ {␊ |
494 | return smbios;␊ |
495 | ␉ }␊ |
496 | smbios = (struct SMBEntryPoint*) ( ((char*) smbios) + 16 );␊ |
497 | ␉}␊ |
498 | ␉printf("ERROR: Unable to find SMBIOS!\n");␊ |
499 | ␉pause();␊ |
500 | ␉return NULL;␊ |
501 | }␊ |
502 | ␊ |
503 | /** Compute necessary space requirements for new smbios */␊ |
504 | static struct SMBEntryPoint *smbios_dry_run(struct SMBEntryPoint *origsmbios)␊ |
505 | {␊ |
506 | ␉struct SMBEntryPoint␉*ret;␊ |
507 | ␉char␉␉␉*smbiostables;␊ |
508 | ␉char␉␉␉*tablesptr;␊ |
509 | ␉int␉␉␉origsmbiosnum;␊ |
510 | ␉int␉␉␉i, j;␊ |
511 | ␉int␉␉␉tablespresent[256];␊ |
512 | ␉bool␉␉␉do_auto=true;␊ |
513 | ␊ |
514 | ␉bzero(tablespresent, sizeof(tablespresent));␊ |
515 | ␊ |
516 | ␉getBoolForKey(kSMBIOSdefaults, &do_auto, &bootInfo->bootConfig);␊ |
517 | ␊ |
518 | ␉ret = (struct SMBEntryPoint *)AllocateKernelMemory(sizeof(struct SMBEntryPoint));␊ |
519 | ␉if (origsmbios) {␊ |
520 | ␉␉smbiostables = (char *)origsmbios->dmi.tableAddress;␊ |
521 | ␉␉origsmbiosnum = origsmbios->dmi.structureCount;␊ |
522 | ␉} else {␊ |
523 | ␉␉smbiostables = NULL;␊ |
524 | ␉␉origsmbiosnum = 0;␊ |
525 | ␉}␊ |
526 | ␊ |
527 | ␉// _SM_␊ |
528 | ␉ret->anchor[0] = 0x5f;␊ |
529 | ␉ret->anchor[1] = 0x53;␊ |
530 | ␉ret->anchor[2] = 0x4d;␊ |
531 | ␉ret->anchor[3] = 0x5f; ␊ |
532 | ␉ret->entryPointLength = sizeof(*ret);␊ |
533 | ␉ret->majorVersion = 2;␊ |
534 | ␉ret->minorVersion = 1;␊ |
535 | ␉ret->maxStructureSize = 0; // will be calculated later in this function␊ |
536 | ␉ret->entryPointRevision = 0;␊ |
537 | ␉for (i=0;i<5;i++) {␊ |
538 | ␉␉ret->formattedArea[i] = 0;␊ |
539 | ␉}␊ |
540 | ␉//_DMI_␊ |
541 | ␉ret->dmi.anchor[0] = 0x5f;␊ |
542 | ␉ret->dmi.anchor[1] = 0x44;␊ |
543 | ␉ret->dmi.anchor[2] = 0x4d;␊ |
544 | ␉ret->dmi.anchor[3] = 0x49;␊ |
545 | ␉ret->dmi.anchor[4] = 0x5f;␊ |
546 | ␉ret->dmi.tableLength = 0; // will be calculated later in this function␊ |
547 | ␉ret->dmi.tableAddress = 0; // will be initialized in smbios_real_run()␊ |
548 | ␉ret->dmi.structureCount = 0; // will be calculated later in this function␊ |
549 | ␉ret->dmi.bcdRevision = 0x21;␊ |
550 | ␉tablesptr = smbiostables;␊ |
551 | ␊ |
552 | // add stringlen of overrides to original stringlen, update maxStructure size adequately, ␊ |
553 | // update structure count and tablepresent[type] with count of type. ␊ |
554 | ␉if (smbiostables) {␊ |
555 | ␉␉for (i=0; i<origsmbiosnum; i++) {␊ |
556 | ␉␉␉struct smbios_table_header␉*cur = (struct smbios_table_header *)tablesptr;␊ |
557 | ␉␉␉char␉␉␉␉*stringsptr;␊ |
558 | ␉␉␉int␉␉␉␉stringlen;␊ |
559 | ␊ |
560 | ␉␉␉tablesptr += cur->length;␊ |
561 | ␉␉␉stringsptr = tablesptr;␊ |
562 | ␉␉␉for (; tablesptr[0]!=0 || tablesptr[1]!=0; tablesptr++);␊ |
563 | ␉␉␉tablesptr += 2;␊ |
564 | ␉␉␉stringlen = tablesptr - stringsptr - 1;␊ |
565 | ␉␉␉if (stringlen == 1) {␊ |
566 | ␉␉␉␉stringlen = 0;␊ |
567 | ␉␉␉}␊ |
568 | ␉␉␉for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {␊ |
569 | ␉␉␉␉const char␉*str;␊ |
570 | ␉␉␉␉int␉␉size;␊ |
571 | ␉␉␉␉char␉␉altname[40];␊ |
572 | ␊ |
573 | ␉␉␉␉sprintf(altname, "%s_%d",smbios_properties[j].name, tablespresent[cur->type] + 1);␉␉␉␉␊ |
574 | ␉␉␉␉if (smbios_properties[j].table_type == cur->type &&␊ |
575 | ␉␉␉␉ smbios_properties[j].value_type == SMSTRING &&␊ |
576 | ␉␉␉␉ (getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig) ||␊ |
577 | ␉␉␉␉ getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)))␊ |
578 | ␉␉␉␉{␊ |
579 | ␉␉␉␉␉stringlen += size + 1;␊ |
580 | ␉␉␉␉} else if (smbios_properties[j].table_type == cur->type &&␊ |
581 | ␉␉␉␉ smbios_properties[j].value_type == SMSTRING &&␊ |
582 | ␉␉␉␉ do_auto && smbios_properties[j].auto_str)␊ |
583 | ␉␉␉␉{␊ |
584 | ␉␉␉␉␉stringlen += strlen(smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[cur->type])) + 1;␊ |
585 | ␉␉␉␉}␊ |
586 | ␉␉␉}␊ |
587 | ␉␉␉if (stringlen == 0) {␊ |
588 | ␉␉␉␉stringlen = 1;␊ |
589 | ␉␉␉}␊ |
590 | ␉␉␉stringlen++;␊ |
591 | ␉␉␉if (ret->maxStructureSize < cur->length+stringlen) {␊ |
592 | ␉␉␉␉ret->maxStructureSize=cur->length+stringlen;␊ |
593 | ␉␉␉}␊ |
594 | ␉␉␉ret->dmi.tableLength += cur->length+stringlen;␊ |
595 | ␉␉␉ret->dmi.structureCount++;␊ |
596 | ␉␉␉tablespresent[cur->type]++;␊ |
597 | ␉␉}␊ |
598 | ␉}␊ |
599 | // Add eventually table types whose detected count would be < required count, and update ret header with:␊ |
600 | // new stringlen addons, structure count, and tablepresent[type] count adequately␊ |
601 | ␉for (i=0; i<sizeof(smbios_table_descriptions)/sizeof(smbios_table_descriptions[0]); i++) {␊ |
602 | ␉␉int␉numnec=-1;␊ |
603 | ␉␉char␉buffer[40];␊ |
604 | ␊ |
605 | ␉␉sprintf(buffer, "SMtable%d", i);␊ |
606 | ␉␉if (!getIntForKey(buffer, &numnec, &bootInfo->smbiosConfig)) {␊ |
607 | ␉␉␉numnec = -1;␊ |
608 | ␉␉}␊ |
609 | ␉␉if (numnec==-1 && do_auto && smbios_table_descriptions[i].numfunc) {␊ |
610 | ␉␉␉numnec = smbios_table_descriptions[i].numfunc(smbios_table_descriptions[i].type);␊ |
611 | ␉␉}␊ |
612 | ␉␉while (tablespresent[smbios_table_descriptions[i].type] < numnec) {␊ |
613 | ␉␉␉int␉stringlen = 0;␊ |
614 | ␉␉␉for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {␊ |
615 | ␉␉␉␉const char␉*str;␊ |
616 | ␉␉␉␉int␉␉size;␊ |
617 | ␉␉␉␉char␉␉altname[40];␊ |
618 | ␊ |
619 | ␉␉␉␉sprintf(altname, "%s_%d",smbios_properties[j].name, tablespresent[smbios_table_descriptions[i].type] + 1);␊ |
620 | ␉␉␉␉if (smbios_properties[j].table_type == smbios_table_descriptions[i].type &&␊ |
621 | ␉␉␉␉ smbios_properties[j].value_type == SMSTRING &&␊ |
622 | ␉␉␉␉ (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||␊ |
623 | ␉␉␉␉ getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig)))␊ |
624 | ␉␉␉␉{␊ |
625 | ␉␉␉␉␉stringlen += size + 1;␊ |
626 | ␉␉␉␉} else if (smbios_properties[j].table_type == smbios_table_descriptions[i].type &&␊ |
627 | ␉␉␉␉ smbios_properties[j].value_type==SMSTRING &&␊ |
628 | ␉␉␉␉ do_auto && smbios_properties[j].auto_str)␊ |
629 | ␉␉␉␉{␊ |
630 | ␉␉␉␉␉stringlen += strlen(smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[smbios_table_descriptions[i].type])) + 1;␊ |
631 | ␉␉␉␉}␊ |
632 | ␉␉␉}␊ |
633 | ␉␉␉if (stringlen == 0) {␊ |
634 | ␉␉␉␉stringlen = 1;␊ |
635 | ␉␉␉}␊ |
636 | ␉␉␉stringlen++;␊ |
637 | ␉␉␉if (ret->maxStructureSize < smbios_table_descriptions[i].len+stringlen) {␊ |
638 | ␉␉␉␉ret->maxStructureSize = smbios_table_descriptions[i].len + stringlen;␊ |
639 | ␉␉␉}␊ |
640 | ␉␉␉ret->dmi.tableLength += smbios_table_descriptions[i].len + stringlen;␊ |
641 | ␉␉␉ret->dmi.structureCount++;␊ |
642 | ␉␉␉tablespresent[smbios_table_descriptions[i].type]++;␊ |
643 | ␉␉}␊ |
644 | ␉}␊ |
645 | ␉return ret;␊ |
646 | }␊ |
647 | ␊ |
648 | /** From the origsmbios detected by getAddressOfSmbiosTable() to newsmbios whose entrypoint ␊ |
649 | * struct has been created by smbios_dry_run, update each table struct content of new smbios␊ |
650 | * int the new allocated table address of size newsmbios->tablelength.␊ |
651 | */␊ |
652 | static void smbios_real_run(struct SMBEntryPoint * origsmbios, struct SMBEntryPoint * newsmbios)␊ |
653 | {␊ |
654 | ␉char *smbiostables;␊ |
655 | ␉char *tablesptr, *newtablesptr;␊ |
656 | ␉int origsmbiosnum;␊ |
657 | ␉// bitmask of used handles␊ |
658 | ␉uint8_t handles[8192]; ␊ |
659 | ␉uint16_t nexthandle=0;␊ |
660 | ␉int i, j;␊ |
661 | ␉int tablespresent[256];␊ |
662 | ␉bool do_auto=true;␊ |
663 | ␉␊ |
664 | static bool done = false; // IMPROVEME: called twice via getSmbios(), but only the second call can get all necessary info !␊ |
665 | ␊ |
666 | ␉extern void dumpPhysAddr(const char * title, void * a, int len);␊ |
667 | ␉␊ |
668 | ␉bzero(tablespresent, sizeof(tablespresent));␊ |
669 | ␉bzero(handles, sizeof(handles));␊ |
670 | ␊ |
671 | ␉getBoolForKey(kSMBIOSdefaults, &do_auto, &bootInfo->bootConfig);␊ |
672 | ␉␊ |
673 | ␉newsmbios->dmi.tableAddress = (uint32_t)AllocateKernelMemory(newsmbios->dmi.tableLength);␊ |
674 | ␉if (origsmbios) {␊ |
675 | ␉␉smbiostables = (char *)origsmbios->dmi.tableAddress;␊ |
676 | ␉␉origsmbiosnum = origsmbios->dmi.structureCount;␊ |
677 | ␉} else {␊ |
678 | ␉␉smbiostables = NULL;␊ |
679 | ␉␉origsmbiosnum = 0;␊ |
680 | ␉}␊ |
681 | ␉tablesptr = smbiostables;␊ |
682 | ␉newtablesptr = (char *)newsmbios->dmi.tableAddress;␊ |
683 | ␊ |
684 | // if old smbios exists then update new smbios with old smbios original content first␊ |
685 | ␉if (smbiostables) {␊ |
686 | ␉␉for (i=0; i<origsmbiosnum; i++) {␊ |
687 | ␉␉␉struct smbios_table_header␉*oldcur = (struct smbios_table_header *) tablesptr;␊ |
688 | ␉␉␉struct smbios_table_header␉*newcur = (struct smbios_table_header *) newtablesptr;␊ |
689 | ␉␉␉char␉␉␉␉*stringsptr;␊ |
690 | ␉␉␉int␉␉␉␉nstrings = 0;␊ |
691 | ␊ |
692 | ␉␉␉handles[(oldcur->handle) / 8] |= 1 << ((oldcur->handle) % 8);␊ |
693 | ␊ |
694 | // copy table length from old table to new table but not the old strings␊ |
695 | ␉␉␉memcpy(newcur,oldcur, oldcur->length);␊ |
696 | ␊ |
697 | ␉␉␉tablesptr += oldcur->length;␊ |
698 | ␉␉␉stringsptr = tablesptr;␊ |
699 | ␉␉␉newtablesptr += oldcur->length;␊ |
700 | ␊ |
701 | // calculate the number of strings in the old content␊ |
702 | ␉␉␉for (;tablesptr[0]!=0 || tablesptr[1]!=0; tablesptr++) {␊ |
703 | ␉␉␉␉if (tablesptr[0] == 0) {␊ |
704 | ␉␉␉␉␉nstrings++;␊ |
705 | ␉␉␉␉}␊ |
706 | ␉␉␉}␊ |
707 | ␉␉␉if (tablesptr != stringsptr) {␊ |
708 | ␉␉␉␉nstrings++;␊ |
709 | ␉␉␉}␊ |
710 | ␉␉␉tablesptr += 2;␊ |
711 | ␊ |
712 | // copy the old strings to new table␊ |
713 | ␉␉␉memcpy(newtablesptr, stringsptr, tablesptr-stringsptr);␊ |
714 | ␊ |
715 | ␉␉␉// point to next possible space for a string (deducting the second 0 char at the end)␊ |
716 | ␉␉␉newtablesptr += tablesptr - stringsptr - 1;␊ |
717 | if (nstrings == 0) { // if no string was found rewind to the first 0 char of the 0,0 terminator␊ |
718 | ␉␉␉␉newtablesptr--;␊ |
719 | ␉␉␉}␊ |
720 | ␊ |
721 | // now for each property in the table update the overrides if any (auto or user)␊ |
722 | ␉␉␉for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {␊ |
723 | ␉␉␉␉const char␉*str;␊ |
724 | ␉␉␉␉int␉␉size;␊ |
725 | ␉␉␉␉int␉␉num;␊ |
726 | ␉␉␉␉char␉␉altname[40];␊ |
727 | ␊ |
728 | ␉␉␉␉sprintf(altname, "%s_%d", smbios_properties[j].name, tablespresent[newcur->type] + 1);␊ |
729 | ␉␉␉␉if (smbios_properties[j].table_type == newcur->type) {␊ |
730 | ␉␉␉␉␉switch (smbios_properties[j].value_type) {␊ |
731 | ␉␉␉␉␉case SMSTRING:␊ |
732 | ␉␉␉␉␉␉if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||␊ |
733 | ␉␉␉␉␉␉ getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))␊ |
734 | ␉␉␉␉␉␉{␊ |
735 | ␉␉␉␉␉␉␉memcpy(newtablesptr, str, size);␊ |
736 | ␉␉␉␉␉␉␉newtablesptr[size] = 0;␊ |
737 | ␉␉␉␉␉␉␉newtablesptr += size + 1;␊ |
738 | ␉␉␉␉␉␉␉*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;␊ |
739 | ␉␉␉␉␉␉} else if (do_auto && smbios_properties[j].auto_str) {␊ |
740 | ␉␉␉␉␉␉␉str = smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]);␊ |
741 | ␉␉␉␉␉␉␉size = strlen(str);␊ |
742 | ␉␉␉␉␉␉␉memcpy(newtablesptr, str, size);␊ |
743 | ␉␉␉␉␉␉␉newtablesptr[size] = 0;␊ |
744 | ␉␉␉␉␉␉␉newtablesptr += size + 1;␊ |
745 | ␉␉␉␉␉␉␉*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;␊ |
746 | ␉␉␉␉␉␉}␊ |
747 | ␉␉␉␉␉␉break;␊ |
748 | ␊ |
749 | ␉␉␉␉␉case SMOWORD:␊ |
750 | ␉␉␉␉␉␉if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||␊ |
751 | ␉␉␉␉␉␉ getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))␊ |
752 | ␉␉␉␉␉␉{␊ |
753 | ␉␉␉␉␉␉␉int␉␉k=0, t=0, kk=0;␊ |
754 | ␉␉␉␉␉␉␉const char␉*ptr = str;␊ |
755 | ␉␉␉␉␉␉␉memset(((char*)newcur) + smbios_properties[j].offset, 0, 16);␊ |
756 | ␉␉␉␉␉␉␉while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n')) {␊ |
757 | ␉␉␉␉␉␉␉␉ptr++;␊ |
758 | ␉␉␉␉␉␉␉}␊ |
759 | ␉␉␉␉␉␉␉if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X')) {␊ |
760 | ␉␉␉␉␉␉␉␉ptr += 2;␊ |
761 | ␉␉␉␉␉␉␉}␊ |
762 | ␉␉␉␉␉␉␉for (;ptr-str<size && *ptr && k<16;ptr++) {␊ |
763 | ␉␉␉␉␉␉␉␉if (*ptr>='0' && *ptr<='9') {␊ |
764 | ␉␉␉␉␉␉␉␉␉(t=(t<<4)|(*ptr-'0')),kk++;␊ |
765 | ␉␉␉␉␉␉␉␉}␊ |
766 | ␉␉␉␉␉␉␉␉if (*ptr>='a' && *ptr<='f') {␊ |
767 | ␉␉␉␉␉␉␉␉␉(t=(t<<4)|(*ptr-'a'+10)),kk++;␊ |
768 | ␉␉␉␉␉␉␉␉}␊ |
769 | ␉␉␉␉␉␉␉␉if (*ptr>='A' && *ptr<='F') {␊ |
770 | ␉␉␉␉␉␉␉␉␉(t=(t<<4)|(*ptr-'A'+10)),kk++;␊ |
771 | ␉␉␉␉␉␉␉␉}␊ |
772 | ␉␉␉␉␉␉␉␉if (kk == 2) {␊ |
773 | ␉␉␉␉␉␉␉␉␉*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset + k)) = t;␊ |
774 | ␉␉␉␉␉␉␉␉␉k++;␊ |
775 | ␉␉␉␉␉␉␉␉␉kk = 0;␊ |
776 | ␉␉␉␉␉␉␉␉␉t = 0;␊ |
777 | ␉␉␉␉␉␉␉␉}␊ |
778 | ␉␉␉␉␉␉␉}␊ |
779 | ␉␉␉␉␉␉}␊ |
780 | ␉␉␉␉␉␉break;␊ |
781 | ␊ |
782 | ␉␉␉␉␉case SMBYTE:␊ |
783 | ␉␉␉␉␉␉if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||␊ |
784 | ␉␉␉␉␉␉ getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))␊ |
785 | ␉␉␉␉␉␉{␊ |
786 | ␉␉␉␉␉␉␉*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;␊ |
787 | ␉␉␉␉␉␉} else if (do_auto && smbios_properties[j].auto_int) {␊ |
788 | ␉␉␉␉␉␉␉*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);␉␉␉␉␉␉␉␊ |
789 | ␉␉␉␉␉␉}␊ |
790 | ␉␉␉␉␉␉break;␊ |
791 | ␊ |
792 | ␉␉␉␉␉case SMWORD:␊ |
793 | ␉␉␉␉␉␉if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||␊ |
794 | ␉␉␉␉␉␉ getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))␊ |
795 | ␉␉␉␉␉␉{␊ |
796 | ␉␉␉␉␉␉␉*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;␊ |
797 | ␉␉␉␉␉␉} else if (do_auto && smbios_properties[j].auto_int) {␊ |
798 | ␉␉␉␉␉␉␉*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);␊ |
799 | ␉␉␉␉␉␉}␊ |
800 | ␉␉␉␉␉␉break;␊ |
801 | ␉␉␉␉␉}␊ |
802 | ␉␉␉␉}␊ |
803 | ␉␉␉}␊ |
804 | ␉␉␉if (nstrings == 0) {␊ |
805 | ␉␉␉␉newtablesptr[0] = 0;␊ |
806 | ␉␉␉␉newtablesptr++;␊ |
807 | ␉␉␉}␊ |
808 | ␉␉␉newtablesptr[0] = 0;␊ |
809 | ␉␉␉newtablesptr++;␊ |
810 | ␉␉␉tablespresent[newcur->type]++;␊ |
811 | ␉␉}␊ |
812 | ␉}␊ |
813 | ␊ |
814 | // for each eventual complementary table not present in the original smbios, do the overrides␊ |
815 | ␉for (i=0; i<sizeof(smbios_table_descriptions)/sizeof(smbios_table_descriptions[0]); i++) {␊ |
816 | ␉␉int␉numnec = -1;␊ |
817 | ␉␉char␉buffer[40];␊ |
818 | ␊ |
819 | ␉␉sprintf(buffer, "SMtable%d", i);␊ |
820 | ␉␉if (!getIntForKey(buffer, &numnec, &bootInfo->smbiosConfig)) {␊ |
821 | ␉␉␉numnec = -1;␊ |
822 | ␉␉}␊ |
823 | ␉␉if (numnec == -1 && do_auto && smbios_table_descriptions[i].numfunc) {␊ |
824 | ␉␉␉numnec = smbios_table_descriptions[i].numfunc(smbios_table_descriptions[i].type);␊ |
825 | ␉␉}␊ |
826 | ␉␉while (tablespresent[smbios_table_descriptions[i].type] < numnec) {␊ |
827 | ␉␉␉struct smbios_table_header␉*newcur = (struct smbios_table_header *) newtablesptr;␊ |
828 | ␉␉␉int␉␉␉␉nstrings = 0;␊ |
829 | ␊ |
830 | ␉␉␉memset(newcur,0, smbios_table_descriptions[i].len);␊ |
831 | ␉␉␉while (handles[(nexthandle)/8] & (1 << ((nexthandle) % 8))) {␊ |
832 | ␉␉␉␉nexthandle++;␊ |
833 | ␉␉␉}␊ |
834 | ␉␉␉newcur->handle = nexthandle;␊ |
835 | ␉␉␉handles[nexthandle / 8] |= 1 << (nexthandle % 8);␊ |
836 | ␉␉␉newcur->type = smbios_table_descriptions[i].type;␊ |
837 | ␉␉␉newcur->length = smbios_table_descriptions[i].len;␊ |
838 | ␉␉␉newtablesptr += smbios_table_descriptions[i].len;␊ |
839 | ␉␉␉for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {␊ |
840 | ␉␉␉␉const char␉*str;␊ |
841 | ␉␉␉␉int␉␉size;␊ |
842 | ␉␉␉␉int␉␉num;␊ |
843 | ␉␉␉␉char␉␉altname[40];␊ |
844 | ␊ |
845 | ␉␉␉␉sprintf(altname, "%s_%d", smbios_properties[j].name, tablespresent[newcur->type] + 1);␊ |
846 | ␉␉␉␉if (smbios_properties[j].table_type == newcur->type) {␊ |
847 | ␉␉␉␉␉switch (smbios_properties[j].value_type) {␊ |
848 | ␉␉␉␉␉case SMSTRING:␊ |
849 | ␉␉␉␉␉␉if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||␊ |
850 | ␉␉␉␉␉␉ getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))␊ |
851 | ␉␉␉␉␉␉{␊ |
852 | ␉␉␉␉␉␉␉memcpy(newtablesptr, str, size);␊ |
853 | ␉␉␉␉␉␉␉newtablesptr[size] = 0;␊ |
854 | ␉␉␉␉␉␉␉newtablesptr += size + 1;␊ |
855 | ␉␉␉␉␉␉␉*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;␊ |
856 | ␉␉␉␉␉␉} else if (do_auto && smbios_properties[j].auto_str) {␊ |
857 | ␉␉␉␉␉␉␉str = smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]);␊ |
858 | ␉␉␉␉␉␉␉size = strlen(str);␊ |
859 | ␉␉␉␉␉␉␉memcpy(newtablesptr, str, size);␊ |
860 | ␉␉␉␉␉␉␉newtablesptr[size] = 0;␊ |
861 | ␉␉␉␉␉␉␉newtablesptr += size + 1;␊ |
862 | ␉␉␉␉␉␉␉*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;␊ |
863 | ␉␉␉␉␉␉}␊ |
864 | ␉␉␉␉␉␉break;␊ |
865 | ␊ |
866 | ␉␉␉␉␉case SMOWORD:␊ |
867 | ␉␉␉␉␉␉if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||␊ |
868 | ␉␉␉␉␉␉ getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))␊ |
869 | ␉␉␉␉␉␉{␊ |
870 | ␉␉␉␉␉␉␉int␉␉k=0, t=0, kk=0;␊ |
871 | ␉␉␉␉␉␉␉const char␉*ptr = str;␊ |
872 | ␊ |
873 | ␉␉␉␉␉␉␉memset(((char*)newcur) + smbios_properties[j].offset, 0, 16);␊ |
874 | ␉␉␉␉␉␉␉while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n')) {␊ |
875 | ␉␉␉␉␉␉␉␉ptr++;␊ |
876 | ␉␉␉␉␉␉␉}␊ |
877 | ␉␉␉␉␉␉␉if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X')) {␊ |
878 | ␉␉␉␉␉␉␉␉ptr += 2;␊ |
879 | ␉␉␉␉␉␉␉}␊ |
880 | ␉␉␉␉␉␉␉for (;ptr-str<size && *ptr && k<16;ptr++) {␊ |
881 | ␉␉␉␉␉␉␉␉if (*ptr>='0' && *ptr<='9') {␊ |
882 | ␉␉␉␉␉␉␉␉␉(t=(t<<4)|(*ptr-'0')),kk++;␊ |
883 | ␉␉␉␉␉␉␉␉}␊ |
884 | ␉␉␉␉␉␉␉␉if (*ptr>='a' && *ptr<='f') {␊ |
885 | ␉␉␉␉␉␉␉␉␉(t=(t<<4)|(*ptr-'a'+10)),kk++;␊ |
886 | ␉␉␉␉␉␉␉␉}␊ |
887 | ␉␉␉␉␉␉␉␉if (*ptr>='A' && *ptr<='F') {␊ |
888 | ␉␉␉␉␉␉␉␉␉(t=(t<<4)|(*ptr-'A'+10)),kk++;␊ |
889 | ␉␉␉␉␉␉␉␉}␊ |
890 | ␉␉␉␉␉␉␉␉if (kk == 2) {␊ |
891 | ␉␉␉␉␉␉␉␉␉*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset + k)) = t;␊ |
892 | ␉␉␉␉␉␉␉␉␉k++;␊ |
893 | ␉␉␉␉␉␉␉␉␉kk = 0;␊ |
894 | ␉␉␉␉␉␉␉␉␉t = 0;␊ |
895 | ␉␉␉␉␉␉␉␉}␊ |
896 | ␉␉␉␉␉␉␉}␊ |
897 | ␉␉␉␉␉␉}␊ |
898 | ␉␉␉␉␉␉break;␊ |
899 | ␉␉␉␉␉␉␊ |
900 | ␉␉␉␉␉case SMBYTE:␊ |
901 | ␉␉␉␉␉␉if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||␊ |
902 | ␉␉␉␉␉␉ getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))␊ |
903 | ␉␉␉␉␉␉{␊ |
904 | ␉␉␉␉␉␉␉*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;␊ |
905 | ␉␉␉␉␉␉} else if (do_auto && smbios_properties[j].auto_int) {␊ |
906 | ␉␉␉␉␉␉␉*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);␊ |
907 | ␉␉␉␉␉␉}␊ |
908 | ␉␉␉␉␉␉break;␊ |
909 | ␉␉␉␉␉␉␊ |
910 | ␉␉␉␉␉case SMWORD:␊ |
911 | ␉␉␉␉␉␉if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||␊ |
912 | ␉␉␉␉␉␉ getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))␊ |
913 | ␉␉␉␉␉␉{␊ |
914 | ␉␉␉␉␉␉␉*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;␊ |
915 | ␉␉␉␉␉␉} else if (do_auto && smbios_properties[j].auto_int) {␊ |
916 | ␉␉␉␉␉␉␉*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);␊ |
917 | ␉␉␉␉␉␉}␊ |
918 | ␉␉␉␉␉␉break;␊ |
919 | ␉␉␉␉␉}␊ |
920 | ␉␉␉␉}␊ |
921 | ␉␉␉}␊ |
922 | ␉␉␉if (nstrings == 0) {␊ |
923 | ␉␉␉␉newtablesptr[0] = 0;␊ |
924 | ␉␉␉␉newtablesptr++;␊ |
925 | ␉␉␉}␊ |
926 | ␉␉␉newtablesptr[0] = 0;␊ |
927 | ␉␉␉newtablesptr++;␊ |
928 | ␉␉␉tablespresent[smbios_table_descriptions[i].type]++;␊ |
929 | ␉␉}␊ |
930 | ␉}␊ |
931 | ␊ |
932 | // calculate new checksums␊ |
933 | ␉newsmbios->dmi.checksum = 0;␊ |
934 | ␉newsmbios->dmi.checksum = 256 - checksum8(&newsmbios->dmi, sizeof(newsmbios->dmi));␊ |
935 | ␉newsmbios->checksum = 0;␊ |
936 | ␉newsmbios->checksum = 256 - checksum8(newsmbios, sizeof(*newsmbios));␊ |
937 | ␉␊ |
938 | ␉if (!done) {␊ |
939 | ␉␉verbose("Patched DMI Table\n");␊ |
940 | ␉␉done=true;␊ |
941 | ␉}␊ |
942 | }␊ |
943 | ␊ |
944 | #define MAX_DMI_TABLES 96␊ |
945 | typedef struct DmiNumAssocTag {␊ |
946 | struct DMIHeader * dmi;␊ |
947 | uint8_t type;␊ |
948 | } DmiNumAssoc;␊ |
949 | ␊ |
950 | static DmiNumAssoc DmiTablePair[MAX_DMI_TABLES];␊ |
951 | static int DmiTablePairCount = 0;␊ |
952 | static int current_pos=0;␊ |
953 | static bool ftTablePairInit = true;␊ |
954 | ␊ |
955 | /** ␊ |
956 | * Get a table structure entry from a type specification and a smbios address␊ |
957 | * return NULL if table is not found␊ |
958 | */␊ |
959 | static void getSmbiosTableStructure(struct SMBEntryPoint *smbios)␊ |
960 | {␊ |
961 | struct DMIHeader * dmihdr=NULL;␊ |
962 | SMBByte* p;␊ |
963 | int i;␊ |
964 | ␊ |
965 | if (ftTablePairInit && smbios!=NULL) {␊ |
966 | ftTablePairInit = false;␊ |
967 | #if DEBUG_SMBIOS␊ |
968 | printf(">>> SMBIOSAddr=0x%08x\n", smbios);␊ |
969 | printf(">>> DMI: addr=0x%08x, len=%d, count=%d\n", smbios->dmi.tableAddress, ␊ |
970 | smbios->dmi.tableLength, smbios->dmi.structureCount);␊ |
971 | #endif␊ |
972 | p = (SMBByte *) smbios->dmi.tableAddress;␊ |
973 | for (i=0; ␊ |
974 | i < smbios->dmi.structureCount && ␊ |
975 | p + 4 <= (SMBByte *)smbios->dmi.tableAddress + smbios->dmi.tableLength; ␊ |
976 | i++) {␊ |
977 | dmihdr = (struct DMIHeader *) p;␊ |
978 | ␊ |
979 | #if DEBUG_SMBIOS␊ |
980 | // verbose(">>>>>> DMI(%d): type=0x%02x, len=0x%d\n",i,dmihdr->type,dmihdr->length);␊ |
981 | #endif␊ |
982 | if (dmihdr->length < 4 || dmihdr->type == 127 /* EOT */) break;␊ |
983 | if (DmiTablePairCount < MAX_DMI_TABLES) {␊ |
984 | DmiTablePair[DmiTablePairCount].dmi = dmihdr;␊ |
985 | DmiTablePair[DmiTablePairCount].type = dmihdr->type;␊ |
986 | DmiTablePairCount++;␊ |
987 | }␊ |
988 | else {␊ |
989 | printf("DMI table entries list is full! Next entries won't be stored.\n");␊ |
990 | }␊ |
991 | #if DEBUG_SMBIOS␊ |
992 | printf("DMI header found for table type %d, length = %d\n", dmihdr->type, dmihdr->length);␊ |
993 | #endif␊ |
994 | p = p + dmihdr->length;␊ |
995 | while ((p - (SMBByte *)smbios->dmi.tableAddress + 1 < smbios->dmi.tableLength) && (p[0] != 0x00 || p[1] != 0x00)) {␊ |
996 | p++;␊ |
997 | ␉ }␊ |
998 | p += 2;␊ |
999 | ␉}␊ |
1000 | ␊ |
1001 | }␊ |
1002 | }␊ |
1003 | ␊ |
1004 | /** Get original or new smbios entry point, if sucessful, the adresses are cached for next time */␊ |
1005 | struct SMBEntryPoint *getSmbios(int which)␊ |
1006 | {␊ |
1007 | static struct SMBEntryPoint *orig = NULL; // cached␊ |
1008 | static struct SMBEntryPoint *patched = NULL; // cached␊ |
1009 | ␊ |
1010 | // whatever we are called with orig or new flag, initialize asap both structures␊ |
1011 | switch (which) {␊ |
1012 | case SMBIOS_ORIGINAL:␊ |
1013 | if (orig==NULL) {␊ |
1014 | orig = getAddressOfSmbiosTable();␊ |
1015 | getSmbiosTableStructure(orig); // generate tables entry list for fast table finding␊ |
1016 | }␊ |
1017 | return orig;␊ |
1018 | case SMBIOS_PATCHED:␊ |
1019 | if (orig==NULL && (orig = getAddressOfSmbiosTable())==NULL ) {␊ |
1020 | printf("Could not find original SMBIOS !!\n");␊ |
1021 | pause();␊ |
1022 | } else {␊ |
1023 | patched = smbios_dry_run(orig);␊ |
1024 | if(patched==NULL) {␊ |
1025 | printf("Could not create new SMBIOS !!\n");␊ |
1026 | pause();␊ |
1027 | }␊ |
1028 | else {␊ |
1029 | smbios_real_run(orig, patched);␊ |
1030 | }␊ |
1031 | }␊ |
1032 | ␊ |
1033 | return patched;␊ |
1034 | default:␊ |
1035 | printf("ERROR: invalid option for getSmbios() !!\n");␊ |
1036 | break;␊ |
1037 | }␊ |
1038 | ␊ |
1039 | return NULL;␊ |
1040 | }␊ |
1041 | ␊ |
1042 | /** Find first original dmi Table with a particular type */␊ |
1043 | struct DMIHeader* FindFirstDmiTableOfType(int type, int minlength)␊ |
1044 | {␊ |
1045 | current_pos = 0;␊ |
1046 | ␊ |
1047 | return FindNextDmiTableOfType(type, minlength);␊ |
1048 | };␊ |
1049 | ␊ |
1050 | /** Find next original dmi Table with a particular type */␊ |
1051 | struct DMIHeader* FindNextDmiTableOfType(int type, int minlength)␊ |
1052 | {␊ |
1053 | int i;␊ |
1054 | ␊ |
1055 | if (ftTablePairInit) getSmbios(SMBIOS_ORIGINAL);␊ |
1056 | ␊ |
1057 | for (i=current_pos; i < DmiTablePairCount; i++) {␊ |
1058 | if (type == DmiTablePair[i].type && ␊ |
1059 | DmiTablePair[i].dmi &&␊ |
1060 | DmiTablePair[i].dmi->length >= minlength ) {␊ |
1061 | current_pos = i+1;␊ |
1062 | return DmiTablePair[i].dmi;␊ |
1063 | }␊ |
1064 | }␊ |
1065 | return NULL; // not found␊ |
1066 | };␊ |
1067 | ␊ |
1068 |