Chameleon

Chameleon Svn Source Tree

Root/branches/chucko/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//
38static const char *
39SMBMemoryDeviceTypes[] =
40{
41 "RAM", /* 00h Undefined */
42 "RAM", /* 01h Other */
43 "RAM", /* 02h Unknown */
44 "DRAM", /* 03h DRAM */
45 "EDRAM", /* 04h EDRAM */
46 "VRAM", /* 05h VRAM */
47 "SRAM", /* 06h SRAM */
48 "RAM", /* 07h RAM */
49 "ROM", /* 08h ROM */
50 "FLASH", /* 09h FLASH */
51 "EEPROM", /* 0Ah EEPROM */
52 "FEPROM", /* 0Bh FEPROM */
53 "EPROM", /* 0Ch EPROM */
54 "CDRAM", /* 0Dh CDRAM */
55 "3DRAM", /* 0Eh 3DRAM */
56 "SDRAM", /* 0Fh SDRAM */
57 "SGRAM", /* 10h SGRAM */
58 "RDRAM", /* 11h RDRAM */
59 "DDR SDRAM", /* 12h DDR */
60 "DDR2 SDRAM", /* 13h DDR2 */
61 "DDR2 FB-DIMM", /* 14h DDR2 FB-DIMM */
62 "RAM",/* 15h unused */
63 "RAM",/* 16h unused */
64 "RAM",/* 17h unused */
65 "DDR3",/* 18h DDR3, chosen in [5776134] */
66 "FBD2"/* 19h FBD2 */
67};
68
69static const int kSMBMemoryDeviceTypeCount = sizeof(SMBMemoryDeviceTypes) /
70 sizeof(SMBMemoryDeviceTypes[0]);
71
72//-------------------------------------------------------------------------------------------------------------------------
73// BIOS Information (Type 0)
74//-------------------------------------------------------------------------------------------------------------------------
75void decodeBIOSInformation(SMBBIOSInformation *structHeader)
76{
77DBG("BIOS Information:\n");
78DBG("\tVendor: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->vendor));
79DBG("\tVersion: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->version));
80// Address Segment
81DBG("\tRelease Date: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->releaseDate));
82// ROM Size
83//DBG("\tSupported BIOS functions: (0x%llX) %s\n", structHeader->characteristics, SMBBIOSInfoChar0[structHeader->characteristics]);
84// Major Release
85// Minor Release
86// Firmware Major Release
87// Firmware Minor Release
88//SMBByte characteristicsExt1;
89//SMBByte characteristicsExt2;
90DBG("\n");
91}
92
93//-------------------------------------------------------------------------------------------------------------------------
94// System Information (Type 1)
95//-------------------------------------------------------------------------------------------------------------------------
96void decodeSystemInformation(SMBSystemInformation *structHeader)
97{
98DBG("System Information:\n");
99DBG("\tManufacturer: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer));
100DBG("\tProduct Name: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->productName));
101DBG("\tVersion: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->version));
102DBG("\tSerial Number: ** PRIVATE **\n"); //%s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber));
103
104if (minorVersion < 1 || structHeader->header.length < 25)
105return;
106uint8_t *uuid = structHeader->uuid;
107if (uuid) {
108DBG("\tuuid: %02X%02X%02X%02X-%02X%02X-%02X%02X-%02x%02X-%02X%02X%02X%02X%02X%02X\n",
109uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
110uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
111}
112DBG("\tWake-up Type: 0x%x\n", structHeader->wakeupReason);
113
114if (minorVersion < 4 || structHeader->header.length < 27)
115return;
116DBG("\tSKU Number: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->skuNumber)); // System SKU#
117DBG("\tFamily: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->family));
118DBG("\n");
119}
120
121//-------------------------------------------------------------------------------------------------------------------------
122// Base Board (or Module) Information (Type 2)
123//-------------------------------------------------------------------------------------------------------------------------
124void decodeBaseBoard(SMBBaseBoard *structHeader)
125{
126DBG("Base Board Information:\n");
127DBG("\tManufacturer: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer));
128DBG("\tProduct Name: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->product));
129DBG("\tVersion: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->version));
130DBG("\tSerial Number: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber));
131DBG("\tAsset Tag: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTagNumber));
132// Feature Flags (BYTE)
133DBG("\tLocation In Chassis: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->locationInChassis)); // Part Component
134// Chassis Handle (WORD)
135DBG("\tType: 0x%X\n", structHeader->boardType);
136// Number of Contained Object Handles (n) (BYTE)
137// Contained Object Handles n(WORDs)
138DBG("\n");
139}
140
141//-------------------------------------------------------------------------------------------------------------------------
142// System Enclosure or Chassis (Type 3)
143//-------------------------------------------------------------------------------------------------------------------------
144void decodeSystemEnclosure(SMBSystemEnclosure *structHeader)
145{
146DBG("Chassis Information:\n");
147DBG("\tManufacturer: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer));
148DBG("\tType: 0x%X\n", structHeader->chassisType);
149DBG("\tVersion: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->version));
150DBG("\tSerial Number: ** PRIVATE **\n"); //%s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber));
151DBG("\tAsset Tag Number: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTagNumber));
152// Boot-up State:
153// Power Supply State
154// Thermal State
155// Security Status:
156// OEM Information:
157// Height;
158// Cords;
159// ElementsCount;
160// ElementLen;
161// Elements[1]; // open array of ElementsCount*ElementLen BYTEs
162DBG("\n");
163}
164
165//-------------------------------------------------------------------------------------------------------------------------
166// Processor Information (Type 4)
167//-------------------------------------------------------------------------------------------------------------------------
168void decodeProcessorInformation(SMBProcessorInformation *structHeader)
169{
170DBG("Processor Information:\n");
171DBG("\tSocket Designation: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->socketDesignation));
172DBG("\tType: %d\n", structHeader->processorType);
173DBG("\tFamily: 0x%X\n", structHeader->processorFamily);
174DBG("\tManufacturer: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer));
175DBG("\tID: 0x%llX\n", structHeader->processorID);
176DBG("\tProcessor Version: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->processorVersion));
177//DBG("\tVoltage: 0.%xV\n", structHeader->voltage);
178DBG("\tExternal Clock: %dMHz\n", structHeader->externalClock);
179DBG("\tMaximum Clock: %dMHz\n", structHeader->maximumClock);
180DBG("\tCurrent Clock: %dMHz\n", structHeader->currentClock);
181
182if (minorVersion < 3 || structHeader->header.length < 35)
183return;
184DBG("\tSerial Number: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber));
185DBG("\tAsset Tag: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTag));
186DBG("\tPart Number: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->partNumber));
187//DBG("\tProcessor Family 2: %d\n", structHeader->processorFamily2);
188DBG("\n");
189}
190
191//-------------------------------------------------------------------------------------------------------------------------
192// Memory Module Information (Type 6)
193//-------------------------------------------------------------------------------------------------------------------------
194//void decodeMemoryModule(SMBMemoryModule *structHeader)
195//{
196//DBG("Memory Module Information:\n");
197//DBG("\tSocket Designation: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->socketDesignation));
198//DBG("\tBank Connections: Type: %d\n", structHeader->bankConnections);
199//DBG("\tCurrent Speed: %X\n", structHeader->currentSpeed);
200//DBG("\tCurrent Memory Type: %llX\n", structHeader->currentMemoryType);
201//DBG("\tInstalled Size: %d\n", structHeader->installedSize);
202//DBG("\tEnabled Size: %d\n", structHeader->enabledSize);
203//DBG("\tError Status: %x\n", structHeader->errorStatus);
204//DBG("\n");
205//}
206
207//-------------------------------------------------------------------------------------------------------------------------
208// OEM Strings (Type 11)
209//-------------------------------------------------------------------------------------------------------------------------
210//void decodeSMBOEMStrings(SMBOEMStrings *structHeader)
211//{
212//DBG("OEM Strings:\n");
213//DBG("\tString 1: %d\n"); //, structHeader->string1);
214//DBG("\tString 2: %d\n"); //, structHeader->string1);
215//DBG("\tString 3: %d\n"); //, structHeader->string1);
216//DBG("\n");
217//}
218
219//-------------------------------------------------------------------------------------------------------------------------
220// MemoryDevice (Type 17)
221//-------------------------------------------------------------------------------------------------------------------------
222void decodeMemoryDevice(SMBMemoryDevice *structHeader)
223{
224DBG("Memory Device:\n");
225DBG("\tDevice Locator: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->deviceLocator));
226DBG("\tBank Locator: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->bankLocator));
227DBG("\tMemory Type: %s\n", SMBMemoryDeviceTypes[structHeader->memoryType]);
228
229if (minorVersion < 3 || structHeader->header.length < 27)
230return;
231DBG("\tSpeed: %d MHz\n", structHeader->memorySpeed);
232DBG("\tError Handle: %x\n", structHeader->errorHandle);
233DBG("\tManufacturer: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer));
234DBG("\tSerial Number: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber));
235DBG("\tAsset Tag: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTag));
236DBG("\tPart Number: %s\n", SMBStringForField((SMBStructHeader *)structHeader, structHeader->partNumber));
237DBG("\n");
238}
239
240//-------------------------------------------------------------------------------------------------------------------------
241// Apple Specific
242//-------------------------------------------------------------------------------------------------------------------------
243void decodeOemProcessorType(SMBOemProcessorType *structHeader)
244{
245DBG("AppleProcessorType:\n");
246DBG("\tProcessorType: 0x%x\n", ((SMBOemProcessorType *)structHeader)->ProcessorType);
247DBG("\n");
248}
249
250void decodeOemProcessorBusSpeed(SMBOemProcessorBusSpeed *structHeader)
251{
252DBG("AppleProcessorBusSpeed:\n");
253DBG("\tProcessorBusSpeed (QPI): %d.%dGT/s\n",
254((SMBOemProcessorBusSpeed *)structHeader)->ProcessorBusSpeed / 1000,
255(((SMBOemProcessorBusSpeed *)structHeader)->ProcessorBusSpeed / 100) % 10);
256DBG("\n");
257}
258//-------------------------------------------------------------------------------------------------------------------------
259
260
261void decodeSMBIOSTable(SMBEntryPoint *eps)
262{
263uint8_t *ptr = (uint8_t *)eps->dmi.tableAddress;
264SMBStructHeader *structHeader = (SMBStructHeader *)ptr;
265
266minorVersion = eps->minorVersion;
267
268DBG("\n");
269for (;((eps->dmi.tableAddress + eps->dmi.tableLength) > ((uint32_t)(uint8_t *)structHeader + sizeof(SMBStructHeader)));)
270{
271DBG("Type: %d, Length: %d, Handle: 0x%x\n",
272structHeader->type, structHeader->length, structHeader->handle);
273
274switch (structHeader->type)
275{
276case kSMBTypeBIOSInformation: // Type 0
277decodeBIOSInformation((SMBBIOSInformation *)structHeader);
278break;
279
280case kSMBTypeSystemInformation: // Type 1
281decodeSystemInformation((SMBSystemInformation *)structHeader);
282break;
283
284case kSMBTypeBaseBoard: // Type 2
285decodeBaseBoard((SMBBaseBoard *)structHeader);
286break;
287
288case kSMBTypeSystemEnclosure: // Type 3
289decodeSystemEnclosure((SMBSystemEnclosure *)structHeader);
290break;
291
292case kSMBTypeProcessorInformation: // Type 4
293decodeProcessorInformation((SMBProcessorInformation *)structHeader);
294break;
295
296//case 6: // kSMBTypeMemoryModule: // Type 6
297//decodeMemoryModule((SMBMemoryModule *)structHeader);
298//break;
299
300//case 11: // kSMBOEMStrings: // Type 11
301//decodeSMBOEMStrings((SMBOEMStrings *)structHeader);
302//break;
303
304case kSMBTypeMemoryDevice: // Type 17
305decodeMemoryDevice((SMBMemoryDevice *)structHeader);
306break;
307
308/* Skip all Apple Specific Structures */
309case kSMBTypeFirmwareVolume: // Type 128
310case kSMBTypeMemorySPD: // Type 130
311break;
312
313case kSMBTypeOemProcessorType: // Type 131
314decodeOemProcessorType((SMBOemProcessorType *)structHeader);
315break;
316
317case kSMBTypeOemProcessorBusSpeed: // Type 132
318decodeOemProcessorBusSpeed((SMBOemProcessorBusSpeed *)structHeader);
319break;
320
321case kSMBTypeEndOfTable: // Type 127
322/* Skip, to be added at the end */
323break;
324
325default:
326break;
327}
328
329ptr = (uint8_t *)((uint32_t)structHeader + structHeader->length);
330for (; ((uint16_t *)ptr)[0] != 0; ptr++);
331
332if (((uint16_t *)ptr)[0] == 0)
333{
334ptr += 2;
335}
336
337structHeader = (SMBStructHeader *)ptr;
338}
339DBG("\n");
340}
341
342

Archive Download this file

Revision: 2329