1 | /*␊ |
2 | * A very simple SMBIOS Table decoder, part of the Chameleon Boot Loader Project␊ |
3 | *␊ |
4 | * Copyright 2010 by Islam M. Ahmed Zaid. All rights reserved.␊ |
5 | *␊ |
6 | */␊ |
7 | ␊ |
8 | #include "libsaio.h"␊ |
9 | #include "smbios.h"␊ |
10 | // Bungo:␊ |
11 | #include "boot.h"␊ |
12 | #include "bootstruct.h"␊ |
13 | ␊ |
14 | #ifndef DEBUG_SMBIOS␊ |
15 | #define DEBUG_SMBIOS 0␊ |
16 | #endif␊ |
17 | ␊ |
18 | #if DEBUG_SMBIOS␊ |
19 | #define DBG(x...)␉printf(x)␊ |
20 | #else␊ |
21 | #define DBG(x...)␉msglog(x)␊ |
22 | #endif␊ |
23 | ␊ |
24 | static SMBByte minorVersion; // SMBIOS rev. minor␊ |
25 | // Bungo:␊ |
26 | static SMBByte majorVersion; // SMBIOS rev. major␊ |
27 | static SMBByte bcdRevisionLo; // DMI rev. minor␊ |
28 | static SMBByte bcdRevisionHi; // DMI rev. major␊ |
29 | ␊ |
30 | extern char *getSMBStringForField(SMBStructHeader *structHeader, uint8_t field);␊ |
31 | ␊ |
32 | // Bungo:␊ |
33 | #define NotSpecifiedStr "Not Specified" // no string␊ |
34 | #define out_of_spec "<OUT OF SPEC>" // value out of smbios spec. range␊ |
35 | #define PrivateStr "** PRIVATE **" // masking private data␊ |
36 | #define alwaysMask true␊ |
37 | #define neverMask false␊ |
38 | static bool privateData = true;␊ |
39 | ␊ |
40 | char *SMBStringForField(SMBStructHeader *structHeader, uint8_t field, const bool mask) // Bungo: fixes random string readout if null in smbios to "Not Specified" as dmidecode displays␊ |
41 | {␊ |
42 | ␉char *str = NULL;␊ |
43 | ␉str = getSMBStringForField(structHeader, field);␊ |
44 | ␉if (!field) {␊ |
45 | ␉␉str = NotSpecifiedStr;␊ |
46 | ␉} else if (mask) {␊ |
47 | ␉␉str = PrivateStr;␊ |
48 | ␉}␊ |
49 | ␊ |
50 | return str;␊ |
51 | };␊ |
52 | ␊ |
53 | /*====␊ |
54 | 7.2.2␊ |
55 | ===*/␊ |
56 | static const char *SMBWakeUpTypes[] = // Bungo: strings for wake-up type (Table Type 1 - System Information)␊ |
57 | {␊ |
58 | ␉"Reserved", /* 00h */␊ |
59 | ␉"Other", /* 01h */␊ |
60 | ␉"Unknown", /* 02h */␊ |
61 | ␉"APM Timer", /* 03h */␊ |
62 | ␉"Modem Ring", /* 04h */␊ |
63 | ␉"LAN Remote", /* 05h */␊ |
64 | ␉"Power Switch", /* 06h */␊ |
65 | ␉"PCI PME#", /* 07h */␊ |
66 | ␉"AC Power Restored" /* 08h */␊ |
67 | };␊ |
68 | ␊ |
69 | /*====␊ |
70 | 7.3.2␊ |
71 | ===*/␊ |
72 | static const char *SMBBaseBoardTypes[] = // Bungo: strings for base board type (Table Type 2 - Base Board Information)␊ |
73 | {␊ |
74 | ␉"Unknown", /* 01h */␊ |
75 | ␉"Other", /* 02h */␊ |
76 | ␉"Server Blade", /* 03h */␊ |
77 | ␉"Connectivity Switch", /* 04h */␊ |
78 | ␉"System Management Module", /* 05h */␊ |
79 | ␉"Processor Module", /* 06h */␊ |
80 | ␉"I/O Module", /* 07h */␊ |
81 | ␉"Memory Module", /* 08h */␊ |
82 | ␉"Daughter Board", /* 09h */␊ |
83 | ␉"Motherboard", /* 0Ah */␊ |
84 | ␉"Processor+Memory Module", /* 0Bh */␊ |
85 | ␉"Processor+I/O Module", /* 0Ch */␊ |
86 | ␉"Interconnect Board" /* 0Dh */␊ |
87 | };␊ |
88 | ␊ |
89 | /*===␊ |
90 | 7.4.1␊ |
91 | ===*/␊ |
92 | static const char *SMBChassisTypes[] = // Bungo: strings for chassis type (Table Type 3 - Chassis Information)␊ |
93 | {␊ |
94 | ␉"Other", /* 01h */␊ |
95 | ␉"Unknown", /* 02h */␊ |
96 | ␉"Desktop", /* 03h */␊ |
97 | ␉"Low Profile Desktop", /* 04h */␊ |
98 | ␉"Pizza Box", /* 05h */␊ |
99 | ␉"Mini Tower", /* 06h */␊ |
100 | ␉"Tower", /* 07h */␊ |
101 | ␉"Portable", /* 08h */␊ |
102 | ␉"Laptop", /* 09h */␊ |
103 | ␉"Notebook", /* 0Ah */␊ |
104 | ␉"Hand Held", /* 0Bh */␊ |
105 | ␉"Docking Station", /* 0Ch */␊ |
106 | ␉"All in One", /* 0Dh */␊ |
107 | ␉"Sub Notebook", /* 0Eh */␊ |
108 | ␉"Space-saving", /* 0Fh */␊ |
109 | ␉"Lunch Box",␉␉/* 10h */␊ |
110 | ␉"Main Server Chassis",␉/* 11h */␊ |
111 | ␉"Expansion Chassis",␉/* 12h */␊ |
112 | ␉"SubChassis",␉␉/* 13h */␊ |
113 | ␉"Bus Expansion Chassis",/* 14h */␊ |
114 | ␉"Peripheral Chassis",␉/* 15h */␊ |
115 | ␉"RAID Chassis",␉␉/* 16h */␊ |
116 | ␉"Rack Mount Chassis", /* 17h */␊ |
117 | ␉"Sealed-case PC",␉/* 18h */␊ |
118 | ␉"Multi-system Chassis", /* 19h */␊ |
119 | ␉"Compact PCI",␉␉/* 1Ah */␊ |
120 | ␉"Advanced TCA",␉␉/* 1Bh */␊ |
121 | ␉"Blade",␉␉/* 1Ch */ // An SMBIOS implementation for a Blade would contain a Type 3 Chassis structure␊ |
122 | ␉"Blade Enclosing"␉/* 1Dh */ // A Blade Enclosure is a specialized chassis that contains a set of Blades.␊ |
123 | };␊ |
124 | ␊ |
125 | /*====␊ |
126 | 7.5.5␊ |
127 | ===*/␊ |
128 | /*static const char *SMBCpuSocket[] = // ErmaC: strings for (Table Type 4 - Processor Information )␊ |
129 | {␊ |
130 | ␉"Other", // 01h␊ |
131 | "Unknown",␊ |
132 | "Daughter Board",␊ |
133 | "ZIF Socket",␊ |
134 | "Replaceable Piggy Back",␊ |
135 | "None",␊ |
136 | "LIF Socket",␊ |
137 | "Slot 1",␊ |
138 | "Slot 2",␊ |
139 | "370-pin Socket",␊ |
140 | "Slot A",␊ |
141 | "Slot M",␊ |
142 | "Socket 423",␊ |
143 | "Socket A (Socket 462)",␊ |
144 | "Socket 478",␊ |
145 | "Socket 754",␊ |
146 | "Socket 940",␊ |
147 | "Socket 939",␊ |
148 | "Socket mPGA604",␊ |
149 | "Socket LGA771",␊ |
150 | "Socket LGA775",␊ |
151 | "Socket S1",␊ |
152 | "Socket AM2",␊ |
153 | "Socket F (1207)",␊ |
154 | "Socket LGA1366",␊ |
155 | "Socket G34",␊ |
156 | "Socket AM3",␊ |
157 | "Socket C32",␊ |
158 | "Socket LGA1156",␊ |
159 | "Socket LGA1567",␊ |
160 | "Socket PGA988A",␊ |
161 | "Socket BGA1288",␊ |
162 | "Socket rPGA988B",␊ |
163 | "Socket BGA1023",␊ |
164 | "Socket BGA1224",␊ |
165 | "Socket BGA1155",␊ |
166 | "Socket LGA1356",␊ |
167 | "Socket LGA2011",␊ |
168 | "Socket FS1",␊ |
169 | "Socket FS2",␊ |
170 | "Socket FM1",␊ |
171 | "Socket FM2",␊ |
172 | "Socket LGA2011-3",␊ |
173 | "Socket LGA1356-3"␉// 2Ch␊ |
174 | };*/␊ |
175 | ␊ |
176 | /*=====␊ |
177 | 7.18.2␊ |
178 | ====*/␊ |
179 | static const char *␊ |
180 | SMBMemoryDeviceTypes[] =␊ |
181 | {␊ |
182 | ␉"RAM", /* 00h Undefined */␊ |
183 | ␉"RAM", /* 01h Other */␊ |
184 | ␉"RAM", /* 02h Unknown */␊ |
185 | ␉"DRAM", /* 03h DRAM */␊ |
186 | ␉"EDRAM", /* 04h EDRAM */␊ |
187 | ␉"VRAM", /* 05h VRAM */␊ |
188 | ␉"SRAM", /* 06h SRAM */␊ |
189 | ␉"RAM", /* 07h RAM */␊ |
190 | ␉"ROM", /* 08h ROM */␊ |
191 | ␉"FLASH", /* 09h FLASH */␊ |
192 | ␉"EEPROM", /* 0Ah EEPROM */␊ |
193 | ␉"FEPROM", /* 0Bh FEPROM */␊ |
194 | ␉"EPROM", /* 0Ch EPROM */␊ |
195 | ␉"CDRAM", /* 0Dh CDRAM */␊ |
196 | ␉"3DRAM", /* 0Eh 3DRAM */␊ |
197 | ␉"SDRAM", /* 0Fh SDRAM */␊ |
198 | ␉"SGRAM", /* 10h SGRAM */␊ |
199 | ␉"RDRAM", /* 11h RDRAM */␊ |
200 | ␉"DDR SDRAM", /* 12h DDR */␊ |
201 | ␉"DDR2 SDRAM", /* 13h DDR2 */␊ |
202 | ␉"DDR2 FB-DIMM", /* 14h DDR2 FB-DIMM */␊ |
203 | ␉"RAM",␉␉/* 15h unused */␊ |
204 | ␉"RAM",␉␉/* 16h unused */␊ |
205 | ␉"RAM",␉␉/* 17h unused */␊ |
206 | ␉"DDR3",␉␉/* 18h DDR3, chosen in [5776134] */␊ |
207 | ␉"FBD2"␉␉/* 19h FBD2 */␊ |
208 | };␊ |
209 | ␊ |
210 | static const int kSMBMemoryDeviceTypeCount = sizeof(SMBMemoryDeviceTypes) /␊ |
211 | sizeof(SMBMemoryDeviceTypes[0]);␊ |
212 | ␊ |
213 | //-------------------------------------------------------------------------------------------------------------------------␊ |
214 | // BIOS Information (Type 0)␊ |
215 | //-------------------------------------------------------------------------------------------------------------------------␊ |
216 | void decodeBIOSInformation(SMBBIOSInformation *structHeader)␊ |
217 | {␊ |
218 | ␉DBG("BIOS Information:\n");␊ |
219 | ␉DBG("\tVendor: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->vendor, neverMask));␊ |
220 | ␉DBG("\tVersion: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->version, neverMask));␊ |
221 | ␉// Address Segment␊ |
222 | ␉DBG("\tRelease Date: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->releaseDate, neverMask));␊ |
223 | ␉DBG("\tBIOS Revision: %d.%d\n", structHeader->releaseMajor, structHeader->releaseMinor);␊ |
224 | ␉// ROM Size␊ |
225 | ␉//DBG("\tSupported BIOS functions: (0x%llX) %s\n", structHeader->characteristics, SMBBIOSInfoChar0[structHeader->characteristics]);␊ |
226 | ␉// Major Release␊ |
227 | ␉// Minor Release␊ |
228 | ␉// Firmware Major Release␊ |
229 | ␉// Firmware Minor Release␊ |
230 | ␉//SMBByte characteristicsExt1;␊ |
231 | ␉//SMBByte characteristicsExt2;␊ |
232 | ␉DBG("\n");␊ |
233 | }␊ |
234 | ␊ |
235 | //-------------------------------------------------------------------------------------------------------------------------␊ |
236 | // System Information (Type 1)␊ |
237 | //-------------------------------------------------------------------------------------------------------------------------␊ |
238 | void decodeSystemInformation(SMBSystemInformation *structHeader)␊ |
239 | {␊ |
240 | ␉DBG("System Information:\n");␊ |
241 | ␉if (structHeader->header.length < 0x08) {␊ |
242 | ␉␉return;␊ |
243 | ␉}␊ |
244 | ␊ |
245 | ␉DBG("\tManufacturer: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer, neverMask));␊ |
246 | ␉DBG("\tProduct Name: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->productName, neverMask));␊ |
247 | ␉DBG("\tVersion: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->version, neverMask));␊ |
248 | ␉DBG("\tSerial Number: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber, privateData));␊ |
249 | ␊ |
250 | ␉if (minorVersion < 0x01 || structHeader->header.length < 0x19) {␊ |
251 | ␉␉return;␊ |
252 | ␉}␊ |
253 | ␊ |
254 | ␉uint8_t *uuid = structHeader->uuid;␊ |
255 | ␉if (uuid) {␊ |
256 | ␉␉if (privateData) {␊ |
257 | ␉␉␉DBG("\tUUID: %s\n", PrivateStr);␊ |
258 | ␉␉} else {␊ |
259 | ␉␉␉DBG("\tUUID: %02X%02X%02X%02X-%02X%02X-%02X%02X-%02x%02X-%02X%02X%02X%02X%02X%02X\n",␊ |
260 | ␉␉␉␉uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],␊ |
261 | ␉␉␉␉uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);␊ |
262 | ␉␉}␊ |
263 | ␉}␊ |
264 | ␊ |
265 | ␉if (structHeader->wakeupReason > 8) {␊ |
266 | ␉␉DBG("\tWake-up Type: %s\n", out_of_spec);␊ |
267 | ␉} else {␊ |
268 | ␉␉DBG("\tWake-up Type: %s\n", SMBWakeUpTypes[structHeader->wakeupReason]);␊ |
269 | ␉}␊ |
270 | ␉if (minorVersion < 0x04 || structHeader->header.length < 0x1B) {␊ |
271 | ␉␉return;␊ |
272 | ␉}␊ |
273 | ␊ |
274 | ␉DBG("\tSKU Number: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->skuNumber, neverMask)); // System SKU#␊ |
275 | ␉DBG("\tFamily: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->family, neverMask));␊ |
276 | ␉DBG("\n");␊ |
277 | }␊ |
278 | ␊ |
279 | //-------------------------------------------------------------------------------------------------------------------------␊ |
280 | // Base Board (or Module) Information (Type 2)␊ |
281 | //-------------------------------------------------------------------------------------------------------------------------␊ |
282 | void decodeBaseBoard(SMBBaseBoard *structHeader)␊ |
283 | {␊ |
284 | ␉DBG("Base Board Information:\n");␊ |
285 | ␉if (structHeader->header.length < 0x08) {␊ |
286 | ␉␉return;␊ |
287 | ␉}␊ |
288 | ␉DBG("\tManufacturer: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer, neverMask));␊ |
289 | ␉DBG("\tProduct Name: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->product, neverMask));␊ |
290 | ␉DBG("\tVersion: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->version, neverMask));␊ |
291 | ␉DBG("\tSerial Number: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber, privateData));␊ |
292 | ␉DBG("\tAsset Tag: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTag, neverMask));␊ |
293 | ␉// Feature Flags (BYTE)␊ |
294 | ␉DBG("\tLocation In Chassis: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->locationInChassis, neverMask)); // Part Component␊ |
295 | ␉// Chassis Handle (WORD)␊ |
296 | ␉if ((structHeader->boardType < kSMBBaseBoardUnknown) || (structHeader->boardType > kSMBBaseBoardInterconnect)) {␊ |
297 | ␉␉DBG("\tType: %s\n", out_of_spec);␊ |
298 | ␉} else {␊ |
299 | ␉␉DBG("\tType: %s\n", SMBBaseBoardTypes[(structHeader->boardType - 1)]);␊ |
300 | ␉}␊ |
301 | ␉// Number of Contained Object Handles (n) (BYTE)␊ |
302 | ␉// Contained Object Handles n(WORDs)␊ |
303 | ␉DBG("\n");␊ |
304 | }␊ |
305 | ␊ |
306 | //-------------------------------------------------------------------------------------------------------------------------␊ |
307 | // System Enclosure or Chassis (Type 3)␊ |
308 | //-------------------------------------------------------------------------------------------------------------------------␊ |
309 | void decodeSystemEnclosure(SMBSystemEnclosure *structHeader)␊ |
310 | {␊ |
311 | ␉DBG("Chassis Information:\n");␊ |
312 | ␉if (structHeader->header.length < 0x09) {␊ |
313 | ␉␉return;␊ |
314 | ␉}␊ |
315 | ␉DBG("\tManufacturer: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer, neverMask));␊ |
316 | ␉// DBG("\tType: 0x%X\n", structHeader->chassisType);␊ |
317 | ␉if ((structHeader->chassisType < kSMBchassisOther) || (structHeader->chassisType > kSMBchassisBladeEnclosing)) {␊ |
318 | ␉␉DBG("\tType: %s\n", out_of_spec);␊ |
319 | ␉} else {␊ |
320 | ␉␉DBG("\tType: %s\n", SMBChassisTypes[(structHeader->chassisType - 1)]);␊ |
321 | ␉}␊ |
322 | ␉DBG("\tVersion: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->version, neverMask));␊ |
323 | ␉DBG("\tSerial Number: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber, privateData));␊ |
324 | ␉DBG("\tAsset Tag: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTag, neverMask));␊ |
325 | ␉// Boot-up State:␊ |
326 | ␉// Power Supply State␊ |
327 | ␉// Thermal State␊ |
328 | ␉// Security Status:␊ |
329 | ␉// OEM Information:␊ |
330 | ␉// Height;␊ |
331 | ␉// Cords;␊ |
332 | ␉// ElementsCount;␊ |
333 | ␉// ElementLen;␊ |
334 | ␉// Elements[1]; // open array of ElementsCount*ElementLen BYTEs␊ |
335 | ␉DBG("\n");␊ |
336 | }␊ |
337 | ␊ |
338 | //-------------------------------------------------------------------------------------------------------------------------␊ |
339 | // Processor Information (Type 4)␊ |
340 | //-------------------------------------------------------------------------------------------------------------------------␊ |
341 | void decodeProcessorInformation(SMBProcessorInformation *structHeader)␊ |
342 | {␊ |
343 | ␉DBG("Processor Information:\n");␊ |
344 | ␉if (structHeader->header.length < 0x1A) {␊ |
345 | ␉␉return;␊ |
346 | ␉}␊ |
347 | ␉DBG("\tSocket Designation: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->socketDesignation, neverMask));␊ |
348 | ␉DBG("\tType: %d\n", structHeader->processorType);␊ |
349 | ␉DBG("\tFamily: 0x%X\n", structHeader->processorFamily);␊ |
350 | ␉DBG("\tManufacturer: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer, neverMask));␊ |
351 | ␉DBG("\tID: 0x%llX\n", structHeader->processorID);␊ |
352 | ␉DBG("\tProcessor Version: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->processorVersion, neverMask));␊ |
353 | //␉DBG("\tVoltage: 0.%xV\n", structHeader->voltage);␊ |
354 | ␉DBG("\tExternal Clock: %dMHz\n", structHeader->externalClock);␊ |
355 | ␉DBG("\tMaximum Clock: %dMHz\n", structHeader->maximumClock);␊ |
356 | ␉DBG("\tCurrent Clock: %dMHz\n", structHeader->currentClock);␊ |
357 | ␊ |
358 | ␉if (minorVersion < 0x03 || structHeader->header.length < 0x23) {␊ |
359 | ␉␉return;␊ |
360 | ␉}␊ |
361 | ␊ |
362 | ␉DBG("\tSerial Number: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber, privateData)); // 20␊ |
363 | ␉DBG("\tAsset Tag: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTag, neverMask)); // 21␊ |
364 | ␉DBG("\tPart Number: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->partNumber, neverMask)); // 22␊ |
365 | ␉DBG("\tCore Count: %d\n", structHeader->coreCount); // 23␊ |
366 | ␉DBG("\tCore Enabled: %d\n", structHeader->coreEnabled); // 24␊ |
367 | ␉DBG("\tThread Count: %d\n", structHeader->threadCount); // 25␊ |
368 | //␉DBG("\tProcessor Family 2: %d\n", structHeader->processorFamily2); //26␊ |
369 | ␉DBG("\n");␊ |
370 | }␊ |
371 | ␊ |
372 | //-------------------------------------------------------------------------------------------------------------------------␊ |
373 | // Memory Module Information (Type 6)␊ |
374 | //-------------------------------------------------------------------------------------------------------------------------␊ |
375 | //void decodeMemoryModule(SMBMemoryModule *structHeader)␊ |
376 | //{␊ |
377 | //␉DBG("Memory Module Information:\n");␊ |
378 | //␉if (structHeader->header.length < 0x0C) {␊ |
379 | //␉ return;␊ |
380 | //␉}␊ |
381 | //␉DBG("\tSocket Designation: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->socketDesignation));␊ |
382 | //␉DBG("\tBank Connections: Type: %d\n", structHeader->bankConnections);␊ |
383 | //␉DBG("\tCurrent Speed: %X\n", structHeader->currentSpeed);␊ |
384 | //␉DBG("\tCurrent Memory Type: %llX\n", structHeader->currentMemoryType);␊ |
385 | //␉DBG("\tInstalled Size: %d\n", structHeader->installedSize);␊ |
386 | //␉DBG("\tEnabled Size: %d\n", structHeader->enabledSize);␊ |
387 | //␉DBG("\tError Status: %x\n", structHeader->errorStatus);␊ |
388 | //␉DBG("\n");␊ |
389 | //}␊ |
390 | ␊ |
391 | //-------------------------------------------------------------------------------------------------------------------------␊ |
392 | // OEM Strings (Type 11)␊ |
393 | //-------------------------------------------------------------------------------------------------------------------------␊ |
394 | //void decodeSMBOEMStrings(SMBOEMStrings *structHeader)␊ |
395 | //{␊ |
396 | //␉DBG("OEM Strings:\n");␊ |
397 | //␉if (structHeader->header.length < 0x05) {␊ |
398 | //␉␉return;␊ |
399 | //␉}␊ |
400 | //␉DBG("\tString 1: %d\n"); //, structHeader->string1);␊ |
401 | //␉DBG("\tString 2: %d\n"); //, structHeader->string1);␊ |
402 | //␉DBG("\tString 3: %d\n"); //, structHeader->string1);␊ |
403 | //␉DBG("\n");␊ |
404 | //}␊ |
405 | ␊ |
406 | //-------------------------------------------------------------------------------------------------------------------------␊ |
407 | // MemoryDevice (Type 17)␊ |
408 | //-------------------------------------------------------------------------------------------------------------------------␊ |
409 | void decodeMemoryDevice(SMBMemoryDevice *structHeader)␊ |
410 | {␊ |
411 | ␉DBG("Memory Device:\n");␊ |
412 | ␉if (structHeader->header.length < 0x15) {␊ |
413 | ␉␉return;␊ |
414 | ␉}␊ |
415 | ␉DBG("\tDevice Locator: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->deviceLocator, neverMask));␊ |
416 | ␉DBG("\tBank Locator: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->bankLocator, neverMask));␊ |
417 | ␉if (structHeader->memoryType > kSMBMemoryDeviceTypeCount) {␊ |
418 | ␉␉DBG("\tMemory Type: %s\n", out_of_spec);␊ |
419 | ␉} else {␊ |
420 | ␉␉DBG("\tMemory Type: %s\n", SMBMemoryDeviceTypes[structHeader->memoryType]);␊ |
421 | ␉}␊ |
422 | ␉if (minorVersion < 0x03 || structHeader->header.length < 0x1B) {␊ |
423 | ␉␉return;␊ |
424 | ␉}␊ |
425 | ␉DBG("\tSpeed: %d MHz\n", structHeader->memorySpeed);␊ |
426 | ␉DBG("\tError Handle: %x\n", structHeader->errorHandle);␊ |
427 | ␉DBG("\tManufacturer: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer, neverMask));␊ |
428 | ␉DBG("\tSerial Number: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber, privateData));␊ |
429 | ␉DBG("\tAsset Tag: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTag, neverMask));␊ |
430 | ␉DBG("\tPart Number: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->partNumber, neverMask));␊ |
431 | ␉DBG("\n");␊ |
432 | }␊ |
433 | ␊ |
434 | //-------------------------------------------------------------------------------------------------------------------------␊ |
435 | // Apple Specific␊ |
436 | //-------------------------------------------------------------------------------------------------------------------------␊ |
437 | void decodeOemProcessorType(SMBOemProcessorType *structHeader)␊ |
438 | {␊ |
439 | ␉DBG("Apple specific Processor Type:\n");␊ |
440 | ␉DBG("\tCpu-type: 0x%x\n", ((SMBOemProcessorType *)structHeader)->ProcessorType);␊ |
441 | ␉DBG("\n");␊ |
442 | }␊ |
443 | ␊ |
444 | void decodeOemProcessorBusSpeed(SMBOemProcessorBusSpeed *structHeader)␊ |
445 | {␊ |
446 | ␉DBG("Apple specific Processor Interconnect Speed:\n");␊ |
447 | ␉DBG("\tQPI = %d.%dGT/s\n",␊ |
448 | ␉␉␉((SMBOemProcessorBusSpeed *)structHeader)->ProcessorBusSpeed / 1000, ␊ |
449 | ␉␉␉(((SMBOemProcessorBusSpeed *)structHeader)->ProcessorBusSpeed / 100) % 10);␊ |
450 | ␉DBG("\n");␊ |
451 | }␊ |
452 | //-------------------------------------------------------------------------------------------------------------------------␊ |
453 | ␊ |
454 | ␊ |
455 | void decodeSMBIOSTable(SMBEntryPoint *eps)␊ |
456 | {␊ |
457 | ␉uint8_t *ptr = (uint8_t *)eps->dmi.tableAddress;␊ |
458 | ␉SMBStructHeader *structHeader = (SMBStructHeader *)ptr;␊ |
459 | ␊ |
460 | ␉minorVersion = eps->minorVersion;␊ |
461 | ␉majorVersion = eps->majorVersion;␊ |
462 | ␉bcdRevisionHi = eps->dmi.bcdRevision >> 4;␊ |
463 | ␉bcdRevisionLo = eps->dmi.bcdRevision & 0x0F;␊ |
464 | ␊ |
465 | ␉getBoolForKey(kPrivateData, &privateData, &bootInfo->chameleonConfig); // Bungo: chek if mask some data␊ |
466 | ␊ |
467 | ␉DBG("\n");␊ |
468 | ␉DBG("SMBIOS rev. %d.%d, DMI rev. %d.%d\n", majorVersion, minorVersion, bcdRevisionHi, bcdRevisionLo);␊ |
469 | ␉DBG("\n");␊ |
470 | ␉for (;((eps->dmi.tableAddress + eps->dmi.tableLength) > ((uint32_t)(uint8_t *)structHeader + sizeof(SMBStructHeader)));)␊ |
471 | ␉{␊ |
472 | ␉␉DBG("Type: %d, Length: %d, Handle: 0x%04x\n", ␊ |
473 | ␉␉␉␉structHeader->type, structHeader->length, structHeader->handle);␊ |
474 | ␊ |
475 | ␉␉switch (structHeader->type)␊ |
476 | ␉␉{␊ |
477 | ␉␉␉case kSMBTypeBIOSInformation: // Type 0␊ |
478 | ␉␉␉␉decodeBIOSInformation((SMBBIOSInformation *)structHeader);␊ |
479 | ␉␉␉␉break;␊ |
480 | ␊ |
481 | ␉␉␉case kSMBTypeSystemInformation: // Type 1␊ |
482 | ␉␉␉␉decodeSystemInformation((SMBSystemInformation *)structHeader);␊ |
483 | ␉␉␉␉break;␊ |
484 | ␊ |
485 | ␉␉␉case kSMBTypeBaseBoard: // Type 2␊ |
486 | ␉␉␉␉decodeBaseBoard((SMBBaseBoard *)structHeader);␊ |
487 | ␉␉␉␉break;␊ |
488 | ␊ |
489 | ␉␉␉case kSMBTypeSystemEnclosure: // Type 3␊ |
490 | ␉␉␉␉decodeSystemEnclosure((SMBSystemEnclosure *)structHeader);␊ |
491 | ␉␉␉␉break;␊ |
492 | ␊ |
493 | ␉␉␉case kSMBTypeProcessorInformation: // Type 4␊ |
494 | ␉␉␉␉decodeProcessorInformation((SMBProcessorInformation *)structHeader);␊ |
495 | ␉␉␉␉break;␊ |
496 | ␊ |
497 | ␉␉␉//case 6: // kSMBTypeMemoryModule: // Type 6␊ |
498 | ␉␉␉//␉decodeMemoryModule((SMBMemoryModule *)structHeader);␊ |
499 | ␉␉␉//␉break;␊ |
500 | ␊ |
501 | ␉␉␉//case 11: // kSMBOEMStrings: // Type 11␊ |
502 | ␉␉␉//␉decodeSMBOEMStrings((SMBOEMStrings *)structHeader);␊ |
503 | ␉␉␉//␉break;␊ |
504 | ␊ |
505 | ␉␉␉case kSMBTypeMemoryDevice: // Type 17␊ |
506 | ␉␉␉␉decodeMemoryDevice((SMBMemoryDevice *)structHeader);␊ |
507 | ␉␉␉␉break;␊ |
508 | ␊ |
509 | ␉␉␉//kSMBTypeMemoryArrayMappedAddress: // Type 19␊ |
510 | ␊ |
511 | ␉␉␉/* Skip all Apple Specific Structures */␊ |
512 | ␉␉␉case kSMBTypeFirmwareVolume: // Type 128␊ |
513 | ␉␉␉case kSMBTypeMemorySPD: // Type 130␊ |
514 | ␉␉␉␉break;␊ |
515 | ␊ |
516 | ␉␉␉case kSMBTypeOemProcessorType: // Type 131␊ |
517 | ␉␉␉␉decodeOemProcessorType((SMBOemProcessorType *)structHeader);␊ |
518 | ␉␉␉␉break;␊ |
519 | ␊ |
520 | ␉␉␉case kSMBTypeOemProcessorBusSpeed: // Type 132␊ |
521 | ␉␉␉␉decodeOemProcessorBusSpeed((SMBOemProcessorBusSpeed *)structHeader);␊ |
522 | ␉␉␉␉break;␊ |
523 | ␊ |
524 | ␉␉␉//kSMBTypeOemPlatformFeature: // Type 133␊ |
525 | ␊ |
526 | ␉␉␉case kSMBTypeEndOfTable: // Type 127␊ |
527 | ␉␉␉␉/* Skip, to be added at the end */␊ |
528 | ␉␉␉␉break;␊ |
529 | ␊ |
530 | ␉␉␉default:␊ |
531 | ␉␉␉␉break;␊ |
532 | ␉␉}␊ |
533 | ␊ |
534 | ␉␉ptr = (uint8_t *)((uint32_t)structHeader + structHeader->length);␊ |
535 | ␉␉for (; ((uint16_t *)ptr)[0] != 0; ptr++);␊ |
536 | ␊ |
537 | ␉␉if (((uint16_t *)ptr)[0] == 0) {␊ |
538 | ␉␉␉ptr += 2;␊ |
539 | ␉␉}␊ |
540 | ␊ |
541 | ␉␉structHeader = (SMBStructHeader *)ptr;␊ |
542 | ␉}␊ |
543 | ␉DBG("\n");␊ |
544 | }␊ |
545 | ␊ |
546 | |