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 "config.h"␊ |
9 | #include "libsaio.h"␊ |
10 | #include "smbios.h"␊ |
11 | // Bungo:␊ |
12 | #include "boot.h"␊ |
13 | #include "bootstruct.h"␊ |
14 | ␊ |
15 | #if DEBUG_SMBIOS␊ |
16 | ␉#define DBG(x...)␉printf(x)␊ |
17 | #else␊ |
18 | ␉#define DBG(x...)␉msglog(x)␊ |
19 | #endif␊ |
20 | ␊ |
21 | extern char *getSMBStringForField(SMBStructHeader *structHeader, uint8_t field);␊ |
22 | // Bungo:␊ |
23 | #define NotSpecifiedStr "Not Specified" // no string␊ |
24 | #define OutOfSpecStr "<OUT OF SPEC>" // value out of smbios spec. range␊ |
25 | #define PrivateStr "** PRIVATE **" // masking private data␊ |
26 | #define neverMask false␊ |
27 | ␊ |
28 | static bool privateData = true;␊ |
29 | static SMBByte minorVersion; // SMBIOS rev. minor␊ |
30 | static SMBByte majorVersion; // SMBIOS rev. major␊ |
31 | static SMBByte bcdRevisionLo; // DMI rev. minor␊ |
32 | static SMBByte bcdRevisionHi; // DMI rev. major␊ |
33 | ␊ |
34 | /*====␊ |
35 | 7.2.2␊ |
36 | ===*/␊ |
37 | static const char *SMBWakeUpTypes[] = // Bungo: strings for wake-up type (Table Type 1 - System Information)␊ |
38 | {␊ |
39 | ␉"Reserved", /* 00h */␊ |
40 | ␉"Other", /* 01h */␊ |
41 | ␉"Unknown", /* 02h */␊ |
42 | ␉"APM Timer", /* 03h */␊ |
43 | ␉"Modem Ring", /* 04h */␊ |
44 | ␉"LAN Remote", /* 05h */␊ |
45 | ␉"Power Switch", /* 06h */␊ |
46 | ␉"PCI PME#", /* 07h */␊ |
47 | ␉"AC Power Restored" /* 08h */␊ |
48 | };␊ |
49 | ␊ |
50 | /*====␊ |
51 | 7.3.2␊ |
52 | ===*/␊ |
53 | static const char *SMBBaseBoardTypes[] = // Bungo: strings for base board type (Table Type 2 - Base Board Information)␊ |
54 | {␊ |
55 | ␉"Unknown", /* 01h */␊ |
56 | ␉"Other", /* 02h */␊ |
57 | ␉"Server Blade", /* 03h */␊ |
58 | ␉"Connectivity Switch", /* 04h */␊ |
59 | ␉"System Management Module", /* 05h */␊ |
60 | ␉"Processor Module", /* 06h */␊ |
61 | ␉"I/O Module", /* 07h */␊ |
62 | ␉"Memory Module", /* 08h */␊ |
63 | ␉"Daughter Board", /* 09h */␊ |
64 | ␉"Motherboard", /* 0Ah */␊ |
65 | ␉"Processor+Memory Module", /* 0Bh */␊ |
66 | ␉"Processor+I/O Module", /* 0Ch */␊ |
67 | ␉"Interconnect Board" /* 0Dh */␊ |
68 | };␊ |
69 | ␊ |
70 | /*===␊ |
71 | 7.4.1␊ |
72 | ===*/␊ |
73 | static const char *SMBChassisTypes[] = // Bungo: strings for chassis type (Table Type 3 - Chassis Information)␊ |
74 | {␊ |
75 | ␉"Other", /* 01h */␊ |
76 | ␉"Unknown", /* 02h */␊ |
77 | ␉"Desktop", /* 03h */␊ |
78 | ␉"Low Profile Desktop", /* 04h */␊ |
79 | ␉"Pizza Box", /* 05h */␊ |
80 | ␉"Mini Tower", /* 06h */␊ |
81 | ␉"Tower", /* 07h */␊ |
82 | ␉"Portable", /* 08h */␊ |
83 | ␉"Laptop", /* 09h */␊ |
84 | ␉"Notebook", /* 0Ah */␊ |
85 | ␉"Hand Held", /* 0Bh */␊ |
86 | ␉"Docking Station", /* 0Ch */␊ |
87 | ␉"All in One", /* 0Dh */␊ |
88 | ␉"Sub Notebook", /* 0Eh */␊ |
89 | ␉"Space-saving", /* 0Fh */␊ |
90 | ␉"Lunch Box",␉␉/* 10h */␊ |
91 | ␉"Main Server Chassis",␉/* 11h */ /* CIM_Chassis.ChassisPackageType says "Main System Chassis" */␊ |
92 | ␉"Expansion Chassis",␉/* 12h */␊ |
93 | ␉"SubChassis",␉␉/* 13h */␊ |
94 | ␉"Bus Expansion Chassis",/* 14h */␊ |
95 | ␉"Peripheral Chassis",␉/* 15h */␊ |
96 | ␉"RAID Chassis",␉␉/* 16h */␊ |
97 | ␉"Rack Mount Chassis", /* 17h */␊ |
98 | ␉"Sealed-case PC",␉/* 18h */␊ |
99 | ␉"Multi-system Chassis", /* 19h */␊ |
100 | ␉"Compact PCI",␉␉/* 1Ah */␊ |
101 | ␉"Advanced TCA",␉␉/* 1Bh */␊ |
102 | ␉"Blade",␉␉/* 1Ch */ // An SMBIOS implementation for a Blade would contain a Type 3 Chassis structure␊ |
103 | ␉"Blade Enclosing",␉/* 1Dh */ // A Blade Enclosure is a specialized chassis that contains a set of Blades.␊ |
104 | ␉"Tablet",␉␉/* 1Eh */␊ |
105 | ␉"Convertible",␉␉/* 1Fh */␊ |
106 | ␉"Detachable"␉␉/* 0x20h */␊ |
107 | };␊ |
108 | ␊ |
109 | /*====␊ |
110 | 7.5.1␊ |
111 | ===*/␊ |
112 | static const char *SMBProcessorTypes[] = // Bungo: strings for processor type (Table Type 4 - Processor Information)␊ |
113 | {␊ |
114 | ␉"Other", /* 01h */␊ |
115 | ␉"Unknown", /* 02h */␊ |
116 | ␉"Central Processor", /* 03h */␊ |
117 | ␉"Math Processor", /* 04h */␊ |
118 | ␉"DSP Processor", /* 05h */␊ |
119 | ␉"Video Processor" /* 06h */␊ |
120 | };␊ |
121 | ␊ |
122 | /*====␊ |
123 | 7.5.5␊ |
124 | ===*/␊ |
125 | static const char *SMBProcessorUpgrades[] = // ErmaC: strings for processor upgrade (Table Type 4 - Processor Information)␊ |
126 | {␊ |
127 | ␉"Other", /* 01h */␊ |
128 | ␉"Unknown", /* 02h */␊ |
129 | ␉"Daughter Board",␊ |
130 | ␉"ZIF Socket",␊ |
131 | ␉"Replaceable Piggy Back",␊ |
132 | ␉"None",␊ |
133 | ␉"LIF Socket",␊ |
134 | ␉"Slot 1",␊ |
135 | ␉"Slot 2",␊ |
136 | ␉"370-pin Socket",␊ |
137 | ␉"Slot A",␊ |
138 | ␉"Slot M",␊ |
139 | ␉"Socket 423",␊ |
140 | ␉"Socket A (Socket 462)",␊ |
141 | ␉"Socket 478",␊ |
142 | ␉"Socket 754",␊ |
143 | ␉"Socket 940",␊ |
144 | ␉"Socket 939",␊ |
145 | ␉"Socket mPGA604",␊ |
146 | ␉"Socket LGA771",␊ |
147 | ␉"Socket LGA775",␊ |
148 | ␉"Socket S1",␊ |
149 | ␉"Socket AM2",␊ |
150 | ␉"Socket F (1207)",␊ |
151 | ␉"Socket LGA1366",␊ |
152 | ␉"Socket G34",␊ |
153 | ␉"Socket AM3",␊ |
154 | ␉"Socket C32",␊ |
155 | ␉"Socket LGA1156",␊ |
156 | ␉"Socket LGA1567",␊ |
157 | ␉"Socket PGA988A",␊ |
158 | ␉"Socket BGA1288",␊ |
159 | ␉"Socket rPGA988B",␊ |
160 | ␉"Socket BGA1023",␊ |
161 | ␉"Socket BGA1224",␊ |
162 | ␉"Socket BGA1155",␊ |
163 | ␉"Socket LGA1356",␊ |
164 | ␉"Socket LGA2011",␊ |
165 | ␉"Socket FS1",␊ |
166 | ␉"Socket FS2",␊ |
167 | ␉"Socket FM1",␊ |
168 | ␉"Socket FM2",␊ |
169 | ␉"Socket LGA2011-3",␊ |
170 | ␉"Socket LGA1356-3", /* 2Ch */␊ |
171 | ␉"Socket LGA1150",␊ |
172 | ␉"Socket BGA1168",␊ |
173 | ␉"Socket BGA1234",␊ |
174 | ␉"Socket BGA1364" /* 0x30h */␊ |
175 | };␊ |
176 | ␊ |
177 | static const char *SMBMemoryDeviceFormFactors[] = // Bungo: strings for form factor (Table Type 17 - Memory Device)␊ |
178 | {␊ |
179 | ␉"Other", /* 01h */␊ |
180 | ␉"Unknown", /* 02h */␊ |
181 | ␉"SIMM", /* 03h */␊ |
182 | ␉"SIP", /* 04h */␊ |
183 | ␉"Chip", /* 05h */␊ |
184 | ␉"DIP", /* 06h */␊ |
185 | ␉"ZIP", /* 07h */␊ |
186 | ␉"Proprietary Card", /* 08h */␊ |
187 | ␉"DIMM", /* 09h */␊ |
188 | ␉"TSOP", /* 0Ah */␊ |
189 | ␉"Row of chips", /* 0Bh */␊ |
190 | ␉"RIMM", /* 0Ch */␊ |
191 | ␉"SODIMM", /* 0Dh */␊ |
192 | ␉"SRIMM", /* 0Eh */␊ |
193 | ␉"FB-DIMM" /* 0Fh */␊ |
194 | };␊ |
195 | ␊ |
196 | /*=====␊ |
197 | 7.18.2␊ |
198 | ====*/␊ |
199 | static const char *SMBMemoryDeviceTypes[] =␊ |
200 | {␊ |
201 | ␉"RAM", /* 00h Undefined */␊ |
202 | ␉"RAM", /* 01h Other */␊ |
203 | ␉"RAM", /* 02h Unknown */␊ |
204 | ␉"DRAM", /* 03h DRAM */␊ |
205 | ␉"EDRAM", /* 04h EDRAM */␊ |
206 | ␉"VRAM", /* 05h VRAM */␊ |
207 | ␉"SRAM", /* 06h SRAM */␊ |
208 | ␉"RAM", /* 07h RAM */␊ |
209 | ␉"ROM", /* 08h ROM */␊ |
210 | ␉"FLASH", /* 09h FLASH */␊ |
211 | ␉"EEPROM", /* 0Ah EEPROM */␊ |
212 | ␉"FEPROM", /* 0Bh FEPROM */␊ |
213 | ␉"EPROM", /* 0Ch EPROM */␊ |
214 | ␉"CDRAM", /* 0Dh CDRAM */␊ |
215 | ␉"3DRAM", /* 0Eh 3DRAM */␊ |
216 | ␉"SDRAM", /* 0Fh SDRAM */␊ |
217 | ␉"SGRAM", /* 10h SGRAM */␊ |
218 | ␉"RDRAM", /* 11h RDRAM */␊ |
219 | ␉"DDR SDRAM", /* 12h DDR */␊ |
220 | ␉"DDR2 SDRAM", /* 13h DDR2 */␊ |
221 | ␉"DDR2 FB-DIMM", /* 14h DDR2 FB-DIMM */␊ |
222 | ␉"RAM",␉␉/* 15h unused */␊ |
223 | ␉"RAM",␉␉/* 16h unused */␊ |
224 | ␉"RAM",␉␉/* 17h unused */␊ |
225 | ␉"DDR3",␉␉/* 18h DDR3, chosen in [5776134] */␊ |
226 | ␉"FBD2",␉␉/* 19h FBD2 */␊ |
227 | ␉"DDR4",␉␉/* 1Ah DDR4 */␊ |
228 | ␉"LPDDR",␉/* 1Bh LPDDR */␊ |
229 | ␉"LPDDR2",␉/* 1Ch LPDDR2 */␊ |
230 | ␉"LPDDR3",␉/* 1Dh LPDDR3 */␊ |
231 | ␉"LPDDR4"␉/* 1Eh LPDDR5 */␊ |
232 | };␊ |
233 | ␊ |
234 | static const int kSMBMemoryDeviceTypeCount = sizeof(SMBMemoryDeviceTypes) / sizeof(SMBMemoryDeviceTypes[0]);␊ |
235 | ␊ |
236 | // Bungo: fixes random string readout if null in smbios to "Not Specified" as dmidecode displays␊ |
237 | char *SMBStringForField(SMBStructHeader *structHeader, uint8_t field, const bool mask)␊ |
238 | {␊ |
239 | ␉char *str = NULL;␊ |
240 | ␉str = getSMBStringForField(structHeader, field);␊ |
241 | ␉if (!field)␊ |
242 | ␉{␊ |
243 | ␉␉str = NotSpecifiedStr;␊ |
244 | ␉}␊ |
245 | ␉else if (mask)␊ |
246 | ␉{␊ |
247 | ␉␉str = PrivateStr;␊ |
248 | ␉}␊ |
249 | ␊ |
250 | ␉return str;␊ |
251 | }␊ |
252 | ␊ |
253 | void printHeader(SMBStructHeader *structHeader)␊ |
254 | {␊ |
255 | ␉DBG("Handle: 0x%04X, DMI type %d, %d bytes\n", structHeader->handle, structHeader->type, structHeader->length);␊ |
256 | }␊ |
257 | ␊ |
258 | //-------------------------------------------------------------------------------------------------------------------------␊ |
259 | // BIOS Information (Type 0)␊ |
260 | //-------------------------------------------------------------------------------------------------------------------------␊ |
261 | void decodeBIOSInformation(SMBStructHeader *structHeader)␊ |
262 | {␊ |
263 | ␉printHeader(structHeader);␊ |
264 | ␉DBG("BIOS Information\n");␊ |
265 | ␉DBG("\tVendor: %s\n", SMBStringForField(structHeader, ((SMBBIOSInformation *)structHeader)->vendor, neverMask));␊ |
266 | ␉DBG("\tVersion: %s\n", SMBStringForField(structHeader, ((SMBBIOSInformation *)structHeader)->version, neverMask));␊ |
267 | ␉DBG("\tRelease Date: %s\n", SMBStringForField(structHeader, ((SMBBIOSInformation *)structHeader)->releaseDate, neverMask));␊ |
268 | // Address:␊ |
269 | // Runtime Size:␊ |
270 | // ROM Size:␊ |
271 | // DBG("\tSupported BIOS functions: (0x%llX) %s\n", ((SMBBIOSInformation *)structHeader)->characteristics, SMBBIOSInfoChar0[((SMBBIOSInformation *)structHeader)->characteristics]);␊ |
272 | ␉DBG("\tBIOS Revision: %d.%d\n", ((SMBBIOSInformation *)structHeader)->releaseMajor, ((SMBBIOSInformation *)structHeader)->releaseMinor);␊ |
273 | // Firmware Major Release␊ |
274 | // Firmware Minor Release␊ |
275 | // SMBByte characteristicsExt1;␊ |
276 | // SMBByte characteristicsExt2;␊ |
277 | ␉DBG("\n");␊ |
278 | }␊ |
279 | ␊ |
280 | //-------------------------------------------------------------------------------------------------------------------------␊ |
281 | // System Information (Type 1)␊ |
282 | //-------------------------------------------------------------------------------------------------------------------------␊ |
283 | void decodeSystemInformation(SMBStructHeader *structHeader)␊ |
284 | {␊ |
285 | ␉printHeader(structHeader);␊ |
286 | ␉DBG("System Information\n");␊ |
287 | ␉DBG("\tManufacturer: %s\n", SMBStringForField(structHeader, ((SMBSystemInformation *)structHeader)->manufacturer, neverMask));␊ |
288 | ␉DBG("\tProduct Name: %s\n", SMBStringForField(structHeader, ((SMBSystemInformation *)structHeader)->productName, neverMask));␊ |
289 | ␉DBG("\tVersion: %s\n", SMBStringForField(structHeader, ((SMBSystemInformation *)structHeader)->version, neverMask));␊ |
290 | ␉DBG("\tSerial Number: %s\n", SMBStringForField(structHeader, ((SMBSystemInformation *)structHeader)->serialNumber, privateData));␊ |
291 | ␉uint8_t *uuid = ((SMBSystemInformation *)structHeader)->uuid;␊ |
292 | ␉if (privateData) {␊ |
293 | ␉␉DBG("\tUUID: %s\n", PrivateStr);␊ |
294 | ␉} else {␊ |
295 | ␉␉DBG("\tUUID: %02X%02X%02X%02X-%02X%02X-%02X%02X-%02x%02X-%02X%02X%02X%02X%02X%02X\n",␊ |
296 | ␉␉␉uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],␊ |
297 | ␉␉␉uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);␊ |
298 | ␉}␊ |
299 | ␉if (((SMBSystemInformation *)structHeader)->wakeupReason > 8) {␊ |
300 | ␉␉DBG("\tWake-up Type: %s\n", OutOfSpecStr);␊ |
301 | ␉} else {␊ |
302 | ␉␉DBG("\tWake-up Type: %s\n", SMBWakeUpTypes[((SMBSystemInformation *)structHeader)->wakeupReason]);␊ |
303 | ␉}␊ |
304 | ␉DBG("\tSKU Number: %s\n", SMBStringForField(structHeader, ((SMBSystemInformation *)structHeader)->skuNumber, neverMask)); // System SKU#␊ |
305 | ␉DBG("\tFamily: %s\n", SMBStringForField(structHeader, ((SMBSystemInformation *)structHeader)->family, neverMask));␊ |
306 | ␉DBG("\n");␊ |
307 | }␊ |
308 | ␊ |
309 | //-------------------------------------------------------------------------------------------------------------------------␊ |
310 | // Base Board (or Module) Information (Type 2)␊ |
311 | //-------------------------------------------------------------------------------------------------------------------------␊ |
312 | void decodeBaseBoard(SMBStructHeader *structHeader)␊ |
313 | {␊ |
314 | ␉printHeader(structHeader);␊ |
315 | ␉DBG("Base Board Information\n");␊ |
316 | ␉DBG("\tManufacturer: %s\n", SMBStringForField(structHeader, ((SMBBaseBoard *)structHeader)->manufacturer, neverMask));␊ |
317 | ␉DBG("\tProduct Name: %s\n", SMBStringForField(structHeader, ((SMBBaseBoard *)structHeader)->product, neverMask));␊ |
318 | ␉DBG("\tVersion: %s\n", SMBStringForField(structHeader, ((SMBBaseBoard *)structHeader)->version, neverMask));␊ |
319 | ␉DBG("\tSerial Number: %s\n", SMBStringForField(structHeader, ((SMBBaseBoard *)structHeader)->serialNumber, privateData));␊ |
320 | ␉DBG("\tAsset Tag: %s\n", SMBStringForField(structHeader, ((SMBBaseBoard *)structHeader)->assetTag, neverMask));␊ |
321 | // Feature Flags (BYTE)␊ |
322 | ␉DBG("\tLocation In Chassis: %s\n", SMBStringForField(structHeader, ((SMBBaseBoard *)structHeader)->locationInChassis, neverMask)); // Part Component␊ |
323 | // Chassis Handle (WORD)␊ |
324 | ␉if ((((SMBBaseBoard *)structHeader)->boardType < kSMBBaseBoardUnknown) || (((SMBBaseBoard *)structHeader)->boardType > kSMBBaseBoardInterconnect)) {␊ |
325 | ␉␉DBG("\tType: %s\n", OutOfSpecStr);␊ |
326 | ␉} else {␊ |
327 | ␉␉DBG("\tType: %s\n", SMBBaseBoardTypes[(((SMBBaseBoard *)structHeader)->boardType - 1)]);␊ |
328 | ␉}␊ |
329 | // Number of Contained Object Handles (n) (BYTE)␊ |
330 | // Contained Object Handles n(WORDs)␊ |
331 | ␉DBG("\n");␊ |
332 | }␊ |
333 | ␊ |
334 | //-------------------------------------------------------------------------------------------------------------------------␊ |
335 | // System Enclosure or Chassis (Type 3)␊ |
336 | //-------------------------------------------------------------------------------------------------------------------------␊ |
337 | void decodeSystemEnclosure(SMBStructHeader *structHeader)␊ |
338 | {␊ |
339 | ␉printHeader(structHeader);␊ |
340 | ␉DBG("Chassis Information\n");␊ |
341 | ␉DBG("\tManufacturer: %s\n", SMBStringForField(structHeader, ((SMBSystemEnclosure *)structHeader)->manufacturer, neverMask));␊ |
342 | ␉if ((((SMBSystemEnclosure *)structHeader)->chassisType < kSMBChassisTypeOther) || (((SMBSystemEnclosure *)structHeader)->chassisType > kSMBChassisTypeBladeEnclosing)) {␊ |
343 | ␉␉DBG("\tType: %s\n", OutOfSpecStr);␊ |
344 | ␉} else {␊ |
345 | ␉␉DBG("\tType: %s\n", SMBChassisTypes[(((SMBSystemEnclosure *)structHeader)->chassisType - 1)]);␊ |
346 | ␉}␊ |
347 | // Lock:␊ |
348 | ␉DBG("\tVersion: %s\n", SMBStringForField(structHeader, ((SMBSystemEnclosure *)structHeader)->version, neverMask));␊ |
349 | ␉DBG("\tSerial Number: %s\n", SMBStringForField(structHeader, ((SMBSystemEnclosure *)structHeader)->serialNumber, privateData));␊ |
350 | ␉DBG("\tAsset Tag: %s\n", SMBStringForField(structHeader, ((SMBSystemEnclosure *)structHeader)->assetTag, neverMask));␊ |
351 | // Boot-up State:␊ |
352 | // Power Supply State␊ |
353 | // Thermal State␊ |
354 | // Security Status:␊ |
355 | // OEM Information:␊ |
356 | // Height;␊ |
357 | // Number Of Power Cords: Cords;␊ |
358 | // Contained Elements: ElementsCount;␊ |
359 | // SKU Number:␊ |
360 | // ElementLen;␊ |
361 | // Elements[1]; // open array of ElementsCount*ElementLen BYTEs␊ |
362 | ␉DBG("\n");␊ |
363 | }␊ |
364 | ␊ |
365 | //-------------------------------------------------------------------------------------------------------------------------␊ |
366 | // Processor Information (Type 4)␊ |
367 | //-------------------------------------------------------------------------------------------------------------------------␊ |
368 | void decodeProcessorInformation(SMBStructHeader *structHeader)␊ |
369 | {␊ |
370 | ␉printHeader(structHeader);␊ |
371 | ␉DBG("Processor Information\n");␊ |
372 | ␉DBG("\tSocket Designation: %s\n", SMBStringForField(structHeader, ((SMBProcessorInformation *)structHeader)->socketDesignation, neverMask));␊ |
373 | ␉if ((((SMBProcessorInformation *)structHeader)->processorType < kSMBProcessorTypeOther) || (((SMBProcessorInformation *)structHeader)->processorType > kSMBProcessorTypeGPU)) {␊ |
374 | ␉␉DBG("\tType: %s\n", OutOfSpecStr);␊ |
375 | ␉} else {␊ |
376 | ␉␉DBG("\tType: %s\n", SMBProcessorTypes[((SMBProcessorInformation *)structHeader)->processorType - 1]);␊ |
377 | ␉}␊ |
378 | ␉DBG("\tFamily: 0x%X\n", ((SMBProcessorInformation *)structHeader)->processorFamily);␊ |
379 | ␉DBG("\tManufacturer: %s\n", SMBStringForField(structHeader, ((SMBProcessorInformation *)structHeader)->manufacturer, neverMask));␊ |
380 | ␉DBG("\tID: 0x%llX\n", ((SMBProcessorInformation *)structHeader)->processorID);␊ |
381 | //␉DBG("\tSignature: Type %u, Family %u, Model %u, Stepping %u\n", (eax >> 12) & 0x3, ((eax >> 20) & 0xFF) + ((eax >> 8) & 0x0F), ((eax >> 12) & 0xF0) + ((eax >> 4) & 0x0F), eax & 0xF);␊ |
382 | // Flags:␊ |
383 | ␉DBG("\tVersion: %s\n", SMBStringForField(structHeader, ((SMBProcessorInformation *)structHeader)->processorVersion, neverMask));␊ |
384 | //␉DBG("\tVoltage: 0.%dV\n", ((SMBProcessorInformation *)structHeader)->voltage);␊ |
385 | ␉DBG("\tExternal Clock: %d MHz\n", ((SMBProcessorInformation *)structHeader)->externalClock);␊ |
386 | ␉DBG("\tMax Speed: %d MHz\n", ((SMBProcessorInformation *)structHeader)->maximumClock);␊ |
387 | ␉DBG("\tCurrent Speed: %d MHz\n", ((SMBProcessorInformation *)structHeader)->currentClock);␊ |
388 | // Status: Populated/Unpopulated␊ |
389 | ␉if ((((SMBProcessorInformation *)structHeader)->processorUpgrade < 1) || (((SMBProcessorInformation *)structHeader)->processorUpgrade > 0x2C))␊ |
390 | ␉{␊ |
391 | ␉␉DBG("\tUpgrade: %s\n", OutOfSpecStr);␊ |
392 | ␉}␊ |
393 | ␉else␊ |
394 | ␉{␊ |
395 | ␉␉DBG("\tUpgrade: %s\n", SMBProcessorUpgrades[((SMBProcessorInformation *)structHeader)->processorUpgrade - 1]);␊ |
396 | ␉}␊ |
397 | // L1 Cache Handle:␊ |
398 | // L2 Cache Handle:␊ |
399 | // L3 Cache Handle:␊ |
400 | ␉DBG("\tSerial Number: %s\n", SMBStringForField(structHeader, ((SMBProcessorInformation *)structHeader)->serialNumber, privateData));␊ |
401 | ␉DBG("\tAsset Tag: %s\n", SMBStringForField(structHeader, ((SMBProcessorInformation *)structHeader)->assetTag, neverMask));␊ |
402 | ␉DBG("\tPart Number: %s\n", SMBStringForField(structHeader, ((SMBProcessorInformation *)structHeader)->partNumber, neverMask));␊ |
403 | ␊ |
404 | //␊ |
405 | // TODO: Check the size before printing this information.␊ |
406 | // Keep in mind that Apple does not use this info, and only uses a 35 bytes struct␊ |
407 | //␊ |
408 | //␉if(((SMBProcessorInformation *)structHeader)->coreCount != 0)␊ |
409 | //␉{␊ |
410 | //␉␉DBG("\tCore Count: %d\n", ((SMBProcessorInformation *)structHeader)->coreCount);␊ |
411 | //␉}␊ |
412 | //␊ |
413 | //␉if(((SMBProcessorInformation *)structHeader)->coreEnabled != 0)␊ |
414 | //␉{␊ |
415 | //␉␉DBG("\tCore Enabled: %d\n", ((SMBProcessorInformation *)structHeader)->coreEnabled);␊ |
416 | //␉}␊ |
417 | //␊ |
418 | //␉if(((SMBProcessorInformation *)structHeader)->threadCount != 0)␊ |
419 | //␉{␊ |
420 | //␉␉DBG("\tThread Count: %d\n", ((SMBProcessorInformation *)structHeader)->threadCount);␊ |
421 | //␉}␊ |
422 | // Characteristics:␊ |
423 | //␉DBG("\tProcessor Family 2: %d\n", ((SMBProcessorInformation *)structHeader)->processorFamily2);␊ |
424 | ␉DBG("\n");␊ |
425 | }␊ |
426 | ␊ |
427 | //-------------------------------------------------------------------------------------------------------------------------␊ |
428 | // Memory Controller Information (Type 5)␊ |
429 | //-------------------------------------------------------------------------------------------------------------------------␊ |
430 | ␊ |
431 | //-------------------------------------------------------------------------------------------------------------------------␊ |
432 | // Memory Module Information (Type 6)␊ |
433 | //-------------------------------------------------------------------------------------------------------------------------␊ |
434 | //void decodeMemoryModule(SMBStructHeader *structHeader)␊ |
435 | //{␊ |
436 | //␉DBG("Memory Module Information\n");␊ |
437 | //␉DBG("\tSocket Designation: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->socketDesignation));␊ |
438 | //␉DBG("\tBank Connections: Type: %d\n", structHeader->bankConnections);␊ |
439 | //␉DBG("\tCurrent Speed: %X\n", structHeader->currentSpeed);␊ |
440 | //␉DBG("\tType: %llX\n", structHeader->currentMemoryType);␊ |
441 | //␉DBG("\tInstalled Size: %d\n", structHeader->installedSize);␊ |
442 | //␉DBG("\tEnabled Size: %d\n", structHeader->enabledSize);␊ |
443 | //␉DBG("\tError Status: %x\n", structHeader->errorStatus);␊ |
444 | //␉DBG("\n");␊ |
445 | //}␊ |
446 | ␊ |
447 | //-------------------------------------------------------------------------------------------------------------------------␊ |
448 | // Cache Information (Type 7)␊ |
449 | //-------------------------------------------------------------------------------------------------------------------------␊ |
450 | ␊ |
451 | //-------------------------------------------------------------------------------------------------------------------------␊ |
452 | // Port Connector Information (Type 8)␊ |
453 | //-------------------------------------------------------------------------------------------------------------------------␊ |
454 | ␊ |
455 | //-------------------------------------------------------------------------------------------------------------------------␊ |
456 | // System Slot Information (Type 9)␊ |
457 | //-------------------------------------------------------------------------------------------------------------------------␊ |
458 | ␊ |
459 | //-------------------------------------------------------------------------------------------------------------------------␊ |
460 | // On Board Device Information (Type 10)␊ |
461 | //-------------------------------------------------------------------------------------------------------------------------␊ |
462 | ␊ |
463 | //-------------------------------------------------------------------------------------------------------------------------␊ |
464 | // OEM Strings (Type 11)␊ |
465 | //-------------------------------------------------------------------------------------------------------------------------␊ |
466 | void decodeSMBOEMStrings(SMBStructHeader *structHeader)␊ |
467 | {␊ |
468 | ␉char *stringPtr = (char *)structHeader + structHeader->length;␊ |
469 | ␉printHeader(structHeader);␊ |
470 | ␉DBG("OEM Strings\n");␊ |
471 | ␉SMBByte i;␊ |
472 | ␉for (i = 1; i <= ((SMBOEMStrings *)structHeader)->count; i++) {␊ |
473 | ␉␉DBG("\tString %d: %s\n", i, stringPtr);␊ |
474 | ␉␉stringPtr = stringPtr + strlen(stringPtr) + 1;␊ |
475 | ␉}␊ |
476 | ␉DBG("\n");␊ |
477 | }␊ |
478 | //-------------------------------------------------------------------------------------------------------------------------␊ |
479 | // System Configuration Options (Type 12)␊ |
480 | //-------------------------------------------------------------------------------------------------------------------------␊ |
481 | ␊ |
482 | //-------------------------------------------------------------------------------------------------------------------------␊ |
483 | // BIOS Language Information (Type 13)␊ |
484 | //-------------------------------------------------------------------------------------------------------------------------␊ |
485 | ␊ |
486 | //-------------------------------------------------------------------------------------------------------------------------␊ |
487 | // Physical Memory Array (Type 16)␊ |
488 | //-------------------------------------------------------------------------------------------------------------------------␊ |
489 | ␊ |
490 | //-------------------------------------------------------------------------------------------------------------------------␊ |
491 | // MemoryDevice (Type 17)␊ |
492 | //-------------------------------------------------------------------------------------------------------------------------␊ |
493 | void decodeMemoryDevice(SMBStructHeader *structHeader)␊ |
494 | {␊ |
495 | ␉printHeader(structHeader);␊ |
496 | ␉DBG("Memory Device\n");␊ |
497 | // Aray Handle␊ |
498 | ␉if (((SMBMemoryDevice *)structHeader)->errorHandle == 0xFFFF)␊ |
499 | ␉{␊ |
500 | ␉␉DBG("\tError Information Handle: No Error\n");␊ |
501 | ␉}␊ |
502 | ␉else␊ |
503 | ␉{␊ |
504 | ␉␉DBG("\tError Information Handle: 0x%x\n", ((SMBMemoryDevice *)structHeader)->errorHandle);␊ |
505 | ␉}␊ |
506 | // Total Width:␊ |
507 | // Data Width:␊ |
508 | ␉switch (((SMBMemoryDevice *)structHeader)->memorySize)␊ |
509 | ␉{␊ |
510 | ␉␉case 0:␊ |
511 | ␉␉␉DBG("\tSize: No Module Installed\n");␊ |
512 | ␉␉␉break;␊ |
513 | ␉␉case 0x7FFF:␊ |
514 | ␉␉␉DBG("\tSize: 32GB or more\n");␊ |
515 | ␉␉␉break;␊ |
516 | ␉␉case 0xFFFF:␊ |
517 | ␉␉␉DBG("\tSize: Unknown\n");␊ |
518 | ␉␉␉break;␊ |
519 | ␉␉default:␊ |
520 | ␉␉␉DBG("\tSize: %d %s\n", ((SMBMemoryDevice *)structHeader)->memorySize & 0x7FFF, ((((SMBMemoryDevice *)structHeader)->memorySize & 0x8000) == 0x8000) ? "kB" : "MB");␊ |
521 | ␉␉␉break;␊ |
522 | ␉}␊ |
523 | ␉if ((((SMBMemoryDevice *)structHeader)->formFactor < 0x01) || (((SMBMemoryDevice *)structHeader)->formFactor > 0x0F))␊ |
524 | ␉{␊ |
525 | ␉␉DBG("\tForm Factor: %s\n", OutOfSpecStr);␊ |
526 | ␉}␊ |
527 | ␉else␊ |
528 | ␉{␊ |
529 | ␉␉DBG("\tForm Factor: %s\n", SMBMemoryDeviceFormFactors[((SMBMemoryDevice *)structHeader)->formFactor - 1]);␊ |
530 | ␉}␊ |
531 | // Set:␊ |
532 | ␉DBG("\tLocator: %s\n", SMBStringForField(structHeader, ((SMBMemoryDevice *)structHeader)->deviceLocator, neverMask));␊ |
533 | ␉DBG("\tBank Locator: %s\n", SMBStringForField(structHeader, ((SMBMemoryDevice *)structHeader)->bankLocator, neverMask));␊ |
534 | ␉if (((SMBMemoryDevice *)structHeader)->memoryType > kSMBMemoryDeviceTypeCount)␊ |
535 | ␉{␊ |
536 | ␉␉DBG("\tMemory Type: %s\n", OutOfSpecStr);␊ |
537 | ␉}␊ |
538 | ␉else␊ |
539 | ␉{␊ |
540 | ␉␉DBG("\tMemory Type: %s\n", SMBMemoryDeviceTypes[((SMBMemoryDevice *)structHeader)->memoryType]);␊ |
541 | ␉}␊ |
542 | // Type Detail:␊ |
543 | ␉DBG("\tSpeed: %d MHz\n", ((SMBMemoryDevice *)structHeader)->memorySpeed);␊ |
544 | ␉DBG("\tManufacturer: %s\n", SMBStringForField(structHeader, ((SMBMemoryDevice *)structHeader)->manufacturer, neverMask));␊ |
545 | ␉DBG("\tSerial Number: %s\n", SMBStringForField(structHeader, ((SMBMemoryDevice *)structHeader)->serialNumber, privateData));␊ |
546 | ␉DBG("\tAsset Tag: %s\n", SMBStringForField(structHeader, ((SMBMemoryDevice *)structHeader)->assetTag, neverMask));␊ |
547 | ␉DBG("\tPart Number: %s\n", SMBStringForField(structHeader, ((SMBMemoryDevice *)structHeader)->partNumber, neverMask));␊ |
548 | // Rank:␊ |
549 | // Configured Clock Speed:␊ |
550 | // Minimum Voltage:␊ |
551 | // Maximum Voltage:␊ |
552 | // Configured Voltage:␊ |
553 | ␉DBG("\n");␊ |
554 | }␊ |
555 | ␊ |
556 | //-------------------------------------------------------------------------------------------------------------------------␊ |
557 | // Apple Specific (Type 131)␊ |
558 | //-------------------------------------------------------------------------------------------------------------------------␊ |
559 | void decodeOemProcessorType(SMBStructHeader *structHeader)␊ |
560 | {␊ |
561 | ␉printHeader(structHeader);␊ |
562 | ␉DBG("Apple specific Processor Type\n");␊ |
563 | ␉DBG("\tCpu-type = 0x%04X\n", ((SMBOemProcessorType *)structHeader)->ProcessorType);␊ |
564 | ␉DBG("\n");␊ |
565 | }␊ |
566 | ␊ |
567 | //-------------------------------------------------------------------------------------------------------------------------␊ |
568 | // Apple Specific (Type 132)␊ |
569 | //-------------------------------------------------------------------------------------------------------------------------␊ |
570 | void decodeOemProcessorBusSpeed(SMBStructHeader *structHeader)␊ |
571 | {␊ |
572 | ␉printHeader(structHeader);␊ |
573 | ␉DBG("Apple specific Processor Interconnect Speed\n");␊ |
574 | ␉DBG("\tQPI = %d MT/s\n", ((SMBOemProcessorBusSpeed *)structHeader)->ProcessorBusSpeed);␊ |
575 | ␉DBG("\n");␊ |
576 | }␊ |
577 | ␊ |
578 | // Info for the Table Above: dmi 2.7+ https://wiki.debian.org/InstallingDebianOn/Thinkpad/T42/lenny?action=AttachFile&do=get&target=dmidecode.Lenny_Thinkpad_T42_2373.txt␊ |
579 | //-------------------------------------------------------------------------------------------------------------------------␊ |
580 | // Apple Specific (Type 133)␊ |
581 | //-------------------------------------------------------------------------------------------------------------------------␊ |
582 | void decodeOemPlatformFeature(SMBStructHeader *structHeader)␊ |
583 | {␊ |
584 | ␉printHeader(structHeader);␊ |
585 | ␉DBG("Apple specific Platform Feature\n");␊ |
586 | ␉DBG("\t%s\n", ((SMBOemPlatformFeature *)structHeader)->PlatformFeature);␊ |
587 | ␉DBG("\n");␊ |
588 | }␊ |
589 | ␊ |
590 | //-------------------------------------------------------------------------------------------------------------------------␊ |
591 | // Specific (Type 134)␊ |
592 | //-------------------------------------------------------------------------------------------------------------------------␊ |
593 | //void decodeOem(SMBStructHeader *structHeader)␊ |
594 | //{␊ |
595 | //␉printHeader(structHeader);␊ |
596 | //␉DBG("Apple specific Feature\n");␊ |
597 | //␉DBG("\t%s\n", ((SMBOemPlatformFeature *)structHeader)->Feature);␊ |
598 | //␉DBG("\n");␊ |
599 | //}␊ |
600 | ␊ |
601 | //-------------------------------------------------------------------------------------------------------------------------␊ |
602 | ␊ |
603 | ␊ |
604 | void decodeSMBIOSTable(SMBEntryPoint *eps)␊ |
605 | {␊ |
606 | ␉uint8_t *ptr = (uint8_t *)eps->dmi.tableAddress;␊ |
607 | ␉SMBStructHeader *structHeader = (SMBStructHeader *)ptr;␊ |
608 | ␊ |
609 | ␉minorVersion = eps->minorVersion;␊ |
610 | ␉majorVersion = eps->majorVersion;␊ |
611 | ␉bcdRevisionHi = eps->dmi.bcdRevision >> 4;␊ |
612 | ␉bcdRevisionLo = eps->dmi.bcdRevision & 0x0F;␊ |
613 | ␊ |
614 | ␉getBoolForKey(kPrivateData, &privateData, &bootInfo->chameleonConfig); // Bungo: chek if mask some data␊ |
615 | ␊ |
616 | ␉DBG("\n");␊ |
617 | ␉DBG("SMBIOS rev.: %d.%d, DMI rev.: %d.%d\n", majorVersion, minorVersion, bcdRevisionHi, bcdRevisionLo);␊ |
618 | ␉DBG("\n");␊ |
619 | ␉for (;((eps->dmi.tableAddress + eps->dmi.tableLength) > ((uint32_t)(uint8_t *)structHeader + sizeof(SMBStructHeader)));)␊ |
620 | ␉{␊ |
621 | ␉␉switch (structHeader->type)␊ |
622 | ␉␉{␊ |
623 | ␉␉␉case kSMBTypeBIOSInformation: // Type 0␊ |
624 | ␉␉␉␉decodeBIOSInformation(structHeader);␊ |
625 | ␉␉␉␉break;␊ |
626 | ␊ |
627 | ␉␉␉case kSMBTypeSystemInformation: // Type 1␊ |
628 | ␉␉␉␉decodeSystemInformation(structHeader);␊ |
629 | ␉␉␉␉break;␊ |
630 | ␊ |
631 | ␉␉␉case kSMBTypeBaseBoard: // Type 2␊ |
632 | ␉␉␉␉decodeBaseBoard(structHeader);␊ |
633 | ␉␉␉␉break;␊ |
634 | ␊ |
635 | ␉␉␉case kSMBTypeSystemEnclosure: // Type 3␊ |
636 | ␉␉␉␉decodeSystemEnclosure(structHeader);␊ |
637 | ␉␉␉␉break;␊ |
638 | ␊ |
639 | ␉␉␉case kSMBTypeProcessorInformation: // Type 4␊ |
640 | ␉␉␉␉decodeProcessorInformation(structHeader);␊ |
641 | ␉␉␉␉break;␊ |
642 | ␊ |
643 | ␉␉␉//case kSMBTypeMemoryModule: // Type 6␊ |
644 | ␉␉␉//␉decodeMemoryModule(structHeader);␊ |
645 | ␉␉␉//␉break;␊ |
646 | ␊ |
647 | ␉␉␉//case kSMBTypeSystemSlot: // Type 9␊ |
648 | ␉␉␉//␉decodeSMBTypeSystemSlot(structHeader);␊ |
649 | ␉␉␉//␉break;␊ |
650 | ␊ |
651 | ␉␉␉case kSMBOEMStrings: // Type 11␊ |
652 | ␉␉␉␉decodeSMBOEMStrings(structHeader);␊ |
653 | ␉␉␉␉break;␊ |
654 | ␊ |
655 | ␉␉␉case kSMBTypeMemoryDevice: // Type 17␊ |
656 | ␉␉␉␉decodeMemoryDevice(structHeader);␊ |
657 | ␉␉␉␉break;␊ |
658 | ␊ |
659 | ␉␉␉//kSMBTypeMemoryArrayMappedAddress: // Type 19␊ |
660 | ␉␉␉//␉break;␊ |
661 | ␊ |
662 | ␉␉␉/* Skip all Apple Specific Structures */␊ |
663 | ␉␉␉case kSMBTypeFirmwareVolume: // Type 128␊ |
664 | ␉␉␉// case kSMBTypeMemorySPD: // Type 130␊ |
665 | ␉␉␉␉break;␊ |
666 | ␊ |
667 | ␉␉␉case kSMBTypeOemProcessorType: // Type 131␊ |
668 | ␉␉␉␉decodeOemProcessorType(structHeader);␊ |
669 | ␉␉␉␉break;␊ |
670 | ␊ |
671 | ␉␉␉case kSMBTypeOemProcessorBusSpeed: // Type 132␊ |
672 | ␉␉␉␉decodeOemProcessorBusSpeed(structHeader);␊ |
673 | ␉␉␉␉break;␊ |
674 | ␊ |
675 | ␉␉␉//case kSMBTypeOemPlatformFeature: // Type 133␊ |
676 | ␉␉␉//␉decodeOemPlatformFeature(structHeader);␊ |
677 | ␉␉␉//␉break;␊ |
678 | ␊ |
679 | ␉␉␉case kSMBTypeEndOfTable: // Type 127␊ |
680 | ␉␉␉␉DBG("Handle 0x%04x, DMI type %d, %d bytes\n", structHeader->handle, structHeader->type, structHeader->length);␊ |
681 | ␉␉␉␉DBG("End of Table\n");␊ |
682 | ␉␉␉␉break;␊ |
683 | ␊ |
684 | ␉␉␉default:␊ |
685 | ␉␉␉␉break;␊ |
686 | ␉␉}␊ |
687 | ␊ |
688 | ␉␉ptr = (uint8_t *)((uint32_t)structHeader + structHeader->length);␊ |
689 | ␉␉for (; ((uint16_t *)ptr)[0] != 0; ptr++);␊ |
690 | ␊ |
691 | ␉␉if (((uint16_t *)ptr)[0] == 0)␊ |
692 | ␉␉{␊ |
693 | ␉␉␉ptr += 2;␊ |
694 | ␉␉}␊ |
695 | ␊ |
696 | ␉␉structHeader = (SMBStructHeader *)ptr;␊ |
697 | ␉}␊ |
698 | ␉DBG("\n");␊ |
699 | }␊ |
700 | ␊ |
701 | |