Root/
Source at commit 2606 created 9 years 4 months ago. By ifabio, DEBUG option for last booted partition | |
---|---|
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 | ␊ |
21 | ␊ |
22 | static SMBWord minorVersion;␊ |
23 | ␊ |
24 | extern char *getSMBStringForField(SMBStructHeader *structHeader, uint8_t field);␊ |
25 | ␊ |
26 | static const char *␊ |
27 | SMBMemoryDeviceTypes[] =␊ |
28 | {␊ |
29 | "RAM", /* 00h Undefined */␊ |
30 | "RAM", /* 01h Other */␊ |
31 | "RAM", /* 02h Unknown */␊ |
32 | "DRAM", /* 03h DRAM */␊ |
33 | "EDRAM", /* 04h EDRAM */␊ |
34 | "VRAM", /* 05h VRAM */␊ |
35 | "SRAM", /* 06h SRAM */␊ |
36 | "RAM", /* 07h RAM */␊ |
37 | "ROM", /* 08h ROM */␊ |
38 | "FLASH", /* 09h FLASH */␊ |
39 | "EEPROM", /* 0Ah EEPROM */␊ |
40 | "FEPROM", /* 0Bh FEPROM */␊ |
41 | "EPROM", /* 0Ch EPROM */␊ |
42 | "CDRAM", /* 0Dh CDRAM */␊ |
43 | "3DRAM", /* 0Eh 3DRAM */␊ |
44 | "SDRAM", /* 0Fh SDRAM */␊ |
45 | "SGRAM", /* 10h SGRAM */␊ |
46 | "RDRAM", /* 11h RDRAM */␊ |
47 | "DDR SDRAM", /* 12h DDR */␊ |
48 | "DDR2 SDRAM", /* 13h DDR2 */␊ |
49 | "DDR2 FB-DIMM", /* 14h DDR2 FB-DIMM */␊ |
50 | "RAM",␉␉␉/* 15h unused */␊ |
51 | "RAM",␉␉␉/* 16h unused */␊ |
52 | "RAM",␉␉␉/* 17h unused */␊ |
53 | "DDR3",␉␉␉/* 18h DDR3, chosen in [5776134] */␊ |
54 | };␊ |
55 | ␊ |
56 | static const int␊ |
57 | kSMBMemoryDeviceTypeCount = sizeof(SMBMemoryDeviceTypes) /␊ |
58 | sizeof(SMBMemoryDeviceTypes[0]);␊ |
59 | ␊ |
60 | //-------------------------------------------------------------------------------------------------------------------------␊ |
61 | // BIOSInformation␊ |
62 | //-------------------------------------------------------------------------------------------------------------------------␊ |
63 | void decodeBIOSInformation(SMBBIOSInformation *structHeader)␊ |
64 | {␊ |
65 | ␉DBG("BIOSInformation:\n");␊ |
66 | ␉DBG("\tvendor: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->vendor));␊ |
67 | ␉DBG("\tversion: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->version));␊ |
68 | ␉DBG("\treleaseDate: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->releaseDate));␊ |
69 | ␉DBG("\n");␊ |
70 | }␊ |
71 | ␊ |
72 | //-------------------------------------------------------------------------------------------------------------------------␊ |
73 | // SystemInformation␊ |
74 | //-------------------------------------------------------------------------------------------------------------------------␊ |
75 | void decodeSystemInformation(SMBSystemInformation *structHeader)␊ |
76 | {␊ |
77 | ␉DBG("SystemInformation:\n");␊ |
78 | ␉DBG("\tmanufacturer: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer));␊ |
79 | ␉DBG("\tproductName: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->productName));␊ |
80 | ␉DBG("\tversion: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->version));␊ |
81 | ␉DBG("\tserialNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber));␊ |
82 | ␊ |
83 | ␉if (minorVersion < 1 || structHeader->header.length < 25)␊ |
84 | ␉␉return;␊ |
85 | ␉uint8_t *uuid = structHeader->uuid;␊ |
86 | ␉DBG("\tuuid: %02X%02X%02X%02X-%02X%02X-%02X%02X-%02x%02X-%02X%02X%02X%02X%02X%02X\n",␊ |
87 | ␉␉uuid[0], uuid[1], uuid[2], uuid[3], ␊ |
88 | ␉␉uuid[4], uuid[5], ␊ |
89 | ␉␉uuid[6], uuid[7], ␊ |
90 | ␉␉uuid[8], uuid[9], ␊ |
91 | ␉␉uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);␊ |
92 | ␉DBG("\twakeupReason: 0x%x\n", structHeader->wakeupReason);␊ |
93 | ␊ |
94 | ␉if (minorVersion < 4 || structHeader->header.length < 27)␊ |
95 | ␉␉return;␊ |
96 | ␉DBG("\tskuNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->skuNumber));␊ |
97 | ␉DBG("\tfamily: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->family));␊ |
98 | ␉DBG("\n");␊ |
99 | }␊ |
100 | ␊ |
101 | //-------------------------------------------------------------------------------------------------------------------------␊ |
102 | // BaseBoard␊ |
103 | //-------------------------------------------------------------------------------------------------------------------------␊ |
104 | void decodeBaseBoard(SMBBaseBoard *structHeader)␊ |
105 | {␊ |
106 | ␉DBG("BaseBoard:\n");␊ |
107 | ␉DBG("\tmanufacturer: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer));␊ |
108 | ␉DBG("\tproduct: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->product));␊ |
109 | ␉DBG("\tversion: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->version));␊ |
110 | ␉DBG("\tserialNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber));␊ |
111 | ␉DBG("\tassetTagNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTagNumber));␊ |
112 | ␉DBG("\tlocationInChassis: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->locationInChassis));␊ |
113 | ␉DBG("\tboardType: 0x%X\n", structHeader->boardType);␊ |
114 | ␉DBG("\n");␊ |
115 | }␊ |
116 | ␊ |
117 | //-------------------------------------------------------------------------------------------------------------------------␊ |
118 | // SystemEnclosure␊ |
119 | //-------------------------------------------------------------------------------------------------------------------------␊ |
120 | void decodeSystemEnclosure(SMBSystemEnclosure *structHeader)␊ |
121 | {␊ |
122 | ␉DBG("SystemEnclosure:\n");␊ |
123 | ␉DBG("\tmanufacturer: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer));␊ |
124 | ␉DBG("\ttype: %d\n", structHeader->type);␊ |
125 | ␉DBG("\tversion: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->version));␊ |
126 | ␉DBG("\tserialNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber));␊ |
127 | ␉DBG("\tassetTagNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTagNumber));␊ |
128 | ␉DBG("\n");␊ |
129 | }␊ |
130 | ␊ |
131 | //-------------------------------------------------------------------------------------------------------------------------␊ |
132 | // ProcessorInformation␊ |
133 | //-------------------------------------------------------------------------------------------------------------------------␊ |
134 | void decodeProcessorInformation(SMBProcessorInformation *structHeader)␊ |
135 | {␊ |
136 | ␉DBG("ProcessorInformation:\n");␊ |
137 | ␉DBG("\tsocketDesignation: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->socketDesignation));␊ |
138 | ␉DBG("\tprocessorType: %d\n", structHeader->processorType);␊ |
139 | ␉DBG("\tprocessorFamily: 0x%X\n", structHeader->processorFamily);␊ |
140 | ␉DBG("\tmanufacturer: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer));␊ |
141 | ␉DBG("\tprocessorID: 0x%llX\n", structHeader->processorID);␊ |
142 | ␉DBG("\tprocessorVersion: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->processorVersion));␊ |
143 | ␉DBG("\texternalClock: %dMHz\n", structHeader->externalClock);␊ |
144 | ␉DBG("\tmaximumClock: %dMHz\n", structHeader->maximumClock);␊ |
145 | ␉DBG("\tcurrentClock: %dMHz\n", structHeader->currentClock);␊ |
146 | ␊ |
147 | ␉if (minorVersion < 3 || structHeader->header.length < 35)␊ |
148 | ␉␉return;␊ |
149 | ␉DBG("\tserialNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber));␊ |
150 | ␉DBG("\tassetTag: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTag));␊ |
151 | ␉DBG("\tpartNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->partNumber));␊ |
152 | ␉DBG("\n");␊ |
153 | }␊ |
154 | ␊ |
155 | //-------------------------------------------------------------------------------------------------------------------------␊ |
156 | // MemoryDevice␊ |
157 | //-------------------------------------------------------------------------------------------------------------------------␊ |
158 | void decodeMemoryDevice(SMBMemoryDevice *structHeader)␊ |
159 | {␊ |
160 | ␉DBG("MemoryDevice:\n");␊ |
161 | ␉DBG("\tdeviceLocator: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->deviceLocator));␊ |
162 | ␉DBG("\tbankLocator: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->bankLocator));␊ |
163 | ␉DBG("\tmemoryType: %s\n", SMBMemoryDeviceTypes[structHeader->memoryType]);␊ |
164 | ␊ |
165 | ␉if (minorVersion < 3 || structHeader->header.length < 27)␊ |
166 | ␉␉return;␊ |
167 | ␉DBG("\tmemorySpeed: %dMHz\n", structHeader->memorySpeed);␊ |
168 | ␉DBG("\tmanufacturer: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer));␊ |
169 | ␉DBG("\tserialNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber));␊ |
170 | ␉DBG("\tassetTag: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTag));␊ |
171 | ␉DBG("\tpartNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->partNumber));␊ |
172 | ␉DBG("\n");␊ |
173 | }␊ |
174 | ␊ |
175 | //-------------------------------------------------------------------------------------------------------------------------␊ |
176 | // Apple Specific␊ |
177 | //-------------------------------------------------------------------------------------------------------------------------␊ |
178 | void decodeOemProcessorType(SMBOemProcessorType *structHeader)␊ |
179 | {␊ |
180 | ␉DBG("AppleProcessorType:\n");␊ |
181 | ␉DBG("\tProcessorType: 0x%x\n", ((SMBOemProcessorType *)structHeader)->ProcessorType);␊ |
182 | ␉DBG("\n");␊ |
183 | }␊ |
184 | ␊ |
185 | void decodeOemProcessorBusSpeed(SMBOemProcessorBusSpeed *structHeader)␊ |
186 | {␊ |
187 | ␉DBG("AppleProcessorBusSpeed:\n");␊ |
188 | ␉DBG("\tProcessorBusSpeed (QPI): %d.%dGT/s\n", ␊ |
189 | ␉␉␉((SMBOemProcessorBusSpeed *)structHeader)->ProcessorBusSpeed / 1000, ␊ |
190 | ␉␉␉(((SMBOemProcessorBusSpeed *)structHeader)->ProcessorBusSpeed / 100) % 10);␊ |
191 | ␉DBG("\n");␊ |
192 | }␊ |
193 | //-------------------------------------------------------------------------------------------------------------------------␊ |
194 | ␊ |
195 | ␊ |
196 | void decodeSMBIOSTable(SMBEntryPoint *eps)␊ |
197 | {␊ |
198 | ␉uint8_t *ptr = (uint8_t *)eps->dmi.tableAddress;␊ |
199 | ␉SMBStructHeader *structHeader = (SMBStructHeader *)ptr;␊ |
200 | ␊ |
201 | ␉minorVersion = eps->minorVersion;␊ |
202 | ␊ |
203 | ␉DBG("\n");␊ |
204 | ␉for (;((eps->dmi.tableAddress + eps->dmi.tableLength) > ((uint32_t)(uint8_t *)structHeader + sizeof(SMBStructHeader)));)␊ |
205 | ␉{␊ |
206 | ␉␉DBG("Type: %d, Length: %d, Handle: 0x%x\n", ␊ |
207 | ␉␉␉␉structHeader->type, structHeader->length, structHeader->handle);␊ |
208 | ␊ |
209 | ␉␉switch (structHeader->type)␊ |
210 | ␉␉{␊ |
211 | ␉␉␉case kSMBTypeBIOSInformation:␊ |
212 | ␉␉␉␉decodeBIOSInformation((SMBBIOSInformation *)structHeader);␊ |
213 | ␉␉␉␉break;␊ |
214 | ␊ |
215 | ␉␉␉case kSMBTypeSystemInformation:␊ |
216 | ␉␉␉␉decodeSystemInformation((SMBSystemInformation *)structHeader);␊ |
217 | ␉␉␉␉break;␊ |
218 | ␊ |
219 | ␉␉␉case kSMBTypeBaseBoard:␊ |
220 | ␉␉␉␉decodeBaseBoard((SMBBaseBoard *)structHeader);␊ |
221 | ␉␉␉␉break;␊ |
222 | ␊ |
223 | ␉␉␉case kSMBTypeSystemEnclosure:␊ |
224 | ␉␉␉␉decodeSystemEnclosure((SMBSystemEnclosure *)structHeader);␊ |
225 | ␉␉␉␉break;␊ |
226 | ␊ |
227 | ␉␉␉case kSMBTypeProcessorInformation:␊ |
228 | ␉␉␉␉decodeProcessorInformation((SMBProcessorInformation *)structHeader);␊ |
229 | ␉␉␉␉break;␊ |
230 | ␊ |
231 | ␉␉␉case kSMBTypeMemoryDevice:␊ |
232 | ␉␉␉␉decodeMemoryDevice((SMBMemoryDevice *)structHeader);␊ |
233 | ␉␉␉␉break;␊ |
234 | ␊ |
235 | ␉␉␉/* Skip all Apple Specific Structures */␊ |
236 | ␉␉␉case kSMBTypeFirmwareVolume:␊ |
237 | ␉␉␉case kSMBTypeMemorySPD:␊ |
238 | ␉␉␉␉break;␊ |
239 | ␊ |
240 | ␉␉␉case kSMBTypeOemProcessorType:␊ |
241 | ␉␉␉␉decodeOemProcessorType((SMBOemProcessorType *)structHeader);␊ |
242 | ␉␉␉␉break;␊ |
243 | ␊ |
244 | ␉␉␉case kSMBTypeOemProcessorBusSpeed:␊ |
245 | ␉␉␉␉decodeOemProcessorBusSpeed((SMBOemProcessorBusSpeed *)structHeader);␊ |
246 | ␉␉␉␉break;␊ |
247 | ␊ |
248 | ␉␉␉case kSMBTypeEndOfTable:␊ |
249 | ␉␉␉␉/* Skip, to be added at the end */␊ |
250 | ␉␉␉␉break;␊ |
251 | ␊ |
252 | ␉␉␉default:␊ |
253 | ␉␉␉␉break;␊ |
254 | ␉␉}␊ |
255 | ␊ |
256 | ␉␉ptr = (uint8_t *)((uint32_t)structHeader + structHeader->length);␊ |
257 | ␉␉for (; ((uint16_t *)ptr)[0] != 0; ptr++);␊ |
258 | ␊ |
259 | ␉␉if (((uint16_t *)ptr)[0] == 0)␊ |
260 | ␉␉␉ptr += 2;␊ |
261 | ␊ |
262 | ␉␉structHeader = (SMBStructHeader *)ptr;␊ |
263 | ␉}␊ |
264 | ␉DBG("\n");␊ |
265 | }␊ |
266 | ␊ |
267 |