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 "convert.h"␊ |
10 | #include "efi_tables.h"␊ |
11 | #include "fake_efi.h"␊ |
12 | #include "platform.h"␊ |
13 | #include "smbios_patcher.h"␊ |
14 | #include "SMBIOS.h"␊ |
15 | #include "pci.h"␊ |
16 | ␊ |
17 | #ifndef DEBUG_SMBIOS␊ |
18 | #define DEBUG_SMBIOS 0␊ |
19 | #endif␊ |
20 | ␊ |
21 | #if DEBUG_SMBIOS␊ |
22 | #define DBG(x...)␉verbose(x)␊ |
23 | #else␊ |
24 | #define DBG(x...)␊ |
25 | #endif␊ |
26 | //Slice - for ACPI patcher templates␊ |
27 | int␉␉ModelLength = 0;␊ |
28 | char␉MacModel[8] = "MacBook";␊ |
29 | unsigned int ModelRev = 0x00010001;␊ |
30 | uint64_t smbios_p;␊ |
31 | ␊ |
32 | char* gSMBIOSBoardModel;␊ |
33 | ␊ |
34 | typedef struct {␊ |
35 | const char* key;␊ |
36 | const char* value;␊ |
37 | } SMStrEntryPair;␊ |
38 | //Slice - TODO must be unique UUID for each model?␊ |
39 | /* Random values␊ |
40 | 19422392-C343-4A3A-92A3-AB1F0A6C3E52␊ |
41 | E3314823-659D-42B6-B42C-147E4E3484D4␊ |
42 | C3D73A74-809A-4804-A747-DDB934A737D0␊ |
43 | */␊ |
44 | // defaults for a MacBook␊ |
45 | static const SMStrEntryPair const sm_macbook11_defaults[]={␊ |
46 | ␉{"SMbiosvendor",␉"Apple Inc."␉␉␉},␊ |
47 | ␉{"SMbiosversion",␉"MB11.0061.B03.0809221748"␉},␊ |
48 | ␉{"SMbiosdate",␉␉"04/01/2007"␉␉␉},␊ |
49 | ␉{"SMmanufacter",␉"Apple Inc."␉␉␉},␊ |
50 | ␉{"SMproductname",␉"MacBook1,1"␉␉␉},␊ |
51 | ␉{"SMsystemversion",␉"1.0"␉␉␉␉},␊ |
52 | ␉{"SMserial",␉␉"W88033AKY51"␉␉␉},␊ |
53 | ␉{"SMfamily",␉␉"MacBook"␉␉␉},␊ |
54 | ␉{"SMboardmanufacter",␉"Apple Inc."␉␉␉},␊ |
55 | ␉{"SMboardproduct",␉"Mac-F4208CA9"␉␉␉},␊ |
56 | ␉{"SMUUID"␉, "19422392-C343-106B-80A3-001F0A6C3E52"},␊ |
57 | ␉{ "",""␉}␊ |
58 | };␊ |
59 | ␊ |
60 | static const SMStrEntryPair const sm_macbook_defaults[]={␊ |
61 | ␉{"SMbiosvendor",␉"Apple Inc."␉␉␉},␊ |
62 | ␉{"SMbiosversion",␉"MB41.88Z.0073.B00.0809221748"␉},␊ |
63 | ␉{"SMbiosdate",␉␉"04/01/2008"␉␉␉},␊ |
64 | ␉{"SMmanufacter",␉"Apple Inc."␉␉␉},␊ |
65 | ␉{"SMproductname",␉"MacBook4,1"␉␉␉},␊ |
66 | ␉{"SMsystemversion",␉"1.0"␉␉␉␉},␊ |
67 | ␉{"SMserial",␉␉"W88033AKY51"␉␉␉},␊ |
68 | ␉{"SMfamily",␉␉"MacBook"␉␉␉},␊ |
69 | ␉{"SMboardmanufacter",␉"Apple Inc."␉␉␉},␊ |
70 | ␉{"SMboardproduct",␉"Mac-F42D89C8"␉␉␉},␊ |
71 | ␉{"SMUUID"␉, "26A96EAC-CD73-7A49-8B7C-2DA8F466D971"},␊ |
72 | ␉{ "",""␉}␊ |
73 | };␊ |
74 | /*␊ |
75 | MacBookAir␊ |
76 | Board Id: Mac-F42C8CC8␊ |
77 | Model Id: MacBookAir1,1␊ |
78 | Boot ROM Version: MBA11.88Z.00BB.B00.0712201139␊ |
79 | Serial Nr: W881101T12G␊ |
80 | W88033AKY51␊ |
81 | SMBIOS Version: 1.0␊ |
82 | SMC Version: 1.3f4 (SMC 1.0)␊ |
83 | */␊ |
84 | ␊ |
85 | // defaults for a MacBook Pro␊ |
86 | static const SMStrEntryPair const sm_macbookpro_defaults[]={␊ |
87 | ␉{"SMbiosvendor",␉"Apple Inc."␉␉␉},␊ |
88 | ␉{"SMbiosversion",␉"MBP51.88Z.0073.B00.0809221748"␉},␊ |
89 | ␉{"SMbiosdate",␉␉"04/01/2008"␉␉␉},␊ |
90 | ␉{"SMmanufacter",␉"Apple Inc."␉␉␉},␊ |
91 | ␉{"SMproductname",␉"MacBookPro5,1"␉␉␉},␊ |
92 | ␉{"SMsystemversion",␉"1.0"␉␉␉␉},␊ |
93 | ␉{"SMserial",␉␉"W8841NP21G0"␉␉␉},␊ |
94 | ␉{"SMfamily",␉␉"MacBookPro"␉␉␉},␊ |
95 | ␉{"SMboardmanufacter",␉"Apple Inc."␉␉␉},␊ |
96 | ␉{"SMboardproduct",␉"Mac-F42D89C8"␉␉␉},␊ |
97 | ␉{"SMUUID"␉, "DCE37B2F-B608-53C2-A314-C248A24A9D06"},␊ |
98 | ␉{ "",""␉}␊ |
99 | };␊ |
100 | ␊ |
101 | // defaults for a Mac mini ␊ |
102 | static const SMStrEntryPair const sm_macmini_defaults[]={␊ |
103 | ␉{"SMbiosvendor",␉"Apple Inc."␉␉␉},␊ |
104 | ␉{"SMbiosversion",␉"MM21.88Z.009A.B00.0706281359"␉},␊ |
105 | ␉{"SMbiosdate",␉␉"04/01/2008"␉␉␉},␊ |
106 | ␉{"SMmanufacter",␉"Apple Inc."␉␉␉},␊ |
107 | ␉{"SMproductname",␉"MacMini2,1"␉␉␉},␊ |
108 | ␉{"SMsystemversion",␉"1.1"␉␉␉␉},␊ |
109 | ␉{"SMserial",␉␉"YM6094QPU36"␉␉␉},␊ |
110 | ␉{"SMfamily",␉␉"Napa Mac"␉␉␉},␊ |
111 | ␉{"SMboardmanufacter",␉"Apple Inc."␉␉␉},␊ |
112 | ␉{"SMboardproduct",␉"Mac-F4208EAA"␉␉␉},␊ |
113 | ␉{"SMUUID"␉, "E3314823-659D-42B6-B42C-147E4E3484D4"},␊ |
114 | ␉{ "",""␉}␊ |
115 | };␊ |
116 | ␊ |
117 | // defaults for an iMac␊ |
118 | static const SMStrEntryPair const sm_imac_defaults[]={␊ |
119 | ␉{"SMbiosvendor",␉"Apple Inc."␉␉␉},␊ |
120 | ␉{"SMbiosversion",␉"IM91.88Z.00C1.B00.0802091538"␉},␊ |
121 | ␉{"SMbiosdate",␉␉"04/01/2008"␉␉␉},␊ |
122 | ␉{"SMmanufacter",␉"Apple Inc."␉␉␉},␊ |
123 | ␉{"SMproductname",␉"iMac9,1"␉␉␉␉␉␉},␉␊ |
124 | ␉{"SMsystemversion",␉"1.0"␉␉␉␉},␊ |
125 | ␉{"SMserial",␉␉"SOMESRLNMBR"␉␉␉},␊ |
126 | ␉{"SMfamily",␉␉"Mac"␉␉␉␉},␊ |
127 | ␉{"SMboardmanufacter",␉"Apple Inc."␉␉␉},␊ |
128 | ␉{"SMboardproduct",␉"Mac-F227BEC8"␉␉␉},␊ |
129 | ␉{"SMUUID"␉, "862F78AF-9B36-40AF-B67A-ABBA8C14A528"},␊ |
130 | ␉{ "",""␉}␊ |
131 | };␊ |
132 | ␊ |
133 | // defaults for a Mac Pro␊ |
134 | static const SMStrEntryPair const sm_macpro_defaults[]={␊ |
135 | ␉{"SMbiosvendor",␉␉"Apple Computer, Inc."␉␉␉},␊ |
136 | ␉{"SMbiosversion",␉␉"MP31.88Z.006C.B05.0802291410"␉},␊ |
137 | ␉{"SMbiosdate",␉␉␉"04/01/2008"␉␉␉␉␉},␊ |
138 | ␉{"SMmanufacter",␉␉"Apple Computer, Inc."␉␉␉},␊ |
139 | ␉{"SMproductname",␉␉"MacPro3,1"␉␉␉␉␉␉},␊ |
140 | ␉{"SMsystemversion",␉␉"1.0"␉␉␉␉␉␉␉},␊ |
141 | ␉{"SMserial",␉␉␉"W88033AKY51"␉␉␉␉␉},␊ |
142 | ␉{"SMfamily",␉␉␉"MacPro"␉␉␉␉␉␉},␊ |
143 | ␉{"SMboardmanufacter",␉"Apple Computer, Inc."␉␉␉},␊ |
144 | ␉{"SMboardproduct",␉␉"Mac-F4208DC8"␉␉␉␉␉},␊ |
145 | ␉{"SMUUID"␉, "862F78AF-9B36-40AF-B67A-ABBA8C14A528"},␊ |
146 | ␉{ "",""␉}␊ |
147 | };␊ |
148 | ␊ |
149 | // defaults for an iMac11,1 core i3/i5/i7␊ |
150 | static const SMStrEntryPair const sm_imac_core_defaults[]={␊ |
151 | ␉{"SMbiosvendor",␉␉"Apple Inc."␉␉␉␉␉},␊ |
152 | ␉{"SMbiosversion",␉␉"IM111.88Z.0034.B00.0802091538"␉},␊ |
153 | ␉{"SMbiosdate",␉␉␉"06/01/2009"␉␉␉␉␉},␊ |
154 | ␉{"SMmanufacter",␉␉"Apple Inc."␉␉␉␉␉},␊ |
155 | ␉{"SMproductname",␉␉"iMac11,1"␉␉␉␉␉␉},␉␊ |
156 | ␉{"SMsystemversion",␉␉"1.0"␉␉␉␉␉␉␉},␊ |
157 | ␉{"SMserial",␉␉␉"W87234JHYA4"␉␉␉␉␉},␊ |
158 | ␉{"SMfamily",␉␉␉"iMac"␉␉␉␉␉␉␉},␊ |
159 | ␉{"SMboardmanufacter",␉"Apple Computer, Inc."␉␉␉},␊ |
160 | ␉{"SMboardproduct",␉␉"Mac-F2268DAE"␉␉␉␉␉},␊ |
161 | ␉{"SMUUID"␉, "862F78AF-9B36-40AF-B67A-ABBA8C14A528"},␊ |
162 | ␉{ "",""␉}␊ |
163 | };␊ |
164 | #if NEVER_USE_MACPRO41␊ |
165 | // defaults for a Mac Pro 4,1 Xeon␊ |
166 | static const SMStrEntryPair const sm_macpro_core_defaults[]={␊ |
167 | ␉{"SMbiosvendor",␉␉"Apple Computer, Inc."␉␉␉},␊ |
168 | ␉{"SMbiosversion",␉␉"MP41.88Z.0081.B04.0903051113"␉},␊ |
169 | ␉{"SMbiosdate",␉␉␉"11/06/2009"␉␉␉␉␉},␊ |
170 | ␉{"SMmanufacter",␉␉"Apple Computer, Inc."␉␉␉},␊ |
171 | ␉{"SMproductname",␉␉"MacPro4,1"␉␉␉␉␉␉},␊ |
172 | ␉{"SMsystemversion",␉␉"1.0"␉␉␉␉␉␉␉},␊ |
173 | ␉{"SMserial",␉␉␉"W88033AKY51"␉␉␉␉␉},␊ |
174 | ␉{"SMfamily",␉␉␉"MacPro"␉␉␉␉␉␉},␊ |
175 | ␉{"SMboardmanufacter",␉"Apple Computer, Inc."␉␉␉},␊ |
176 | ␉{"SMboardproduct",␉␉"Mac-F221BEC8"␉␉␉␉␉},␊ |
177 | ␉{"SMUUID"␉, "862F78AF-9B36-40AF-B67A-ABBA8C14A528"},␊ |
178 | ␉{ "",""␉}␊ |
179 | };␊ |
180 | #endif␊ |
181 | static const char* sm_get_defstr(const char * key, int table_num)␊ |
182 | {␊ |
183 | ␉int␉i;␊ |
184 | ␉const SMStrEntryPair*␉sm_defaults;␊ |
185 | ␊ |
186 | //␉if (platformCPUFeature(CPU_FEATURE_MOBILE)) {␊ |
187 | ␉if (Platform->CPU.Mobile) {␊ |
188 | ␉␉if (Platform->CPU.NoCores > 1) {␊ |
189 | ␉␉␉//TODO if NVidia - MBP else MB␊ |
190 | ␉␉␉sm_defaults=sm_macbookpro_defaults;␊ |
191 | ␉␉} else {␊ |
192 | ␉␉␉sm_defaults=sm_macbook_defaults;␊ |
193 | ␉␉}␊ |
194 | ␉} else {␊ |
195 | ␉␉switch (Platform->CPU.NoCores) ␊ |
196 | ␉␉{␊ |
197 | ␉␉␉case 1: ␊ |
198 | ␉␉␉␉sm_defaults=sm_macmini_defaults; ␊ |
199 | ␉␉␉␉break;␊ |
200 | ␉␉␉case 2:␊ |
201 | ␉␉␉␉sm_defaults=sm_imac_defaults;␊ |
202 | ␉␉␉␉break;␊ |
203 | ␉␉␉default:␊ |
204 | ␉␉␉{␊ |
205 | ␉␉␉␉switch (Platform->CPU.Family) ␊ |
206 | ␉␉␉␉{␊ |
207 | ␉␉␉␉␉case 0x06:␊ |
208 | ␉␉␉␉␉{␊ |
209 | ␉␉␉␉␉␉switch (Platform->CPU.Model)␊ |
210 | ␉␉␉␉␉␉{␊ |
211 | ␉␉␉␉␉␉␉case CPU_MODEL_FIELDS: // Intel Core i5, i7 LGA1156 (45nm)␊ |
212 | ␉␉␉␉␉␉␉case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) ???␊ |
213 | ␉␉␉␉␉␉␉case CPU_MODEL_DALES_32NM: // Intel Core i3, i5, i7 LGA1156 (32nm) (Clarkdale, Arrandale)␊ |
214 | ␉␉␉␉␉␉␉case 0x19: // Intel Core i5 650 @3.20 Ghz ␊ |
215 | ␉␉␉␉␉␉//␉␉sm_defaults=sm_imac_defaults; ␊ |
216 | ␉␉␉␉␉␉//␉␉break;␊ |
217 | ␉␉␉␉␉␉␉case CPU_MODEL_NEHALEM: ␊ |
218 | ␉␉␉␉␉␉␉case CPU_MODEL_NEHALEM_EX:␊ |
219 | ␉␉␉␉␉␉␉case CPU_MODEL_WESTMERE: ␊ |
220 | ␉␉␉␉␉␉␉case CPU_MODEL_WESTMERE_EX:␊ |
221 | ␉␉␉␉␉␉␉␉sm_defaults=sm_imac_core_defaults; ␊ |
222 | ␉␉␉␉␉␉␉␉break;␊ |
223 | ␉␉␉␉␉␉␉default:␊ |
224 | ␉␉␉␉␉␉␉␉sm_defaults=sm_imac_core_defaults; ␊ |
225 | ␉␉␉␉␉␉␉␉break;␊ |
226 | ␉␉␉␉␉␉}␊ |
227 | ␉␉␉␉␉␉break;␊ |
228 | ␉␉␉␉␉}␊ |
229 | ␉␉␉␉␉default:␊ |
230 | ␉␉␉␉␉␉sm_defaults=sm_macpro_defaults; ␊ |
231 | ␉␉␉␉␉␉break;␊ |
232 | ␉␉␉␉}␊ |
233 | ␉␉␉␉break;␊ |
234 | ␉␉␉}␊ |
235 | ␉␉}␊ |
236 | ␉}␊ |
237 | ␉␊ |
238 | ␉for (i=0; sm_defaults[i].key[0]; i++) {␊ |
239 | ␉␉if (!strcmp (sm_defaults[i].key, key)) {␊ |
240 | ␉␉␉return sm_defaults[i].value;␊ |
241 | ␉␉}␊ |
242 | ␉}␊ |
243 | ␊ |
244 | ␉// Shouldn't happen␊ |
245 | ␉printf ("Error: no default for '%s' known\n", key);␊ |
246 | ␉sleep (2);␊ |
247 | ␉return "";␊ |
248 | }␊ |
249 | ␊ |
250 | static int sm_get_fsb(const char *name, int table_num)␊ |
251 | {␊ |
252 | ␉return Platform->CPU.FSBFrequency/1000000;␊ |
253 | }␊ |
254 | ␊ |
255 | static int sm_get_cpu (const char *name, int table_num)␊ |
256 | {␊ |
257 | ␉return Platform->CPU.CPUFrequency/1000000;␊ |
258 | }␊ |
259 | ␊ |
260 | static int sm_get_bus_speed (const char *name, int table_num)␊ |
261 | {␊ |
262 | ␉if (Platform->CPU.Vendor == 0x756E6547) // Intel␊ |
263 | ␉{␉␉␊ |
264 | ␉␉switch (Platform->CPU.Family) ␊ |
265 | ␉␉{␊ |
266 | ␉␉␉case 0x06:␊ |
267 | ␉␉␉{␊ |
268 | ␉␉␉␉switch (Platform->CPU.Model)␊ |
269 | ␉␉␉␉{␊ |
270 | ␉␉␉␉␉case CPU_MODEL_PENTIUM_M: // Pentium M 0x0D␊ |
271 | ␉␉␉␉␉case CPU_MODEL_YONAH:␉// Yonah␉␉0x0E␊ |
272 | ␉␉␉␉␉case CPU_MODEL_MEROM:␉// Merom␉␉0x0F␊ |
273 | ␉␉␉␉␉case CPU_MODEL_PENRYN:␉// Penryn␉␉0x17␊ |
274 | ␉␉␉␉␉case CPU_MODEL_ATOM:␉// Atom 45nm␉0x1C␊ |
275 | ␉␉␉␉␉␉return 0; // TODO: populate bus speed for these processors␊ |
276 | ␉␉␉␉␉␉␊ |
277 | //␉␉␉␉␉case CPU_MODEL_FIELDS: // Intel Core i5, i7 LGA1156 (45nm)␊ |
278 | //␉␉␉␉␉␉if (strstr(Platform->CPU.BrandString, "Core(TM) i5"))␊ |
279 | //␉␉␉␉␉␉␉return 2500; // Core i5␊ |
280 | //␉␉␉␉␉␉return 4800; // Core i7␊ |
281 | ␉␉␉␉␉␉␊ |
282 | //␉␉␉␉␉case CPU_MODEL_NEHALEM: // Intel Core i7 LGA1366 (45nm)␊ |
283 | //␉␉␉␉␉case CPU_MODEL_NEHALEM_EX:␊ |
284 | //␉␉␉␉␉case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) ???␊ |
285 | //␉␉␉␉␉␉return 4800; // GT/s / 1000␊ |
286 | //␉␉␉␉␉␉␊ |
287 | ␉␉␉␉␉case CPU_MODEL_WESTMERE_EX: // Intel Core i7 LGA1366 (45nm) 6 Core ???␊ |
288 | ␉␉␉␉␉␉return 0; // TODO: populate bus speed for these processors␊ |
289 | ␉␉␉␉␉␉␊ |
290 | //␉␉␉␉␉case 0x19: // Intel Core i5 650 @3.20 Ghz␊ |
291 | //␉␉␉␉␉␉return 2500; // why? Intel spec says 2.5GT/s ␊ |
292 | ␊ |
293 | ␉␉␉␉␉case 0x19: // Intel Core i5 650 @3.20 Ghz␊ |
294 | ␉␉␉␉␉case CPU_MODEL_NEHALEM: // Intel Core i7 LGA1366 (45nm)␊ |
295 | ␉␉␉␉␉case CPU_MODEL_FIELDS: // Intel Core i5, i7 LGA1156 (45nm)␊ |
296 | ␉␉␉␉␉case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) ???␊ |
297 | ␉␉␉␉␉case CPU_MODEL_DALES_32NM: // Intel Core i3, i5, i7 LGA1156 (32nm)␊ |
298 | ␉␉␉␉␉case CPU_MODEL_WESTMERE: // Intel Core i7 LGA1366 (32nm) 6 Core␊ |
299 | ␉␉␉␉␉case CPU_MODEL_NEHALEM_EX: // Intel Core i7 LGA1366 (45nm) 6 Core ???␊ |
300 | ␉␉␉␉␉{ // thanks to dgobe for i3/i5/i7 bus speed detection␊ |
301 | ␉␉␉␉␉␉int nhm_bus = 0x3F;␊ |
302 | ␉␉␉␉␉␉static long possible_nhm_bus[] = {0xFF, 0x7F, 0x3F};␊ |
303 | ␉␉␉␉␉␉unsigned long did, vid;␊ |
304 | ␉␉␉␉␉␉int i;␊ |
305 | ␉␉␉␉␉␉␊ |
306 | ␉␉␉␉␉␉// Nehalem supports Scrubbing␊ |
307 | ␉␉␉␉␉␉// First, locate the PCI bus where the MCH is located␊ |
308 | ␉␉␉␉␉␉for(i = 0; i < sizeof(possible_nhm_bus); i++)␊ |
309 | ␉␉␉␉␉␉{␊ |
310 | ␉␉␉␉␉␉␉vid = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), 0x00);␊ |
311 | ␉␉␉␉␉␉␉did = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), 0x02);␊ |
312 | ␉␉␉␉␉␉␉vid &= 0xFFFF;␊ |
313 | ␉␉␉␉␉␉␉did &= 0xFF00;␊ |
314 | ␉␉␉␉␉␉␉␊ |
315 | ␉␉␉␉␉␉␉if(vid == 0x8086 && did >= 0x2C00)␊ |
316 | ␉␉␉␉␉␉␉␉nhm_bus = possible_nhm_bus[i]; ␊ |
317 | ␉␉␉␉␉␉}␊ |
318 | ␉␉␉␉␉␉␊ |
319 | ␉␉␉␉␉␉unsigned long qpimult, qpibusspeed;␊ |
320 | ␉␉␉␉␉␉qpimult = pci_config_read32(PCIADDR(nhm_bus, 2, 1), 0x50);␊ |
321 | ␉␉␉␉␉␉qpimult &= 0x7F;␊ |
322 | ␉␉␉␉␉␉DBG("qpimult %d\n", qpimult);␊ |
323 | ␉␉␉␉␉␉qpibusspeed = (qpimult * 2 * (Platform->CPU.FSBFrequency/1000000));␊ |
324 | ␉␉␉␉␉␉// Rek: rounding decimals to match original mac profile info␊ |
325 | ␉␉␉␉␉␉if (qpibusspeed%100 != 0)qpibusspeed = ((qpibusspeed+50)/100)*100;␊ |
326 | ␉␉␉␉␉␉DBG("qpibusspeed %d\n", qpibusspeed);␊ |
327 | ␉␉␉␉␉␉return qpibusspeed;␊ |
328 | ␉␉␉␉␉}␊ |
329 | ␉␉␉␉}␊ |
330 | ␉␉␉}␊ |
331 | ␉␉}␊ |
332 | ␉}␊ |
333 | ␉return 0;␊ |
334 | }␊ |
335 | ␊ |
336 | static int sm_get_simplecputype()␊ |
337 | {␊ |
338 | ␉if (Platform->CPU.NoCores >= 4) ␊ |
339 | ␉{␊ |
340 | ␉␉return 0x0501; // Quad-Core Xeon␊ |
341 | ␉}␊ |
342 | ␉else if (Platform->CPU.NoCores == 1) ␊ |
343 | ␉{␊ |
344 | ␉␉return 0x0201; // Core Solo␊ |
345 | ␉};␊ |
346 | ␉␊ |
347 | ␉return 0x0301; // Core 2 Duo␊ |
348 | }␊ |
349 | ␊ |
350 | static int sm_get_cputype (const char *name, int table_num)␊ |
351 | {␊ |
352 | ␉static bool done = false;␉␉␊ |
353 | ␉␉␊ |
354 | ␉if (Platform->CPU.Vendor == 0x756E6547) // Intel␊ |
355 | ␉{␊ |
356 | ␉␉if (!done) {␊ |
357 | ␉␉␉verbose("CPU is %s, family 0x%x, model 0x%x\n", Platform->CPU.BrandString, Platform->CPU.Family, Platform->CPU.Model);␊ |
358 | ␉␉␉done = true;␊ |
359 | ␉␉}␊ |
360 | ␉␉␊ |
361 | ␉␉switch (Platform->CPU.Family) ␊ |
362 | ␉␉{␊ |
363 | ␉␉␉case 0x06:␊ |
364 | ␉␉␉{␊ |
365 | ␉␉␉␉switch (Platform->CPU.Model)␊ |
366 | ␉␉␉␉{␊ |
367 | ␉␉␉␉␉case CPU_MODEL_PENTIUM_M: // Pentium M = 0x0D␊ |
368 | ␉␉␉␉␉␉return 0x0101;␊ |
369 | ␉␉␉␉␉case CPU_MODEL_YONAH: // Yonah␊ |
370 | ␉␉␉␉␉case CPU_MODEL_MEROM: // Merom␊ |
371 | ␉␉␉␉␉case CPU_MODEL_PENRYN: // Penryn␊ |
372 | ␉␉␉␉␉case CPU_MODEL_ATOM: // Intel Atom (45nm)␊ |
373 | ␉␉␉␉␉␉return sm_get_simplecputype();␊ |
374 | ␉␉␉␉␉␉␊ |
375 | ␉␉␉␉␉case CPU_MODEL_NEHALEM: // Intel Core i7 LGA1366 (45nm)␊ |
376 | ␉␉␉␉␉␉return 0x0701; // Core i7␊ |
377 | ␉␉␉␉␉␉␊ |
378 | ␉␉␉␉␉case CPU_MODEL_FIELDS: // Lynnfield, Clarksfield, Jasper␊ |
379 | ␉␉␉␉␉␉if (strstr(Platform->CPU.BrandString, "Core(TM) i5"))␊ |
380 | ␉␉␉␉␉␉␉return 0x601; // Core i5␊ |
381 | ␉␉␉␉␉␉return 0x701; // Core i7␊ |
382 | ␉␉␉␉␉␉␊ |
383 | ␉␉␉␉␉case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) (Havendale, Auburndale)␊ |
384 | ␉␉␉␉␉␉if (strstr(Platform->CPU.BrandString, "Core(TM) i5"))␊ |
385 | ␉␉␉␉␉␉␉return 0x601; // Core i5␊ |
386 | ␉␉␉␉␉␉return 0x0701; // Core i7␊ |
387 | ␉␉␉␉␉␉␊ |
388 | ␉␉␉␉␉case CPU_MODEL_DALES_32NM: // Intel Core i3, i5, i7 LGA1156 (32nm) (Clarkdale, Arrandale)␊ |
389 | ␉␉␉␉␉␉if (strstr(Platform->CPU.BrandString, "Core(TM) i3"))␊ |
390 | ␉␉␉␉␉␉␉return 0x901; // Core i3␊ |
391 | ␉␉␉␉␉␉if (strstr(Platform->CPU.BrandString, "Core(TM) i5"))␊ |
392 | ␉␉␉␉␉␉␉return 0x601; // Core i5␊ |
393 | ␉␉␉␉␉␉return 0x0701; // Core i7␊ |
394 | ␉␉␉␉␉␉␊ |
395 | ␉␉␉␉␉case CPU_MODEL_WESTMERE: // Intel Core i7 LGA1366 (32nm) 6 Core (Gulftown, Westmere-EP, Westmere-WS)␊ |
396 | ␉␉␉␉␉case CPU_MODEL_WESTMERE_EX: // Intel Core i7 LGA1366 (45nm) 6 Core ???␊ |
397 | ␉␉␉␉␉␉return 0x0701; // Core i7␊ |
398 | ␉␉␉␉␉␉␊ |
399 | ␉␉␉␉␉case 0x19: // Intel Core i5 650 @3.20 Ghz␊ |
400 | ␉␉␉␉␉␉return 0x601; // Core i5␊ |
401 | ␉␉␉␉}␊ |
402 | ␉␉␉}␊ |
403 | ␉␉}␊ |
404 | ␉}␊ |
405 | ␉␊ |
406 | ␉return sm_get_simplecputype();␊ |
407 | }␊ |
408 | ␊ |
409 | static int sm_get_memtype (const char *name, int table_num)␊ |
410 | {␊ |
411 | ␉int␉map;␊ |
412 | ␊ |
413 | ␉if (table_num < MAX_RAM_SLOTS) {␊ |
414 | ␉␉map = Platform->DMI.DIMM[table_num];␊ |
415 | ␉␉if (Platform->RAM.DIMM[map].InUse && Platform->RAM.DIMM[map].Type != 0) {␊ |
416 | DBG("RAM Detected Type = %d\n", Platform->RAM.DIMM[map].Type);␊ |
417 | return Platform->RAM.DIMM[map].Type;␊ |
418 | ␉␉}␊ |
419 | ␉}␊ |
420 | ␉␊ |
421 | ␉return SMB_MEM_TYPE_DDR2;␊ |
422 | }␊ |
423 | ␊ |
424 | static int sm_get_memspeed (const char *name, int table_num)␊ |
425 | {␊ |
426 | ␉int␉map;␊ |
427 | ␊ |
428 | ␉if (table_num < MAX_RAM_SLOTS) {␊ |
429 | ␉␉map = Platform->DMI.DIMM[table_num];␊ |
430 | ␉␉if (Platform->RAM.DIMM[map].InUse && Platform->RAM.DIMM[map].Frequency != 0) {␊ |
431 | DBG("RAM Detected Freq = %d Mhz\n", Platform->RAM.DIMM[map].Frequency);␊ |
432 | return Platform->RAM.DIMM[map].Frequency;␊ |
433 | ␉␉}␊ |
434 | ␉}␊ |
435 | ␊ |
436 | ␉return 800;␊ |
437 | }␊ |
438 | ␊ |
439 | static const char *sm_get_memvendor (const char *name, int table_num)␊ |
440 | {␊ |
441 | ␉int␉map;␊ |
442 | ␊ |
443 | ␉if (table_num < MAX_RAM_SLOTS) {␊ |
444 | ␉␉map = Platform->DMI.DIMM[table_num];␊ |
445 | ␉␉if (Platform->RAM.DIMM[map].InUse && strlen(Platform->RAM.DIMM[map].Vendor) > 0) {␊ |
446 | ␉␉␉DBG("RAM Detected Vendor[%d]='%s'\n", table_num, Platform->RAM.DIMM[map].Vendor);␊ |
447 | ␉␉␉return Platform->RAM.DIMM[map].Vendor;␊ |
448 | ␉␉}␊ |
449 | ␉}␊ |
450 | ␉return "N/A";␊ |
451 | }␊ |
452 | ␉␊ |
453 | static const char *sm_get_memserial (const char *name, int table_num)␊ |
454 | {␊ |
455 | ␉int␉map;␊ |
456 | ␊ |
457 | ␉if (table_num < MAX_RAM_SLOTS) {␊ |
458 | ␉␉map = Platform->DMI.DIMM[table_num];␊ |
459 | ␉␉if (Platform->RAM.DIMM[map].InUse && strlen(Platform->RAM.DIMM[map].SerialNo) > 0) {␊ |
460 | DBG("name = %s, map=%d, RAM Detected SerialNo[%d]='%s'\n", name ? name : "", ␊ |
461 | map, table_num, Platform->RAM.DIMM[map].SerialNo);␊ |
462 | return Platform->RAM.DIMM[map].SerialNo;␊ |
463 | ␉␉}␊ |
464 | ␉}␊ |
465 | ␉return "N/A";␊ |
466 | }␊ |
467 | ␊ |
468 | static const char *sm_get_mempartno (const char *name, int table_num)␊ |
469 | {␊ |
470 | ␉int␉map;␊ |
471 | ␊ |
472 | ␉if (table_num < MAX_RAM_SLOTS) {␊ |
473 | ␉␉map = Platform->DMI.DIMM[table_num];␊ |
474 | ␉␉if (Platform->RAM.DIMM[map].InUse && strlen(Platform->RAM.DIMM[map].PartNo) > 0) {␊ |
475 | ␉␉␉DBG("Ram Detected PartNo[%d]='%s'\n", table_num, Platform->RAM.DIMM[map].PartNo);␊ |
476 | ␉␉␉return Platform->RAM.DIMM[map].PartNo;␊ |
477 | ␉␉}␊ |
478 | ␉}␊ |
479 | ␉return "N/A";␊ |
480 | }␊ |
481 | ␊ |
482 | static int sm_one (int tablen)␊ |
483 | {␊ |
484 | ␉return 1;␊ |
485 | }␊ |
486 | ␊ |
487 | struct smbios_property smbios_properties[]=␊ |
488 | {␊ |
489 | ␉{.name="SMbiosvendor",␉␉.table_type= 0,␉.value_type=SMSTRING,␉.offset=0x04,␉.auto_str=sm_get_defstr␉},␊ |
490 | ␉{.name="SMbiosversion",␉␉.table_type= 0,␉.value_type=SMSTRING,␉.offset=0x05,␉.auto_str=sm_get_defstr␉},␊ |
491 | ␉{.name="SMbiosdate",␉␉.table_type= 0,␉.value_type=SMSTRING,␉.offset=0x08,␉.auto_str=sm_get_defstr␉},␊ |
492 | ␉{.name="SMmanufacter",␉␉.table_type= 1,␉.value_type=SMSTRING,␉.offset=0x04,␉.auto_str=sm_get_defstr␉},␊ |
493 | ␉{.name="SMproductname",␉␉.table_type= 1,␉.value_type=SMSTRING,␉.offset=0x05,␉.auto_str=sm_get_defstr␉},␊ |
494 | ␉{.name="SMsystemversion",␉.table_type= 1,␉.value_type=SMSTRING,␉.offset=0x06,␉.auto_str=sm_get_defstr␉},␊ |
495 | ␉{.name="SMserial",␉␉.table_type= 1,␉.value_type=SMSTRING,␉.offset=0x07,␉.auto_str=sm_get_defstr␉},␊ |
496 | ␉{.name="SMUUID",␉␉␉.table_type= 1, .value_type=SMOWORD,␉.offset=0x08,␉.auto_oword=sm_get_defstr},␊ |
497 | ␉{.name="SMfamily",␉␉.table_type= 1,␉.value_type=SMSTRING,␉.offset=0x1a,␉.auto_str=sm_get_defstr␉},␊ |
498 | ␉{.name="SMboardmanufacter",␉.table_type= 2, .value_type=SMSTRING,␉.offset=0x04,␉.auto_str=sm_get_defstr␉},␊ |
499 | ␉{.name="SMboardproduct",␉.table_type= 2, .value_type=SMSTRING,␉.offset=0x05,␉.auto_str=sm_get_defstr␉},␊ |
500 | ␉{.name="SMexternalclock",␉.table_type= 4,␉.value_type=SMWORD,␉.offset=0x12,␉.auto_int=sm_get_fsb␉},␊ |
501 | ␉{.name="SMmaximalclock",␉.table_type= 4,␉.value_type=SMWORD,␉.offset=0x14,␉.auto_int=sm_get_cpu␉},␊ |
502 | ␉{.name="SMmemdevloc",␉␉.table_type=17,␉.value_type=SMSTRING,␉.offset=0x10,␉.auto_str=0␉␉},␊ |
503 | ␉{.name="SMmembankloc",␉␉.table_type=17,␉.value_type=SMSTRING,␉.offset=0x11,␉.auto_str=0␉␉},␊ |
504 | ␉{.name="SMmemtype",␉␉.table_type=17,␉.value_type=SMBYTE,␉.offset=0x12,␉.auto_int=sm_get_memtype},␊ |
505 | ␉{.name="SMmemspeed",␉␉.table_type=17,␉.value_type=SMWORD,␉.offset=0x15,␉.auto_int=sm_get_memspeed},␊ |
506 | ␉{.name="SMmemmanufacter",␉.table_type=17,␉.value_type=SMSTRING,␉.offset=0x17,␉.auto_str=sm_get_memvendor},␊ |
507 | ␉{.name="SMmemserial",␉␉.table_type=17,␉.value_type=SMSTRING,␉.offset=0x18,␉.auto_str=sm_get_memserial},␊ |
508 | ␉{.name="SMmempart",␉␉.table_type=17,␉.value_type=SMSTRING,␉.offset=0x1A,␉.auto_str=sm_get_mempartno},␊ |
509 | ␉{.name="SMcputype",␉␉.table_type=131,.value_type=SMWORD,␉.offset=0x04,␉.auto_int=sm_get_cputype},␊ |
510 | ␉{.name="SMbusspeed",␉␉.table_type=132,.value_type=SMWORD,␉.offset=0x04,␉.auto_int=sm_get_bus_speed}␊ |
511 | };␊ |
512 | ␊ |
513 | struct smbios_table_description smbios_table_descriptions[]=␊ |
514 | {␊ |
515 | ␉{.type=kSMBTypeBIOSInformation,␉␉␉.len=0x18,␉.numfunc=sm_one},␊ |
516 | ␉{.type=kSMBTypeSystemInformation,␉␉.len=0x1b,␉.numfunc=sm_one},␊ |
517 | ␉{.type=kSMBTypeBaseBoard,␉␉␉␉.len=0x0f,␉.numfunc=sm_one}, //except kSMBBaseBoardProcessorMemoryModule␊ |
518 | ␉{.type=kSMBTypeProcessorInformation,␉.len=0x2a,␉.numfunc=sm_one},␊ |
519 | //kSMBTypeMemoryModule len=12 obsolete but Used by AppleSMBIOS␉␊ |
520 | //kSMBTypeSystemSlot␉ len=13 Used by AppleSMBIOS␊ |
521 | //kSMBTypePhysicalMemoryArray len=15 Used by AppleSMBIOS␉␊ |
522 | ␉{.type=kSMBTypeMemoryDevice,␉␉␉.len=0x24,␉.numfunc=0},␊ |
523 | //Slice - we are not ready to fill the data␉␊ |
524 | //␉{.type=kSMBTypeFirmwareVolume,␉␉␉.len=0x56,␉.numfunc=0},␊ |
525 | //␉{.type=kSMBTypeMemorySPD,␉␉␉␉.len=0x0c,␉.numfunc=0},␊ |
526 | ␉{.type=kSMBTypeOemProcessorType,␉␉.len=0x06,␉.numfunc=sm_one},␊ |
527 | ␉{.type=kSMBTypeOemProcessorBusSpeed,␉.len=0x06,␉.numfunc=sm_one}␊ |
528 | };␊ |
529 | /* Apple known types␊ |
530 | enum {␊ |
531 | kSMBTypeBIOSInformation = 0,␊ |
532 | kSMBTypeSystemInformation = 1,␊ |
533 | kSMBTypeBaseBoard␉␉␉␉␉ = 2,␊ |
534 | kSMBTypeSystemEnclosure = 3,␊ |
535 | kSMBTypeProcessorInformation = 4,␊ |
536 | kSMBTypeMemoryModule = 6,␊ |
537 | kSMBTypeCacheInformation = 7,␊ |
538 | kSMBTypeSystemSlot = 9,␊ |
539 | kSMBTypePhysicalMemoryArray = 16,␊ |
540 | kSMBTypeMemoryDevice = 17,␊ |
541 | kSMBType32BitMemoryErrorInfo = 18,␊ |
542 | kSMBType64BitMemoryErrorInfo = 33,␊ |
543 | ␊ |
544 | // Apple Specific Structures ␊ |
545 | kSMBTypeFirmwareVolume = 128,␊ |
546 | kSMBTypeMemorySPD = 130,␊ |
547 | kSMBTypeOemProcessorType = 131,␊ |
548 | kSMBTypeOemProcessorBusSpeed = 132␊ |
549 | };␊ |
550 | ␊ |
551 | */␊ |
552 | ␊ |
553 | // getting smbios addr with fast compare ops, late checksum testing ...␊ |
554 | #define COMPARE_DWORD(a,b) ( *((u_int32_t *) a) == *((u_int32_t *) b) )␊ |
555 | static const char * const SMTAG = "_SM_";␊ |
556 | static const char* const DMITAG= "_DMI_";␊ |
557 | ␊ |
558 | static struct SMBEntryPoint *getAddressOfSmbiosTable(void)␊ |
559 | {␊ |
560 | ␉struct SMBEntryPoint␉*smbios;␊ |
561 | ␉/* ␊ |
562 | ␉ * The logic is to start at 0xf0000 and end at 0xfffff iterating 16 bytes at a time looking␊ |
563 | ␉ * for the SMBIOS entry-point structure anchor (literal ASCII "_SM_").␊ |
564 | ␉ */␊ |
565 | ␉smbios = (struct SMBEntryPoint*) SMBIOS_RANGE_START;␊ |
566 | ␉while (smbios <= (struct SMBEntryPoint *)SMBIOS_RANGE_END) {␊ |
567 | if (COMPARE_DWORD(smbios->anchor, SMTAG) && ␊ |
568 | COMPARE_DWORD(smbios->dmi.anchor, DMITAG) &&␊ |
569 | smbios->dmi.anchor[4]==DMITAG[4] &&␊ |
570 | checksum8(smbios, sizeof(struct SMBEntryPoint)) == 0)␊ |
571 | ␉ {␉␉␉␊ |
572 | return smbios;␊ |
573 | ␉ }␊ |
574 | smbios = (struct SMBEntryPoint*) ( ((char*) smbios) + 16 );␊ |
575 | ␉}␊ |
576 | ␉printf("ERROR: Unable to find SMBIOS!\n");␊ |
577 | ␉pause();␊ |
578 | ␉return NULL;␊ |
579 | }␊ |
580 | ␊ |
581 | /** Compute necessary space requirements for new smbios */␊ |
582 | static struct SMBEntryPoint *smbios_dry_run(struct SMBEntryPoint *origsmbios)␊ |
583 | {␊ |
584 | ␉struct SMBEntryPoint␉*ret;␊ |
585 | ␉char␉␉␉*smbiostables;␊ |
586 | ␉char␉␉␉*tablesptr;␊ |
587 | ␉int␉␉␉origsmbiosnum;␊ |
588 | ␉int␉␉␉i, j;␊ |
589 | ␉int␉␉␉tablespresent[256];␊ |
590 | ␉bool␉␉␉do_auto=true;␊ |
591 | ␊ |
592 | ␉bzero(tablespresent, sizeof(tablespresent));␊ |
593 | ␊ |
594 | ␉getBoolForKey(kSMBIOSdefaults, &do_auto, &bootInfo->bootConfig);␊ |
595 | ␊ |
596 | ␉ret = (struct SMBEntryPoint *)AllocateKernelMemory(sizeof(struct SMBEntryPoint));␊ |
597 | ␉if (origsmbios) {␊ |
598 | ␉␉smbiostables = (char *)origsmbios->dmi.tableAddress;␊ |
599 | ␉␉origsmbiosnum = origsmbios->dmi.structureCount;␊ |
600 | ␉} else {␊ |
601 | ␉␉smbiostables = NULL;␊ |
602 | ␉␉origsmbiosnum = 0;␊ |
603 | ␉}␊ |
604 | ␊ |
605 | ␉// _SM_␊ |
606 | ␉ret->anchor[0] = 0x5f;␊ |
607 | ␉ret->anchor[1] = 0x53;␊ |
608 | ␉ret->anchor[2] = 0x4d;␊ |
609 | ␉ret->anchor[3] = 0x5f; ␊ |
610 | ␉ret->entryPointLength = sizeof(*ret);␊ |
611 | ␉ret->majorVersion = 2;␊ |
612 | ␉ret->minorVersion = 1;␊ |
613 | ␉ret->maxStructureSize = 0; // will be calculated later in this function␊ |
614 | ␉ret->entryPointRevision = 0;␊ |
615 | ␉for (i=0;i<5;i++) {␊ |
616 | ␉␉ret->formattedArea[i] = 0;␊ |
617 | ␉}␊ |
618 | ␉//_DMI_␊ |
619 | ␉ret->dmi.anchor[0] = 0x5f;␊ |
620 | ␉ret->dmi.anchor[1] = 0x44;␊ |
621 | ␉ret->dmi.anchor[2] = 0x4d;␊ |
622 | ␉ret->dmi.anchor[3] = 0x49;␊ |
623 | ␉ret->dmi.anchor[4] = 0x5f;␊ |
624 | ␉ret->dmi.tableLength = 0; // will be calculated later in this function␊ |
625 | ␉ret->dmi.tableAddress = 0; // will be initialized in smbios_real_run()␊ |
626 | ␉ret->dmi.structureCount = 0; // will be calculated later in this function␊ |
627 | ␉ret->dmi.bcdRevision = 0x21;␊ |
628 | ␉tablesptr = smbiostables;␊ |
629 | ␊ |
630 | // add stringlen of overrides to original stringlen, update maxStructure size adequately, ␊ |
631 | // update structure count and tablepresent[type] with count of type. ␊ |
632 | ␉if (smbiostables) {␊ |
633 | ␉␉for (i=0; i<origsmbiosnum; i++) {␊ |
634 | ␉␉␉struct smbios_table_header␉*cur = (struct smbios_table_header *)tablesptr;␊ |
635 | ␉␉␉char␉␉␉␉*stringsptr;␊ |
636 | ␉␉␉int␉␉␉␉stringlen;␊ |
637 | ␊ |
638 | ␉␉␉tablesptr += cur->length;␊ |
639 | ␉␉␉stringsptr = tablesptr;␊ |
640 | ␉␉␉for (; tablesptr[0]!=0 || tablesptr[1]!=0; tablesptr++);␊ |
641 | ␉␉␉tablesptr += 2;␊ |
642 | ␉␉␉stringlen = tablesptr - stringsptr - 1;␊ |
643 | ␉␉␉if (stringlen == 1) {␊ |
644 | ␉␉␉␉stringlen = 0;␊ |
645 | ␉␉␉}␊ |
646 | ␉␉␉for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {␊ |
647 | ␉␉␉␉const char␉*str;␊ |
648 | ␉␉␉␉int␉␉size;␊ |
649 | ␉␉␉␉char␉␉altname[40];␊ |
650 | ␊ |
651 | ␉␉␉␉sprintf(altname, "%s_%d",smbios_properties[j].name, tablespresent[cur->type] + 1);␉␉␉␉␊ |
652 | ␉␉␉␉if (smbios_properties[j].table_type == cur->type &&␊ |
653 | ␉␉␉␉ smbios_properties[j].value_type == SMSTRING &&␊ |
654 | ␉␉␉␉ (getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig) ||␊ |
655 | ␉␉␉␉ getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)))␊ |
656 | ␉␉␉␉{␊ |
657 | ␉␉␉␉␉stringlen += size + 1;␊ |
658 | ␉␉␉␉} else if (smbios_properties[j].table_type == cur->type &&␊ |
659 | ␉␉␉␉ smbios_properties[j].value_type == SMSTRING &&␊ |
660 | ␉␉␉␉ do_auto && smbios_properties[j].auto_str)␊ |
661 | ␉␉␉␉{␊ |
662 | ␉␉␉␉␉stringlen += strlen(smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[cur->type])) + 1;␊ |
663 | ␉␉␉␉}␊ |
664 | ␉␉␉}␊ |
665 | ␉␉␉if (stringlen == 0) {␊ |
666 | ␉␉␉␉stringlen = 1;␊ |
667 | ␉␉␉}␊ |
668 | ␉␉␉stringlen++;␊ |
669 | ␉␉␉if (ret->maxStructureSize < cur->length+stringlen) {␊ |
670 | ␉␉␉␉ret->maxStructureSize=cur->length+stringlen;␊ |
671 | ␉␉␉}␊ |
672 | ␉␉␉ret->dmi.tableLength += cur->length+stringlen;␊ |
673 | ␉␉␉ret->dmi.structureCount++;␊ |
674 | ␉␉␉tablespresent[cur->type]++;␊ |
675 | ␉␉}␊ |
676 | ␉}␊ |
677 | // Add eventually table types whose detected count would be < required count, and update ret header with:␊ |
678 | // new stringlen addons, structure count, and tablepresent[type] count adequately␊ |
679 | ␉for (i=0; i<sizeof(smbios_table_descriptions)/sizeof(smbios_table_descriptions[0]); i++) {␊ |
680 | ␉␉int␉numnec=-1;␊ |
681 | ␉␉char␉buffer[40];␊ |
682 | ␊ |
683 | ␉␉sprintf(buffer, "SMtable%d", i);␊ |
684 | ␉␉if (!getIntForKey(buffer, &numnec, &bootInfo->smbiosConfig)) {␊ |
685 | ␉␉␉numnec = -1;␊ |
686 | ␉␉}␊ |
687 | ␉␉if (numnec==-1 && do_auto && smbios_table_descriptions[i].numfunc) {␊ |
688 | ␉␉␉numnec = smbios_table_descriptions[i].numfunc(smbios_table_descriptions[i].type);␊ |
689 | ␉␉}␊ |
690 | ␉␉while (tablespresent[smbios_table_descriptions[i].type] < numnec) {␊ |
691 | ␉␉␉int␉stringlen = 0;␊ |
692 | ␉␉␉for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {␊ |
693 | ␉␉␉␉const char␉*str;␊ |
694 | ␉␉␉␉int␉␉size;␊ |
695 | ␉␉␉␉char␉␉altname[40];␊ |
696 | ␊ |
697 | ␉␉␉␉sprintf(altname, "%s_%d",smbios_properties[j].name, tablespresent[smbios_table_descriptions[i].type] + 1);␊ |
698 | ␉␉␉␉if (smbios_properties[j].table_type == smbios_table_descriptions[i].type &&␊ |
699 | ␉␉␉␉ smbios_properties[j].value_type == SMSTRING &&␊ |
700 | ␉␉␉␉ (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||␊ |
701 | ␉␉␉␉ getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig)))␊ |
702 | ␉␉␉␉{␊ |
703 | ␉␉␉␉␉stringlen += size + 1;␊ |
704 | ␉␉␉␉} else if (smbios_properties[j].table_type == smbios_table_descriptions[i].type &&␊ |
705 | ␉␉␉␉ smbios_properties[j].value_type==SMSTRING &&␊ |
706 | ␉␉␉␉ do_auto && smbios_properties[j].auto_str)␊ |
707 | ␉␉␉␉{␊ |
708 | ␉␉␉␉␉stringlen += strlen(smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[smbios_table_descriptions[i].type])) + 1;␊ |
709 | ␉␉␉␉}␊ |
710 | ␉␉␉}␊ |
711 | ␉␉␉if (stringlen == 0) {␊ |
712 | ␉␉␉␉stringlen = 1;␊ |
713 | ␉␉␉}␊ |
714 | ␉␉␉stringlen++;␊ |
715 | ␉␉␉if (ret->maxStructureSize < smbios_table_descriptions[i].len+stringlen) {␊ |
716 | ␉␉␉␉ret->maxStructureSize = smbios_table_descriptions[i].len + stringlen;␊ |
717 | ␉␉␉}␊ |
718 | ␉␉␉ret->dmi.tableLength += smbios_table_descriptions[i].len + stringlen;␊ |
719 | ␉␉␉ret->dmi.structureCount++;␊ |
720 | ␉␉␉tablespresent[smbios_table_descriptions[i].type]++;␊ |
721 | ␉␉}␊ |
722 | ␉}␊ |
723 | ␉return ret;␊ |
724 | }␊ |
725 | ␊ |
726 | /** From the origsmbios detected by getAddressOfSmbiosTable() to newsmbios whose entrypoint ␊ |
727 | * struct has been created by smbios_dry_run, update each table struct content of new smbios␊ |
728 | * int the new allocated table address of size newsmbios->tablelength.␊ |
729 | */␊ |
730 | static void smbios_real_run(struct SMBEntryPoint * origsmbios, struct SMBEntryPoint * newsmbios)␊ |
731 | {␊ |
732 | ␉char *smbiostables;␊ |
733 | ␉char *tablesptr, *newtablesptr;␊ |
734 | ␉int origsmbiosnum=0;␊ |
735 | ␉// bitmask of used handles␊ |
736 | ␉uint8_t handles[8192]; ␊ |
737 | ␉uint16_t nexthandle=0;␊ |
738 | ␉int i, j;␊ |
739 | ␉int tablespresent[256];␊ |
740 | ␉bool do_auto=true;␊ |
741 | ␉␊ |
742 | static bool done = false; // IMPROVEME: called twice via getSmbios(), but only the second call can get all necessary info !␊ |
743 | ␊ |
744 | ␉extern void dumpPhysAddr(const char * title, void * a, int len);␊ |
745 | ␉␊ |
746 | ␉bzero(tablespresent, sizeof(tablespresent));␊ |
747 | ␉bzero(handles, sizeof(handles));␊ |
748 | ␊ |
749 | ␉getBoolForKey(kSMBIOSdefaults, &do_auto, &bootInfo->bootConfig);␊ |
750 | ␉␊ |
751 | ␉newsmbios->dmi.tableAddress = (uint32_t)AllocateKernelMemory(newsmbios->dmi.tableLength);␊ |
752 | ␉if (origsmbios) {␊ |
753 | ␉␉smbiostables = (char *)origsmbios->dmi.tableAddress;␊ |
754 | ␉␉origsmbiosnum = origsmbios->dmi.structureCount;␊ |
755 | ␉} else {␊ |
756 | ␉␉smbiostables = NULL;␊ |
757 | ␉␉origsmbiosnum = 0;␊ |
758 | ␉}␊ |
759 | ␉tablesptr = smbiostables;␊ |
760 | ␉newtablesptr = (char *)newsmbios->dmi.tableAddress;␊ |
761 | ␊ |
762 | // if old smbios exists then update new smbios with old smbios original content first␊ |
763 | ␉if (smbiostables) {␊ |
764 | ␉␉for (i=0; i<origsmbiosnum; i++) {␊ |
765 | ␉␉␉struct smbios_table_header␉*oldcur = (struct smbios_table_header *) tablesptr;␊ |
766 | ␉␉␉struct smbios_table_header␉*newcur = (struct smbios_table_header *) newtablesptr;␊ |
767 | ␉␉␉char␉␉␉␉*stringsptr;␊ |
768 | ␉␉␉int␉␉␉␉nstrings = 0;␊ |
769 | ␊ |
770 | ␉␉␉handles[(oldcur->handle) / 8] |= 1 << ((oldcur->handle) % 8);␊ |
771 | ␊ |
772 | // copy table length from old table to new table but not the old strings␊ |
773 | ␉␉␉memcpy(newcur,oldcur, oldcur->length);␊ |
774 | ␊ |
775 | ␉␉␉tablesptr += oldcur->length;␊ |
776 | ␉␉␉stringsptr = tablesptr;␊ |
777 | ␉␉␉newtablesptr += oldcur->length;␊ |
778 | ␊ |
779 | // calculate the number of strings in the old content␊ |
780 | ␉␉␉for (;tablesptr[0]!=0 || tablesptr[1]!=0; tablesptr++) {␊ |
781 | ␉␉␉␉if (tablesptr[0] == 0) {␊ |
782 | ␉␉␉␉␉nstrings++;␊ |
783 | ␉␉␉␉}␊ |
784 | ␉␉␉}␊ |
785 | ␉␉␉if (tablesptr != stringsptr) {␊ |
786 | ␉␉␉␉nstrings++;␊ |
787 | ␉␉␉}␊ |
788 | ␉␉␉tablesptr += 2;␊ |
789 | ␊ |
790 | // copy the old strings to new table␊ |
791 | ␉␉␉memcpy(newtablesptr, stringsptr, tablesptr-stringsptr);␊ |
792 | ␊ |
793 | ␉␉␉// point to next possible space for a string (deducting the second 0 char at the end)␊ |
794 | ␉␉␉newtablesptr += tablesptr - stringsptr - 1;␊ |
795 | if (nstrings == 0) { // if no string was found rewind to the first 0 char of the 0,0 terminator␊ |
796 | ␉␉␉␉newtablesptr--;␊ |
797 | ␉␉␉}␊ |
798 | ␊ |
799 | // now for each property in the table update the overrides if any (auto or user)␊ |
800 | ␉␉␉for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {␊ |
801 | ␉␉␉␉const char␉*str;␊ |
802 | ␉␉␉␉int␉␉size;␊ |
803 | ␉␉␉␉int␉␉num;␊ |
804 | ␉␉␉␉char␉␉altname[40];␊ |
805 | ␊ |
806 | ␉␉␉␉sprintf(altname, "%s_%d", smbios_properties[j].name, tablespresent[newcur->type] + 1);␊ |
807 | ␉␉␉␉if (smbios_properties[j].table_type == newcur->type) {␊ |
808 | ␉␉␉␉␉switch (smbios_properties[j].value_type) {␊ |
809 | ␉␉␉␉␉case SMSTRING:␊ |
810 | ␉␉␉␉␉␉if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||␊ |
811 | ␉␉␉␉␉␉ getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))␊ |
812 | ␉␉␉␉␉␉{␊ |
813 | ␉␉␉␉␉␉␉memcpy(newtablesptr, str, size);␊ |
814 | ␉␉␉␉␉␉␉newtablesptr[size] = 0;␊ |
815 | ␉␉␉␉␉␉␉newtablesptr += size + 1;␊ |
816 | ␉␉␉␉␉␉␉*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;␊ |
817 | ␉␉␉␉␉␉} else if (do_auto && smbios_properties[j].auto_str) {␊ |
818 | ␉␉␉␉␉␉␉str = smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]);␊ |
819 | ␉␉␉␉␉␉␉size = strlen(str);␊ |
820 | ␉␉␉␉␉␉␉memcpy(newtablesptr, str, size);␊ |
821 | ␉␉␉␉␉␉␉newtablesptr[size] = 0;␊ |
822 | ␉␉␉␉␉␉␉newtablesptr += size + 1;␊ |
823 | ␉␉␉␉␉␉␉*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;␊ |
824 | ␉␉␉␉␉␉}␊ |
825 | ␉␉␉␉␉␉break;␊ |
826 | ␊ |
827 | ␉␉␉␉␉case SMOWORD:␊ |
828 | ␉␉␉␉␉␉if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||␊ |
829 | ␉␉␉␉␉␉ getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))␊ |
830 | ␉␉␉␉␉␉{␊ |
831 | ␉␉␉␉␉␉␉//int␉␉k=0, t=0, kk=0;␊ |
832 | ␉␉␉␉␉␉␉//const char␉*ptr = str;␊ |
833 | ␉␉␉␉␉␉␉verbose("Set SMUUID to %s\n", str);␊ |
834 | ␉␉␉␉␉␉␉//memset(((char*)newcur) + smbios_properties[j].offset, 0, 16);␊ |
835 | ␉␉␉␉␉␉␉EFI_GUID* p = getUUIDFromString(str);␊ |
836 | ␉␉␉␉␉␉␉memcpy(((char*)newcur) + smbios_properties[j].offset, p, 16);␊ |
837 | ␉␉␉␉␉␉␉/*␊ |
838 | ␉␉␉␉␉␉␉while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n')) {␊ |
839 | ␉␉␉␉␉␉␉␉ptr++;␊ |
840 | ␉␉␉␉␉␉␉}␊ |
841 | ␉␉␉␉␉␉␉if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X')) {␊ |
842 | ␉␉␉␉␉␉␉␉ptr += 2;␊ |
843 | ␉␉␉␉␉␉␉}␊ |
844 | ␉␉␉␉␉␉␉for (;ptr-str<size && *ptr && k<16;ptr++) {␊ |
845 | ␉␉␉␉␉␉␉␉if (*ptr=='-') {␊ |
846 | ␉␉␉␉␉␉␉␉␉continue; //Slice - ignore "-" inside UUID string␊ |
847 | ␉␉␉␉␉␉␉␉}␊ |
848 | ␉␉␉␉␉␉␉␉if (*ptr>='0' && *ptr<='9') {␊ |
849 | ␉␉␉␉␉␉␉␉␉(t=(t<<4)|(*ptr-'0')),kk++;␊ |
850 | ␉␉␉␉␉␉␉␉}␊ |
851 | ␉␉␉␉␉␉␉␉if (*ptr>='a' && *ptr<='f') {␊ |
852 | ␉␉␉␉␉␉␉␉␉(t=(t<<4)|(*ptr-'a'+10)),kk++;␊ |
853 | ␉␉␉␉␉␉␉␉}␊ |
854 | ␉␉␉␉␉␉␉␉if (*ptr>='A' && *ptr<='F') {␊ |
855 | ␉␉␉␉␉␉␉␉␉(t=(t<<4)|(*ptr-'A'+10)),kk++;␊ |
856 | ␉␉␉␉␉␉␉␉}␊ |
857 | ␉␉␉␉␉␉␉␉if (kk == 2) {␊ |
858 | ␉␉␉␉␉␉␉␉␉*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset + k)) = t;␊ |
859 | ␉␉␉␉␉␉␉␉␉k++;␊ |
860 | ␉␉␉␉␉␉␉␉␉kk = 0;␊ |
861 | ␉␉␉␉␉␉␉␉␉t = 0;␊ |
862 | ␉␉␉␉␉␉␉␉}␊ |
863 | ␉␉␉␉␉␉␉}␊ |
864 | ␉␉␉␉␉␉␉ */␊ |
865 | ␉␉␉␉␉␉}␊ |
866 | ␉␉␉␉␉␉break;␊ |
867 | ␊ |
868 | ␉␉␉␉␉case SMBYTE:␊ |
869 | ␉␉␉␉␉␉if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||␊ |
870 | ␉␉␉␉␉␉ getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))␊ |
871 | ␉␉␉␉␉␉{␊ |
872 | ␉␉␉␉␉␉␉*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;␊ |
873 | ␉␉␉␉␉␉} else if (do_auto && smbios_properties[j].auto_int) {␊ |
874 | ␉␉␉␉␉␉␉*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);␉␉␉␉␉␉␉␊ |
875 | ␉␉␉␉␉␉}␊ |
876 | ␉␉␉␉␉␉break;␊ |
877 | ␊ |
878 | ␉␉␉␉␉case SMWORD:␊ |
879 | ␉␉␉␉␉␉if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||␊ |
880 | ␉␉␉␉␉␉ getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))␊ |
881 | ␉␉␉␉␉␉{␊ |
882 | ␉␉␉␉␉␉␉*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;␊ |
883 | ␉␉␉␉␉␉} else if (do_auto && smbios_properties[j].auto_int) {␊ |
884 | ␉␉␉␉␉␉␉*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);␊ |
885 | ␉␉␉␉␉␉}␊ |
886 | ␉␉␉␉␉␉break;␊ |
887 | ␉␉␉␉␉}␊ |
888 | ␉␉␉␉}␊ |
889 | ␉␉␉}␊ |
890 | ␉␉␉if (nstrings == 0) {␊ |
891 | ␉␉␉␉newtablesptr[0] = 0;␊ |
892 | ␉␉␉␉newtablesptr++;␊ |
893 | ␉␉␉}␊ |
894 | ␉␉␉newtablesptr[0] = 0;␊ |
895 | ␉␉␉newtablesptr++;␊ |
896 | ␉␉␉tablespresent[newcur->type]++;␊ |
897 | ␉␉}␊ |
898 | ␉}␊ |
899 | ␊ |
900 | // for each eventual complementary table not present in the original smbios, do the overrides␊ |
901 | ␉for (i=0; i<sizeof(smbios_table_descriptions)/sizeof(smbios_table_descriptions[0]); i++) {␊ |
902 | ␉␉int␉numnec = -1;␊ |
903 | ␉␉char␉buffer[40];␊ |
904 | ␊ |
905 | ␉␉sprintf(buffer, "SMtable%d", i);␊ |
906 | ␉␉if (!getIntForKey(buffer, &numnec, &bootInfo->smbiosConfig)) {␊ |
907 | ␉␉␉numnec = -1;␊ |
908 | ␉␉}␊ |
909 | ␉␉if (numnec == -1 && do_auto && smbios_table_descriptions[i].numfunc) {␊ |
910 | ␉␉␉numnec = smbios_table_descriptions[i].numfunc(smbios_table_descriptions[i].type);␊ |
911 | ␉␉}␊ |
912 | ␉␉while (tablespresent[smbios_table_descriptions[i].type] < numnec) {␊ |
913 | ␉␉␉struct smbios_table_header␉*newcur = (struct smbios_table_header *) newtablesptr;␊ |
914 | ␉␉␉int␉␉␉␉nstrings = 0;␊ |
915 | ␊ |
916 | ␉␉␉memset(newcur,0, smbios_table_descriptions[i].len);␊ |
917 | ␉␉␉while (handles[(nexthandle)/8] & (1 << ((nexthandle) % 8))) {␊ |
918 | ␉␉␉␉nexthandle++;␊ |
919 | ␉␉␉}␊ |
920 | ␉␉␉newcur->handle = nexthandle;␊ |
921 | ␉␉␉handles[nexthandle / 8] |= 1 << (nexthandle % 8);␊ |
922 | ␉␉␉newcur->type = smbios_table_descriptions[i].type;␊ |
923 | ␉␉␉newcur->length = smbios_table_descriptions[i].len;␊ |
924 | ␉␉␉newtablesptr += smbios_table_descriptions[i].len;␊ |
925 | ␉␉␉for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {␊ |
926 | ␉␉␉␉const char␉*str;␊ |
927 | ␉␉␉␉int␉␉size;␊ |
928 | ␉␉␉␉int␉␉num;␊ |
929 | ␉␉␉␉char␉␉altname[40];␊ |
930 | ␊ |
931 | ␉␉␉␉sprintf(altname, "%s_%d", smbios_properties[j].name, tablespresent[newcur->type] + 1);␊ |
932 | ␉␉␉␉if (smbios_properties[j].table_type == newcur->type) {␊ |
933 | ␉␉␉␉␉switch (smbios_properties[j].value_type) {␊ |
934 | ␉␉␉␉␉case SMSTRING:␊ |
935 | ␉␉␉␉␉␉if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||␊ |
936 | ␉␉␉␉␉␉ getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))␊ |
937 | ␉␉␉␉␉␉{␊ |
938 | ␉␉␉␉␉␉␉memcpy(newtablesptr, str, size);␊ |
939 | ␉␉␉␉␉␉␉newtablesptr[size] = 0;␊ |
940 | ␉␉␉␉␉␉␉newtablesptr += size + 1;␊ |
941 | ␉␉␉␉␉␉␉*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;␊ |
942 | ␉␉␉␉␉␉} else if (do_auto && smbios_properties[j].auto_str) {␊ |
943 | ␉␉␉␉␉␉␉str = smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]);␊ |
944 | ␉␉␉␉␉␉␉size = strlen(str);␊ |
945 | ␉␉␉␉␉␉␉memcpy(newtablesptr, str, size);␊ |
946 | ␉␉␉␉␉␉␉newtablesptr[size] = 0;␊ |
947 | ␉␉␉␉␉␉␉newtablesptr += size + 1;␊ |
948 | ␉␉␉␉␉␉␉*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;␊ |
949 | ␉␉␉␉␉␉}␊ |
950 | ␉␉␉␉␉␉break;␊ |
951 | ␊ |
952 | ␉␉␉␉␉case SMOWORD:␊ |
953 | ␉␉␉␉␉␉if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||␊ |
954 | ␉␉␉␉␉␉ getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))␊ |
955 | ␉␉␉␉␉␉{␊ |
956 | ␉␉␉␉␉␉␉EFI_GUID* p = getUUIDFromString(str);␊ |
957 | ␉␉␉␉␉␉␉memcpy(((char*)newcur) + smbios_properties[j].offset, p, 16);␊ |
958 | /*␊ |
959 | ␉␉␉␉␉␉␉int␉␉k=0, t=0, kk=0;␊ |
960 | ␉␉␉␉␉␉␉const char␉*ptr = str;␊ |
961 | ␉␉␉␉␉␉␉verbose("Set SMUUID to %s\n", str);␊ |
962 | ␊ |
963 | ␉␉␉␉␉␉␉memset(((char*)newcur) + smbios_properties[j].offset, 0, 16);␊ |
964 | ␉␉␉␉␉␉␉while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n')) {␊ |
965 | ␉␉␉␉␉␉␉␉ptr++;␊ |
966 | ␉␉␉␉␉␉␉}␊ |
967 | ␉␉␉␉␉␉␉if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X')) {␊ |
968 | ␉␉␉␉␉␉␉␉ptr += 2;␊ |
969 | ␉␉␉␉␉␉␉}␊ |
970 | ␉␉␉␉␉␉␉for (;ptr-str<size && *ptr && k<16;ptr++) {␊ |
971 | ␉␉␉␉␉␉␉␉if (*ptr=='-') {␊ |
972 | ␉␉␉␉␉␉␉␉␉continue; //Slice - ignore "-" inside UUID string␊ |
973 | ␉␉␉␉␉␉␉␉}␊ |
974 | ␉␉␉␉␉␉␉␉if (*ptr>='0' && *ptr<='9') {␊ |
975 | ␉␉␉␉␉␉␉␉␉(t=(t<<4)|(*ptr-'0')),kk++;␊ |
976 | ␉␉␉␉␉␉␉␉}␊ |
977 | ␉␉␉␉␉␉␉␉if (*ptr>='a' && *ptr<='f') {␊ |
978 | ␉␉␉␉␉␉␉␉␉(t=(t<<4)|(*ptr-'a'+10)),kk++;␊ |
979 | ␉␉␉␉␉␉␉␉}␊ |
980 | ␉␉␉␉␉␉␉␉if (*ptr>='A' && *ptr<='F') {␊ |
981 | ␉␉␉␉␉␉␉␉␉(t=(t<<4)|(*ptr-'A'+10)),kk++;␊ |
982 | ␉␉␉␉␉␉␉␉}␊ |
983 | ␉␉␉␉␉␉␉␉if (kk == 2) {␊ |
984 | ␉␉␉␉␉␉␉␉␉*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset + k)) = t;␊ |
985 | ␉␉␉␉␉␉␉␉␉k++;␊ |
986 | ␉␉␉␉␉␉␉␉␉kk = 0;␊ |
987 | ␉␉␉␉␉␉␉␉␉t = 0;␊ |
988 | ␉␉␉␉␉␉␉␉}␊ |
989 | ␉␉␉␉␉␉␉}␊ |
990 | */␊ |
991 | ␉␉␉␉␉␉}␊ |
992 | ␉␉␉␉␉␉break;␊ |
993 | ␉␉␉␉␉␉␊ |
994 | ␉␉␉␉␉case SMBYTE:␊ |
995 | ␉␉␉␉␉␉if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||␊ |
996 | ␉␉␉␉␉␉ getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))␊ |
997 | ␉␉␉␉␉␉{␊ |
998 | ␉␉␉␉␉␉␉*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;␊ |
999 | ␉␉␉␉␉␉} else if (do_auto && smbios_properties[j].auto_int) {␊ |
1000 | ␉␉␉␉␉␉␉*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);␊ |
1001 | ␉␉␉␉␉␉}␊ |
1002 | ␉␉␉␉␉␉break;␊ |
1003 | ␉␉␉␉␉␉␊ |
1004 | ␉␉␉␉␉case SMWORD:␊ |
1005 | ␉␉␉␉␉␉if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||␊ |
1006 | ␉␉␉␉␉␉ getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))␊ |
1007 | ␉␉␉␉␉␉{␊ |
1008 | ␉␉␉␉␉␉␉*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;␊ |
1009 | ␉␉␉␉␉␉} else if (do_auto && smbios_properties[j].auto_int) {␊ |
1010 | ␉␉␉␉␉␉␉*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);␊ |
1011 | ␉␉␉␉␉␉}␊ |
1012 | ␉␉␉␉␉␉break;␊ |
1013 | ␉␉␉␉␉}␊ |
1014 | ␉␉␉␉}␊ |
1015 | ␉␉␉}␊ |
1016 | ␉␉␉if (nstrings == 0) {␊ |
1017 | ␉␉␉␉newtablesptr[0] = 0;␊ |
1018 | ␉␉␉␉newtablesptr++;␊ |
1019 | ␉␉␉}␊ |
1020 | ␉␉␉newtablesptr[0] = 0;␊ |
1021 | ␉␉␉newtablesptr++;␊ |
1022 | ␉␉␉tablespresent[smbios_table_descriptions[i].type]++;␊ |
1023 | ␉␉}␊ |
1024 | ␉}␊ |
1025 | ␊ |
1026 | // calculate new checksums␊ |
1027 | ␉newsmbios->dmi.checksum = 0;␊ |
1028 | ␉newsmbios->dmi.checksum = 256 - checksum8(&newsmbios->dmi, sizeof(newsmbios->dmi));␊ |
1029 | ␉newsmbios->checksum = 0;␊ |
1030 | ␉newsmbios->checksum = 256 - checksum8(newsmbios, sizeof(*newsmbios));␊ |
1031 | ␉␊ |
1032 | ␉if (!done) {␊ |
1033 | ␉␉verbose("Patched DMI Table\n");␊ |
1034 | ␉␉done=true;␊ |
1035 | ␉}␊ |
1036 | }␊ |
1037 | ␊ |
1038 | #define MAX_DMI_TABLES 96␊ |
1039 | typedef struct DmiNumAssocTag {␊ |
1040 | struct DMIHeader * dmi;␊ |
1041 | uint8_t type;␊ |
1042 | } DmiNumAssoc;␊ |
1043 | ␊ |
1044 | static DmiNumAssoc DmiTablePair[MAX_DMI_TABLES];␊ |
1045 | static int DmiTablePairCount = 0;␊ |
1046 | static int current_pos=0;␊ |
1047 | static bool ftTablePairInit = true; //use twice first run and after␊ |
1048 | ␊ |
1049 | /** ␊ |
1050 | * Get a table structure entry from a type specification and a smbios address␊ |
1051 | * return NULL if table is not found␊ |
1052 | */␊ |
1053 | static void getSmbiosTableStructure(struct SMBEntryPoint *smbios)␊ |
1054 | {␊ |
1055 | struct DMIHeader * dmihdr=NULL;␊ |
1056 | SMBByte* p;␊ |
1057 | int i;␊ |
1058 | ␊ |
1059 | if (ftTablePairInit && smbios!=NULL) {␊ |
1060 | ftTablePairInit = false;␊ |
1061 | #if DEBUG_SMBIOS␊ |
1062 | verbose(">>> SMBIOSAddr=0x%08x\n", smbios);␊ |
1063 | verbose(">>> DMI: addr=0x%08x, len=%d, count=%d\n", smbios->dmi.tableAddress, ␊ |
1064 | smbios->dmi.tableLength, smbios->dmi.structureCount);␊ |
1065 | #endif␊ |
1066 | p = (SMBByte *) smbios->dmi.tableAddress;␊ |
1067 | for (i=0; ␊ |
1068 | i < smbios->dmi.structureCount && ␊ |
1069 | p + 4 <= (SMBByte *)smbios->dmi.tableAddress + smbios->dmi.tableLength; ␊ |
1070 | i++) {␊ |
1071 | dmihdr = (struct DMIHeader *) p;␊ |
1072 | ␊ |
1073 | #if DEBUG_SMBIOS␊ |
1074 | // verbose(">>>>>> DMI(%d): type=0x%02x, len=0x%d\n",i,dmihdr->type,dmihdr->length);␊ |
1075 | #endif␊ |
1076 | if (dmihdr->length < 4 || dmihdr->type == 127 /* EOT */) break;␊ |
1077 | if (DmiTablePairCount < MAX_DMI_TABLES) {␊ |
1078 | DmiTablePair[DmiTablePairCount].dmi = dmihdr;␊ |
1079 | DmiTablePair[DmiTablePairCount].type = dmihdr->type;␊ |
1080 | DmiTablePairCount++;␊ |
1081 | }␊ |
1082 | else {␊ |
1083 | verbose("DMI table entries list is full! Next entries won't be stored.\n");␊ |
1084 | }␊ |
1085 | #if DEBUG_SMBIOS␊ |
1086 | verbose("DMI header found for table type %d, length = %d\n", dmihdr->type, dmihdr->length);␊ |
1087 | #endif␊ |
1088 | p = p + dmihdr->length;␊ |
1089 | while ((p - (SMBByte *)smbios->dmi.tableAddress + 1 < smbios->dmi.tableLength) && (p[0] != 0x00 || p[1] != 0x00)) {␊ |
1090 | p++;␊ |
1091 | ␉ }␊ |
1092 | p += 2;␊ |
1093 | ␉}␊ |
1094 | ␊ |
1095 | }␊ |
1096 | }␊ |
1097 | ␊ |
1098 | void getSmbiosMacModel(void)␊ |
1099 | {␊ |
1100 | #define MAX_MODEL_LEN␉32␊ |
1101 | ␉␊ |
1102 | ␉//Slice - I want to use MacModel for ACPITables so I need char* representation␊ |
1103 | ␉const char␉*value = getStringForKey("SMproductname", &bootInfo->smbiosConfig);␊ |
1104 | ␉int i, n=0, first=0, rev1=0, rev2=0;␉␉␊ |
1105 | ␉for (i=0; i<8; i++) ␊ |
1106 | ␉{␊ |
1107 | ␉␉char c = value[i];␊ |
1108 | ␉␉if (isalpha(c))␊ |
1109 | ␉␉{␊ |
1110 | ␉␉␉MacModel[i]=c;␊ |
1111 | ␉␉␉n++;␊ |
1112 | ␉␉} else ␊ |
1113 | ␉␉␉if ((c) >= '0' && (c) <= '9')␊ |
1114 | ␉␉␉{␊ |
1115 | ␉␉␉␉if (first)␊ |
1116 | ␉␉␉␉{␊ |
1117 | ␉␉␉␉␉rev1 = rev1 * 10 + (int)(c) & 0xf;␊ |
1118 | ␉␉␉␉} else␊ |
1119 | ␉␉␉␉␉rev2 = rev2 * 10 + (int)(c) & 0xf;␊ |
1120 | ␉␉␉} else ␊ |
1121 | ␉␉␉␉first = 1;␊ |
1122 | ␉␉␉//␉␉␉␉printf("char=%c first=%d rev1=%d rev2=%d\n", c, first, rev1, rev2);␊ |
1123 | ␉}␊ |
1124 | ␉for (i=n; i<8; i++) {␊ |
1125 | ␉␉MacModel[i] = 0x20;␊ |
1126 | ␉}␊ |
1127 | ␉ModelRev = (rev2 << 16) + rev1;␊ |
1128 | //␉␉ModelLength = (len + 1) * 2;␊ |
1129 | //␉␉printf("Model=%s %08x\n", MacModel, ModelRev);␊ |
1130 | //␉␉getc();␊ |
1131 | ␉␉␊ |
1132 | }␊ |
1133 | ␊ |
1134 | static struct SMBEntryPoint *orig = NULL; // cached␊ |
1135 | static struct SMBEntryPoint *patched = NULL; // cached␊ |
1136 | ␊ |
1137 | /** Get original or new smbios entry point, if successful, the addresses are cached for next time */␊ |
1138 | struct SMBEntryPoint *getSmbios(int which)␊ |
1139 | {␊ |
1140 | ␊ |
1141 | // whatever we are called with orig or new flag, initialize asap both structures␊ |
1142 | switch (which) {␊ |
1143 | case SMBIOS_ORIGINAL:␊ |
1144 | if (orig==NULL) {␊ |
1145 | orig = getAddressOfSmbiosTable();␊ |
1146 | getSmbiosTableStructure(orig); // generate tables entry list for fast table finding␊ |
1147 | }␊ |
1148 | return orig;␊ |
1149 | case SMBIOS_PATCHED:␊ |
1150 | if (orig==NULL && (orig = getAddressOfSmbiosTable())==NULL ) {␊ |
1151 | verbose("Could not find original SMBIOS !!\n");␊ |
1152 | pause();␊ |
1153 | } else {␊ |
1154 | patched = smbios_dry_run(orig);␊ |
1155 | if(patched==NULL) {␊ |
1156 | verbose("Could not create new SMBIOS !!\n");␊ |
1157 | pause();␊ |
1158 | }␊ |
1159 | else {␊ |
1160 | smbios_real_run(orig, patched);␊ |
1161 | }␊ |
1162 | }␊ |
1163 | ␉␉␉getSmbiosMacModel();␉//Dunno if it is a right place to do that␊ |
1164 | return patched;␊ |
1165 | default:␊ |
1166 | verbose("ERROR: invalid option for getSmbios() !!\n");␊ |
1167 | break;␊ |
1168 | }␊ |
1169 | ␊ |
1170 | return NULL;␊ |
1171 | }␊ |
1172 | ␊ |
1173 | /** Find first original dmi Table with a particular type */␊ |
1174 | struct DMIHeader* FindFirstDmiTableOfType(int type, int minlength)␊ |
1175 | {␊ |
1176 | current_pos = 0; //static variable␊ |
1177 | ␊ |
1178 | return FindNextDmiTableOfType(type, minlength);␊ |
1179 | };␊ |
1180 | ␊ |
1181 | /** Find next original dmi Table with a particular type */␊ |
1182 | struct DMIHeader* FindNextDmiTableOfType(int type, int minlength)␊ |
1183 | {␊ |
1184 | int i;␊ |
1185 | ␊ |
1186 | if (ftTablePairInit) getSmbios(SMBIOS_ORIGINAL);␊ |
1187 | ␊ |
1188 | for (i=current_pos; i < DmiTablePairCount; i++) {␊ |
1189 | if (type == DmiTablePair[i].type && ␊ |
1190 | DmiTablePair[i].dmi &&␊ |
1191 | DmiTablePair[i].dmi->length >= minlength ) {␊ |
1192 | current_pos = i+1;␊ |
1193 | return DmiTablePair[i].dmi;␊ |
1194 | }␊ |
1195 | }␊ |
1196 | return NULL; // not found␊ |
1197 | };␊ |
1198 | ␊ |
1199 | #if 1 //NOTUSED //Slice -- it is used?␊ |
1200 | const char * smbiosStringAtIndex(DMIHeader* smHeader, int index, int* length )␊ |
1201 | {␊ |
1202 | const char * last = 0;␊ |
1203 | const char * next = (const char *) smHeader + smHeader->length;␊ |
1204 | ␉␊ |
1205 | if ( length ) *length = 0;␊ |
1206 | while ( index-- )␊ |
1207 | {␊ |
1208 | last = 0;␊ |
1209 | ␉␉const char * cp = 0;␊ |
1210 | ␉␉for ( cp = next; *cp || cp[1]; cp++ )␊ |
1211 | {␊ |
1212 | if ( *cp == '\0' )␊ |
1213 | {␊ |
1214 | last = next;␊ |
1215 | next = cp + 1;␊ |
1216 | break;␊ |
1217 | }␊ |
1218 | }␊ |
1219 | if ( last == 0 ) break;␊ |
1220 | }␊ |
1221 | ␉␊ |
1222 | if ( last )␊ |
1223 | {␊ |
1224 | while (*last == ' ') last++;␊ |
1225 | if (length)␊ |
1226 | {␊ |
1227 | UInt8 len;␊ |
1228 | for ( len = next - last - 1; len && last[len - 1] == ' '; len-- )␊ |
1229 | ;␊ |
1230 | *length = len; // number of chars not counting the terminating NULL␊ |
1231 | }␊ |
1232 | }␊ |
1233 | ␉␊ |
1234 | return last ? last : "";␊ |
1235 | }␊ |
1236 | ␊ |
1237 | ␊ |
1238 | void getSmbiosProductName()␊ |
1239 | {␊ |
1240 | //␉struct SMBEntryPoint␉*smbios;␊ |
1241 | ␉DMISystemInformation␉*p;␊ |
1242 | ␉char*␉␉␉␉␉tempString;␊ |
1243 | ␉int␉␉␉␉␉␉tmpLen;␊ |
1244 | ␉␊ |
1245 | //␉smbios = getSmbios(SMBIOS_ORIGINAL);␊ |
1246 | //␉if (smbios==NULL) return 0; ␊ |
1247 | ␉␊ |
1248 | ␉p = (DMISystemInformation*) FindFirstDmiTableOfType(1, 0x19); // Type 1: (3.3.2) System Information␊ |
1249 | ␉if (p==NULL) return; // NULL;␊ |
1250 | ␉␊ |
1251 | ␉␊ |
1252 | ␉tempString = (char*)smbiosStringAtIndex((DMIHeader*)p, p->productName, &tmpLen);␊ |
1253 | ␉tempString[tmpLen] = 0;␊ |
1254 | ␉␊ |
1255 | ␉gSMBIOSBoardModel = malloc(tmpLen + 1);␊ |
1256 | ␉if(gSMBIOSBoardModel)␊ |
1257 | ␉{␊ |
1258 | ␉␉strncpy(gSMBIOSBoardModel, tempString, tmpLen);␊ |
1259 | ␉␉Node* node = DT__FindNode("/", false);␊ |
1260 | ␉␉DT__AddProperty(node, "orig-model", tmpLen, gSMBIOSBoardModel);␊ |
1261 | ␉}␊ |
1262 | ␉verbose("Actual model name is '%s'\n", tempString);␊ |
1263 | }␊ |
1264 | #endif␊ |
1265 | ␊ |
1266 | //Slice␊ |
1267 | //#define MEGA 1000000LL - now in mem.h␊ |
1268 | void scan_cpu_DMI(void) //PlatformInfo_t *p)␊ |
1269 | {␊ |
1270 | ␉// int i=0;␊ |
1271 | ␉int maxClock = 0;␊ |
1272 | struct DMIHeader * dmihdr = NULL; ␊ |
1273 | struct DMIProcessorInformation* cpuInfo; // Type 4␊ |
1274 | ␉␊ |
1275 | ␉for (dmihdr = FindFirstDmiTableOfType(4, 30); dmihdr; dmihdr = FindNextDmiTableOfType(4, 30)) ␊ |
1276 | ␉{␊ |
1277 | ␉␉cpuInfo = (struct DMIProcessorInformation*)dmihdr;␊ |
1278 | ␉␉if (cpuInfo->processorType != 3) { // CPU␊ |
1279 | ␉␉␉continue;␊ |
1280 | ␉␉}␊ |
1281 | ␉␉//TODO validate␊ |
1282 | #if 1 //NOTYET␉␊ |
1283 | ␉␉msglog("Platform CPU Info:\n FSB=%d\n MaxSpeed=%d\n CurrentSpeed=%d\n", Platform->CPU.FSBFrequency/MEGA, Platform->CPU.TSCFrequency/MEGA, Platform->CPU.CPUFrequency/MEGA);␊ |
1284 | ␉␉␊ |
1285 | ␉␉if ((cpuInfo->externalClock) && (cpuInfo->externalClock < 400)) { //<400MHz␊ |
1286 | ␉␉␉Platform->CPU.FSBFrequency = (cpuInfo->externalClock) * MEGA;␊ |
1287 | ␉␉}␊ |
1288 | ␉␉maxClock = cpuInfo->maximumClock;␊ |
1289 | ␉␉if (cpuInfo->maximumClock < cpuInfo->currentClock) {␊ |
1290 | ␉␉␉maxClock = cpuInfo->currentClock;␊ |
1291 | ␉␉}␊ |
1292 | ␉␉if ((maxClock) && (maxClock < 10000)) { //<10GHz␊ |
1293 | ␉␉␉Platform->CPU.TSCFrequency = maxClock * MEGA;␊ |
1294 | ␉␉}␊ |
1295 | ␉␉if ((cpuInfo->currentClock) && (cpuInfo->currentClock < 10000)) { //<10GHz␊ |
1296 | ␉␉␉Platform->CPU.CPUFrequency = cpuInfo->currentClock * MEGA;␊ |
1297 | ␉␉}␊ |
1298 | #endif␊ |
1299 | ␉␉msglog("DMI CPU Info:\n FSB=%d\n MaxSpeed=%d\n CurrentSpeed=%d\n", cpuInfo->externalClock, cpuInfo->maximumClock, cpuInfo->currentClock);␊ |
1300 | ␉␉msglog("DMI CPU Info 2:\n Family=%x\n Socket=%x\n Cores=%d Enabled=%d Threads=%d\n", cpuInfo->processorFamily, cpuInfo->processorUpgrade, cpuInfo->coreCount, cpuInfo->coreEnabled, cpuInfo->Threads);␊ |
1301 | #if 1 //NOTYET␊ |
1302 | ␉␉if ((cpuInfo->coreCount) && (cpuInfo->coreCount<Platform->CPU.NoCores)) {␊ |
1303 | ␉␉␉if (cpuInfo->coreEnabled < cpuInfo->coreCount) {␊ |
1304 | ␉␉␉␉cpuInfo->coreCount = cpuInfo->coreEnabled;␊ |
1305 | ␉␉␉}␊ |
1306 | ␉␉␉Platform->CPU.NoCores = cpuInfo->coreCount;␊ |
1307 | ␉␉}␊ |
1308 | ␉␉if ((cpuInfo->Threads) && (cpuInfo->Threads<Platform->CPU.NoThreads)) {␉␉␊ |
1309 | ␉␉␉Platform->CPU.NoThreads = cpuInfo->Threads;␊ |
1310 | ␉␉}␊ |
1311 | #endif␊ |
1312 | ␉␉␊ |
1313 | ␉␉return;␊ |
1314 | ␉}␊ |
1315 | ␉␊ |
1316 | ␉return;␊ |
1317 | }␊ |
1318 | //Slice - check other DMI info␊ |
1319 | bool scanDMI(void)␊ |
1320 | {␊ |
1321 | ␉struct DMIHeader * dmihdr = NULL; ␊ |
1322 | struct DMISystemEnclosure* encInfo; // Type 3␊ |
1323 | ␉␊ |
1324 | ␉for (dmihdr = FindFirstDmiTableOfType(3, 13); dmihdr; dmihdr = FindNextDmiTableOfType(3, 13)) ␊ |
1325 | ␉{␊ |
1326 | ␉␉encInfo = (struct DMISystemEnclosure*)dmihdr;␊ |
1327 | ␉␉msglog("DMI Chassis Info:\n Type=%x\n Boot-up State=%x\n Power Supply=%x Thermal State=%x\n", encInfo->type, encInfo->bootupState, encInfo->powerSupplyState, encInfo->thermalState);␊ |
1328 | ␉␉switch (encInfo->type) {␊ |
1329 | ␉␉␉case 1:␊ |
1330 | ␉␉␉case 2:␊ |
1331 | ␉␉␉␉return FALSE;␊ |
1332 | ␉␉␉case 3:␊ |
1333 | ␉␉␉case 4:␊ |
1334 | ␉␉␉case 6:␊ |
1335 | ␉␉␉case 7:␊ |
1336 | ␉␉␉␉Platform->CPU.Mobile = FALSE;␊ |
1337 | ␉␉␉␉break;␊ |
1338 | ␉␉␉case 8:␊ |
1339 | ␉␉␉case 9:␊ |
1340 | ␉␉␉case 0x0A:␊ |
1341 | ␉␉␉case 0x0B:␉␉␉␉␊ |
1342 | ␉␉␉case 0x0E:␊ |
1343 | ␉␉␉␉Platform->CPU.Mobile = TRUE;␊ |
1344 | ␉␉␉␉break;␊ |
1345 | ␉␉␉␉␊ |
1346 | ␉␉␉default:␊ |
1347 | ␉␉␉␉break;␊ |
1348 | ␉␉}␊ |
1349 | ␉␉return TRUE;␊ |
1350 | ␉}␊ |
1351 | ␉return FALSE;␉␊ |
1352 | }␊ |
1353 | |