1 | /*␊ |
2 | * Add (c) here␊ |
3 | *␊ |
4 | * Copyright .... All rights reserved.␊ |
5 | *␊ |
6 | */␊ |
7 | ␊ |
8 | #include "smbios_getters.h"␊ |
9 | #include "bootstruct.h"␊ |
10 | ␊ |
11 | #ifndef DEBUG_SMBIOS␊ |
12 | #define DEBUG_SMBIOS 0␊ |
13 | #endif␊ |
14 | ␊ |
15 | #if DEBUG_SMBIOS␊ |
16 | #define DBG(x...)␉printf(x)␊ |
17 | #else␊ |
18 | #define DBG(x...)␊ |
19 | #endif␊ |
20 | ␊ |
21 | //Slice - for ACPI patcher templates␊ |
22 | int␉␉ModelLength = 0;␊ |
23 | char␉MacModel[8] = "MacBook";␊ |
24 | unsigned int ModelRev = 0x00010001;␊ |
25 | uint64_t smbios_p;␊ |
26 | char*␉gSMBIOSBoardModel;␊ |
27 | ␊ |
28 | bool getProcessorInformationExternalClock(returnType *value)␊ |
29 | {␊ |
30 | ␉value->word = Platform->CPU.FSBFrequency/1000000;␊ |
31 | ␉return true;␊ |
32 | }␊ |
33 | ␊ |
34 | bool getProcessorInformationMaximumClock(returnType *value)␊ |
35 | {␊ |
36 | ␉value->word = Platform->CPU.CPUFrequency/1000000;␊ |
37 | ␉return true;␊ |
38 | }␊ |
39 | ␊ |
40 | bool getSMBOemProcessorBusSpeed(returnType *value)␊ |
41 | {␊ |
42 | ␉if (Platform->CPU.Vendor == 0x756E6547) // Intel␊ |
43 | ␉{␉␉␊ |
44 | ␉␉switch (Platform->CPU.Family) ␊ |
45 | ␉␉{␊ |
46 | ␉␉␉case 0x06:␊ |
47 | ␉␉␉{␊ |
48 | ␉␉␉␉switch (Platform->CPU.Model)␊ |
49 | ␉␉␉␉{␊ |
50 | ␉␉␉␉␉case 0x0D:␉␉␉␉␉// ???␊ |
51 | ␉␉␉␉␉case CPU_MODEL_YONAH:␉␉// Intel Mobile Core Solo, Duo␊ |
52 | ␉␉␉␉␉case CPU_MODEL_MEROM:␉␉// Intel Mobile Core 2 Solo, Duo, Xeon 30xx, Xeon 51xx, Xeon X53xx, Xeon E53xx, Xeon X32xx␊ |
53 | ␉␉␉␉␉case CPU_MODEL_PENRYN:␉␉// Intel Core 2 Solo, Duo, Quad, Extreme, Xeon X54xx, Xeon X33xx␊ |
54 | ␉␉␉␉␉case CPU_MODEL_ATOM:␉␉// Intel Atom (45nm)␊ |
55 | ␉␉␉␉␉␉return false;␊ |
56 | ␊ |
57 | ␉␉␉␉␉case 0x19:␉␉␉␉␉// ??? Intel Core i5 650 @3.20 GHz ␊ |
58 | ␉␉␉␉␉case CPU_MODEL_NEHALEM:␉␉// Intel Core i7, Xeon W35xx, Xeon X55xx, Xeon E55xx LGA1366 (45nm)␊ |
59 | ␉␉␉␉␉case CPU_MODEL_FIELDS:␉␉// Intel Core i5, i7, Xeon X34xx LGA1156 (45nm)␊ |
60 | ␉␉␉␉␉case CPU_MODEL_DALES:␊ |
61 | ␉␉␉␉␉case CPU_MODEL_DALES_32NM:␉// Intel Core i3, i5 LGA1156 (32nm)␊ |
62 | ␉␉␉␉␉case CPU_MODEL_WESTMERE:␉// Intel Core i7, Xeon X56xx, Xeon E56xx, Xeon W36xx LGA1366 (32nm) 6 Core␊ |
63 | ␉␉␉␉␉case CPU_MODEL_NEHALEM_EX:␉// Intel Xeon X75xx, Xeon X65xx, Xeon E75xx, Xeon E65x␊ |
64 | ␉␉␉␉␉case CPU_MODEL_WESTMERE_EX:␉// Intel Xeon E7␊ |
65 | ␉␉␉␉␉{␊ |
66 | ␉␉␉␉␉␉// thanks to dgobe for i3/i5/i7 bus speed detection␊ |
67 | ␉␉␉␉␉␉int nhm_bus = 0x3F;␊ |
68 | ␉␉␉␉␉␉static long possible_nhm_bus[] = {0xFF, 0x7F, 0x3F};␊ |
69 | ␉␉␉␉␉␉unsigned long did, vid;␊ |
70 | ␉␉␉␉␉␉int i;␊ |
71 | ␉␉␉␉␉␉␊ |
72 | ␉␉␉␉␉␉// Nehalem supports Scrubbing␊ |
73 | ␉␉␉␉␉␉// First, locate the PCI bus where the MCH is located␊ |
74 | ␉␉␉␉␉␉for(i = 0; i < sizeof(possible_nhm_bus); i++)␊ |
75 | ␉␉␉␉␉␉{␊ |
76 | ␉␉␉␉␉␉␉vid = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), 0x00);␊ |
77 | ␉␉␉␉␉␉␉did = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), 0x02);␊ |
78 | ␉␉␉␉␉␉␉vid &= 0xFFFF;␊ |
79 | ␉␉␉␉␉␉␉did &= 0xFF00;␊ |
80 | ␉␉␉␉␉␉␉␊ |
81 | ␉␉␉␉␉␉␉if(vid == 0x8086 && did >= 0x2C00)␊ |
82 | ␉␉␉␉␉␉␉␉nhm_bus = possible_nhm_bus[i]; ␊ |
83 | ␉␉␉␉␉␉}␊ |
84 | ␉␉␉␉␉␉␊ |
85 | ␉␉␉␉␉␉unsigned long qpimult, qpibusspeed;␊ |
86 | ␉␉␉␉␉␉qpimult = pci_config_read32(PCIADDR(nhm_bus, 2, 1), 0x50);␊ |
87 | ␉␉␉␉␉␉qpimult &= 0x7F;␊ |
88 | ␉␉␉␉␉␉DBG("qpimult %d\n", qpimult);␊ |
89 | ␉␉␉␉␉␉qpibusspeed = (qpimult * 2 * (Platform->CPU.FSBFrequency/1000000));␊ |
90 | ␉␉␉␉␉␉// Rek: rounding decimals to match original mac profile info␊ |
91 | ␉␉␉␉␉␉if (qpibusspeed%100 != 0)qpibusspeed = ((qpibusspeed+50)/100)*100;␊ |
92 | ␉␉␉␉␉␉DBG("qpibusspeed %d\n", qpibusspeed);␊ |
93 | ␉␉␉␉␉␉value->word = qpibusspeed;␊ |
94 | ␉␉␉␉␉␉return true;␊ |
95 | ␉␉␉␉␉}␊ |
96 | ␉␉␉␉}␊ |
97 | ␉␉␉}␊ |
98 | ␉␉}␊ |
99 | ␉}␊ |
100 | ␉return false;␊ |
101 | }␊ |
102 | ␊ |
103 | uint16_t simpleGetSMBOemProcessorType(void)␊ |
104 | {␊ |
105 | ␉if (Platform->CPU.NoCores >= 4) ␊ |
106 | ␉{␊ |
107 | ␉␉return 0x0501;␉// Quad-Core Xeon␊ |
108 | ␉}␊ |
109 | ␉else if (Platform->CPU.NoCores == 1) ␊ |
110 | ␉{␊ |
111 | ␉␉return 0x0201;␉// Core Solo␊ |
112 | ␉};␊ |
113 | ␉␊ |
114 | ␉return 0x0301;␉␉// Core 2 Duo␊ |
115 | }␊ |
116 | ␊ |
117 | bool getSMBOemProcessorType(returnType *value)␊ |
118 | {␊ |
119 | ␉static bool done = false;␉␉␊ |
120 | ␉␉␊ |
121 | ␉value->word = simpleGetSMBOemProcessorType();␊ |
122 | ␊ |
123 | ␉if (Platform->CPU.Vendor == 0x756E6547) // Intel␊ |
124 | ␉{␊ |
125 | ␉␉if (!done)␊ |
126 | ␉␉{␊ |
127 | ␉␉␉verbose("CPU is %s, family 0x%x, model 0x%x\n", Platform->CPU.BrandString, Platform->CPU.Family, Platform->CPU.Model);␊ |
128 | ␉␉␉done = true;␊ |
129 | ␉␉}␊ |
130 | ␉␉␊ |
131 | ␉␉switch (Platform->CPU.Family) ␊ |
132 | ␉␉{␊ |
133 | ␉␉␉case 0x06:␊ |
134 | ␉␉␉{␊ |
135 | ␉␉␉␉switch (Platform->CPU.Model)␊ |
136 | ␉␉␉␉{␊ |
137 | ␉␉␉␉␉case 0x0D:␉␉␉␉␉␉␉// ???␊ |
138 | ␉␉␉␉␉case CPU_MODEL_YONAH:␉␉␉␉// Intel Mobile Core Solo, Duo␊ |
139 | ␉␉␉␉␉case CPU_MODEL_MEROM:␉␉␉␉// Intel Mobile Core 2 Solo, Duo, Xeon 30xx, Xeon 51xx, Xeon X53xx, Xeon E53xx, Xeon X32xx␊ |
140 | ␉␉␉␉␉case CPU_MODEL_PENRYN:␉␉␉␉// Intel Core 2 Solo, Duo, Quad, Extreme, Xeon X54xx, Xeon X33xx␊ |
141 | ␉␉␉␉␉case CPU_MODEL_ATOM:␉␉␉␉// Intel Atom (45nm)␊ |
142 | ␉␉␉␉␉␉return true;␊ |
143 | ␊ |
144 | ␉␉␉␉␉case CPU_MODEL_NEHALEM:␉␉␉␉// Intel Core i7, Xeon W35xx, Xeon X55xx, Xeon E55xx LGA1366 (45nm)␊ |
145 | ␉␉␉␉␉␉if (strstr(Platform->CPU.BrandString, "Xeon(R)"))␊ |
146 | ␉␉␉␉␉␉␉value->word = 0x0501;␉␉␉// Xeon ␊ |
147 | ␉␉␉␉␉␉else␊ |
148 | ␉␉␉␉␉␉␉value->word = 0x0701;␉␉␉// Core i7␊ |
149 | ␊ |
150 | ␉␉␉␉␉␉return true;␊ |
151 | ␊ |
152 | ␉␉␉␉␉case CPU_MODEL_FIELDS:␉␉␉␉// Intel Core i5, i7, Xeon X34xx LGA1156 (45nm)␊ |
153 | ␉␉␉␉␉␉if (strstr(Platform->CPU.BrandString, "Core(TM) i5"))␊ |
154 | ␉␉␉␉␉␉␉value->word = 0x0601;␉␉␉// Core i5␊ |
155 | ␉␉␉␉␉␉else␊ |
156 | ␉␉␉␉␉␉␉value->word = 0x0701;␉␉␉// Core i7␊ |
157 | ␉␉␉␉␉␉return true;␊ |
158 | ␊ |
159 | ␉␉␉␉␉case CPU_MODEL_DALES:␊ |
160 | ␉␉␉␉␉␉if (strstr(Platform->CPU.BrandString, "Core(TM) i5"))␊ |
161 | ␉␉␉␉␉␉␉value->word = 0x0601;␉␉␉// Core i5␊ |
162 | ␉␉␉␉␉␉else␊ |
163 | ␉␉␉␉␉␉␉value->word = 0x0701;␉␉␉// Core i7␊ |
164 | ␉␉␉␉␉␉return true;␊ |
165 | ␊ |
166 | ␉␉␉␉␉case CPU_MODEL_SANDY:␉␉␉␉// Intel Core i3, i5, i7 LGA1155 (32nm)␊ |
167 | case CPU_MODEL_SANDY_XEON:␉␉␉// Intel Xeon E3␊ |
168 | ␉␉␉␉␉case CPU_MODEL_DALES_32NM:␉␉␉// Intel Core i3, i5 LGA1156 (32nm)␊ |
169 | ␉␉␉␉␉␉if (strstr(Platform->CPU.BrandString, "Core(TM) i3"))␊ |
170 | ␉␉␉␉␉␉␉value->word = 0x0901;␉␉␉// Core i3␊ |
171 | ␉␉␉␉␉␉else␊ |
172 | ␉␉␉␉␉␉␉if (strstr(Platform->CPU.BrandString, "Core(TM) i5"))␊ |
173 | ␉␉␉␉␉␉␉␉value->word = 0x0601;␉␉// Core i5␊ |
174 | ␉␉␉␉␉␉␉else␊ |
175 | ␉␉␉␉␉␉␉␉value->word = 0x0701;␉␉// Core i7␊ |
176 | ␉␉␉␉␉␉return true;␊ |
177 | ␊ |
178 | ␉␉␉␉␉case CPU_MODEL_WESTMERE:␉␉␉// Intel Core i7, Xeon X56xx, Xeon E56xx, Xeon W36xx LGA1366 (32nm) 6 Core␊ |
179 | ␉␉␉␉␉case CPU_MODEL_WESTMERE_EX:␉␉␉// Intel Xeon E7␊ |
180 | ␉␉␉␉␉␉value->word = 0x0501;␉␉␉␉// Core i7␊ |
181 | ␉␉␉␉␉␉return true;␊ |
182 | ␊ |
183 | ␉␉␉␉␉case 0x19:␉␉␉␉␉␉␉// ??? Intel Core i5 650 @3.20 GHz␊ |
184 | ␉␉␉␉␉␉value->word = 0x0601;␉␉␉␉// Core i5␊ |
185 | ␉␉␉␉␉␉return true;␊ |
186 | ␉␉␉␉}␊ |
187 | ␉␉␉}␊ |
188 | ␉␉}␊ |
189 | ␉}␊ |
190 | ␉␊ |
191 | ␉return false;␊ |
192 | }␊ |
193 | ␊ |
194 | bool getSMBMemoryDeviceMemoryType(returnType *value)␊ |
195 | {␊ |
196 | ␉static int idx = -1;␊ |
197 | ␉int␉map;␊ |
198 | ␊ |
199 | ␉idx++;␊ |
200 | ␉if (idx < MAX_RAM_SLOTS)␊ |
201 | ␉{␊ |
202 | ␉␉map = Platform->DMI.DIMM[idx];␊ |
203 | ␉␉if (Platform->RAM.DIMM[map].InUse && Platform->RAM.DIMM[map].Type != 0)␊ |
204 | ␉␉{␊ |
205 | ␉␉␉DBG("RAM Detected Type = %d\n", Platform->RAM.DIMM[map].Type);␊ |
206 | ␉␉␉value->byte = Platform->RAM.DIMM[map].Type;␊ |
207 | ␉␉␉return true;␊ |
208 | ␉␉}␊ |
209 | ␉}␊ |
210 | ␉␊ |
211 | ␉return false;␊ |
212 | //␉value->byte = SMB_MEM_TYPE_DDR2;␊ |
213 | //␉return true;␊ |
214 | }␊ |
215 | ␊ |
216 | bool getSMBMemoryDeviceMemorySpeed(returnType *value)␊ |
217 | {␊ |
218 | ␉static int idx = -1;␊ |
219 | ␉int␉map;␊ |
220 | ␊ |
221 | ␉idx++;␊ |
222 | ␉if (idx < MAX_RAM_SLOTS)␊ |
223 | ␉{␊ |
224 | ␉␉map = Platform->DMI.DIMM[idx];␊ |
225 | ␉␉if (Platform->RAM.DIMM[map].InUse && Platform->RAM.DIMM[map].Frequency != 0)␊ |
226 | ␉␉{␊ |
227 | ␉␉␉DBG("RAM Detected Freq = %d Mhz\n", Platform->RAM.DIMM[map].Frequency);␊ |
228 | ␉␉␉value->dword = Platform->RAM.DIMM[map].Frequency;␊ |
229 | ␉␉␉return true;␊ |
230 | ␉␉}␊ |
231 | ␉}␊ |
232 | ␊ |
233 | ␉return false;␊ |
234 | //␉value->dword = 800;␊ |
235 | //␉return true;␊ |
236 | }␊ |
237 | ␊ |
238 | bool getSMBMemoryDeviceManufacturer(returnType *value)␊ |
239 | {␊ |
240 | ␉static int idx = -1;␊ |
241 | ␉int␉map;␊ |
242 | ␊ |
243 | ␉idx++;␊ |
244 | ␉if (idx < MAX_RAM_SLOTS)␊ |
245 | ␉{␊ |
246 | ␉␉map = Platform->DMI.DIMM[idx];␊ |
247 | ␉␉if (Platform->RAM.DIMM[map].InUse && strlen(Platform->RAM.DIMM[map].Vendor) > 0)␊ |
248 | ␉␉{␊ |
249 | ␉␉␉DBG("RAM Detected Vendor[%d]='%s'\n", idx, Platform->RAM.DIMM[map].Vendor);␊ |
250 | ␉␉␉value->string = Platform->RAM.DIMM[map].Vendor;␊ |
251 | ␉␉␉return true;␊ |
252 | ␉␉}␊ |
253 | ␉}␊ |
254 | ␊ |
255 | ␉if (!bootInfo->memDetect)␊ |
256 | ␉␉return false;␊ |
257 | ␉value->string = NOT_AVAILABLE;␊ |
258 | ␉return true;␊ |
259 | }␊ |
260 | ␉␊ |
261 | bool getSMBMemoryDeviceSerialNumber(returnType *value)␊ |
262 | {␊ |
263 | ␉static int idx = -1;␊ |
264 | ␉int␉map;␊ |
265 | ␊ |
266 | ␉idx++;␊ |
267 | ␊ |
268 | DBG("getSMBMemoryDeviceSerialNumber index: %d, MAX_RAM_SLOTS: %d\n",idx,MAX_RAM_SLOTS);␊ |
269 | ␊ |
270 | ␉if (idx < MAX_RAM_SLOTS)␊ |
271 | ␉{␊ |
272 | ␉␉map = Platform->DMI.DIMM[idx];␊ |
273 | ␉␉if (Platform->RAM.DIMM[map].InUse && strlen(Platform->RAM.DIMM[map].SerialNo) > 0)␊ |
274 | ␉␉{␊ |
275 | ␉␉␉DBG("map=%d, RAM Detected SerialNo[%d]='%s'\n", map, idx, Platform->RAM.DIMM[map].SerialNo);␊ |
276 | ␉␉␉value->string = Platform->RAM.DIMM[map].SerialNo;␊ |
277 | ␉␉␉return true;␊ |
278 | ␉␉}␊ |
279 | ␉}␊ |
280 | ␊ |
281 | ␉if (!bootInfo->memDetect)␊ |
282 | ␉␉return false;␊ |
283 | ␉value->string = NOT_AVAILABLE;␊ |
284 | ␉return true;␊ |
285 | }␊ |
286 | ␊ |
287 | bool getSMBMemoryDevicePartNumber(returnType *value)␊ |
288 | {␊ |
289 | ␉static int idx = -1;␊ |
290 | ␉int␉map;␊ |
291 | ␊ |
292 | ␉idx++;␊ |
293 | ␉if (idx < MAX_RAM_SLOTS)␊ |
294 | ␉{␊ |
295 | ␉␉map = Platform->DMI.DIMM[idx];␊ |
296 | ␉␉if (Platform->RAM.DIMM[map].InUse && strlen(Platform->RAM.DIMM[map].PartNo) > 0)␊ |
297 | ␉␉{␊ |
298 | ␉␉␉DBG("map=%d, RAM Detected PartNo[%d]='%s'\n", map, idx, Platform->RAM.DIMM[map].PartNo);␊ |
299 | ␉␉␉value->string = Platform->RAM.DIMM[map].PartNo;␊ |
300 | ␉␉␉return true;␊ |
301 | ␉␉}␊ |
302 | ␉}␊ |
303 | ␊ |
304 | ␉if (!bootInfo->memDetect)␊ |
305 | ␉␉return false;␊ |
306 | ␉value->string = NOT_AVAILABLE;␊ |
307 | ␉return true;␊ |
308 | }␊ |
309 | ␊ |
310 | ␊ |
311 | // getting smbios addr with fast compare ops, late checksum testing ...␊ |
312 | #define COMPARE_DWORD(a,b) ( *((uint32_t *) a) == *((uint32_t *) b) )␊ |
313 | static const char * const SMTAG = "_SM_";␊ |
314 | static const char* const DMITAG = "_DMI_";␊ |
315 | ␊ |
316 | SMBEntryPoint *getAddressOfSmbiosTable(void)␊ |
317 | {␊ |
318 | ␉SMBEntryPoint␉*smbios;␊ |
319 | ␉/* ␊ |
320 | ␉ * The logic is to start at 0xf0000 and end at 0xfffff iterating 16 bytes at a time looking␊ |
321 | ␉ * for the SMBIOS entry-point structure anchor (literal ASCII "_SM_").␊ |
322 | ␉ */␊ |
323 | ␉smbios = (SMBEntryPoint*)SMBIOS_RANGE_START;␊ |
324 | ␉while (smbios <= (SMBEntryPoint *)SMBIOS_RANGE_END) {␊ |
325 | ␉␉if (COMPARE_DWORD(smbios->anchor, SMTAG) && ␊ |
326 | ␉␉␉COMPARE_DWORD(smbios->dmi.anchor, DMITAG) &&␊ |
327 | ␉␉␉smbios->dmi.anchor[4] == DMITAG[4] &&␊ |
328 | ␉␉␉checksum8(smbios, sizeof(SMBEntryPoint)) == 0)␊ |
329 | ␉ {␊ |
330 | ␉␉␉return smbios;␊ |
331 | ␉ }␊ |
332 | ␉␉smbios = (SMBEntryPoint*)(((char*)smbios) + 16);␊ |
333 | ␉}␊ |
334 | ␉printf("ERROR: Unable to find SMBIOS!\n");␊ |
335 | ␉pause();␊ |
336 | ␉return NULL;␊ |
337 | }␊ |
338 | ␊ |
339 | void getSmbiosMacModel(void)␊ |
340 | {␊ |
341 | #define MAX_MODEL_LEN␉32␊ |
342 | ␉␊ |
343 | ␉//Slice - I want to use MacModel for ACPITables so I need char* representation␊ |
344 | ␉const char␉*value = getStringForKey("SMproductname", &bootInfo->smbiosConfig);␊ |
345 | ␉int i, n=0, first=0, rev1=0, rev2=0;␉␉␊ |
346 | ␉for (i=0; i<8; i++) ␊ |
347 | ␉{␊ |
348 | ␉␉char c = value[i];␊ |
349 | ␉␉if (isalpha(c))␊ |
350 | ␉␉{␊ |
351 | ␉␉␉MacModel[i]=c;␊ |
352 | ␉␉␉n++;␊ |
353 | ␉␉} else ␊ |
354 | ␉␉␉if ((c) >= '0' && (c) <= '9')␊ |
355 | ␉␉␉{␊ |
356 | ␉␉␉␉if (first)␊ |
357 | ␉␉␉␉{␊ |
358 | ␉␉␉␉␉rev1 = rev1 * 10 + (int)(c) & 0xf;␊ |
359 | ␉␉␉␉} else␊ |
360 | ␉␉␉␉␉rev2 = rev2 * 10 + (int)(c) & 0xf;␊ |
361 | ␉␉␉} else ␊ |
362 | ␉␉␉␉first = 1;␊ |
363 | ␉␉//␉␉␉␉printf("char=%c first=%d rev1=%d rev2=%d\n", c, first, rev1, rev2);␊ |
364 | ␉}␊ |
365 | ␉for (i=n; i<8; i++) {␊ |
366 | ␉␉MacModel[i] = 0x20;␊ |
367 | ␉}␊ |
368 | ␉ModelRev = (rev2 << 16) + rev1;␊ |
369 | ␉//␉␉ModelLength = (len + 1) * 2;␊ |
370 | ␉//␉␉printf("Model=%s %08x\n", MacModel, ModelRev);␊ |
371 | ␉//␉␉getc();␊ |
372 | ␉␊ |
373 | }␊ |
374 | ␊ |
375 | //static struct SMBEntryPoint *orig = NULL; // cached␊ |
376 | //static struct SMBEntryPoint *patched = NULL; // cached␊ |
377 | void getSmbiosProductName()␊ |
378 | {␊ |
379 | ␉//␉struct SMBEntryPoint␉*smbios;␊ |
380 | ␉SMBSystemInformation␉*p;␊ |
381 | ␉char*␉␉␉␉␉tempString;␊ |
382 | ␉int␉␉␉␉␉␉tmpLen;␊ |
383 | ␉␊ |
384 | ␉//␉smbios = getSmbios(SMBIOS_ORIGINAL);␊ |
385 | ␉//␉if (smbios==NULL) return 0; ␊ |
386 | ␉␊ |
387 | ␉p = (SMBSystemInformation*) FindFirstDmiTableOfType(1, 0x19); // Type 1: (3.3.2) System Information␊ |
388 | ␉if (p==NULL) return; // NULL;␊ |
389 | ␉␊ |
390 | ␉tempString = (char*)smbiosStringAtIndex((SMBStructHeader*)p, p->productName, &tmpLen);␊ |
391 | ␉tempString[tmpLen] = 0;␊ |
392 | ␉␊ |
393 | ␉gSMBIOSBoardModel = malloc(tmpLen + 1);␊ |
394 | ␉if(gSMBIOSBoardModel)␊ |
395 | ␉{␊ |
396 | ␉␉strncpy(gSMBIOSBoardModel, tempString, tmpLen);␊ |
397 | ␉␉Node* node = DT__FindNode("/", false);␊ |
398 | ␉␉DT__AddProperty(node, "orig-model", tmpLen, gSMBIOSBoardModel);␊ |
399 | ␉}␊ |
400 | ␉verbose("Actual model name is '%s'\n", tempString);␊ |
401 | }␊ |
402 | ␊ |
403 | const char * smbiosStringAtIndex(SMBStructHeader* smHeader, int index, int* length )␊ |
404 | {␊ |
405 | const char * last = 0;␊ |
406 | const char * next = (const char *) smHeader + smHeader->length;␊ |
407 | ␉␊ |
408 | if ( length ) *length = 0;␊ |
409 | while ( index-- )␊ |
410 | {␊ |
411 | last = 0;␊ |
412 | ␉␉const char * cp = 0;␊ |
413 | ␉␉for ( cp = next; *cp || cp[1]; cp++ )␊ |
414 | {␊ |
415 | if ( *cp == '\0' )␊ |
416 | {␊ |
417 | last = next;␊ |
418 | next = cp + 1;␊ |
419 | break;␊ |
420 | }␊ |
421 | }␊ |
422 | if ( last == 0 ) break;␊ |
423 | }␊ |
424 | ␉␊ |
425 | if ( last )␊ |
426 | {␊ |
427 | while (*last == ' ') last++;␊ |
428 | if (length)␊ |
429 | {␊ |
430 | UInt8 len;␊ |
431 | for ( len = next - last - 1; len && last[len - 1] == ' '; len-- )␊ |
432 | ;␊ |
433 | *length = len; // number of chars not counting the terminating NULL␊ |
434 | }␊ |
435 | }␊ |
436 | ␉␊ |
437 | return last ? last : "";␊ |
438 | }␊ |
439 | ␊ |
440 | //Slice␊ |
441 | //#define MEGA 1000000LL - now in mem.h␊ |
442 | void scan_cpu_DMI(void) //PlatformInfo_t *p)␊ |
443 | {␊ |
444 | ␉// int i=0;␊ |
445 | ␉int maxClock = 0;␊ |
446 | SMBStructHeader * dmihdr = NULL; ␊ |
447 | SMBProcessorInformation* cpuInfo; // Type 4␊ |
448 | ␉␊ |
449 | ␉for (dmihdr = FindFirstDmiTableOfType(4, 30); dmihdr; dmihdr = FindNextDmiTableOfType(4, 30)) ␊ |
450 | ␉{␊ |
451 | ␉␉cpuInfo = (SMBProcessorInformation*)dmihdr;␊ |
452 | ␉␉if (cpuInfo->processorType != 3) { // CPU␊ |
453 | ␉␉␉continue;␊ |
454 | ␉␉}␊ |
455 | ␉␉//TODO validate␊ |
456 | #if 1 //NOTYET␉␊ |
457 | ␉␉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);␊ |
458 | ␉␉␊ |
459 | ␉␉if ((cpuInfo->externalClock) && (cpuInfo->externalClock < 400)) { //<400MHz␊ |
460 | ␉␉␉Platform->CPU.FSBFrequency = (cpuInfo->externalClock) * MEGA;␊ |
461 | ␉␉}␊ |
462 | ␉␉maxClock = cpuInfo->maximumClock;␊ |
463 | ␉␉if (cpuInfo->maximumClock < cpuInfo->currentClock) {␊ |
464 | ␉␉␉maxClock = cpuInfo->currentClock;␊ |
465 | ␉␉}␊ |
466 | ␉␉if ((maxClock) && (maxClock < 10000)) { //<10GHz␊ |
467 | ␉␉␉Platform->CPU.TSCFrequency = maxClock * MEGA;␊ |
468 | ␉␉}␊ |
469 | ␉␉if ((cpuInfo->currentClock) && (cpuInfo->currentClock < 10000)) { //<10GHz␊ |
470 | ␉␉␉Platform->CPU.CPUFrequency = cpuInfo->currentClock * MEGA;␊ |
471 | ␉␉}␊ |
472 | #endif␊ |
473 | ␉␉msglog("DMI CPU Info:\n FSB=%d\n MaxSpeed=%d\n CurrentSpeed=%d\n", cpuInfo->externalClock, cpuInfo->maximumClock, cpuInfo->currentClock);␊ |
474 | ␉␉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);␊ |
475 | #if 1 //NOTYET␊ |
476 | ␉␉if ((cpuInfo->coreCount) && (cpuInfo->coreCount<Platform->CPU.NoCores)) {␊ |
477 | ␉␉␉if (cpuInfo->coreEnabled < cpuInfo->coreCount) {␊ |
478 | ␉␉␉␉cpuInfo->coreCount = cpuInfo->coreEnabled;␊ |
479 | ␉␉␉}␊ |
480 | ␉␉␉Platform->CPU.NoCores = cpuInfo->coreCount;␊ |
481 | ␉␉}␊ |
482 | ␉␉if ((cpuInfo->Threads) && (cpuInfo->Threads<Platform->CPU.NoThreads)) {␉␉␊ |
483 | ␉␉␉Platform->CPU.NoThreads = cpuInfo->Threads;␊ |
484 | ␉␉}␊ |
485 | #endif␊ |
486 | ␉␉␊ |
487 | ␉␉return;␊ |
488 | ␉}␊ |
489 | ␉␊ |
490 | ␉return;␊ |
491 | }␊ |
492 | //Slice - check other DMI info␊ |
493 | bool scanDMI(void)␊ |
494 | {␊ |
495 | ␉SMBStructHeader * dmihdr = NULL; ␊ |
496 | SMBSystemEnclosure* encInfo; // Type 3␊ |
497 | ␉␊ |
498 | ␉for (dmihdr = FindFirstDmiTableOfType(3, 13); dmihdr; dmihdr = FindNextDmiTableOfType(3, 13)) ␊ |
499 | ␉{␊ |
500 | ␉␉encInfo = (SMBSystemEnclosure*)dmihdr;␊ |
501 | ␉␉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);␊ |
502 | ␉␉switch (encInfo->type) {␊ |
503 | ␉␉␉case 1:␊ |
504 | ␉␉␉case 2:␊ |
505 | ␉␉␉␉return FALSE;␊ |
506 | ␉␉␉case 3:␊ |
507 | ␉␉␉case 4:␊ |
508 | ␉␉␉case 6:␊ |
509 | ␉␉␉case 7:␊ |
510 | ␉␉␉␉Platform->CPU.Mobile = FALSE;␊ |
511 | ␉␉␉␉break;␊ |
512 | ␉␉␉case 8:␊ |
513 | ␉␉␉case 9:␊ |
514 | ␉␉␉case 0x0A:␊ |
515 | ␉␉␉case 0x0B:␉␉␉␉␊ |
516 | ␉␉␉case 0x0E:␊ |
517 | ␉␉␉␉Platform->CPU.Mobile = TRUE;␊ |
518 | ␉␉␉␉break;␊ |
519 | ␉␉␉␉␊ |
520 | ␉␉␉default:␊ |
521 | ␉␉␉␉break;␊ |
522 | ␉␉}␊ |
523 | ␉␉return TRUE;␊ |
524 | ␉}␊ |
525 | ␉return FALSE;␉␊ |
526 | }␊ |
527 | |