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

Archive Download this file

Revision: 2340