Chameleon

Chameleon Svn Source Tree

Root/trunk/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", /* 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 ===*/
72static 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 ===*/
92static 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 ====*/
179static const char *
180SMBMemoryDeviceTypes[] =
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
210static const int kSMBMemoryDeviceTypeCount = sizeof(SMBMemoryDeviceTypes) /
211 sizeof(SMBMemoryDeviceTypes[0]);
212
213//-------------------------------------------------------------------------------------------------------------------------
214// BIOS Information (Type 0)
215//-------------------------------------------------------------------------------------------------------------------------
216void decodeBIOSInformation(SMBBIOSInformation *structHeader)
217{
218DBG("BIOS Information:\n");
219DBG("\tVendor: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->vendor, neverMask));
220DBG("\tVersion: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->version, neverMask));
221// Address Segment
222DBG("\tRelease Date: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->releaseDate, neverMask));
223DBG("\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;
232DBG("\n");
233}
234
235//-------------------------------------------------------------------------------------------------------------------------
236// System Information (Type 1)
237//-------------------------------------------------------------------------------------------------------------------------
238void decodeSystemInformation(SMBSystemInformation *structHeader)
239{
240DBG("System Information:\n");
241DBG("\tManufacturer: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer, neverMask));
242DBG("\tProduct Name: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->productName, neverMask));
243DBG("\tVersion: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->version, neverMask));
244DBG("\tSerial Number: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber, privateData));
245
246if (minorVersion < 0x01 || structHeader->header.length < 0x19) {
247return;
248}
249
250uint8_t *uuid = structHeader->uuid;
251if (uuid) {
252if (privateData) {
253DBG("\tUUID: %s\n", PrivateStr);
254} else {
255DBG("\tUUID: %02X%02X%02X%02X-%02X%02X-%02X%02X-%02x%02X-%02X%02X%02X%02X%02X%02X\n",
256uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
257uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
258}
259}
260
261if (structHeader->wakeupReason > 8) {
262DBG("\tWake-up Type: %s\n", OutOfSpecStr);
263} else {
264DBG("\tWake-up Type: %s\n", SMBWakeUpTypes[structHeader->wakeupReason]);
265}
266if (minorVersion < 0x04 || structHeader->header.length < 0x1B) {
267return;
268}
269
270DBG("\tSKU Number: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->skuNumber, neverMask)); // System SKU#
271DBG("\tFamily: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->family, neverMask));
272DBG("\n");
273}
274
275//-------------------------------------------------------------------------------------------------------------------------
276// Base Board (or Module) Information (Type 2)
277//-------------------------------------------------------------------------------------------------------------------------
278void decodeBaseBoard(SMBBaseBoard *structHeader)
279{
280DBG("Base Board Information:\n");
281DBG("\tManufacturer: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer, neverMask));
282DBG("\tProduct Name: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->product, neverMask));
283DBG("\tVersion: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->version, neverMask));
284DBG("\tSerial Number: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber, privateData));
285DBG("\tAsset Tag: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTag, neverMask));
286// Feature Flags (BYTE)
287DBG("\tLocation In Chassis: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->locationInChassis, neverMask)); // Part Component
288// Chassis Handle (WORD)
289if ((structHeader->boardType < kSMBBaseBoardUnknown) || (structHeader->boardType > kSMBBaseBoardInterconnect)) {
290DBG("\tType: %s\n", OutOfSpecStr);
291} else {
292DBG("\tType: %s\n", SMBBaseBoardTypes[(structHeader->boardType - 1)]);
293}
294// Number of Contained Object Handles (n) (BYTE)
295// Contained Object Handles n(WORDs)
296DBG("\n");
297}
298
299//-------------------------------------------------------------------------------------------------------------------------
300// System Enclosure or Chassis (Type 3)
301//-------------------------------------------------------------------------------------------------------------------------
302void decodeSystemEnclosure(SMBSystemEnclosure *structHeader)
303{
304DBG("Chassis Information:\n");
305DBG("\tManufacturer: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer, neverMask));
306// DBG("\tType: 0x%X\n", structHeader->chassisType);
307if ((structHeader->chassisType < kSMBchassisOther) || (structHeader->chassisType > kSMBchassisBladeEnclosing)) {
308DBG("\tType: %s\n", OutOfSpecStr);
309} else {
310DBG("\tType: %s\n", SMBChassisTypes[(structHeader->chassisType - 1)]);
311}
312DBG("\tVersion: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->version, neverMask));
313DBG("\tSerial Number: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber, privateData));
314DBG("\tAsset Tag: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTag, neverMask));
315// Boot-up State:
316// Power Supply State
317// Thermal State
318// Security Status:
319// OEM Information:
320// Height;
321// Cords;
322// ElementsCount;
323// ElementLen;
324// Elements[1]; // open array of ElementsCount*ElementLen BYTEs
325DBG("\n");
326}
327
328//-------------------------------------------------------------------------------------------------------------------------
329// Processor Information (Type 4)
330//-------------------------------------------------------------------------------------------------------------------------
331void decodeProcessorInformation(SMBProcessorInformation *structHeader)
332{
333DBG("Processor Information:\n");
334DBG("\tSocket Designation: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->socketDesignation, neverMask));
335DBG("\tType: %d\n", structHeader->processorType);
336DBG("\tFamily: 0x%X\n", structHeader->processorFamily);
337DBG("\tManufacturer: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer, neverMask));
338DBG("\tID: 0x%llX\n", structHeader->processorID);
339DBG("\tProcessor Version: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->processorVersion, neverMask));
340//DBG("\tVoltage: 0.%xV\n", structHeader->voltage);
341DBG("\tExternal Clock: %dMHz\n", structHeader->externalClock);
342DBG("\tMaximum Clock: %dMHz\n", structHeader->maximumClock);
343DBG("\tCurrent Clock: %dMHz\n", structHeader->currentClock);
344
345if (minorVersion < 3 || structHeader->header.length < 35) {
346return;
347}
348
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));
352//DBG("\tCore Count: %d\n", structHeader->coreCount);
353//DBG("\tCore Enabled: %d\n", structHeader->coreEnabled);
354//DBG("\tThread Count: %d\n", structHeader->threadCount);
355//DBG("\tProcessor Family 2: %d\n", structHeader->processorFamily2);
356DBG("\n");
357}
358
359//-------------------------------------------------------------------------------------------------------------------------
360// Memory Module Information (Type 6)
361//-------------------------------------------------------------------------------------------------------------------------
362//void decodeMemoryModule(SMBMemoryModule *structHeader)
363//{
364//DBG("Memory Module Information:\n");
365//DBG("\tSocket Designation: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->socketDesignation));
366//DBG("\tBank Connections: Type: %d\n", structHeader->bankConnections);
367//DBG("\tCurrent Speed: %X\n", structHeader->currentSpeed);
368//DBG("\tCurrent Memory Type: %llX\n", structHeader->currentMemoryType);
369//DBG("\tInstalled Size: %d\n", structHeader->installedSize);
370//DBG("\tEnabled Size: %d\n", structHeader->enabledSize);
371//DBG("\tError Status: %x\n", structHeader->errorStatus);
372//DBG("\n");
373//}
374
375//-------------------------------------------------------------------------------------------------------------------------
376// OEM Strings (Type 11)
377//-------------------------------------------------------------------------------------------------------------------------
378//void decodeSMBOEMStrings(SMBOEMStrings *structHeader)
379//{
380//DBG("OEM Strings:\n");
381//DBG("\tString 1: %d\n"); //, structHeader->string1);
382//DBG("\tString 2: %d\n"); //, structHeader->string1);
383//DBG("\tString 3: %d\n"); //, structHeader->string1);
384//DBG("\n");
385//}
386
387//-------------------------------------------------------------------------------------------------------------------------
388// MemoryDevice (Type 17)
389//-------------------------------------------------------------------------------------------------------------------------
390void decodeMemoryDevice(SMBMemoryDevice *structHeader)
391{
392DBG("Memory Device:\n");
393DBG("\tDevice Locator: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->deviceLocator, neverMask));
394DBG("\tBank Locator: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->bankLocator, neverMask));
395DBG("\tMemory Type: %s\n", SMBMemoryDeviceTypes[structHeader->memoryType]);
396
397if (minorVersion < 0x03 || structHeader->header.length < 0x1B) {
398return;
399}
400DBG("\tSpeed: %d MHz\n", structHeader->memorySpeed);
401DBG("\tError Handle: %x\n", structHeader->errorHandle);
402DBG("\tManufacturer: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer, neverMask));
403DBG("\tSerial Number: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber, privateData));
404DBG("\tAsset Tag: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTag, neverMask));
405DBG("\tPart Number: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->partNumber, neverMask));
406DBG("\n");
407}
408
409//-------------------------------------------------------------------------------------------------------------------------
410// Apple Specific
411//-------------------------------------------------------------------------------------------------------------------------
412void decodeOemProcessorType(SMBOemProcessorType *structHeader)
413{
414DBG("Apple specific Processor Type:\n");
415DBG("\tCpu-type: 0x%x\n", ((SMBOemProcessorType *)structHeader)->ProcessorType);
416DBG("\n");
417}
418
419void decodeOemProcessorBusSpeed(SMBOemProcessorBusSpeed *structHeader)
420{
421DBG("Apple specific Processor Interconnect Speed:\n");
422DBG("\tQPI = %d.%dGT/s\n",
423((SMBOemProcessorBusSpeed *)structHeader)->ProcessorBusSpeed / 1000,
424(((SMBOemProcessorBusSpeed *)structHeader)->ProcessorBusSpeed / 100) % 10);
425DBG("\n");
426}
427//-------------------------------------------------------------------------------------------------------------------------
428
429
430void decodeSMBIOSTable(SMBEntryPoint *eps)
431{
432uint8_t *ptr = (uint8_t *)eps->dmi.tableAddress;
433SMBStructHeader *structHeader = (SMBStructHeader *)ptr;
434
435minorVersion = eps->minorVersion;
436majorVersion = eps->majorVersion;
437bcdRevisionHi = eps->dmi.bcdRevision >> 4;
438bcdRevisionLo = eps->dmi.bcdRevision & 0x0F;
439
440getBoolForKey(kPrivateData, &privateData, &bootInfo->chameleonConfig); // Bungo: chek if mask some data
441
442DBG("\n");
443DBG("SMBIOS rev. %d.%d, DMI rev. %d.%d\n", majorVersion, minorVersion, bcdRevisionHi, bcdRevisionLo);
444DBG("\n");
445for (;((eps->dmi.tableAddress + eps->dmi.tableLength) > ((uint32_t)(uint8_t *)structHeader + sizeof(SMBStructHeader)));)
446{
447DBG("Type: %d, Length: %d, Handle: 0x%04x\n",
448structHeader->type, structHeader->length, structHeader->handle);
449
450switch (structHeader->type)
451{
452case kSMBTypeBIOSInformation: // Type 0
453decodeBIOSInformation((SMBBIOSInformation *)structHeader);
454break;
455
456case kSMBTypeSystemInformation: // Type 1
457decodeSystemInformation((SMBSystemInformation *)structHeader);
458break;
459
460case kSMBTypeBaseBoard: // Type 2
461decodeBaseBoard((SMBBaseBoard *)structHeader);
462break;
463
464case kSMBTypeSystemEnclosure: // Type 3
465decodeSystemEnclosure((SMBSystemEnclosure *)structHeader);
466break;
467
468case kSMBTypeProcessorInformation: // Type 4
469decodeProcessorInformation((SMBProcessorInformation *)structHeader);
470break;
471
472//case 6: // kSMBTypeMemoryModule: // Type 6
473//decodeMemoryModule((SMBMemoryModule *)structHeader);
474//break;
475
476//case 11: // kSMBOEMStrings: // Type 11
477//decodeSMBOEMStrings((SMBOEMStrings *)structHeader);
478//break;
479
480case kSMBTypeMemoryDevice: // Type 17
481decodeMemoryDevice((SMBMemoryDevice *)structHeader);
482break;
483
484//kSMBTypeMemoryArrayMappedAddress: // Type 19
485
486/* Skip all Apple Specific Structures */
487case kSMBTypeFirmwareVolume: // Type 128
488case kSMBTypeMemorySPD: // Type 130
489break;
490
491case kSMBTypeOemProcessorType: // Type 131
492decodeOemProcessorType((SMBOemProcessorType *)structHeader);
493break;
494
495case kSMBTypeOemProcessorBusSpeed: // Type 132
496decodeOemProcessorBusSpeed((SMBOemProcessorBusSpeed *)structHeader);
497break;
498
499//kSMBTypeOemPlatformFeature: // Type 133
500
501case kSMBTypeEndOfTable: // Type 127
502/* Skip, to be added at the end */
503break;
504
505default:
506break;
507}
508
509ptr = (uint8_t *)((uint32_t)structHeader + structHeader->length);
510for (; ((uint16_t *)ptr)[0] != 0; ptr++);
511
512if (((uint16_t *)ptr)[0] == 0) {
513ptr += 2;
514}
515
516structHeader = (SMBStructHeader *)ptr;
517}
518DBG("\n");
519}
520
521

Archive Download this file

Revision: 2349