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

Archive Download this file

Revision: 2347