5 static uint8_t smbios_checksum(const intptr_t start
, const uint32_t count
)
11 for(i
= 0; i
< count
; i
++)
13 chksum
+= *(uint8_t*)(start
+ i
);
20 static char * smbios_get_string(intptr_t location
, uint8_t id
)
35 buf
= (char *)(malloc(strlen((char *)location
+ 1)));
36 memcpy((uint8_t*)buf
, (uint8_t*)location
, strlen((char *)location
) + 1);
40 while(*(uint8_t*)location
++ != 0x00){}
41 if(*(uint8_t*)location
== 0x00 && *(uint8_t*)(location
+ 1) == 0x00){break;}
50 static void parse_smbios_memdev(intptr_t location
)
52 memcpy((uint8_t*)&sm_memdev
[sm_memdev_count
-1], (uint8_t*)(location
+ 4), sm_hdr
.length
- 4);
54 location
+= sm_hdr
.length
;
56 sm_memdev
[sm_memdev_count
-1].device_locator_s
= smbios_get_string(location
, sm_memdev
[sm_memdev_count
-1].device_locator
);
57 sm_memdev
[sm_memdev_count
-1].bank_locator_s
= smbios_get_string(location
, sm_memdev
[sm_memdev_count
-1].bank_locator
);
58 sm_memdev
[sm_memdev_count
-1].manufacturer_s
= smbios_get_string(location
, sm_memdev
[sm_memdev_count
-1].manufacturer
);
59 sm_memdev
[sm_memdev_count
-1].serial_s
= smbios_get_string(location
, sm_memdev
[sm_memdev_count
-1].serial
);
60 sm_memdev
[sm_memdev_count
-1].asset_s
= smbios_get_string(location
, sm_memdev
[sm_memdev_count
-1].asset
);
61 sm_memdev
[sm_memdev_count
-1].part_s
= smbios_get_string(location
, sm_memdev
[sm_memdev_count
-1].part
);
65 if(sm_memdev[sm_memdev_count-1].manufacturer_s){
66 console_printf(get_vterm(0), " manufacturer = %s \n", sm_memdev[sm_memdev_count-1].manufacturer_s);}
68 if(sm_memdev[sm_memdev_count-1].size > 0 && sm_memdev[sm_memdev_count-1].size < 0xFFFF)
70 console_printf(get_vterm(0), " size = %u", sm_memdev[sm_memdev_count-1].size);
71 if(sm_memdev[sm_memdev_count-1].size)
72 {console_printf(get_vterm(0), "MB\n");}
73 else{console_printf(get_vterm(0), "KB\n");}
76 if(sm_memdev[sm_memdev_count-1].speed)
77 {console_printf(get_vterm(0), " speed = %uMHz\n", sm_memdev[sm_memdev_count-1].speed);}
79 if(sm_memdev[sm_memdev_count-1].device_locator_s){
80 console_printf(get_vterm(0), " device = %s \n", sm_memdev[sm_memdev_count-1].device_locator_s);}
81 if(sm_memdev[sm_memdev_count-1].bank_locator_s){
82 console_printf(get_vterm(0), " bank = %s \n", sm_memdev[sm_memdev_count-1].bank_locator_s);}
83 if(sm_memdev[sm_memdev_count-1].serial_s){
84 console_printf(get_vterm(0), " serial = %s \n", sm_memdev[sm_memdev_count-1].serial_s);}
85 if(sm_memdev[sm_memdev_count-1].asset_s){
86 console_printf(get_vterm(0), " asset = %s \n", sm_memdev[sm_memdev_count-1].asset_s);}
87 if(sm_memdev[sm_memdev_count-1].part_s){
88 console_printf(get_vterm(0), " part = %s \n", sm_memdev[sm_memdev_count-1].part_s);}
92 static void parse_smbios_cpu(intptr_t location
)
94 memcpy((uint8_t*)&sm_cpu
[sm_cpu_count
-1], (uint8_t*)(location
+ 4), sm_hdr
.length
- 4);
96 location
+= sm_hdr
.length
;
98 sm_cpu
[sm_cpu_count
-1].socket_s
= smbios_get_string(location
, sm_cpu
[sm_cpu_count
-1].socket
);
99 sm_cpu
[sm_cpu_count
-1].manufacturer_s
= smbios_get_string(location
, sm_cpu
[sm_cpu_count
-1].manufacturer
);
100 sm_cpu
[sm_cpu_count
-1].version_s
= smbios_get_string(location
, sm_cpu
[sm_cpu_count
-1].version
);
101 sm_cpu
[sm_cpu_count
-1].serial_s
= smbios_get_string(location
, sm_cpu
[sm_cpu_count
-1].serial
);
102 sm_cpu
[sm_cpu_count
-1].asset_s
= smbios_get_string(location
, sm_cpu
[sm_cpu_count
-1].asset
);
103 sm_cpu
[sm_cpu_count
-1].part_s
= smbios_get_string(location
, sm_cpu
[sm_cpu_count
-1].part
);
106 if(sm_cpu[sm_cpu_count-1].socket_s){
107 console_printf(get_vterm(0), " socket = %s \n", sm_cpu[sm_cpu_count-1].socket_s);}
108 if(sm_cpu[sm_cpu_count-1].manufacturer_s){
109 console_printf(get_vterm(0), " manufacturer = %s \n", sm_cpu[sm_cpu_count-1].manufacturer_s);}
110 if(sm_cpu[sm_cpu_count-1].version_s){
111 console_printf(get_vterm(0), " version = %s \n", sm_cpu[sm_cpu_count-1].version_s);}
112 if(sm_cpu[sm_cpu_count-1].serial_s){
113 console_printf(get_vterm(0), " serial = %s \n", sm_cpu[sm_cpu_count-1].serial_s);}
114 if(sm_cpu[sm_cpu_count-1].asset_s){
115 console_printf(get_vterm(0), " asset = %s \n", sm_cpu[sm_cpu_count-1].asset_s);}
116 if(sm_cpu[sm_cpu_count-1].part_s){
117 console_printf(get_vterm(0), " part = %s \n", sm_cpu[sm_cpu_count-1].part_s);}
121 static void parse_smbios_chassis(intptr_t location
)
123 memcpy((uint8_t*)&sm_chas
[sm_chas_count
-1], (uint8_t*)(location
+ 4), sm_hdr
.length
- 4);
125 location
+= sm_hdr
.length
;
127 sm_chas
[sm_chas_count
-1].manufacturer_s
= smbios_get_string(location
, sm_chas
[sm_chas_count
-1].manufacturer
);
128 sm_chas
[sm_chas_count
-1].version_s
= smbios_get_string(location
, sm_chas
[sm_chas_count
-1].version
);
129 sm_chas
[sm_chas_count
-1].serial_s
= smbios_get_string(location
, sm_chas
[sm_chas_count
-1].serial
);
130 sm_chas
[sm_chas_count
-1].asset_s
= smbios_get_string(location
, sm_chas
[sm_chas_count
-1].asset
);
133 if(sm_chas[sm_chas_count-1].manufacturer_s){
134 console_printf(get_vterm(0), " manufacturer = %s \n", sm_chas[sm_chas_count-1].manufacturer_s);}
135 if(sm_chas[sm_chas_count-1].version_s){
136 console_printf(get_vterm(0), " version = %s \n", sm_chas[sm_chas_count-1].version_s);}
137 if(sm_chas[sm_chas_count-1].serial_s){
138 console_printf(get_vterm(0), " serial = %s \n", sm_chas[sm_chas_count-1].serial_s);}
139 if(sm_chas[sm_chas_count-1].asset_s){
140 console_printf(get_vterm(0), " asset = %s \n", sm_chas[sm_chas_count-1].asset_s);}
144 static void parse_smbios_module(intptr_t location
)
146 memcpy((uint8_t*)&sm_mod
[sm_mod_count
-1], (uint8_t*)(location
+ 4), sm_hdr
.length
- 4);
148 location
+= sm_hdr
.length
;
150 sm_mod
[sm_mod_count
-1].manufacturer_s
= smbios_get_string(location
, sm_mod
[sm_mod_count
-1].manufacturer
);
151 sm_mod
[sm_mod_count
-1].product_s
= smbios_get_string(location
, sm_mod
[sm_mod_count
-1].product
);
152 sm_mod
[sm_mod_count
-1].version_s
= smbios_get_string(location
, sm_mod
[sm_mod_count
-1].version
);
153 sm_mod
[sm_mod_count
-1].serial_s
= smbios_get_string(location
, sm_mod
[sm_mod_count
-1].serial
);
154 sm_mod
[sm_mod_count
-1].asset_s
= smbios_get_string(location
, sm_mod
[sm_mod_count
-1].asset
);
155 sm_mod
[sm_mod_count
-1].location_s
= smbios_get_string(location
, sm_mod
[sm_mod_count
-1].location
);
158 if(sm_mod[sm_mod_count-1].manufacturer_s){
159 console_printf(get_vterm(0), " manufacturer = %s \n", sm_mod[sm_mod_count-1].manufacturer_s);}
160 if(sm_mod[sm_mod_count-1].product_s){
161 console_printf(get_vterm(0), " product = %s \n", sm_mod[sm_mod_count-1].product_s);}
162 if(sm_mod[sm_mod_count-1].version_s){
163 console_printf(get_vterm(0), " version = %s \n", sm_mod[sm_mod_count-1].version_s);}
164 if(sm_mod[sm_mod_count-1].serial_s){
165 console_printf(get_vterm(0), " serial = %s \n", sm_mod[sm_mod_count-1].serial_s);}
166 if(sm_mod[sm_mod_count-1].asset_s){
167 console_printf(get_vterm(0), " asset = %s \n", sm_mod[sm_mod_count-1].asset_s);}
168 if(sm_mod[sm_mod_count-1].location_s){
169 console_printf(get_vterm(0), " location = %s \n", sm_mod[sm_mod_count-1].location_s);}
173 static void parse_smbios_system(intptr_t location
)
175 memcpy((uint8_t*)&sm_sys
[sm_sys_count
-1], (uint8_t*)(location
+ 4), sm_hdr
.length
- 4);
177 location
+= sm_hdr
.length
;
179 sm_sys
[sm_sys_count
-1].manufacturer_s
= smbios_get_string(location
, sm_sys
[sm_sys_count
-1].manufacturer
);
180 sm_sys
[sm_sys_count
-1].product_s
= smbios_get_string(location
, sm_sys
[sm_sys_count
-1].product
);
181 sm_sys
[sm_sys_count
-1].version_s
= smbios_get_string(location
, sm_sys
[sm_sys_count
-1].version
);
182 sm_sys
[sm_sys_count
-1].serial_s
= smbios_get_string(location
, sm_sys
[sm_sys_count
-1].serial
);
183 sm_sys
[sm_sys_count
-1].sku_s
= smbios_get_string(location
, sm_sys
[sm_sys_count
-1].sku
);
184 sm_sys
[sm_sys_count
-1].family_s
= smbios_get_string(location
, sm_sys
[sm_sys_count
-1].family
);
187 if(sm_sys[sm_sys_count-1].manufacturer_s){
188 console_printf(get_vterm(0), " manufacturer = %s \n", sm_sys[sm_sys_count-1].manufacturer_s);}
189 if(sm_sys[sm_sys_count-1].product_s){
190 console_printf(get_vterm(0), " product = %s \n", sm_sys[sm_sys_count-1].product_s);}
191 if(sm_sys[sm_sys_count-1].version_s){
192 console_printf(get_vterm(0), " version = %s \n", sm_sys[sm_sys_count-1].version_s);}
193 if(sm_sys[sm_sys_count-1].serial_s){
194 console_printf(get_vterm(0), " serial = %s \n", sm_sys[sm_sys_count-1].serial_s);}
195 if(sm_sys[sm_sys_count-1].sku_s){
196 console_printf(get_vterm(0), " sku = %s \n", sm_sys[sm_sys_count-1].sku_s);}
197 if(sm_sys[sm_sys_count-1].family_s){
198 console_printf(get_vterm(0), " family = %s \n", sm_sys[sm_sys_count-1].family_s);}
202 static void parse_smbios_bios(intptr_t location
)
204 memcpy((uint8_t*)&sm_bios
, (uint8_t*)(location
+ 4), sm_hdr
.length
- 4);
206 location
+= sm_hdr
.length
;
208 sm_bios
.vendor_s
= smbios_get_string(location
, sm_bios
.vendor
);
209 sm_bios
.version_s
= smbios_get_string(location
, sm_bios
.version
);
210 sm_bios
.release_date_s
= smbios_get_string(location
, sm_bios
.release_date
);
213 if(sm_bios.vendor_s){
214 console_printf(get_vterm(0), " vendor = %s \n", sm_bios.vendor_s);}
215 if(sm_bios.version_s){
216 console_printf(get_vterm(0), " version = %s \n", sm_bios.version_s);}
217 if(sm_bios.release_date_s){
218 console_printf(get_vterm(0), " release date = %s \n", sm_bios.release_date_s);}
222 static void parse_structures(intptr_t location
)
225 sm_bios_count
= sm_sys_count
= 0;
226 sm_mod_count
= sm_chas_count
= 0;
227 sm_cpu_count
= sm_memdev_count
= 0;
231 sm_hdr
.type
= *(uint8_t*)location
;
232 sm_hdr
.length
= *(uint8_t*)(location
+ 1);
233 sm_hdr
.handle
= *(uint16_t*)(location
+ 2);
238 // specs say that there should only be one BIOS structure
239 //console_printf(get_vterm(0), "SMBIOS: BIOS: \n");
240 if(sm_bios_count
>= 1){break;}else{sm_bios_count
++;}
241 parse_smbios_bios(location
);
245 //console_printf(get_vterm(0), "SMBIOS: SYSTEM: \n");
246 if(sm_sys_count
>= 4){break;}else{sm_sys_count
++;}
247 parse_smbios_system(location
);
251 //console_printf(get_vterm(0), "SMBIOS: MODULE: \n");
252 if(sm_mod_count
>= 8){break;}else{sm_mod_count
++;}
253 parse_smbios_module(location
);
257 //console_printf(get_vterm(0), "SMBIOS: CHASSIS: \n");
258 if(sm_chas_count
>= 4){break;}else{sm_chas_count
++;}
259 parse_smbios_chassis(location
);
263 //console_printf(get_vterm(0), "SMBIOS: CPU: \n");
264 if(sm_cpu_count
>= 64){break;}else{sm_cpu_count
++;}
265 parse_smbios_cpu(location
);
269 //console_printf(get_vterm(0), "SMBIOS: MEMORY DEVICE: \n");
270 if(sm_memdev_count
>= 64){break;}else{sm_memdev_count
++;}
271 parse_smbios_memdev(location
);
278 //console_printf(get_vterm(0), "SMBIOS: structure(%u): \n", sm_hdr.type);
282 location
+= sm_hdr
.length
;
283 while(*(uint16_t*)location
++ != 0x0000){}
288 static void parse_eps(intptr_t location
)
290 memcpy((uint8_t*)&sm_eps
, (uint8_t*)location
, sizeof(sm_eps
));
292 if(smbios_checksum(location
, sm_eps
.length
))
293 {console_printf(get_vterm(0), "SMBIOS: EPS checksum is incorrect \n"); return;}
295 if(sm_eps
.major_version
== 0x02 && sm_eps
.minor_version
== 0x01)
297 if(sm_eps
.length
== 0x1E)
298 {console_printf(get_vterm(0), "SMBIOS: known bug found (sm_eps.length == 0x1E) \n");}
299 else if(sm_eps
.length
!= 0x1F)
300 {console_printf(get_vterm(0), "SMBIOS: incorrect EPS length defined \n"); return;}
304 if(sm_eps
.length
!= 0x1F)
305 {console_printf(get_vterm(0), "SMBIOS: incorrect EPS length defined \n"); return;}
308 if(memcmp((uint8_t*)(location
+ 0x10), "_DMI_", 5))
309 {console_printf(get_vterm(0), "SMBIOS: IEPS anchor string is incorrect \n"); return;}
311 if(smbios_checksum(location
+ 0x10, 0x0F))
312 {console_printf(get_vterm(0), "SMBIOS: IEPS checksum is incorrect \n"); return;}
314 console_printf(get_vterm(0), "SMBIOS: version %u.%u \n", sm_eps
.major_version
, sm_eps
.minor_version
);
316 parse_structures(sm_eps
.struct_table_address
);
319 void parse_smbios(void)
323 for(i
= 0xF0000; i
< 0x100000; i
+= 16)
325 if(!memcmp((uint8_t*)i
, "_SM_", 4))
327 console_printf(get_vterm(0), "SMBIOS: EPS found at %x \n", i
);
333 console_printf(get_vterm(0), "SMBIOS: structure entry point was not found, skipping... \n");