Chameleon

Chameleon Svn Source Tree

Root/branches/Bungo/i386/libsaio/smbios_decode.c

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
24extern char *getSMBStringForField(SMBStructHeader *structHeader, uint8_t field);
25// Bungo:
26#define NotSpecifiedStr "Not Specified" // no string
27#define OutOfSpecStr "<OUT OF SPEC>" // value out of smbios spec. range
28#define PrivateStr "** PRIVATE **" // masking private data
29#define neverMask false
30
31static bool privateData = true;
32static SMBByte minorVersion; // SMBIOS rev. minor
33static SMBByte majorVersion; // SMBIOS rev. major
34static SMBByte bcdRevisionLo; // DMI rev. minor
35static SMBByte bcdRevisionHi; // DMI rev. major
36
37/*====
38 7.2.2
39 ===*/
40static const char *SMBWakeUpTypes[] = // Bungo: strings for wake-up type (Table Type 1 - System Information)
41{
42"Reserved", /* 00h */
43"Other", /* 01h */
44"Unknown", /* 02h */
45"APM Timer", /* 03h */
46"Modem Ring", /* 04h */
47"LAN Remote", /* 05h */
48"Power Switch", /* 06h */
49"PCI PME#", /* 07h */
50"AC Power Restored" /* 08h */
51};
52
53/*====
54 7.3.2
55 ===*/
56static const char *SMBBaseBoardTypes[] = // Bungo: strings for base board type (Table Type 2 - Base Board Information)
57{
58"Unknown", /* 01h */
59"Other", /* 02h */
60"Server Blade", /* 03h */
61"Connectivity Switch", /* 04h */
62"System Management Module", /* 05h */
63"Processor Module", /* 06h */
64"I/O Module", /* 07h */
65"Memory Module", /* 08h */
66"Daughter Board", /* 09h */
67"Motherboard", /* 0Ah */
68"Processor+Memory Module", /* 0Bh */
69"Processor+I/O Module", /* 0Ch */
70"Interconnect Board" /* 0Dh */
71};
72
73 /*===
74 7.4.1
75 ===*/
76static const char *SMBChassisTypes[] = // Bungo: strings for chassis type (Table Type 3 - Chassis Information)
77{
78"Other", /* 01h */
79"Unknown", /* 02h */
80"Desktop", /* 03h */
81"Low Profile Desktop", /* 04h */
82"Pizza Box", /* 05h */
83"Mini Tower", /* 06h */
84"Tower", /* 07h */
85"Portable", /* 08h */
86"Laptop", /* 09h */
87"Notebook", /* 0Ah */
88"Hand Held", /* 0Bh */
89"Docking Station", /* 0Ch */
90"All in One", /* 0Dh */
91"Sub Notebook", /* 0Eh */
92"Space-saving", /* 0Fh */
93"Lunch Box",/* 10h */
94"Main Server Chassis",/* 11h */
95"Expansion Chassis",/* 12h */
96"SubChassis",/* 13h */
97"Bus Expansion Chassis",/* 14h */
98"Peripheral Chassis",/* 15h */
99"RAID Chassis",/* 16h */
100"Rack Mount Chassis", /* 17h */
101"Sealed-case PC",/* 18h */
102"Multi-system Chassis", /* 19h */
103"Compact PCI",/* 1Ah */
104"Advanced TCA",/* 1Bh */
105"Blade",/* 1Ch */ // An SMBIOS implementation for a Blade would contain a Type 3 Chassis structure
106"Blade Enclosing"/* 1Dh */ // A Blade Enclosure is a specialized chassis that contains a set of Blades.
107};
108
109/*====
110 7.5.1
111 ===*/
112static 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 ===*/
125static const char *SMBProcessorUpgrades[] = // ErmaC: strings for processor upgrade (Table Type 4 - Processor Information)
126{
127"Other", // 01h
128 "Unknown",
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};
172
173/*=====
174 7.18.2
175 ====*/
176static const char *
177SMBMemoryDeviceTypes[] =
178{
179"RAM", /* 00h Undefined */
180"RAM", /* 01h Other */
181"RAM", /* 02h Unknown */
182"DRAM", /* 03h DRAM */
183"EDRAM", /* 04h EDRAM */
184"VRAM", /* 05h VRAM */
185"SRAM", /* 06h SRAM */
186"RAM", /* 07h RAM */
187"ROM", /* 08h ROM */
188"FLASH", /* 09h FLASH */
189"EEPROM", /* 0Ah EEPROM */
190"FEPROM", /* 0Bh FEPROM */
191"EPROM", /* 0Ch EPROM */
192"CDRAM", /* 0Dh CDRAM */
193"3DRAM", /* 0Eh 3DRAM */
194"SDRAM", /* 0Fh SDRAM */
195"SGRAM", /* 10h SGRAM */
196"RDRAM", /* 11h RDRAM */
197"DDR SDRAM", /* 12h DDR */
198"DDR2 SDRAM", /* 13h DDR2 */
199"DDR2 FB-DIMM", /* 14h DDR2 FB-DIMM */
200"RAM", /* 15h unused */
201"RAM", /* 16h unused */
202"RAM", /* 17h unused */
203"DDR3", /* 18h DDR3, chosen in [5776134] */
204"FBD2" /* 19h FBD2 */
205};
206
207static const int kSMBMemoryDeviceTypeCount = sizeof(SMBMemoryDeviceTypes) /
208 sizeof(SMBMemoryDeviceTypes[0]);
209
210// Bungo: fixes random string readout if null in smbios to "Not Specified" as dmidecode displays
211char *SMBStringForField(SMBStructHeader *structHeader, uint8_t field, const bool mask)
212{
213char *str = NULL;
214str = getSMBStringForField(structHeader, field);
215if (!field) {
216str = NotSpecifiedStr;
217}
218 else if (mask) {
219str = PrivateStr;
220}
221
222 return str;
223};
224
225void printHeader(SMBStructHeader *structHeader)
226{
227 DBG("Type: %d, Length: %d, Handle: 0x%04x\n", structHeader->type, structHeader->length, structHeader->handle);
228}
229
230//-------------------------------------------------------------------------------------------------------------------------
231// BIOS Information (Type 0)
232//-------------------------------------------------------------------------------------------------------------------------
233void decodeBIOSInformation(SMBStructHeader *structHeader)
234{
235 printHeader(structHeader);
236DBG("BIOS Information:\n");
237DBG("\tVendor: %s\n", SMBStringForField(structHeader, ((SMBBIOSInformation *)structHeader)->vendor, neverMask));
238DBG("\tVersion: %s\n", SMBStringForField(structHeader, ((SMBBIOSInformation *)structHeader)->version, neverMask));
239// Address Segment
240DBG("\tRelease Date: %s\n", SMBStringForField(structHeader, ((SMBBIOSInformation *)structHeader)->releaseDate, neverMask));
241DBG("\tBIOS Revision: %d.%d\n", ((SMBBIOSInformation *)structHeader)->releaseMajor, ((SMBBIOSInformation *)structHeader)->releaseMinor);
242// ROM Size
243// DBG("\tSupported BIOS functions: (0x%llX) %s\n", ((SMBBIOSInformation *)structHeader)->characteristics, SMBBIOSInfoChar0[((SMBBIOSInformation *)structHeader)->characteristics]);
244// Firmware Major Release
245// Firmware Minor Release
246// SMBByte characteristicsExt1;
247// SMBByte characteristicsExt2;
248DBG("\n");
249}
250
251//-------------------------------------------------------------------------------------------------------------------------
252// System Information (Type 1)
253//-------------------------------------------------------------------------------------------------------------------------
254void decodeSystemInformation(SMBStructHeader *structHeader)
255{
256 printHeader(structHeader);
257DBG("System Information:\n");
258DBG("\tManufacturer: %s\n", SMBStringForField(structHeader, ((SMBSystemInformation *)structHeader)->manufacturer, neverMask));
259DBG("\tProduct Name: %s\n", SMBStringForField(structHeader, ((SMBSystemInformation *)structHeader)->productName, neverMask));
260DBG("\tVersion: %s\n", SMBStringForField(structHeader, ((SMBSystemInformation *)structHeader)->version, neverMask));
261DBG("\tSerial Number: %s\n", SMBStringForField(structHeader, ((SMBSystemInformation *)structHeader)->serialNumber, privateData));
262uint8_t *uuid = ((SMBSystemInformation *)structHeader)->uuid;
263if (privateData) {
264DBG("\tUUID: %s\n", PrivateStr);
265} else {
266DBG("\tUUID: %02X%02X%02X%02X-%02X%02X-%02X%02X-%02x%02X-%02X%02X%02X%02X%02X%02X\n",
267uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
268uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
269 }
270if (((SMBSystemInformation *)structHeader)->wakeupReason > 8) {
271DBG("\tWake-up Type: %s\n", OutOfSpecStr);
272} else {
273DBG("\tWake-up Type: %s\n", SMBWakeUpTypes[((SMBSystemInformation *)structHeader)->wakeupReason]);
274 }
275DBG("\tSKU Number: %s\n", SMBStringForField(structHeader, ((SMBSystemInformation *)structHeader)->skuNumber, neverMask)); // System SKU#
276DBG("\tFamily: %s\n", SMBStringForField(structHeader, ((SMBSystemInformation *)structHeader)->family, neverMask));
277DBG("\n");
278}
279
280//-------------------------------------------------------------------------------------------------------------------------
281// Base Board (or Module) Information (Type 2)
282//-------------------------------------------------------------------------------------------------------------------------
283void decodeBaseBoard(SMBStructHeader *structHeader)
284{
285 printHeader(structHeader);
286DBG("Base Board Information:\n");
287DBG("\tManufacturer: %s\n", SMBStringForField(structHeader, ((SMBBaseBoard *)structHeader)->manufacturer, neverMask));
288DBG("\tProduct Name: %s\n", SMBStringForField(structHeader, ((SMBBaseBoard *)structHeader)->product, neverMask));
289DBG("\tVersion: %s\n", SMBStringForField(structHeader, ((SMBBaseBoard *)structHeader)->version, neverMask));
290DBG("\tSerial Number: %s\n", SMBStringForField(structHeader, ((SMBBaseBoard *)structHeader)->serialNumber, privateData));
291DBG("\tAsset Tag: %s\n", SMBStringForField(structHeader, ((SMBBaseBoard *)structHeader)->assetTag, neverMask));
292// Feature Flags (BYTE)
293DBG("\tLocation In Chassis: %s\n", SMBStringForField(structHeader, ((SMBBaseBoard *)structHeader)->locationInChassis, neverMask)); // Part Component
294// Chassis Handle (WORD)
295if ((((SMBBaseBoard *)structHeader)->boardType < kSMBBaseBoardUnknown) || (((SMBBaseBoard *)structHeader)->boardType > kSMBBaseBoardInterconnect)) {
296DBG("\tType: %s\n", OutOfSpecStr);
297} else {
298DBG("\tType: %s\n", SMBBaseBoardTypes[(((SMBBaseBoard *)structHeader)->boardType - 1)]);
299 }
300// Number of Contained Object Handles (n) (BYTE)
301// Contained Object Handles n(WORDs)
302DBG("\n");
303}
304
305//-------------------------------------------------------------------------------------------------------------------------
306// System Enclosure or Chassis (Type 3)
307//-------------------------------------------------------------------------------------------------------------------------
308void decodeSystemEnclosure(SMBStructHeader *structHeader)
309{
310 printHeader(structHeader);
311DBG("Chassis Information:\n");
312DBG("\tManufacturer: %s\n", SMBStringForField(structHeader, ((SMBSystemEnclosure *)structHeader)->manufacturer, neverMask));
313if ((((SMBSystemEnclosure *)structHeader)->chassisType < kSMBchassisOther) || (((SMBSystemEnclosure *)structHeader)->chassisType > kSMBchassisBladeEnclosing)) {
314DBG("\tType: %s\n", OutOfSpecStr);
315} else {
316DBG("\tType: %s\n", SMBChassisTypes[(((SMBSystemEnclosure *)structHeader)->chassisType - 1)]);
317 }
318DBG("\tVersion: %s\n", SMBStringForField(structHeader, ((SMBSystemEnclosure *)structHeader)->version, neverMask));
319DBG("\tSerial Number: %s\n", SMBStringForField(structHeader, ((SMBSystemEnclosure *)structHeader)->serialNumber, privateData));
320DBG("\tAsset Tag: %s\n", SMBStringForField(structHeader, ((SMBSystemEnclosure *)structHeader)->assetTag, neverMask));
321// Boot-up State:
322// Power Supply State
323// Thermal State
324// Security Status:
325// OEM Information:
326// Height;
327// Cords;
328// ElementsCount;
329// ElementLen;
330// Elements[1]; // open array of ElementsCount*ElementLen BYTEs
331DBG("\n");
332}
333
334//-------------------------------------------------------------------------------------------------------------------------
335// Processor Information (Type 4)
336//-------------------------------------------------------------------------------------------------------------------------
337void decodeProcessorInformation(SMBStructHeader *structHeader)
338{
339 printHeader(structHeader);
340DBG("Processor Information:\n");
341DBG("\tSocket Designation: %s\n", SMBStringForField(structHeader, ((SMBProcessorInformation *)structHeader)->socketDesignation, neverMask));
342 if ((((SMBProcessorInformation *)structHeader)->processorType < kSMBprocessorTypeOther) || (((SMBProcessorInformation *)structHeader)->processorType > kSMBprocessorTypeGPU)) {
343DBG("\tType: %s\n", OutOfSpecStr);
344} else {
345DBG("\tType: %s\n", SMBProcessorTypes[((SMBProcessorInformation *)structHeader)->processorType - 1]);
346 }
347DBG("\tFamily: 0x%X\n", ((SMBProcessorInformation *)structHeader)->processorFamily);
348DBG("\tManufacturer: %s\n", SMBStringForField(structHeader, ((SMBProcessorInformation *)structHeader)->manufacturer, neverMask));
349DBG("\tID: 0x%llX\n", ((SMBProcessorInformation *)structHeader)->processorID);
350DBG("\tProcessor Version: %s\n", SMBStringForField(structHeader, ((SMBProcessorInformation *)structHeader)->processorVersion, neverMask));
351//DBG("\tVoltage: 0.%xV\n", ((SMBProcessorInformation *)structHeader)->voltage);
352DBG("\tExternal Clock: %dMHz\n", ((SMBProcessorInformation *)structHeader)->externalClock);
353DBG("\tMaximal Clock: %dMHz\n", ((SMBProcessorInformation *)structHeader)->maximumClock);
354DBG("\tCurrent Clock: %dMHz\n", ((SMBProcessorInformation *)structHeader)->currentClock);
355 if ((((SMBProcessorInformation *)structHeader)->processorUpgrade < 1) || (((SMBProcessorInformation *)structHeader)->processorUpgrade > 0x2C)) {
356DBG("\tUpgrade: %s\n", OutOfSpecStr);
357} else {
358DBG("\tUpgrade: %s\n", SMBProcessorUpgrades[((SMBProcessorInformation *)structHeader)->processorUpgrade - 1]);
359 }
360DBG("\tSerial Number: %s\n", SMBStringForField(structHeader, ((SMBProcessorInformation *)structHeader)->serialNumber, privateData));
361DBG("\tAsset Tag: %s\n", SMBStringForField(structHeader, ((SMBProcessorInformation *)structHeader)->assetTag, neverMask));
362DBG("\tPart Number: %s\n", SMBStringForField(structHeader, ((SMBProcessorInformation *)structHeader)->partNumber, neverMask));
363//DBG("\tProcessor Family 2: %d\n", ((SMBProcessorInformation *)structHeader)->processorFamily2);
364DBG("\n");
365}
366
367//-------------------------------------------------------------------------------------------------------------------------
368// OEM Strings (Type 11)
369//-------------------------------------------------------------------------------------------------------------------------
370void decodeSMBOEMStrings(SMBStructHeader *structHeader)
371{
372 char *stringPtr = (char *)structHeader + structHeader->length;
373 printHeader(structHeader);
374DBG("OEM Strings:\n");
375 for (SMBByte i = 1; i <= ((SMBOEMStrings *)structHeader)->count; i++) {
376 DBG("\tString %d: %s\n", i, stringPtr);
377 stringPtr = stringPtr + strlen(stringPtr) + 1;
378 }
379DBG("\n");
380}
381
382//-------------------------------------------------------------------------------------------------------------------------
383// MemoryDevice (Type 17)
384//-------------------------------------------------------------------------------------------------------------------------
385void decodeMemoryDevice(SMBStructHeader *structHeader)
386{
387 printHeader(structHeader);
388DBG("Memory Device:\n");
389DBG("\tDevice Locator: %s\n", SMBStringForField(structHeader, ((SMBMemoryDevice *)structHeader)->deviceLocator, neverMask));
390DBG("\tBank Locator: %s\n", SMBStringForField(structHeader, ((SMBMemoryDevice *)structHeader)->bankLocator, neverMask));
391DBG("\tMemory Type: %s\n", SMBMemoryDeviceTypes[((SMBMemoryDevice *)structHeader)->memoryType]);
392DBG("\tSpeed: %d MHz\n", ((SMBMemoryDevice *)structHeader)->memorySpeed);
393DBG("\tError Handle: %x\n", ((SMBMemoryDevice *)structHeader)->errorHandle);
394DBG("\tManufacturer: %s\n", SMBStringForField(structHeader, ((SMBMemoryDevice *)structHeader)->manufacturer, neverMask));
395DBG("\tSerial Number: %s\n", SMBStringForField(structHeader, ((SMBMemoryDevice *)structHeader)->serialNumber, privateData));
396DBG("\tAsset Tag: %s\n", SMBStringForField(structHeader, ((SMBMemoryDevice *)structHeader)->assetTag, neverMask));
397DBG("\tPart Number: %s\n", SMBStringForField(structHeader, ((SMBMemoryDevice *)structHeader)->partNumber, neverMask));
398DBG("\n");
399}
400
401//-------------------------------------------------------------------------------------------------------------------------
402// Apple Specific
403//-------------------------------------------------------------------------------------------------------------------------
404void decodeOemProcessorType(SMBStructHeader *structHeader)
405{
406 printHeader(structHeader);
407 DBG("Apple specific Processor Type:\n");
408DBG("\tcpu=0x%x\n", ((SMBOemProcessorType *)structHeader)->ProcessorType);
409DBG("\n");
410}
411
412void decodeOemProcessorBusSpeed(SMBStructHeader *structHeader)
413{
414 printHeader(structHeader);
415 DBG("Apple specific Processor Interconnect Speed:\n");
416 DBG("\tqpi=%d MT/s\n", ((SMBOemProcessorBusSpeed *)structHeader)->ProcessorBusSpeed);
417DBG("\n");
418}
419//-------------------------------------------------------------------------------------------------------------------------
420
421
422void decodeSMBIOSTable(SMBEntryPoint *eps)
423{
424uint8_t *ptr = (uint8_t *)eps->dmi.tableAddress;
425SMBStructHeader *structHeader = (SMBStructHeader *)ptr;
426
427minorVersion = eps->minorVersion;
428majorVersion = eps->majorVersion;
429bcdRevisionHi = eps->dmi.bcdRevision >> 4;
430bcdRevisionLo = eps->dmi.bcdRevision & 0x0F;
431
432getBoolForKey(kPrivateData, &privateData, &bootInfo->chameleonConfig); // Bungo: chek if mask some data
433
434 DBG("\n");
435DBG("SMBIOS rev.: %d.%d, DMI rev.: %d.%d\n", majorVersion, minorVersion, bcdRevisionHi, bcdRevisionLo);
436 DBG("\n");
437for (;((eps->dmi.tableAddress + eps->dmi.tableLength) > ((uint32_t)(uint8_t *)structHeader + sizeof(SMBStructHeader)));)
438{
439switch (structHeader->type)
440{
441case kSMBTypeBIOSInformation: // Type 0
442decodeBIOSInformation(structHeader);
443break;
444
445case kSMBTypeSystemInformation: // Type 1
446decodeSystemInformation(structHeader);
447break;
448
449case kSMBTypeBaseBoard: // Type 2
450decodeBaseBoard(structHeader);
451break;
452
453case kSMBTypeSystemEnclosure: // Type 3
454decodeSystemEnclosure(structHeader);
455break;
456
457case kSMBTypeProcessorInformation: // Type 4
458decodeProcessorInformation(structHeader);
459break;
460
461//case 6: // kSMBTypeMemoryModule: // Type 6
462//decodeMemoryModule(structHeader);
463//break;
464
465case kSMBOEMStrings: // Type 11
466decodeSMBOEMStrings(structHeader);
467break;
468
469case kSMBTypeMemoryDevice: // Type 17
470decodeMemoryDevice(structHeader);
471break;
472
473// kSMBTypeMemoryArrayMappedAddress: // Type 19
474
475/* Skip all Apple Specific Structures */
476// case kSMBTypeFirmwareVolume: // Type 128
477// case kSMBTypeMemorySPD: // Type 130
478// break;
479
480case kSMBTypeOemProcessorType: // Type 131
481decodeOemProcessorType(structHeader);
482break;
483
484case kSMBTypeOemProcessorBusSpeed: // Type 132
485decodeOemProcessorBusSpeed(structHeader);
486break;
487
488//kSMBTypeOemPlatformFeature: // Type 133
489
490case kSMBTypeEndOfTable: // Type 127
491 DBG("Type: %d, Length: %d, Handle: 0x%04x\n", structHeader->type, structHeader->length, structHeader->handle);
492 DBG("End of Table\n");
493break;
494
495default:
496break;
497}
498
499ptr = (uint8_t *)((uint32_t)structHeader + structHeader->length);
500for (; ((uint16_t *)ptr)[0] != 0; ptr++);
501
502if (((uint16_t *)ptr)[0] == 0) {
503ptr += 2;
504}
505
506structHeader = (SMBStructHeader *)ptr;
507}
508DBG("\n");
509}
510
511

Archive Download this file

Revision: 2353