1 | ␊ |
2 | ␊ |
3 | #include "SMBIOS.h"␊ |
4 | #include "Platform.h"␊ |
5 | #include "boot.h"␊ |
6 | ␊ |
7 | static const char * const SMTAG = "_SM_";␊ |
8 | static const char* const DMITAG= "_DMI_";␊ |
9 | static struct SMBEntryPoint *getAddressOfSmbiosTable(void);␊ |
10 | ␊ |
11 | static struct SMBEntryPoint *getAddressOfSmbiosTable(void)␊ |
12 | {␊ |
13 | ␉struct SMBEntryPoint␉*smbios;␊ |
14 | ␉/* ␊ |
15 | ␉ * The logic is to start at 0xf0000 and end at 0xfffff iterating 16 bytes at a time looking␊ |
16 | ␉ * for the SMBIOS entry-point structure anchor (literal ASCII "_SM_").␊ |
17 | ␉ */␊ |
18 | ␉smbios = (struct SMBEntryPoint*) SMBIOS_RANGE_START;␊ |
19 | ␉while (smbios <= (struct SMBEntryPoint *)SMBIOS_RANGE_END)␊ |
20 | ␉{␊ |
21 | ␉␉if (COMPARE_DWORD(smbios->anchor, SMTAG) && ␊ |
22 | ␉␉␉COMPARE_DWORD(smbios->dmi.anchor, DMITAG) &&␊ |
23 | ␉␉␉smbios->dmi.anchor[4]==DMITAG[4] &&␊ |
24 | ␉␉␉checksum8(smbios, sizeof(struct SMBEntryPoint)) == 0)␊ |
25 | ␉ {␉␉␉␊ |
26 | ␉␉␉return ((void*)smbios);␊ |
27 | ␉ }␊ |
28 | ␉␉smbios = (struct SMBEntryPoint*) ( ((char*) smbios) + 16 );␊ |
29 | ␉}␊ |
30 | ␉printf("Error: Could not find original SMBIOS !!\n");␊ |
31 | ␉pause();␊ |
32 | ␉return NULL;␊ |
33 | }␊ |
34 | ␊ |
35 | struct SMBEntryPoint *getSmbiosOriginal()␊ |
36 | { ␉␊ |
37 | static struct SMBEntryPoint *orig = NULL; // cached␊ |
38 | ␊ |
39 | if (orig == NULL)␊ |
40 | ␉{␊ |
41 | ␉␉orig = getAddressOfSmbiosTable();␉␉␊ |
42 | ␉␉␊ |
43 | ␉␉if (orig)␊ |
44 | ␉␉{␊ |
45 | ␉␉␉verbose("Found System Management BIOS (SMBIOS) table\n");␉␉␉␊ |
46 | ␉␉}␊ |
47 | ␊ |
48 | }␊ |
49 | return orig; ␊ |
50 | }␊ |
51 | ␊ |
52 | /* get product Name from original SMBIOS */␊ |
53 | char* readDefaultPlatformName(void)␊ |
54 | {␉␉␉␊ |
55 | ␉␊ |
56 | ␉SMBEntryPoint *eps = getSmbiosOriginal();␊ |
57 | ␉if (eps == NULL) return NULL;␊ |
58 | ␉␊ |
59 | ␉uint8_t *structPtr = (uint8_t *)eps->dmi.tableAddress;␊ |
60 | ␉SMBStructHeader *structHeader = (SMBStructHeader *)structPtr;␊ |
61 | ␉␊ |
62 | ␉for (;((eps->dmi.tableAddress + eps->dmi.tableLength) > ((uint32_t)(uint8_t *)structHeader + sizeof(SMBStructHeader)));)␊ |
63 | ␉{␊ |
64 | ␉␉switch (structHeader->type)␊ |
65 | ␉␉{␉␉␉␉␊ |
66 | ␉␉␉case kSMBTypeSystemInformation: ␊ |
67 | ␉␉␉{␊ |
68 | ␉␉␉␉uint8_t *stringPtr = (uint8_t *)structHeader + structHeader->length;␊ |
69 | ␉␉␉␉uint8_t field = ((SMBSystemInformation *)structHeader)->productName;␊ |
70 | ␉␉␉␉␊ |
71 | ␉␉␉␉if (!field)␊ |
72 | ␉␉␉␉␉return NULL;␊ |
73 | ␉␉␉␉␊ |
74 | ␉␉␉␉for (field--; field != 0 && strlen((char *)stringPtr) > 0; ␊ |
75 | ␉␉␉␉␉ field--, stringPtr = (uint8_t *)((uint32_t)stringPtr + strlen((char *)stringPtr) + 1));␊ |
76 | ␉␉␉␉␊ |
77 | ␉␉␉␉//DBG("original SMBIOS Product name: %s\n",(char *)stringPtr);␊ |
78 | ␉␉␉␉if (stringPtr)␊ |
79 | ␉␉␉␉␉return (char *)stringPtr;␊ |
80 | ␉␉␉␉else ␊ |
81 | ␉␉␉␉␉return NULL;␉␉␉␊ |
82 | ␉␉␉␉␊ |
83 | ␉␉␉␉break;␉␊ |
84 | ␉␉␉}␉␉␉␊ |
85 | ␉␉␉default:␊ |
86 | ␉␉␉␉break;␊ |
87 | ␉␉␉␉␊ |
88 | ␉␉}␊ |
89 | ␉␉␊ |
90 | ␉␉structPtr = (uint8_t *)((uint32_t)structHeader + structHeader->length);␊ |
91 | ␉␉for (; ((uint16_t *)structPtr)[0] != 0; structPtr++);␊ |
92 | ␉␉␊ |
93 | ␉␉if (((uint16_t *)structPtr)[0] == 0)␊ |
94 | ␉␉␉structPtr += 2;␊ |
95 | ␉␉␊ |
96 | ␉␉structHeader = (SMBStructHeader *)structPtr;␊ |
97 | ␉}␉␊ |
98 | ␉return NULL;␊ |
99 | }␊ |
100 | ␊ |
101 | /* get UUID or product Name from original SMBIOS, stripped version of kabyl's readSMBIOSInfo */␊ |
102 | int readSMBIOS(int value)␊ |
103 | {␉␉␉␊ |
104 | ␉␊ |
105 | ␉SMBEntryPoint *eps = getSmbiosOriginal();␊ |
106 | ␉if (eps == NULL) return 0;␊ |
107 | ␉␊ |
108 | ␉uint8_t *structPtr = (uint8_t *)eps->dmi.tableAddress;␊ |
109 | ␉SMBStructHeader *structHeader = (SMBStructHeader *)structPtr;␊ |
110 | ␉␊ |
111 | ␉for (;((eps->dmi.tableAddress + eps->dmi.tableLength) > ((uint32_t)(uint8_t *)structHeader + sizeof(SMBStructHeader)));)␊ |
112 | ␉{␊ |
113 | ␉␉switch (structHeader->type)␊ |
114 | ␉␉{␉␉␉␉␊ |
115 | ␉␉␉case kSMBTypeSystemInformation: ␊ |
116 | ␉␉␉{␊ |
117 | ␉␉␉␉switch (value) {␊ |
118 | ␉␉␉␉␉case theUUID:␊ |
119 | ␉␉␉␉␉␉Platform->UUID = ((SMBSystemInformation *)structHeader)->uuid;␊ |
120 | ␉␉␉␉␉␉return 1;␊ |
121 | ␉␉␉␉␉␉break;␊ |
122 | ␉␉␉␉␉case thePlatformName:␊ |
123 | ␉␉␉␉␉{␊ |
124 | ␉␉␉␉␉␉uint8_t *stringPtr = (uint8_t *)structHeader + structHeader->length;␊ |
125 | ␉␉␉␉␉␉uint8_t field = ((SMBSystemInformation *)structHeader)->productName;␊ |
126 | ␉␉␉␉␉␉␊ |
127 | ␉␉␉␉␉␉if (!field)␊ |
128 | ␉␉␉␉␉␉␉return 0;␊ |
129 | ␉␉␉␉␉␉␊ |
130 | ␉␉␉␉␉␉for (field--; field != 0 && strlen((char *)stringPtr) > 0; ␊ |
131 | ␉␉␉␉␉␉␉ field--, stringPtr = (uint8_t *)((uint32_t)stringPtr + strlen((char *)stringPtr) + 1));␊ |
132 | ␉␉␉␉␉␉␊ |
133 | ␉␉␉␉␉␉//DBG("original SMBIOS Product name: %s\n",(char *)stringPtr);␊ |
134 | ␉␉␉␉␉␉gPlatformName = (char *)stringPtr;␊ |
135 | ␉␉␉␉␉␉if (gPlatformName) return 1;␊ |
136 | ␉␉␉␉␉␉break;␊ |
137 | ␉␉␉␉␉}␊ |
138 | ␉␉␉␉␉default:␊ |
139 | ␉␉␉␉␉␉break;␊ |
140 | ␉␉␉␉}␉␉␉␉␊ |
141 | ␉␉␉␉␊ |
142 | ␉␉␉␉break;␉␊ |
143 | ␉␉␉}␊ |
144 | ␉␉␉case kSMBTypeBaseBoard:␊ |
145 | {␊ |
146 | ␉␉␉␉switch (value) {␊ |
147 | ␉␉␉␉␉case theProducBoard:␊ |
148 | ␉␉␉␉␉{␊ |
149 | ␉␉␉␉␉␉uint8_t *stringPtr = (uint8_t *)structHeader + structHeader->length;␊ |
150 | ␉␉␉␉␉␉uint8_t field = ((SMBBaseBoard *)structHeader)->product;␊ |
151 | ␉␉␉␉␉␉␊ |
152 | ␉␉␉␉␉␉if (!field)␊ |
153 | ␉␉␉␉␉␉␉return 0;␊ |
154 | ␉␉␉␉␉␉␊ |
155 | ␉␉␉␉␉␉for (field--; field != 0 && strlen((char *)stringPtr) > 0; ␊ |
156 | ␉␉␉␉␉␉␉ field--, stringPtr = (uint8_t *)((uint32_t)stringPtr + strlen((char *)stringPtr) + 1));␊ |
157 | ␉␉␉␉␉␉␊ |
158 | ␉␉␉␉␉␉gboardproduct = (char *)stringPtr;␊ |
159 | ␉␉␉␉␉␉if (gboardproduct) return 1;␊ |
160 | ␉␉␉␉␉␉break;␊ |
161 | ␉␉␉␉␉}␊ |
162 | ␉␉␉␉␉default:␊ |
163 | ␉␉␉␉␉␉break;␊ |
164 | ␉␉␉␉}␊ |
165 | ␉␉␉␉break;␊ |
166 | }␊ |
167 | ␉␉␉default:␊ |
168 | ␉␉␉␉break;␊ |
169 | ␉␉␉␉␊ |
170 | ␉␉}␊ |
171 | ␉␉␊ |
172 | ␉␉structPtr = (uint8_t *)((uint32_t)structHeader + structHeader->length);␊ |
173 | ␉␉for (; ((uint16_t *)structPtr)[0] != 0; structPtr++);␊ |
174 | ␉␉␊ |
175 | ␉␉if (((uint16_t *)structPtr)[0] == 0)␊ |
176 | ␉␉␉structPtr += 2;␊ |
177 | ␉␉␊ |
178 | ␉␉structHeader = (SMBStructHeader *)structPtr;␊ |
179 | ␉}␉␊ |
180 | ␉return 0;␊ |
181 | } |