Chameleon

Chameleon Svn Source Tree

Root/branches/ErmaC/Enoch/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 < 1 || structHeader->header.length < 25) {
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 < 4 || structHeader->header.length < 27) {
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("\tProcessor Family 2: %d\n", structHeader->processorFamily2);
353DBG("\n");
354}
355
356//-------------------------------------------------------------------------------------------------------------------------
357// Memory Module Information (Type 6)
358//-------------------------------------------------------------------------------------------------------------------------
359//void decodeMemoryModule(SMBMemoryModule *structHeader)
360//{
361//DBG("Memory Module Information:\n");
362//DBG("\tSocket Designation: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->socketDesignation));
363//DBG("\tBank Connections: Type: %d\n", structHeader->bankConnections);
364//DBG("\tCurrent Speed: %X\n", structHeader->currentSpeed);
365//DBG("\tCurrent Memory Type: %llX\n", structHeader->currentMemoryType);
366//DBG("\tInstalled Size: %d\n", structHeader->installedSize);
367//DBG("\tEnabled Size: %d\n", structHeader->enabledSize);
368//DBG("\tError Status: %x\n", structHeader->errorStatus);
369//DBG("\n");
370//}
371
372//-------------------------------------------------------------------------------------------------------------------------
373// OEM Strings (Type 11)
374//-------------------------------------------------------------------------------------------------------------------------
375//void decodeSMBOEMStrings(SMBOEMStrings *structHeader)
376//{
377//DBG("OEM Strings:\n");
378//DBG("\tString 1: %d\n"); //, structHeader->string1);
379//DBG("\tString 2: %d\n"); //, structHeader->string1);
380//DBG("\tString 3: %d\n"); //, structHeader->string1);
381//DBG("\n");
382//}
383
384//-------------------------------------------------------------------------------------------------------------------------
385// MemoryDevice (Type 17)
386//-------------------------------------------------------------------------------------------------------------------------
387void decodeMemoryDevice(SMBMemoryDevice *structHeader)
388{
389DBG("Memory Device:\n");
390DBG("\tDevice Locator: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->deviceLocator, neverMask));
391DBG("\tBank Locator: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->bankLocator, neverMask));
392DBG("\tMemory Type: %s\n", SMBMemoryDeviceTypes[structHeader->memoryType]);
393
394if (minorVersion < 3 || structHeader->header.length < 27) {
395return;
396}
397DBG("\tSpeed: %d MHz\n", structHeader->memorySpeed);
398DBG("\tError Handle: %x\n", structHeader->errorHandle);
399DBG("\tManufacturer: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer, neverMask));
400DBG("\tSerial Number: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber, privateData));
401DBG("\tAsset Tag: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTag, neverMask));
402DBG("\tPart Number: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->partNumber, neverMask));
403DBG("\n");
404}
405
406//-------------------------------------------------------------------------------------------------------------------------
407// Apple Specific
408//-------------------------------------------------------------------------------------------------------------------------
409void decodeOemProcessorType(SMBOemProcessorType *structHeader)
410{
411DBG("Apple specific Processor Type:\n");
412DBG("\tCpu-type: 0x%x\n", ((SMBOemProcessorType *)structHeader)->ProcessorType);
413DBG("\n");
414}
415
416void decodeOemProcessorBusSpeed(SMBOemProcessorBusSpeed *structHeader)
417{
418DBG("Apple specific Processor Interconnect Speed:\n");
419DBG("\tQPI = %d.%dGT/s\n",
420((SMBOemProcessorBusSpeed *)structHeader)->ProcessorBusSpeed / 1000,
421(((SMBOemProcessorBusSpeed *)structHeader)->ProcessorBusSpeed / 100) % 10);
422DBG("\n");
423}
424//-------------------------------------------------------------------------------------------------------------------------
425
426
427void decodeSMBIOSTable(SMBEntryPoint *eps)
428{
429uint8_t *ptr = (uint8_t *)eps->dmi.tableAddress;
430SMBStructHeader *structHeader = (SMBStructHeader *)ptr;
431
432minorVersion = eps->minorVersion;
433majorVersion = eps->majorVersion;
434bcdRevisionHi = eps->dmi.bcdRevision >> 4;
435bcdRevisionLo = eps->dmi.bcdRevision & 0x0F;
436
437getBoolForKey(kPrivateData, &privateData, &bootInfo->chameleonConfig); // Bungo: chek if mask some data
438
439DBG("\n");
440DBG("SMBIOS rev. %d.%d, DMI rev. %d.%d\n", majorVersion, minorVersion, bcdRevisionHi, bcdRevisionLo);
441DBG("\n");
442for (;((eps->dmi.tableAddress + eps->dmi.tableLength) > ((uint32_t)(uint8_t *)structHeader + sizeof(SMBStructHeader)));)
443{
444DBG("Type: %d, Length: %d, Handle: 0x%04x\n",
445structHeader->type, structHeader->length, structHeader->handle);
446
447switch (structHeader->type)
448{
449case kSMBTypeBIOSInformation: // Type 0
450decodeBIOSInformation((SMBBIOSInformation *)structHeader);
451break;
452
453case kSMBTypeSystemInformation: // Type 1
454decodeSystemInformation((SMBSystemInformation *)structHeader);
455break;
456
457case kSMBTypeBaseBoard: // Type 2
458decodeBaseBoard((SMBBaseBoard *)structHeader);
459break;
460
461case kSMBTypeSystemEnclosure: // Type 3
462decodeSystemEnclosure((SMBSystemEnclosure *)structHeader);
463break;
464
465case kSMBTypeProcessorInformation: // Type 4
466decodeProcessorInformation((SMBProcessorInformation *)structHeader);
467break;
468
469//case 6: // kSMBTypeMemoryModule: // Type 6
470//decodeMemoryModule((SMBMemoryModule *)structHeader);
471//break;
472
473//case 11: // kSMBOEMStrings: // Type 11
474//decodeSMBOEMStrings((SMBOEMStrings *)structHeader);
475//break;
476
477case kSMBTypeMemoryDevice: // Type 17
478decodeMemoryDevice((SMBMemoryDevice *)structHeader);
479break;
480
481//kSMBTypeMemoryArrayMappedAddress: // Type 19
482
483/* Skip all Apple Specific Structures */
484case kSMBTypeFirmwareVolume: // Type 128
485case kSMBTypeMemorySPD: // Type 130
486break;
487
488case kSMBTypeOemProcessorType: // Type 131
489decodeOemProcessorType((SMBOemProcessorType *)structHeader);
490break;
491
492case kSMBTypeOemProcessorBusSpeed: // Type 132
493decodeOemProcessorBusSpeed((SMBOemProcessorBusSpeed *)structHeader);
494break;
495
496//kSMBTypeOemPlatformFeature: // Type 133
497
498case kSMBTypeEndOfTable: // Type 127
499/* Skip, to be added at the end */
500break;
501
502default:
503break;
504}
505
506ptr = (uint8_t *)((uint32_t)structHeader + structHeader->length);
507for (; ((uint16_t *)ptr)[0] != 0; ptr++);
508
509if (((uint16_t *)ptr)[0] == 0) {
510ptr += 2;
511}
512
513structHeader = (SMBStructHeader *)ptr;
514}
515DBG("\n");
516}
517
518

Archive Download this file

Revision: 2341