9 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
11 enum sm_map_type
{ sm_map_str
, sm_map_num2str
};
13 typedef struct { unsigned num
; char *str
; } sm_num2str_t
;
16 enum sm_map_type type
;
20 sm_num2str_t
*num2str
;
25 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
27 static char *get_string(str_list_t
*sl
, int index
);
28 static void smbios_bitmap_print(FILE *f
, hd_bitmap_t
*hbm
, char *label
, int style
);
29 static void smbios_id_print(FILE *f
, hd_id_t
*hid
, char *label
);
30 static void smbios_str_print(FILE *f
, char *str
, char *label
);
31 static void smbios_id2str(hd_id_t
*hid
, sm_str_map_t
*map
, unsigned def
);
32 static void smbios_bitmap2str(hd_bitmap_t
*hbm
, sm_str_map_t
*map
);
35 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
37 #define SMBIOS_PRINT_ID(a, b) smbios_id_print(f, &sm->a, b)
38 #define SMBIOS_PRINT_STR(a, b) smbios_str_print(f, sm->a, b)
39 #define SMBIOS_PRINT_BITMAP_SHORT(a, b) smbios_bitmap_print(f, &sm->a, b, 0)
40 #define SMBIOS_PRINT_BITMAP_LONG(a, b) smbios_bitmap_print(f, &sm->a, b, 1)
42 #define SMBIOS_DEF_MAP(a) \
43 static sm_str_map_t a = { \
44 sizeof *a ## _ == sizeof (sm_num2str_t) ? sm_map_num2str : sm_map_str, \
45 sizeof a ## _ / sizeof *a ## _, \
49 /* ptr is (unsigned char *) */
50 #define READ_MEM16(ptr) ((ptr)[0] + ((ptr)[1] << 8))
51 #define READ_MEM32(ptr) ((ptr)[0] + ((ptr)[1] << 8) + ((ptr)[2] << 16) + ((ptr)[3] << 24))
52 #define READ_MEM64(ptr) (READ_MEM32(ptr) + ((uint64_t) READ_MEM32(ptr + 4) << 32))
55 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
57 static sm_num2str_t smbios_bios_feature_
[] = {
58 { 4, "ISA supported" },
59 { 5, "MCA supported" },
60 { 6, "EISA supported" },
61 { 7, "PCI supported" },
62 { 8, "PCMCIA supported" },
63 { 9, "PnP supported" },
64 { 10, "APM supported" },
65 { 11, "BIOS flashable" },
66 { 12, "BIOS shadowing allowed" },
67 { 13, "VL-VESA supported" },
68 { 14, "ESCD supported" },
69 { 15, "CD boot supported" },
70 { 16, "Selectable boot supported" },
71 { 17, "BIOS ROM socketed" },
72 { 18, "PCMCIA boot supported" },
73 { 19, "EDD spec supported" },
74 { 20, "1.2MB NEC 9800 Japanese Floppy supported" },
75 { 21, "1.2MB Toshiba Japanese Floppy supported" },
76 { 22, "360kB Floppy supported" },
77 { 23, "1.2MB Floppy supported" },
78 { 24, "720kB Floppy supported" },
79 { 25, "2.88MB Floppy supported" },
80 { 26, "Print Screen supported" },
81 { 27, "8042 Keyboard Services supported" },
82 { 28, "Serial Services supported" },
83 { 29, "Printer Services supported" },
84 { 30, "CGA/Mono Video supported" },
86 { 64 + 0, "ACPI supported" },
87 { 64 + 1, "USB Legacy supported" },
88 { 64 + 2, "AGP supported" },
89 { 64 + 3, "I2O boot supported" },
90 { 64 + 4, "LS-120 boot supported" },
91 { 64 + 5, "ATAPI ZIP boot supported" },
92 { 64 + 6, "IEEE1394 boot supported" },
93 { 64 + 7, "Smart Battery supported" },
94 { 64 + 8, "BIOS Boot Spec supported" },
95 { 64 + 9, "F12 Network boot supported" }
97 SMBIOS_DEF_MAP(smbios_bios_feature
);
100 static char *smbios_system_wakeups_
[] = {
101 "Reserved", "Other", "Unknown", "APM Timer",
102 "Modem Ring", "LAN Remote", "Power Switch", "PCI PME#",
105 SMBIOS_DEF_MAP(smbios_system_wakeups
);
108 static char *smbios_board_feature_
[] = {
109 "Hosting Board", "Needs One Daughter Board", "Removable", "Replaceable",
112 SMBIOS_DEF_MAP(smbios_board_feature
);
115 static char *smbios_board_types_
[] = {
116 NULL
, "Other", "Unknown", "Server Blade",
117 "Connectivity Switch", "System Management Module", "Processor Module", "I/O Module",
118 "Memory Module", "Daughter Board", "Motherboard", "Processor/Memory Module",
119 "Processor/IO Module", "Interconnect Board"
121 SMBIOS_DEF_MAP(smbios_board_types
);
124 static char *smbios_chassis_types_
[] = {
125 NULL
, "Other", "Unknown", "Desktop",
126 "Low Profile Desktop", "Pizza Box", "Mini Tower", "Tower",
127 "Portable", "LapTop", "Notebook", "Hand Held",
128 "Docking Station", "All in One", "Sub Notebook", "Space Saving",
129 "Lunch Box", "Main Server Chassis", "Expansion Chassis", "SubChassis",
130 "Bus Expansion Chassis", "Peripheral Chassis", "RAID Chassis", "Rack Mount Chassis",
131 "Sealed-case PC", "Multi-System Chassis"
133 SMBIOS_DEF_MAP(smbios_chassis_types
);
136 static char *smbios_chassis_states_
[] = {
137 NULL
, "Other", "Unknown", "Safe",
138 "Warning", "Critical", "Non-recoverable"
140 SMBIOS_DEF_MAP(smbios_chassis_states
);
143 static char *smbios_chassis_sec_states_
[] = {
144 NULL
, "Other", "Unknown", "None",
145 "External interface locked out", "External interface enabled"
147 SMBIOS_DEF_MAP(smbios_chassis_sec_states
);
150 static char *smbios_proc_upgrades_
[] = {
151 NULL
, "Other", "Unknown", "Daughter Board",
152 "ZIF Socket", "Replaceable Piggy Back", "None", "LIF Socket",
153 "Slot 1", "Slot 2", "370-Pin Socket", "Slot A",
154 "Slot M", "Socket 423", "Socket A (Socket 462)", "Socket 478",
155 "Socket 754", "Socket 940"
157 SMBIOS_DEF_MAP(smbios_proc_upgrades
);
160 static char *smbios_proc_cpu_status_
[8] = {
161 "Unknown", "Enabled", "Disabled by User", "Disabled by BIOS",
162 "Idle", "Reserved", "Reserved", "Other"
164 SMBIOS_DEF_MAP(smbios_proc_cpu_status
);
167 static char *smbios_proc_types_
[] = {
168 NULL
, "Other", "Unknown", "CPU",
169 "Math", "DSP", "Video"
171 SMBIOS_DEF_MAP(smbios_proc_types
);
174 static sm_num2str_t smbios_proc_families_
[] = {
180 { 0x05, "Intel386" },
181 { 0x06, "Intel486" },
187 { 0x0c, "Pentium Pro" },
188 { 0x0d, "Pentium II" },
189 { 0x0e, "Pentium MMX" },
191 { 0x10, "Pentium II Xeon" },
192 { 0x11, "Pentium III" },
203 { 0x78, "Crusoe TM5000" },
204 { 0x79, "Crusoe TM3000" },
206 { 0x83, "Athlon 64" },
207 { 0x84, "Opteron Processor" },
208 { 0xb0, "Pentium III Xeon" },
209 { 0xb1, "Pentium III with SpeedStep" },
210 { 0xb2, "Pentium 4" },
214 { 0xb6, "Athlon XP" },
215 { 0xb7, "Athlon MP" },
216 { 0xb8, "Itanium 2" }
218 SMBIOS_DEF_MAP(smbios_proc_families
);
221 static char *smbios_cache_mode_
[] = {
222 "Write Through", "Write Back", "Varies with Memory Address", "Unknown"
224 SMBIOS_DEF_MAP(smbios_cache_mode
);
227 static char *smbios_cache_location_
[] = {
228 "Internal", "External", "Reserved", "Unknown"
230 SMBIOS_DEF_MAP(smbios_cache_location
);
233 static char *smbios_cache_ecc_
[] = {
234 NULL
, "Other", "Unknown", "None",
235 "Parity", "Single-bit", "Multi-bit", "CRC"
237 SMBIOS_DEF_MAP(smbios_cache_ecc
);
238 #define smbios_memarray_ecc smbios_cache_ecc
241 static char *smbios_cache_type_
[] = {
242 NULL
, "Other", "Unknown", "Instruction",
245 SMBIOS_DEF_MAP(smbios_cache_type
);
248 static char *smbios_cache_assoc_
[] = {
249 NULL
, "Other", "Unknown", "Direct Mapped",
250 "2-way Set-Associative", "4-way Set-Associative", "Fully Associative", "8-way Set-Associative",
251 "16-way Set-Associative"
253 SMBIOS_DEF_MAP(smbios_cache_assoc
);
256 static char *smbios_cache_sram_
[] = {
257 "Other", "Unknown", "Non-Burst", "Burst",
258 "Pipeline Burst", "Synchronous", "Asynchronous"
260 SMBIOS_DEF_MAP(smbios_cache_sram
);
263 static sm_num2str_t smbios_connect_conn_type_
[] = {
265 { 0x01, "Centronics" },
266 { 0x02, "Mini Centronics" },
267 { 0x03, "Proprietary" },
268 { 0x04, "DB-25 pin male" },
269 { 0x05, "DB-25 pin female" },
270 { 0x06, "DB-15 pin male" },
271 { 0x07, "DB-15 pin female" },
272 { 0x08, "DB-9 pin male" },
273 { 0x09, "DB-9 pin female" },
276 { 0x0c, "50 Pin MiniSCSI" },
277 { 0x0d, "Mini-DIN" },
278 { 0x0e, "Micro-DIN" },
280 { 0x10, "Infrared" },
282 { 0x12, "Access Bus [USB]" },
283 { 0x13, "SSA SCSI" },
284 { 0x14, "Circular DIN-8 male" },
285 { 0x15, "Circular DIN-8 female" },
286 { 0x16, "On Board IDE" },
287 { 0x17, "On Board Floppy" },
288 { 0x18, "9 Pin Dual Inline [pin 10 cut]" },
289 { 0x19, "25 Pin Dual Inline [pin 26 cut]" },
290 { 0x1a, "50 Pin Dual Inline" },
291 { 0x1b, "68 Pin Dual Inline" },
292 { 0x1c, "On Board Sound Input from CD-ROM" },
293 { 0x1d, "Mini-Centronics Type-14" },
294 { 0x1e, "Mini-Centronics Type-26" },
295 { 0x1f, "Mini-jack [headphones]" },
299 { 0xa1, "PC-98Hireso" },
301 { 0xa3, "PC-98Note" },
302 { 0xa4, "PC-98Full" },
305 SMBIOS_DEF_MAP(smbios_connect_conn_type
);
308 static sm_num2str_t smbios_connect_port_type_
[] = {
310 { 0x01, "Parallel Port XT/AT Compatible" },
311 { 0x02, "Parallel Port PS/2" },
312 { 0x03, "Parallel Port ECP" },
313 { 0x04, "Parallel Port EPP" },
314 { 0x05, "Parallel Port ECP/EPP" },
315 { 0x06, "Serial Port XT/AT Compatible" },
316 { 0x07, "Serial Port 16450 Compatible" },
317 { 0x08, "Serial Port 16550 Compatible" },
318 { 0x09, "Serial Port 16550A Compatible" },
319 { 0x0a, "SCSI Port" },
320 { 0x0b, "MIDI Port" },
321 { 0x0c, "Joy Stick Port" },
322 { 0x0d, "Keyboard Port" },
323 { 0x0e, "Mouse Port" },
324 { 0x0f, "SSA SCSI" },
326 { 0x11, "FireWire [IEEE P1394]" },
327 { 0x12, "PCMCIA Type I" },
328 { 0x13, "PCMCIA Type II" },
329 { 0x14, "PCMCIA Type III" },
331 { 0x16, "Access Bus Port" },
333 { 0x18, "SCSI Wide" },
335 { 0x1a, "PC-98-Hireso" },
337 { 0x1c, "Video Port" },
338 { 0x1d, "Audio Port" },
339 { 0x1e, "Modem Port" },
340 { 0x1f, "Network Port" },
341 { 0xa0, "8251 Compatible" },
342 { 0xa1, "8251 FIFO Compatible" },
345 SMBIOS_DEF_MAP(smbios_connect_port_type
);
348 static sm_num2str_t smbios_slot_type_
[] = {
356 { 0x07, "PC Card [PCMCIA]" },
358 { 0x09, "Proprietary" },
359 { 0x0a, "Processor Card" },
360 { 0x0b, "Proprietary Memory Card" },
361 { 0x0c, "I/O Riser Card" },
363 { 0x0e, "PCI - 66MHz Capable" },
369 { 0xa0, "PC-98/C20" },
370 { 0xa1, "PC-98/C24" },
372 { 0xa3, "PC-98/Local Bus" },
373 { 0xa4, "PC-98/Card" }
375 SMBIOS_DEF_MAP(smbios_slot_type
);
378 static char *smbios_slot_bus_width_
[] = {
379 NULL
, "Other", "Unknown", "8 bit",
380 "16 bit", "32 bit", "64 bit", "128 bit"
382 SMBIOS_DEF_MAP(smbios_slot_bus_width
);
385 static char *smbios_slot_usage_
[] = {
386 NULL
, "Other", "Unknown", "Available",
389 SMBIOS_DEF_MAP(smbios_slot_usage
);
392 static char *smbios_slot_length_
[] = {
393 NULL
, "Other", "Unknown", "Short",
396 SMBIOS_DEF_MAP(smbios_slot_length
);
399 static char *smbios_slot_feature_
[] = {
400 "Unknown", "5.0 V", "3.3 V", "Shared",
401 "PC Card-16", "CardBus", "Zoom Video", "Modem Ring Resume",
404 SMBIOS_DEF_MAP(smbios_slot_feature
);
407 static char *smbios_onboard_type_
[] = {
408 "Other", "Other", "Unknown", "Video",
409 "SCSI Controller", "Ethernet", "Token Ring", "Sound"
411 SMBIOS_DEF_MAP(smbios_onboard_type
);
414 static sm_num2str_t smbios_memarray_location_
[] = {
418 { 0x03, "Motherboard" },
419 { 0x04, "ISA add-on card" },
420 { 0x05, "EISA add-on card" },
421 { 0x06, "PCI add-on card" },
422 { 0x07, "MCA add-on card" },
423 { 0x08, "PCMCIA add-on card" },
424 { 0x09, "Proprietary add-on card" },
426 { 0xa0, "PC-98/C20 add-on card" },
427 { 0xa1, "PC-98/C24 add-on card" },
428 { 0xa2, "PC-98/E add-on card" },
429 { 0xa3, "PC-98/Local bus add-on card" }
431 SMBIOS_DEF_MAP(smbios_memarray_location
);
434 static char *smbios_memarray_use_
[] = {
435 NULL
, "Other", "Unknown", "System memory",
436 "Video memory", "Flash memory", "Non-volatile RAM", "Cache memory"
438 SMBIOS_DEF_MAP(smbios_memarray_use
);
441 static char *smbios_mouse_type_
[] = {
442 NULL
, "Other", "Unknown", "Mouse",
443 "Track Ball", "Track Point", "Glide Point", "Touch Pad",
444 "Touch Screen", "Optical Sensor"
446 SMBIOS_DEF_MAP(smbios_mouse_type
);
449 static sm_num2str_t smbios_mouse_interface_
[] = {
455 { 0x05, "Infrared" },
457 { 0x07, "Bus Mouse" },
459 { 0xa0, "Bus mouse DB-9" },
460 { 0xa1, "Bus mouse micro-DIN" },
463 SMBIOS_DEF_MAP(smbios_mouse_interface
);
466 static char *smbios_memdevice_form_
[] = {
467 NULL
, "Other", "Unknown", "SIMM",
468 "SIP", "Chip", "DIP", "ZIP",
469 "Proprietary Card", "DIMM", "TSOP", "Row of Chips",
470 "RIMM", "SODIMM", "SRIMM"
472 SMBIOS_DEF_MAP(smbios_memdevice_form
);
475 static char *smbios_memdevice_type_
[] = {
476 NULL
, "Other", "Unknown", "DRAM",
477 "EDRAM", "VRAM", "SRAM", "RAM",
478 "ROM", "FLASH", "EEPROM", "FEPROM",
479 "EPROM", "CDRAM", "3DRAM", "SDRAM",
480 "SGRAM", "RDRAM", "DDR"
482 SMBIOS_DEF_MAP(smbios_memdevice_type
);
485 static char *smbios_memdevice_detail_
[] = {
486 NULL
, "Other", "Unknown", "Fast-paged",
487 "Static column", "Pseudo-static", "RAMBUS", "Synchronous",
488 "CMOS", "EDO", "Window DRAM", "Cache DRAM",
491 SMBIOS_DEF_MAP(smbios_memdevice_detail
);
494 static char *smbios_memerror_type_
[] = {
495 NULL
, "Other", "Unknown", "OK",
496 "Bad read", "Parity error", "Single-bit error", "Double-bit error",
497 "Multi-bit error", "Nibble error", "Checksum error", "CRC error",
498 "Corrected single-bit error", "Corrected error", "Uncorrectable error"
500 SMBIOS_DEF_MAP(smbios_memerror_type
);
503 static char *smbios_memerror_granularity_
[] = {
504 NULL
, "Other", "Unknown", "Device level",
505 "Memory partition level"
507 SMBIOS_DEF_MAP(smbios_memerror_granularity
);
510 static char *smbios_memerror_operation_
[] = {
511 NULL
, "Other", "Unknown", "Read",
512 "Write", "Partial write"
514 SMBIOS_DEF_MAP(smbios_memerror_operation
);
517 static char *smbios_secure_state_
[] = {
518 "Disabled", "Enabled", "Not Implemented", "Unknown"
520 SMBIOS_DEF_MAP(smbios_secure_state
);
523 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
526 * return the index'th string from sl
528 char *get_string(str_list_t
*sl
, int index
)
530 if(!sl
|| !index
) return NULL
;
532 for(; sl
; sl
= sl
->next
, index
--) {
533 if(index
== 1) return new_str(sl
->str
&& *sl
->str
? sl
->str
: NULL
);
542 * Style: 0: short, 1: long.
544 void smbios_bitmap_print(FILE *f
, hd_bitmap_t
*hbm
, char *label
, int style
)
550 fprintf(f
, " %s: 0x", label
);
551 for(u
= (hbm
->bits
+ 7) >> 3; u
; u
--) {
552 fprintf(f
, "%02x", hbm
->bitmap
[u
- 1]);
554 fprintf(f
, style
? "\n" : " (");
555 for(sl
= hbm
->str
; sl
; sl
= sl
->next
) {
557 fprintf(f
, " %s\n", sl
->str
);
560 fprintf(f
, "%s%s", sl
->str
, sl
->next
? ", " : "");
563 if(!style
) fprintf(f
, ")\n");
569 * Print id/name pair.
571 void smbios_id_print(FILE *f
, hd_id_t
*hid
, char *label
)
573 if(hid
->name
) fprintf(f
, " %s: 0x%02x (%s)\n", label
, hid
->id
, hid
->name
);
580 void smbios_str_print(FILE *f
, char *str
, char *label
)
582 if(str
) fprintf(f
, " %s: \"%s\"\n", label
, str
);
587 * Look up the name that corresponds to the id (if any).
589 void smbios_id2str(hd_id_t
*hid
, sm_str_map_t
*map
, unsigned def
)
594 if(map
->type
== sm_map_str
) {
595 str
= map
->list
.str
[hid
->id
< map
->len
? hid
->id
: def
];
596 if(hid
->id
&& !str
) str
= map
->list
.str
[def
];
599 for(str
= def_str
= NULL
, u
= 0; u
< map
->len
; u
++) {
600 if(map
->list
.num2str
[u
].num
== hid
->id
) str
= map
->list
.num2str
[u
].str
;
602 if(map
->list
.num2str
[u
].num
== def
) def_str
= map
->list
.num2str
[u
].str
;
604 if(hid
->id
&& !str
) str
= def_str
;
606 hid
->name
= new_str(str
);
611 * Convert a bitmap into a list of strings. (That is, interpret the
614 void smbios_bitmap2str(hd_bitmap_t
*hbm
, sm_str_map_t
*map
)
619 for(u
= 0; u
< (hbm
->bits
+ 7) >> 3; u
++) {
626 if(map
->type
== sm_map_str
) {
627 for(u
= 0; u
< map
->len
; u
++) {
628 if(u
< hbm
->bits
&& hbm
->bitmap
[u
>> 3] & (1 << (u
& 7))) {
629 str
= map
->list
.str
[u
];
630 if(str
) add_str_list(&hbm
->str
, str
);
635 for(u
= 0; u
< map
->len
; u
++) {
636 bit
= map
->list
.num2str
[u
].num
;
637 if(bit
< hbm
->bits
&& hbm
->bitmap
[bit
>> 3] & (1 << (bit
& 7))) {
638 str
= map
->list
.num2str
[u
].str
;
639 if(str
) add_str_list(&hbm
->str
, str
);
647 * Interpret raw smbios data.
649 void smbios_parse(hd_data_t
*hd_data
)
652 str_list_t
*sl_any
, *sl
;
654 unsigned char *sm_data
;
657 if(!hd_data
->smbios
) return;
659 for(cnt
= 0, sm
= hd_data
->smbios
; sm
; sm
= sm
->next
, cnt
++) {
660 sm_data
= sm
->any
.data
;
661 data_len
= sm
->any
.data_len
;
662 sl_any
= sm
->any
.strings
;
663 switch(sm
->any
.type
) {
665 if(data_len
>= 0x12) {
666 sm
->biosinfo
.start
= READ_MEM16(sm_data
+ 6) << 4;
667 sm
->biosinfo
.rom_size
= (sm_data
[9] + 1) << 16;
668 sm
->biosinfo
.vendor
= get_string(sl_any
, sm_data
[4]);
669 sm
->biosinfo
.version
= get_string(sl_any
, sm_data
[5]);
670 sm
->biosinfo
.date
= get_string(sl_any
, sm_data
[8]);
671 memcpy(sm
->biosinfo
.feature
.bitmap
, sm_data
+ 0xa, 8);
673 if(data_len
>= 0x13) {
674 sm
->biosinfo
.feature
.bitmap
[8] = sm_data
[0x12];
676 if(data_len
>= 0x14) {
677 sm
->biosinfo
.feature
.bitmap
[9] = sm_data
[0x13];
679 sm
->biosinfo
.feature
.bits
= 80;
680 smbios_bitmap2str(&sm
->biosinfo
.feature
, &smbios_bios_feature
);
685 sm
->sysinfo
.manuf
= get_string(sl_any
, sm_data
[4]);
686 sm
->sysinfo
.product
= get_string(sl_any
, sm_data
[5]);
687 sm
->sysinfo
.version
= get_string(sl_any
, sm_data
[6]);
688 sm
->sysinfo
.serial
= get_string(sl_any
, sm_data
[7]);
690 if(data_len
>= 0x19) {
691 memcpy(sm
->sysinfo
.uuid
, sm_data
+ 8, 16);
692 sm
->sysinfo
.wake_up
.id
= sm_data
[0x18];
693 smbios_id2str(&sm
->sysinfo
.wake_up
, &smbios_system_wakeups
, 1);
699 sm
->boardinfo
.manuf
= get_string(sl_any
, sm_data
[4]);
700 sm
->boardinfo
.product
= get_string(sl_any
, sm_data
[5]);
701 sm
->boardinfo
.version
= get_string(sl_any
, sm_data
[6]);
702 sm
->boardinfo
.serial
= get_string(sl_any
, sm_data
[7]);
705 sm
->boardinfo
.asset
= get_string(sl_any
, sm_data
[8]);
707 if(data_len
>= 0x0e) {
708 sm
->boardinfo
.feature
.bitmap
[0] = sm_data
[9];
709 sm
->boardinfo
.feature
.bits
= 8;
710 smbios_bitmap2str(&sm
->boardinfo
.feature
, &smbios_board_feature
);
711 sm
->boardinfo
.location
= get_string(sl_any
, sm_data
[0x0a]);
712 sm
->boardinfo
.chassis
= READ_MEM16(sm_data
+ 0x0b);
713 sm
->boardinfo
.board_type
.id
= sm_data
[0x0d];
714 smbios_id2str(&sm
->boardinfo
.board_type
, &smbios_board_types
, 1);
716 if(data_len
>= 0x0f) {
718 if(u
&& data_len
>= 0x0f + 2 * u
) {
719 sm
->boardinfo
.objects_len
= u
;
720 sm
->boardinfo
.objects
= new_mem(u
* sizeof *sm
->boardinfo
.objects
);
721 for(u
= 0; u
< sm
->boardinfo
.objects_len
; u
++) {
722 sm
->boardinfo
.objects
[u
] = READ_MEM16(sm_data
+ 0x0f + 2 * u
);
730 sm
->chassis
.manuf
= get_string(sl_any
, sm_data
[4]);
731 sm
->chassis
.lock
= sm_data
[5] >> 7;
732 sm
->chassis
.ch_type
.id
= sm_data
[5] & 0x7f;
733 smbios_id2str(&sm
->chassis
.ch_type
, &smbios_chassis_types
, 1);
736 sm
->chassis
.version
= get_string(sl_any
, sm_data
[6]);
737 sm
->chassis
.serial
= get_string(sl_any
, sm_data
[7]);
738 sm
->chassis
.asset
= get_string(sl_any
, sm_data
[8]);
740 if(data_len
>= 0x0d) {
741 sm
->chassis
.bootup
.id
= sm_data
[9];
742 sm
->chassis
.power
.id
= sm_data
[0x0a];
743 sm
->chassis
.thermal
.id
= sm_data
[0x0b];
744 sm
->chassis
.security
.id
= sm_data
[0x0c];
745 smbios_id2str(&sm
->chassis
.bootup
, &smbios_chassis_states
, 1);
746 smbios_id2str(&sm
->chassis
.power
, &smbios_chassis_states
, 1);
747 smbios_id2str(&sm
->chassis
.thermal
, &smbios_chassis_states
, 1);
748 smbios_id2str(&sm
->chassis
.security
, &smbios_chassis_sec_states
, 1);
750 if(data_len
>= 0x11) {
751 sm
->chassis
.oem
= READ_MEM32(sm_data
+ 0x0d);
756 if(data_len
>= 0x1a) {
757 sm
->processor
.socket
= get_string(sl_any
, sm_data
[4]);
758 sm
->processor
.manuf
= get_string(sl_any
, sm_data
[7]);
759 sm
->processor
.version
= get_string(sl_any
, sm_data
[0x10]);
760 sm
->processor
.voltage
= sm_data
[0x11];
761 if(sm
->processor
.voltage
& 0x80) {
762 sm
->processor
.voltage
&= 0x7f;
765 switch(sm
->processor
.voltage
) {
767 sm
->processor
.voltage
= 50;
770 sm
->processor
.voltage
= 33;
773 sm
->processor
.voltage
= 29;
776 sm
->processor
.voltage
= 0;
779 sm
->processor
.pr_type
.id
= sm_data
[5];
780 sm
->processor
.family
.id
= sm_data
[6];
781 sm
->processor
.cpu_id
= READ_MEM64(sm_data
+ 8);
782 sm
->processor
.ext_clock
= READ_MEM16(sm_data
+ 0x12);
783 sm
->processor
.max_speed
= READ_MEM16(sm_data
+ 0x14);
784 sm
->processor
.current_speed
= READ_MEM16(sm_data
+ 0x16);
785 sm
->processor
.sock_status
= (sm_data
[0x18] >> 6) & 1;
786 sm
->processor
.cpu_status
.id
= sm_data
[0x18] & 7;
787 sm
->processor
.upgrade
.id
= sm_data
[0x19];
788 smbios_id2str(&sm
->processor
.pr_type
, &smbios_proc_types
, 1);
789 smbios_id2str(&sm
->processor
.family
, &smbios_proc_families
, 1);
790 smbios_id2str(&sm
->processor
.cpu_status
, &smbios_proc_cpu_status
, 0);
791 smbios_id2str(&sm
->processor
.upgrade
, &smbios_proc_upgrades
, 1);
793 if(data_len
>= 0x20) {
794 sm
->processor
.l1_cache
= READ_MEM16(sm_data
+ 0x1a);
795 sm
->processor
.l2_cache
= READ_MEM16(sm_data
+ 0x1c);
796 sm
->processor
.l3_cache
= READ_MEM16(sm_data
+ 0x1e);
797 if(sm
->processor
.l1_cache
== 0xffff) sm
->processor
.l1_cache
= 0;
798 if(sm
->processor
.l2_cache
== 0xffff) sm
->processor
.l2_cache
= 0;
799 if(sm
->processor
.l3_cache
== 0xffff) sm
->processor
.l3_cache
= 0;
801 if(data_len
>= 0x21) {
802 sm
->processor
.serial
= get_string(sl_any
, sm_data
[0x20]);
804 if(data_len
>= 0x22) {
805 sm
->processor
.asset
= get_string(sl_any
, sm_data
[0x21]);
806 sm
->processor
.part
= get_string(sl_any
, sm_data
[0x22]);
811 if(data_len
>= 0x0f) {
812 sm
->cache
.socket
= get_string(sl_any
, sm_data
[4]);
813 u
= READ_MEM16(sm_data
+ 7);
814 if((u
& 0x8000)) u
= (u
& 0x7fff) << 6;
815 sm
->cache
.max_size
= u
;
816 u
= READ_MEM16(sm_data
+ 9);
817 if((u
& 0x8000)) u
= (u
& 0x7fff) << 6;
818 sm
->cache
.current_size
= u
;
819 u
= READ_MEM16(sm_data
+ 5);
820 sm
->cache
.mode
.id
= (u
>> 8) & 3;
821 sm
->cache
.state
= (u
>> 7) & 1;
822 sm
->cache
.location
.id
= (u
>> 5) & 3;
823 sm
->cache
.socketed
= (u
>> 3) & 1;
824 sm
->cache
.level
= u
& 7;
825 smbios_id2str(&sm
->cache
.mode
, &smbios_cache_mode
, 0);
826 smbios_id2str(&sm
->cache
.location
, &smbios_cache_location
, 0);
827 sm
->cache
.supp_sram
.bitmap
[0] = sm_data
[0x0b];
828 sm
->cache
.supp_sram
.bitmap
[1] = sm_data
[0x0c];
829 sm
->cache
.supp_sram
.bits
= 16;
830 sm
->cache
.sram
.bitmap
[0] = sm_data
[0x0d];
831 sm
->cache
.sram
.bitmap
[1] = sm_data
[0x0e];
832 sm
->cache
.sram
.bits
= 16;
833 smbios_bitmap2str(&sm
->cache
.supp_sram
, &smbios_cache_sram
);
834 smbios_bitmap2str(&sm
->cache
.sram
, &smbios_cache_sram
);
836 if(data_len
>= 0x13) {
837 sm
->cache
.speed
= sm_data
[0x0f];
838 sm
->cache
.ecc
.id
= sm_data
[0x10];
839 sm
->cache
.cache_type
.id
= sm_data
[0x11];
840 sm
->cache
.assoc
.id
= sm_data
[0x12];
841 smbios_id2str(&sm
->cache
.ecc
, &smbios_cache_ecc
, 1);
842 smbios_id2str(&sm
->cache
.cache_type
, &smbios_cache_type
, 1);
843 smbios_id2str(&sm
->cache
.assoc
, &smbios_cache_assoc
, 1);
849 sm
->connect
.i_des
= get_string(sl_any
, sm_data
[4]);
850 sm
->connect
.x_des
= get_string(sl_any
, sm_data
[6]);
851 sm
->connect
.i_type
.id
= sm_data
[5];
852 sm
->connect
.x_type
.id
= sm_data
[7];
853 sm
->connect
.port_type
.id
= sm_data
[8];
854 smbios_id2str(&sm
->connect
.port_type
, &smbios_connect_conn_type
, 0xff);
855 smbios_id2str(&sm
->connect
.x_type
, &smbios_connect_conn_type
, 0xff);
856 smbios_id2str(&sm
->connect
.port_type
, &smbios_connect_port_type
, 0xff);
861 if(data_len
>= 0x0c) {
862 sm
->slot
.desig
= get_string(sl_any
, sm_data
[4]);
863 sm
->slot
.slot_type
.id
= sm_data
[5];
864 sm
->slot
.bus_width
.id
= sm_data
[6];
865 sm
->slot
.usage
.id
= sm_data
[7];
866 sm
->slot
.length
.id
= sm_data
[8];
867 sm
->slot
.id
= READ_MEM16(sm_data
+ 9);
868 sm
->slot
.feature
.bitmap
[0] = sm_data
[0x0b];
870 if(data_len
>= 0x0d) {
871 sm
->slot
.feature
.bitmap
[1] = sm_data
[0x0c];
873 sm
->slot
.feature
.bits
= 16;
874 smbios_id2str(&sm
->slot
.slot_type
, &smbios_slot_type
, 1);
875 smbios_id2str(&sm
->slot
.bus_width
, &smbios_slot_bus_width
, 1);
876 smbios_id2str(&sm
->slot
.usage
, &smbios_slot_usage
, 1);
877 smbios_id2str(&sm
->slot
.length
, &smbios_slot_length
, 1);
878 smbios_bitmap2str(&sm
->slot
.feature
, &smbios_slot_feature
);
887 sm
->onboard
.dev_len
= u
;
888 sm
->onboard
.dev
= new_mem(u
* sizeof *sm
->onboard
.dev
);
890 for(u
= 0; u
< sm
->onboard
.dev_len
; u
++) {
891 sm
->onboard
.dev
[u
].name
= get_string(sl_any
, sm_data
[4 + (u
<< 1) + 1]);
892 v
= sm_data
[4 + (u
<< 1)];
893 sm
->onboard
.dev
[u
].status
= v
>> 7;
894 sm
->onboard
.dev
[u
].type
.id
= v
& 0x7f;
895 smbios_id2str(&sm
->onboard
.dev
[u
].type
, &smbios_onboard_type
, 1);
902 for(sl
= sl_any
; sl
; sl
= sl
->next
) {
903 if(sl
->str
&& *sl
->str
) add_str_list(&sm
->oem
.oem_strings
, sl
->str
);
908 for(sl
= sl_any
; sl
; sl
= sl
->next
) {
909 if(sl
->str
&& *sl
->str
) add_str_list(&sm
->config
.options
, sl
->str
);
914 if(data_len
>= 0x16) {
915 sm
->lang
.current
= get_string(sl_any
, sm_data
[0x15]);
921 sm
->group
.name
= get_string(sl_any
, sm_data
[4]);
922 u
= (data_len
- 5) / 3;
924 sm
->group
.items_len
= u
;
925 sm
->group
.item_handles
= new_mem(u
* sizeof *sm
->group
.item_handles
);
926 for(u
= 0; u
< sm
->group
.items_len
; u
++) {
927 sm
->group
.item_handles
[u
] = READ_MEM16(sm_data
+ 6 + 3 * u
);
934 if(data_len
>= 0x0f) {
935 sm
->memarray
.location
.id
= sm_data
[4];
936 sm
->memarray
.use
.id
= sm_data
[5];
937 sm
->memarray
.ecc
.id
= sm_data
[6];
938 sm
->memarray
.max_size
= READ_MEM32(sm_data
+ 7);
939 if(sm
->memarray
.max_size
== 0x80000000) sm
->memarray
.max_size
= 0;
940 sm
->memarray
.error_handle
= READ_MEM16(sm_data
+ 0x0b);
941 sm
->memarray
.slots
= READ_MEM16(sm_data
+ 0x0d);
942 smbios_id2str(&sm
->memarray
.location
, &smbios_memarray_location
, 1);
943 smbios_id2str(&sm
->memarray
.use
, &smbios_memarray_use
, 1);
944 smbios_id2str(&sm
->memarray
.ecc
, &smbios_memarray_ecc
, 1);
949 if(data_len
>= 0x15) {
950 sm
->memdevice
.array_handle
= READ_MEM16(sm_data
+ 0x04);
951 sm
->memdevice
.error_handle
= READ_MEM16(sm_data
+ 0x06);
952 sm
->memdevice
.eccbits
= READ_MEM16(sm_data
+ 8);
953 sm
->memdevice
.width
= READ_MEM16(sm_data
+ 0xa);
954 if(sm
->memdevice
.width
== 0xffff) sm
->memdevice
.width
= 0;
955 if(sm
->memdevice
.eccbits
== 0xffff) sm
->memdevice
.eccbits
= 0;
956 if(sm
->memdevice
.eccbits
>= sm
->memdevice
.width
) {
957 sm
->memdevice
.eccbits
-= sm
->memdevice
.width
;
960 sm
->memdevice
.eccbits
= 0;
962 sm
->memdevice
.size
= READ_MEM16(sm_data
+ 0xc);
963 if(sm
->memdevice
.size
== 0xffff) sm
->memdevice
.size
= 0;
964 if((sm
->memdevice
.size
& 0x8000)) {
965 sm
->memdevice
.size
&= 0x7fff;
968 sm
->memdevice
.size
<<= 10;
970 sm
->memdevice
.form
.id
= sm_data
[0xe];
971 sm
->memdevice
.set
= sm_data
[0xf];
972 sm
->memdevice
.location
= get_string(sl_any
, sm_data
[0x10]);
973 sm
->memdevice
.bank
= get_string(sl_any
, sm_data
[0x11]);
974 sm
->memdevice
.mem_type
.id
= sm_data
[0x12];
975 smbios_id2str(&sm
->memdevice
.form
, &smbios_memdevice_form
, 1);
976 smbios_id2str(&sm
->memdevice
.mem_type
, &smbios_memdevice_type
, 1);
977 sm
->memdevice
.type_detail
.bitmap
[0] = sm_data
[0x13];
978 sm
->memdevice
.type_detail
.bitmap
[1] = sm_data
[0x14];
979 sm
->memdevice
.type_detail
.bits
= 16;
980 smbios_bitmap2str(&sm
->memdevice
.type_detail
, &smbios_memdevice_detail
);
982 if(data_len
>= 0x17) {
983 sm
->memdevice
.speed
= READ_MEM16(sm_data
+ 0x15);
985 if(data_len
>= 0x1b) {
986 sm
->memdevice
.manuf
= get_string(sl_any
, sm_data
[0x17]);
987 sm
->memdevice
.serial
= get_string(sl_any
, sm_data
[0x18]);
988 sm
->memdevice
.asset
= get_string(sl_any
, sm_data
[0x19]);
989 sm
->memdevice
.part
= get_string(sl_any
, sm_data
[0x1a]);
994 if(data_len
>= 0x17) {
995 sm
->memerror
.err_type
.id
= sm_data
[4];
996 sm
->memerror
.granularity
.id
= sm_data
[5];
997 sm
->memerror
.operation
.id
= sm_data
[6];
998 sm
->memerror
.syndrome
= READ_MEM32(sm_data
+ 7);
999 sm
->memerror
.array_addr
= READ_MEM32(sm_data
+ 0xb);
1000 sm
->memerror
.device_addr
= READ_MEM32(sm_data
+ 0xf);
1001 sm
->memerror
.range
= READ_MEM32(sm_data
+ 0x13);
1002 smbios_id2str(&sm
->memerror
.err_type
, &smbios_memerror_type
, 1);
1003 smbios_id2str(&sm
->memerror
.granularity
, &smbios_memerror_granularity
, 1);
1004 smbios_id2str(&sm
->memerror
.operation
, &smbios_memerror_operation
, 1);
1008 case sm_memarraymap
:
1009 if(data_len
>= 0x0f) {
1010 sm
->memarraymap
.start_addr
= READ_MEM32(sm_data
+ 4);
1011 sm
->memarraymap
.start_addr
<<= 10;
1012 sm
->memarraymap
.end_addr
= 1 + READ_MEM32(sm_data
+ 8);
1013 sm
->memarraymap
.end_addr
<<= 10;
1014 sm
->memarraymap
.array_handle
= READ_MEM16(sm_data
+ 0xc);
1015 sm
->memarraymap
.part_width
= sm_data
[0x0e];
1019 case sm_memdevicemap
:
1020 if(data_len
>= 0x13) {
1021 sm
->memdevicemap
.start_addr
= READ_MEM32(sm_data
+ 4);
1022 sm
->memdevicemap
.start_addr
<<= 10;
1023 sm
->memdevicemap
.end_addr
= 1 + READ_MEM32(sm_data
+ 8);
1024 sm
->memdevicemap
.end_addr
<<= 10;
1025 sm
->memdevicemap
.memdevice_handle
= READ_MEM16(sm_data
+ 0xc);
1026 sm
->memdevicemap
.arraymap_handle
= READ_MEM16(sm_data
+ 0xe);
1027 sm
->memdevicemap
.row_pos
= sm_data
[0x10];
1028 sm
->memdevicemap
.interleave_pos
= sm_data
[0x11];
1029 sm
->memdevicemap
.interleave_depth
= sm_data
[0x12];
1035 sm
->mouse
.mtype
.id
= sm_data
[4];
1036 sm
->mouse
.interface
.id
= sm_data
[5];
1037 sm
->mouse
.buttons
= sm_data
[6];
1038 smbios_id2str(&sm
->mouse
.mtype
, &smbios_mouse_type
, 1);
1039 smbios_id2str(&sm
->mouse
.interface
, &smbios_mouse_interface
, 1);
1046 sm
->secure
.power
.id
= u
>> 6;
1047 sm
->secure
.keyboard
.id
= (u
>> 4) & 3;
1048 sm
->secure
.admin
.id
= (u
>> 2) & 3;
1049 sm
->secure
.reset
.id
= u
& 3;
1050 smbios_id2str(&sm
->secure
.power
, &smbios_secure_state
, 3);
1051 smbios_id2str(&sm
->secure
.keyboard
, &smbios_secure_state
, 3);
1052 smbios_id2str(&sm
->secure
.admin
, &smbios_secure_state
, 3);
1053 smbios_id2str(&sm
->secure
.reset
, &smbios_secure_state
, 3);
1059 sm
->power
.month
= sm_data
[4];
1060 sm
->power
.day
= sm_data
[5];
1061 sm
->power
.hour
= sm_data
[6];
1062 sm
->power
.minute
= sm_data
[7];
1063 sm
->power
.second
= sm_data
[8];
1068 if(data_len
>= 0x1f) {
1069 sm
->mem64error
.err_type
.id
= sm_data
[4];
1070 sm
->mem64error
.granularity
.id
= sm_data
[5];
1071 sm
->mem64error
.operation
.id
= sm_data
[6];
1072 sm
->mem64error
.syndrome
= READ_MEM32(sm_data
+ 7);
1073 sm
->mem64error
.array_addr
= READ_MEM64(sm_data
+ 0xb);
1074 sm
->mem64error
.device_addr
= READ_MEM64(sm_data
+ 0x13);
1075 sm
->mem64error
.range
= READ_MEM32(sm_data
+ 0x1b);
1076 smbios_id2str(&sm
->mem64error
.err_type
, &smbios_memerror_type
, 1);
1077 smbios_id2str(&sm
->mem64error
.granularity
, &smbios_memerror_granularity
, 1);
1078 smbios_id2str(&sm
->mem64error
.operation
, &smbios_memerror_operation
, 1);
1090 * Note: new_sm is directly inserted into the list, so you *must* make sure
1091 * that new_sm points to a malloc'ed pice of memory.
1093 hd_smbios_t
*smbios_add_entry(hd_smbios_t
**sm
, hd_smbios_t
*new_sm
)
1095 while(*sm
) sm
= &(*sm
)->next
;
1097 return *sm
= new_sm
;
1102 * Free the memory allocated by a smbios list.
1104 hd_smbios_t
*smbios_free(hd_smbios_t
*sm
)
1109 for(; sm
; sm
= next
) {
1112 free_mem(sm
->any
.data
);
1113 free_str_list(sm
->any
.strings
);
1115 switch(sm
->any
.type
) {
1117 free_mem(sm
->biosinfo
.vendor
);
1118 free_mem(sm
->biosinfo
.version
);
1119 free_mem(sm
->biosinfo
.date
);
1120 free_str_list(sm
->biosinfo
.feature
.str
);
1124 free_mem(sm
->sysinfo
.manuf
);
1125 free_mem(sm
->sysinfo
.product
);
1126 free_mem(sm
->sysinfo
.version
);
1127 free_mem(sm
->sysinfo
.serial
);
1128 free_mem(sm
->sysinfo
.wake_up
.name
);
1132 free_mem(sm
->boardinfo
.manuf
);
1133 free_mem(sm
->boardinfo
.product
);
1134 free_mem(sm
->boardinfo
.version
);
1135 free_mem(sm
->boardinfo
.serial
);
1136 free_mem(sm
->boardinfo
.asset
);
1137 free_mem(sm
->boardinfo
.location
);
1138 free_mem(sm
->boardinfo
.board_type
.name
);
1139 free_str_list(sm
->boardinfo
.feature
.str
);
1140 free_mem(sm
->boardinfo
.objects
);
1144 free_mem(sm
->chassis
.manuf
);
1145 free_mem(sm
->chassis
.version
);
1146 free_mem(sm
->chassis
.serial
);
1147 free_mem(sm
->chassis
.asset
);
1148 free_mem(sm
->chassis
.ch_type
.name
);
1149 free_mem(sm
->chassis
.bootup
.name
);
1150 free_mem(sm
->chassis
.power
.name
);
1151 free_mem(sm
->chassis
.thermal
.name
);
1152 free_mem(sm
->chassis
.security
.name
);
1156 free_mem(sm
->processor
.socket
);
1157 free_mem(sm
->processor
.manuf
);
1158 free_mem(sm
->processor
.version
);
1159 free_mem(sm
->processor
.serial
);
1160 free_mem(sm
->processor
.asset
);
1161 free_mem(sm
->processor
.part
);
1162 free_mem(sm
->processor
.upgrade
.name
);
1163 free_mem(sm
->processor
.pr_type
.name
);
1164 free_mem(sm
->processor
.family
.name
);
1165 free_mem(sm
->processor
.cpu_status
.name
);
1169 free_mem(sm
->cache
.socket
);
1170 free_mem(sm
->cache
.mode
.name
);
1171 free_mem(sm
->cache
.location
.name
);
1172 free_mem(sm
->cache
.ecc
.name
);
1173 free_mem(sm
->cache
.cache_type
.name
);
1174 free_mem(sm
->cache
.assoc
.name
);
1175 free_str_list(sm
->cache
.supp_sram
.str
);
1176 free_str_list(sm
->cache
.sram
.str
);
1180 free_mem(sm
->connect
.port_type
.name
);
1181 free_mem(sm
->connect
.i_des
);
1182 free_mem(sm
->connect
.x_des
);
1183 free_mem(sm
->connect
.i_type
.name
);
1184 free_mem(sm
->connect
.x_type
.name
);
1188 free_mem(sm
->slot
.desig
);
1189 free_mem(sm
->slot
.slot_type
.name
);
1190 free_mem(sm
->slot
.bus_width
.name
);
1191 free_mem(sm
->slot
.usage
.name
);
1192 free_mem(sm
->slot
.length
.name
);
1193 free_str_list(sm
->slot
.feature
.str
);
1197 for(u
= 0; u
< sm
->onboard
.dev_len
; u
++) {
1198 free_mem(sm
->onboard
.dev
[u
].name
);
1199 free_mem(sm
->onboard
.dev
[u
].type
.name
);
1201 free_mem(sm
->onboard
.dev
);
1205 free_str_list(sm
->oem
.oem_strings
);
1209 free_str_list(sm
->config
.options
);
1213 free_mem(sm
->lang
.current
);
1217 free_mem(sm
->group
.name
);
1218 free_mem(sm
->group
.item_handles
);
1222 free_mem(sm
->memarray
.location
.name
);
1223 free_mem(sm
->memarray
.use
.name
);
1224 free_mem(sm
->memarray
.ecc
.name
);
1228 free_mem(sm
->memdevice
.location
);
1229 free_mem(sm
->memdevice
.bank
);
1230 free_mem(sm
->memdevice
.manuf
);
1231 free_mem(sm
->memdevice
.serial
);
1232 free_mem(sm
->memdevice
.asset
);
1233 free_mem(sm
->memdevice
.part
);
1234 free_mem(sm
->memdevice
.form
.name
);
1235 free_mem(sm
->memdevice
.mem_type
.name
);
1236 free_str_list(sm
->memdevice
.type_detail
.str
);
1240 free_mem(sm
->memerror
.err_type
.name
);
1241 free_mem(sm
->memerror
.granularity
.name
);
1242 free_mem(sm
->memerror
.operation
.name
);
1246 free_mem(sm
->mouse
.mtype
.name
);
1247 free_mem(sm
->mouse
.interface
.name
);
1251 free_mem(sm
->secure
.power
.name
);
1252 free_mem(sm
->secure
.keyboard
.name
);
1253 free_mem(sm
->secure
.admin
.name
);
1254 free_mem(sm
->secure
.reset
.name
);
1258 free_mem(sm
->mem64error
.err_type
.name
);
1259 free_mem(sm
->mem64error
.granularity
.name
);
1260 free_mem(sm
->mem64error
.operation
.name
);
1275 * print SMBIOS entries
1277 void smbios_dump(hd_data_t
*hd_data
, FILE *f
)
1285 if(!hd_data
->smbios
) return;
1287 for(sm
= hd_data
->smbios
; sm
; sm
= sm
->next
) {
1288 switch(sm
->any
.type
) {
1290 fprintf(f
, " BIOS Info: #%d\n", sm
->any
.handle
);
1291 if(sm
->biosinfo
.vendor
) fprintf(f
, " Vendor: \"%s\"\n", sm
->biosinfo
.vendor
);
1292 if(sm
->biosinfo
.version
) fprintf(f
, " Version: \"%s\"\n", sm
->biosinfo
.version
);
1293 if(sm
->biosinfo
.date
) fprintf(f
, " Date: \"%s\"\n", sm
->biosinfo
.date
);
1294 fprintf(f
, " Start Address: 0x%05x\n", sm
->biosinfo
.start
);
1295 fprintf(f
, " ROM Size: %d kB\n", sm
->biosinfo
.rom_size
>> 10);
1296 SMBIOS_PRINT_BITMAP_LONG(biosinfo
.feature
, "Features");
1300 fprintf(f
, " System Info: #%d\n", sm
->any
.handle
);
1301 if(sm
->sysinfo
.manuf
) fprintf(f
, " Manufacturer: \"%s\"\n", sm
->sysinfo
.manuf
);
1302 if(sm
->sysinfo
.product
) fprintf(f
, " Product: \"%s\"\n", sm
->sysinfo
.product
);
1303 if(sm
->sysinfo
.version
) fprintf(f
, " Version: \"%s\"\n", sm
->sysinfo
.version
);
1304 if(sm
->sysinfo
.serial
) fprintf(f
, " Serial: \"%s\"\n", sm
->sysinfo
.serial
);
1305 for(i
= u
= 0; (unsigned) i
< sizeof sm
->sysinfo
.uuid
/ sizeof *sm
->sysinfo
.uuid
; i
++) {
1306 u
|= sm
->sysinfo
.uuid
[i
];
1308 fprintf(f
, " UUID: ");
1309 if(u
== 0 || u
== 0xff) {
1310 fprintf(f
, "undefined");
1311 if(u
== 0xff) fprintf(f
, ", but settable");
1314 for(i
= sizeof sm
->sysinfo
.uuid
/ sizeof *sm
->sysinfo
.uuid
- 1; i
>= 0; i
--) {
1315 fprintf(f
, "%02x", sm
->sysinfo
.uuid
[i
]);
1319 SMBIOS_PRINT_ID(sysinfo
.wake_up
, "Wake-up");
1323 fprintf(f
, " Board Info: #%d\n", sm
->any
.handle
);
1324 if(sm
->boardinfo
.manuf
) fprintf(f
, " Manufacturer: \"%s\"\n", sm
->boardinfo
.manuf
);
1325 if(sm
->boardinfo
.product
) fprintf(f
, " Product: \"%s\"\n", sm
->boardinfo
.product
);
1326 if(sm
->boardinfo
.version
) fprintf(f
, " Version: \"%s\"\n", sm
->boardinfo
.version
);
1327 if(sm
->boardinfo
.serial
) fprintf(f
, " Serial: \"%s\"\n", sm
->boardinfo
.serial
);
1328 if(sm
->boardinfo
.asset
) fprintf(f
, " Asset Tag: \"%s\"\n", sm
->boardinfo
.asset
);
1329 SMBIOS_PRINT_ID(boardinfo
.board_type
, "Type");
1330 SMBIOS_PRINT_BITMAP_LONG(boardinfo
.feature
, "Features");
1331 if(sm
->boardinfo
.location
) fprintf(f
, " Location: \"%s\"\n", sm
->boardinfo
.location
);
1332 if(sm
->boardinfo
.chassis
) fprintf(f
, " Chassis: #%d\n", sm
->boardinfo
.chassis
);
1333 if(sm
->boardinfo
.objects_len
) {
1334 fprintf(f
, " Contained Objects: ");
1335 for(i
= 0; i
< sm
->boardinfo
.objects_len
; i
++) {
1336 fprintf(f
, "%s#%d", i
? ", " : "", sm
->boardinfo
.objects
[i
]);
1343 fprintf(f
, " Chassis Info: #%d\n", sm
->any
.handle
);
1344 if(sm
->chassis
.manuf
) fprintf(f
, " Manufacturer: \"%s\"\n", sm
->chassis
.manuf
);
1345 if(sm
->chassis
.version
) fprintf(f
, " Version: \"%s\"\n", sm
->chassis
.version
);
1346 if(sm
->chassis
.serial
) fprintf(f
, " Serial: \"%s\"\n", sm
->chassis
.serial
);
1347 if(sm
->chassis
.asset
) fprintf(f
, " Asset Tag: \"%s\"\n", sm
->chassis
.asset
);
1348 SMBIOS_PRINT_ID(chassis
.ch_type
, "Type");
1349 if(sm
->chassis
.lock
) fprintf(f
, " Lock: present\n");
1350 SMBIOS_PRINT_ID(chassis
.bootup
, "Bootup State");
1351 SMBIOS_PRINT_ID(chassis
.power
, "Power Supply State");
1352 SMBIOS_PRINT_ID(chassis
.thermal
, "Thermal State");
1353 SMBIOS_PRINT_ID(chassis
.security
, "Security Status");
1354 if(sm
->chassis
.oem
) fprintf(f
, " OEM Info: 0x%08x\n", sm
->chassis
.oem
);
1358 fprintf(f
, " Processor Info: #%d\n", sm
->any
.handle
);
1359 SMBIOS_PRINT_STR(processor
.socket
, "Socket");
1360 SMBIOS_PRINT_ID(processor
.upgrade
, "Socket Type");
1361 fprintf(f
, " Socket Status: %s\n", sm
->processor
.sock_status
? "Populated" : "Empty");
1362 SMBIOS_PRINT_ID(processor
.pr_type
, "Type");
1363 SMBIOS_PRINT_ID(processor
.family
, "Family");
1364 SMBIOS_PRINT_STR(processor
.manuf
, "Manufacturer");
1365 SMBIOS_PRINT_STR(processor
.version
, "Version");
1366 SMBIOS_PRINT_STR(processor
.serial
, "Serial");
1367 SMBIOS_PRINT_STR(processor
.asset
, "Asset Tag");
1368 SMBIOS_PRINT_STR(processor
.part
, "Part Number");
1369 if(sm
->processor
.cpu_id
) {
1370 fprintf(f
, " Processor ID: 0x%016"PRIx64
"\n", sm
->processor
.cpu_id
);
1372 SMBIOS_PRINT_ID(processor
.cpu_status
, "Status");
1373 if(sm
->processor
.voltage
) {
1374 fprintf(f
, " Voltage: %u.%u V\n", sm
->processor
.voltage
/ 10, sm
->processor
.voltage
% 10);
1376 if(sm
->processor
.ext_clock
) fprintf(f
, " External Clock: %u MHz\n", sm
->processor
.ext_clock
);
1377 if(sm
->processor
.max_speed
) fprintf(f
, " Max. Speed: %u MHz\n", sm
->processor
.max_speed
);
1378 if(sm
->processor
.current_speed
) fprintf(f
, " Current Speed: %u MHz\n", sm
->processor
.current_speed
);
1380 if(sm
->processor
.l1_cache
) fprintf(f
, " L1 Cache: #%d\n", sm
->processor
.l1_cache
);
1381 if(sm
->processor
.l2_cache
) fprintf(f
, " L2 Cache: #%d\n", sm
->processor
.l2_cache
);
1382 if(sm
->processor
.l3_cache
) fprintf(f
, " L3 Cache: #%d\n", sm
->processor
.l3_cache
);
1386 fprintf(f
, " Cache Info: #%d\n", sm
->any
.handle
);
1387 SMBIOS_PRINT_STR(cache
.socket
, "Designation");
1388 fprintf(f
, " Level: L%u\n", sm
->cache
.level
+ 1);
1389 fprintf(f
, " State: %s\n", sm
->cache
.state
? "Enabled" : "Disabled");
1390 SMBIOS_PRINT_ID(cache
.mode
, "Mode");
1391 if(sm
->cache
.location
.name
) {
1392 fprintf(f
, " Location: 0x%02x (%s, %sSocketed)\n",
1393 sm
->cache
.location
.id
,
1394 sm
->cache
.location
.name
,
1395 sm
->cache
.socketed
? "" : "Not "
1398 SMBIOS_PRINT_ID(cache
.ecc
, "ECC");
1399 SMBIOS_PRINT_ID(cache
.cache_type
, "Type");
1400 SMBIOS_PRINT_ID(cache
.assoc
, "Associativity");
1401 if(sm
->cache
.max_size
) fprintf(f
, " Max. Size: %u kB\n", sm
->cache
.max_size
);
1402 if(sm
->cache
.current_size
) fprintf(f
, " Current Size: %u kB\n", sm
->cache
.current_size
);
1403 if(sm
->cache
.speed
) fprintf(f
, " Speed: %u ns\n", sm
->cache
.speed
);
1404 SMBIOS_PRINT_BITMAP_SHORT(cache
.supp_sram
, "Supported SRAM Types");
1405 SMBIOS_PRINT_BITMAP_SHORT(cache
.sram
, "Current SRAM Type");
1409 fprintf(f
, " Port Connector: #%d\n", sm
->any
.handle
);
1410 SMBIOS_PRINT_ID(connect
.port_type
, "Type");
1411 SMBIOS_PRINT_STR(connect
.i_des
, "Internal Designator");
1412 SMBIOS_PRINT_ID(connect
.i_type
, "Internal Connector");
1413 SMBIOS_PRINT_STR(connect
.x_des
, "External Designator");
1414 SMBIOS_PRINT_ID(connect
.x_type
, "External Connector");
1418 fprintf(f
, " System Slot: #%d\n", sm
->any
.handle
);
1419 SMBIOS_PRINT_STR(slot
.desig
, "Designation");
1420 SMBIOS_PRINT_ID(slot
.slot_type
, "Type");
1421 SMBIOS_PRINT_ID(slot
.bus_width
, "Bus Width");
1422 SMBIOS_PRINT_ID(slot
.usage
, "Status");
1423 SMBIOS_PRINT_ID(slot
.length
, "Length");
1424 fprintf(f
, " Slot ID: %u\n", sm
->slot
.id
);
1425 SMBIOS_PRINT_BITMAP_SHORT(slot
.feature
, "Characteristics");
1429 fprintf(f
, " On Board Devices: #%d\n", sm
->any
.handle
);
1430 for(u
= 0; u
< sm
->onboard
.dev_len
; u
++) {
1431 fprintf(f
, " %s: \"%s\"%s\n",
1432 sm
->onboard
.dev
[u
].type
.name
,
1433 sm
->onboard
.dev
[u
].name
,
1434 sm
->onboard
.dev
[u
].status
? "" : " (disabled)"
1440 fprintf(f
, " OEM Strings: #%d\n", sm
->any
.handle
);
1441 for(sl
= sm
->oem
.oem_strings
; sl
; sl
= sl
->next
) {
1442 fprintf(f
, " %s\n", sl
->str
);
1447 fprintf(f
, " System Config Options (Jumpers & Switches) #%d:\n", sm
->any
.handle
);
1448 for(sl
= sm
->config
.options
; sl
; sl
= sl
->next
) {
1449 fprintf(f
, " %s\n", sl
->str
);
1454 fprintf(f
, " Language Info: #%d\n", sm
->any
.handle
);
1455 if((sl
= sm
->lang
.strings
)) {
1456 fprintf(f
, " Languages: ");
1457 for(; sl
; sl
= sl
->next
) {
1458 fprintf(f
, "%s%s", sl
->str
, sl
->next
? ", " : "");
1462 if(sm
->lang
.current
) fprintf(f
, " Current: %s\n", sm
->lang
.current
);
1466 fprintf(f
, " Group Associations: #%d\n", sm
->any
.handle
);
1467 if(sm
->group
.name
) fprintf(f
, " Group Name: \"%s\"\n", sm
->group
.name
);
1468 if(sm
->group
.items_len
) {
1469 fprintf(f
, " Items: ");
1470 for(i
= 0; i
< sm
->group
.items_len
; i
++) {
1471 fprintf(f
, "%s#%d", i
? ", " : "", sm
->group
.item_handles
[i
]);
1478 fprintf(f
, " Physical Memory Array: #%d\n", sm
->any
.handle
);
1479 SMBIOS_PRINT_ID(memarray
.use
, "Use");
1480 SMBIOS_PRINT_ID(memarray
.location
, "Location");
1481 fprintf(f
, " Slots: %u\n", sm
->memarray
.slots
);
1482 if(sm
->memarray
.max_size
) {
1483 u
= sm
->memarray
.max_size
;
1485 if(!(u
& 0x3ff)) { u
>>= 10; c
= 'M'; }
1486 if(!(u
& 0x3ff)) { u
>>= 10; c
= 'G'; }
1487 fprintf(f
, " Max. Size: %u %cB\n", u
, c
);
1489 SMBIOS_PRINT_ID(memarray
.ecc
, "ECC");
1490 if(sm
->memarray
.error_handle
!= 0xfffe) {
1491 fprintf(f
, " Error Info: ");
1492 if(sm
->memarray
.error_handle
!= 0xffff) {
1493 fprintf(f
, "#%d\n", sm
->memarray
.error_handle
);
1496 fprintf(f
, "No Error\n");
1502 fprintf(f
, " Memory Device: #%d\n", sm
->any
.handle
);
1503 SMBIOS_PRINT_STR(memdevice
.location
, "Location");
1504 SMBIOS_PRINT_STR(memdevice
.bank
, "Bank");
1505 SMBIOS_PRINT_STR(memdevice
.manuf
, "Manufacturer");
1506 SMBIOS_PRINT_STR(memdevice
.serial
, "Serial");
1507 SMBIOS_PRINT_STR(memdevice
.asset
, "Asset Tag");
1508 SMBIOS_PRINT_STR(memdevice
.part
, "Part Number");
1509 fprintf(f
, " Memory Array: #%d\n", sm
->memdevice
.array_handle
);
1510 if(sm
->memdevice
.error_handle
!= 0xfffe) {
1511 fprintf(f
, " Error Info: ");
1512 if(sm
->memdevice
.error_handle
!= 0xffff) {
1513 fprintf(f
, "#%d\n", sm
->memdevice
.error_handle
);
1516 fprintf(f
, "No Error\n");
1519 SMBIOS_PRINT_ID(memdevice
.form
, "Form Factor");
1520 SMBIOS_PRINT_ID(memdevice
.mem_type
, "Type");
1521 SMBIOS_PRINT_BITMAP_SHORT(memdevice
.type_detail
, "Type Detail");
1522 fprintf(f
, " Data Width: %u bits", sm
->memdevice
.width
);
1523 if(sm
->memdevice
.eccbits
) fprintf(f
, " (+%u ECC bits)", sm
->memdevice
.eccbits
);
1525 if(sm
->memdevice
.size
) {
1526 u
= sm
->memdevice
.size
;
1528 if(!(u
& 0x3ff)) { u
>>= 10; c
= 'M'; }
1529 if(!(u
& 0x3ff)) { u
>>= 10; c
= 'G'; }
1530 fprintf(f
, " Size: %u %cB\n", u
, c
);
1533 fprintf(f
, " Size: No Memory Installed\n");
1535 if(sm
->memdevice
.speed
) fprintf(f
, " Speed: %u MHz\n", sm
->memdevice
.speed
);
1539 fprintf(f
, " 32bit-Memory Error Info: #%d\n", sm
->any
.handle
);
1540 SMBIOS_PRINT_ID(memerror
.err_type
, "Type");
1541 SMBIOS_PRINT_ID(memerror
.granularity
, "Granularity");
1542 SMBIOS_PRINT_ID(memerror
.operation
, "Operation");
1543 if(sm
->memerror
.syndrome
) fprintf(f
, " Syndrome: 0x%08x\n", sm
->memerror
.syndrome
);
1544 if(sm
->memerror
.array_addr
!= (1 << 31)) fprintf(f
, " Mem Array Addr: 0x%08x\n", sm
->memerror
.array_addr
);
1545 if(sm
->memerror
.device_addr
!= (1 << 31)) fprintf(f
, " Mem Device Addr: 0x%08x\n", sm
->memerror
.device_addr
);
1546 if(sm
->memerror
.range
!= (1 << 31)) fprintf(f
, " Range: 0x%08x\n", sm
->memerror
.range
);
1549 case sm_memarraymap
:
1550 fprintf(f
, " Memory Array Mapping: #%d\n", sm
->any
.handle
);
1551 fprintf(f
, " Memory Array: #%d\n", sm
->memarraymap
.array_handle
);
1552 fprintf(f
, " Partition Width: %u\n", sm
->memarraymap
.part_width
);
1553 if((sm
->memarraymap
.start_addr
| sm
->memarraymap
.end_addr
) >> 32) {
1554 fprintf(f
, " Start Address: 0x%016"PRIx64
"\n", sm
->memarraymap
.start_addr
);
1555 fprintf(f
, " End Address: 0x%016"PRIx64
"\n", sm
->memarraymap
.end_addr
);
1558 fprintf(f
, " Start Address: 0x%08x\n", (unsigned) sm
->memarraymap
.start_addr
);
1559 fprintf(f
, " End Address: 0x%08x\n", (unsigned) sm
->memarraymap
.end_addr
);
1563 case sm_memdevicemap
:
1564 fprintf(f
, " Memory Device Mapping: #%d\n", sm
->any
.handle
);
1565 fprintf(f
, " Memory Device: #%d\n", sm
->memdevicemap
.memdevice_handle
);
1566 fprintf(f
, " Array Mapping: #%d\n", sm
->memdevicemap
.arraymap_handle
);
1567 if(sm
->memdevicemap
.row_pos
!= 0xff) fprintf(f
, " Row: %u\n", sm
->memdevicemap
.row_pos
);
1569 !sm
->memdevicemap
.interleave_pos
||
1570 sm
->memdevicemap
.interleave_pos
!= 0xff
1572 fprintf(f
, " Interleave Pos: %u\n", sm
->memdevicemap
.interleave_pos
);
1575 !sm
->memdevicemap
.interleave_depth
||
1576 sm
->memdevicemap
.interleave_depth
!= 0xff
1578 fprintf(f
, " Interleaved Depth: %u\n", sm
->memdevicemap
.interleave_depth
);
1580 if((sm
->memdevicemap
.start_addr
| sm
->memdevicemap
.end_addr
) >> 32) {
1581 fprintf(f
, " Start Address: 0x%016"PRIx64
"\n", sm
->memdevicemap
.start_addr
);
1582 fprintf(f
, " End Address: 0x%016"PRIx64
"\n", sm
->memdevicemap
.end_addr
);
1585 fprintf(f
, " Start Address: 0x%08x\n", (unsigned) sm
->memdevicemap
.start_addr
);
1586 fprintf(f
, " End Address: 0x%08x\n", (unsigned) sm
->memdevicemap
.end_addr
);
1591 fprintf(f
, " Pointing Device: #%d\n", sm
->any
.handle
);
1592 SMBIOS_PRINT_ID(mouse
.mtype
, "Type");
1593 SMBIOS_PRINT_ID(mouse
.interface
, "Interface");
1594 if(sm
->mouse
.buttons
) fprintf(f
, " Buttons: %u\n", sm
->mouse
.buttons
);
1598 fprintf(f
, " Hardware Security: #%d\n", sm
->any
.handle
);
1599 SMBIOS_PRINT_ID(secure
.power
, "Power-on Password");
1600 SMBIOS_PRINT_ID(secure
.keyboard
, "Keyboard Password");
1601 SMBIOS_PRINT_ID(secure
.admin
, "Admin Password");
1602 SMBIOS_PRINT_ID(secure
.reset
, "Front Panel Reset");
1606 fprintf(f
, " System Power Controls: #%d\n", sm
->any
.handle
);
1608 " Next Power-on: %02x:%02x:%02x %02x/%02x\n",
1609 sm
->power
.hour
, sm
->power
.minute
, sm
->power
.second
,
1610 sm
->power
.day
, sm
->power
.month
1615 fprintf(f
, " 64bit-Memory Error Info: #%d\n", sm
->any
.handle
);
1616 SMBIOS_PRINT_ID(mem64error
.err_type
, "Type");
1617 SMBIOS_PRINT_ID(mem64error
.granularity
, "Granularity");
1618 SMBIOS_PRINT_ID(mem64error
.operation
, "Operation");
1619 if(sm
->mem64error
.syndrome
) fprintf(f
, " Syndrome: 0x%08x\n", sm
->mem64error
.syndrome
);
1621 sm
->mem64error
.array_addr
!= (1ll << 63) &&
1622 sm
->mem64error
.array_addr
!= (1ll << 31)
1624 fprintf(f
, " Mem Array Addr: 0x%016"PRIx64
"\n", sm
->mem64error
.array_addr
);
1627 sm
->mem64error
.device_addr
!= (1ll << 63) &&
1628 sm
->mem64error
.device_addr
!= (1ll << 31)
1630 fprintf(f
, " Mem Device Addr: 0x%016"PRIx64
"\n", sm
->mem64error
.device_addr
);
1632 if(sm
->mem64error
.range
!= (1 << 31)) fprintf(f
, " Range: 0x%08x\n", sm
->mem64error
.range
);
1639 if(sm
->any
.type
== sm_inactive
) {
1640 fprintf(f
, " Inactive Record: #%d\n", sm
->any
.handle
);
1643 fprintf(f
, " Type %d Record: #%d\n", sm
->any
.type
, sm
->any
.handle
);
1645 if(sm
->any
.data_len
) {
1646 for(i
= 0; i
< sm
->any
.data_len
; i
+= 0x10) {
1647 u
= sm
->any
.data_len
- i
;
1648 if(u
> 0x10) u
= 0x10;
1650 hexdump(&s
, 0, u
, sm
->any
.data
+ i
);
1651 fprintf(f
, " Data %02x: %s\n", i
, s
);
1655 for(u
= 1, sl
= sm
->any
.strings
; sl
; sl
= sl
->next
, u
++) {
1656 if(sl
->str
&& *sl
->str
) fprintf(f
, " String %u: \"%s\"\n", u
, sl
->str
);