Added .gitignore
[comos.git] / kernel / smbios.c
blob81944c86686bb073071f5f8da1acf41055bf6f73
1 #include "smbios.h"
2 #include "stdlib.h"
3 #include "console.h"
5 static uint8_t smbios_checksum(const intptr_t start, const uint32_t count)
6 {
7 uint32_t i;
8 uint8_t chksum;
10 chksum = 0;
11 for(i = 0; i < count; i++)
13 chksum += *(uint8_t*)(start + i);
16 return chksum;
20 static char * smbios_get_string(intptr_t location, uint8_t id)
22 char * buf;
23 uint8_t counter;
25 if(!id)
26 {return 0;}
28 counter = 0;
29 id--;
31 while(1)
33 if(id == counter)
35 buf = (char *)(malloc(strlen((char *)location + 1)));
36 memcpy((uint8_t*)buf, (uint8_t*)location, strlen((char *)location) + 1);
37 return buf;
40 while(*(uint8_t*)location++ != 0x00){}
41 if(*(uint8_t*)location == 0x00 && *(uint8_t*)(location + 1) == 0x00){break;}
43 location++;
44 counter++;
47 return 0;
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;
229 while(1)
231 sm_hdr.type = *(uint8_t*)location;
232 sm_hdr.length = *(uint8_t*)(location + 1);
233 sm_hdr.handle = *(uint16_t*)(location + 2);
235 switch(sm_hdr.type)
237 case 0:
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);
242 break;
244 case 1:
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);
248 break;
250 case 2:
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);
254 break;
256 case 3:
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);
260 break;
262 case 4:
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);
266 break;
268 case 17:
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);
272 break;
274 case 127:
275 return;
277 default:
278 //console_printf(get_vterm(0), "SMBIOS: structure(%u): \n", sm_hdr.type);
279 break;
282 location += sm_hdr.length;
283 while(*(uint16_t*)location++ != 0x0000){}
284 location++;
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;}
302 else
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)
321 intptr_t i;
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);
328 parse_eps(i);
329 return;
333 console_printf(get_vterm(0), "SMBIOS: structure entry point was not found, skipping... \n");