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

Archive Download this file

Revision: 2323