1 # Copyright (c) 2015, Intel Corporation
4 # SPDX-License-Identifier: BSD-3-Clause
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions are met:
9 # * Redistributions of source code must retain the above copyright notice,
10 # this list of conditions and the following disclaimer.
11 # * Redistributions in binary form must reproduce the above copyright notice,
12 # this list of conditions and the following disclaimer in the documentation
13 # and/or other materials provided with the distribution.
14 # * Neither the name of Intel Corporation nor the names of its contributors
15 # may be used to endorse or promote products derived from this software
16 # without specific prior written permission.
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
22 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 # This script runs only from the biosbits VM.
31 """SMBIOS/DMI module."""
43 class SMBIOS(unpack.Struct):
45 if sys.platform == "BITS-EFI":
47 sm_ptr = efi.system_table.ConfigurationTableDict.get(efi.SMBIOS_TABLE_GUID)
50 mem = bits.memory(0xF0000, 0x10000)
51 for offset in range(0, len(mem), 16):
52 signature = (ctypes.c_char * 4).from_address(address + offset).value
53 if signature == "_SM_":
54 entry_point_length = ctypes.c_ubyte.from_address(address + offset + 5).value
55 csum = sum(map(ord, mem[offset:offset + entry_point_length])) & 0xff
57 sm_ptr = address + offset
65 sm = super(SMBIOS, cls).__new__(cls)
66 sm._header_memory = bits.memory(sm_ptr, 0x1f)
70 super(SMBIOS, self).__init__()
71 u = unpack.Unpackable(self._header_memory)
72 self.add_field('header', Header(u))
73 self._structure_memory = bits.memory(self.header.structure_table_address, self.header.structure_table_length)
74 u = unpack.Unpackable(self._structure_memory)
75 self.add_field('structures', unpack.unpack_all(u, _smbios_structures, self), unpack.format_each("\n\n{!r}"))
77 def structure_type(self, num):
78 '''Dumps structure of given Type if present'''
80 types_present = [self.structures[x].smbios_structure_type for x in range(len(self.structures))]
82 for index in range(len(types_present)):
83 if types_present.count(types_present[index]) == 1:
84 matrix[types_present[index]] = self.structures[index]
85 else: # if multiple structures of the same type, return a list of structures for the type number
86 if matrix.has_key(types_present[index]):
87 matrix[types_present[index]].append(self.structures[index])
89 matrix[types_present[index]] = [self.structures[index]]
92 print "Failure: Type {} - not found".format(num)
94 class Header(unpack.Struct):
96 return super(Header, cls).__new__(cls)
98 def __init__(self, u):
99 super(Header, self).__init__()
100 self.raw_data = u.unpack_rest()
101 u = unpack.Unpackable(self.raw_data)
102 self.add_field('anchor_string', u.unpack_one("4s"))
103 self.add_field('checksum', u.unpack_one("B"))
104 self.add_field('length', u.unpack_one("B"))
105 self.add_field('major_version', u.unpack_one("B"))
106 self.add_field('minor_version', u.unpack_one("B"))
107 self.add_field('max_structure_size', u.unpack_one("<H"))
108 self.add_field('entry_point_revision', u.unpack_one("B"))
109 self.add_field('formatted_area', u.unpack_one("5s"))
110 self.add_field('intermediate_anchor_string', u.unpack_one("5s"))
111 self.add_field('intermediate_checksum', u.unpack_one("B"))
112 self.add_field('structure_table_length', u.unpack_one("<H"))
113 self.add_field('structure_table_address', u.unpack_one("<I"))
114 self.add_field('number_structures', u.unpack_one("<H"))
115 self.add_field('bcd_revision', u.unpack_one("B"))
117 self.add_field('data', u.unpack_rest())
119 class SmbiosBaseStructure(unpack.Struct):
120 def __new__(cls, u, sm):
121 t = u.unpack_peek_one("B")
122 if cls.smbios_structure_type is not None and t != cls.smbios_structure_type:
124 return super(SmbiosBaseStructure, cls).__new__(cls)
126 def __init__(self, u, sm):
127 super(SmbiosBaseStructure, self).__init__()
128 self.start_offset = u.offset
129 length = u.unpack_peek_one("<xB")
130 self.raw_data = u.unpack_raw(length)
131 self.u = unpack.Unpackable(self.raw_data)
133 self.strings_offset = u.offset
135 return "".join(iter(lambda: u.unpack_one("c"), "\x00"))
136 strings = list(iter(unpack_string, ""))
140 self.strings_length = u.offset - self.strings_offset
141 self.raw_strings = str(bits.memory(sm.header.structure_table_address + self.strings_offset, self.strings_length))
144 self.strings = strings
146 self.add_field('type', self.u.unpack_one("B"))
147 self.add_field('length', self.u.unpack_one("B"))
148 self.add_field('handle', self.u.unpack_one("<H"))
151 if not self.u.at_end():
152 self.add_field('data', self.u.unpack_rest())
156 """Format the specified index and the associated string"""
157 return "{} '{}'".format(i, self.getstr(i))
160 """Get the string associated with the given index"""
163 if not hasattr(self, "strings"):
164 return "(error: structure has no strings)"
165 if i > len(self.strings):
166 return "(error: string index out of range)"
167 return self.strings[i - 1]
169 class BIOSInformation(SmbiosBaseStructure):
170 smbios_structure_type = 0
172 def __init__(self, u, sm):
173 super(BIOSInformation, self).__init__(u, sm)
176 self.add_field('vendor', u.unpack_one("B"), self.fmtstr)
177 self.add_field('version', u.unpack_one("B"), self.fmtstr)
178 self.add_field('starting_address_segment', u.unpack_one("<H"))
179 self.add_field('release_date', u.unpack_one("B"), self.fmtstr)
180 self.add_field('rom_size', u.unpack_one("B"))
181 self.add_field('characteristics', u.unpack_one("<Q"))
182 minor_version_str = str(sm.header.minor_version) # 34 is .34, 4 is .4, 41 is .41; compare ASCIIbetically to compare initial digits rather than numeric value
183 if (sm.header.major_version, minor_version_str) >= (2,"4"):
184 characteristic_bytes = 2
186 characteristic_bytes = self.length - 0x12
187 self.add_field('characteristics_extensions', [u.unpack_one("B") for b in range(characteristic_bytes)])
188 if (sm.header.major_version, minor_version_str) >= (2,"4"):
189 self.add_field('major_release', u.unpack_one("B"))
190 self.add_field('minor_release', u.unpack_one("B"))
191 self.add_field('ec_major_release', u.unpack_one("B"))
192 self.add_field('ec_minor_release', u.unpack_one("B"))
194 self.decode_failure = True
195 print "Error parsing BIOSInformation"
197 traceback.print_exc()
200 class SystemInformation(SmbiosBaseStructure):
201 smbios_structure_type = 1
203 def __init__(self, u, sm):
204 super(SystemInformation, self).__init__(u, sm)
207 self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr)
208 self.add_field('product_name', u.unpack_one("B"), self.fmtstr)
209 self.add_field('version', u.unpack_one("B"), self.fmtstr)
210 self.add_field('serial_number', u.unpack_one("B"), self.fmtstr)
211 if self.length > 0x8:
212 self.add_field('uuid', uuid.UUID(bytes_le=u.unpack_one("16s")))
222 8: 'AC Power Restored'
224 self.add_field('wakeup_type', u.unpack_one("B"), unpack.format_table("{}", wakeup_types))
225 if self.length > 0x19:
226 self.add_field('sku_number', u.unpack_one("B"), self.fmtstr)
227 self.add_field('family', u.unpack_one("B"), self.fmtstr)
229 self.decode_failure = True
230 print "Error parsing SystemInformation"
232 traceback.print_exc()
239 4: 'Connectivity Switch',
240 5: 'System Management Module',
241 6: 'Processor Module',
246 0xB: 'Processor/Memory Module',
247 0xC: 'Processor/IO Module',
248 0xD: 'Interconnect Board'
251 class BaseboardInformation(SmbiosBaseStructure):
252 smbios_structure_type = 2
254 def __init__(self, u, sm):
255 super(BaseboardInformation, self).__init__(u, sm)
258 self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr)
259 self.add_field('product', u.unpack_one("B"), self.fmtstr)
260 self.add_field('version', u.unpack_one("B"), self.fmtstr)
261 self.add_field('serial_number', u.unpack_one("B"), self.fmtstr)
263 if self.length > 0x8:
264 self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr)
266 if self.length > 0x9:
267 self.add_field('feature_flags', u.unpack_one("B"))
268 self.add_field('hosting_board', bool(bitfields.getbits(self.feature_flags, 0)), "feature_flags[0]={}")
269 self.add_field('requires_daughter_card', bool(bitfields.getbits(self.feature_flags, 1)), "feature_flags[1]={}")
270 self.add_field('removable', bool(bitfields.getbits(self.feature_flags, 2)), "feature_flags[2]={}")
271 self.add_field('replaceable', bool(bitfields.getbits(self.feature_flags, 3)), "feature_flags[3]={}")
272 self.add_field('hot_swappable', bool(bitfields.getbits(self.feature_flags, 4)), "feature_flags[4]={}")
274 if self.length > 0xA:
275 self.add_field('location', u.unpack_one("B"), self.fmtstr)
277 if self.length > 0xB:
278 self.add_field('chassis_handle', u.unpack_one("<H"))
280 if self.length > 0xD:
281 self.add_field('board_type', u.unpack_one("B"), unpack.format_table("{}", _board_types))
283 if self.length > 0xE:
284 self.add_field('handle_count', u.unpack_one("B"))
285 if self.handle_count > 0:
286 self.add_field('contained_object_handles', tuple(u.unpack_one("<H") for i in range(self.handle_count)))
288 self.decode_failure = True
289 print "Error parsing BaseboardInformation"
291 traceback.print_exc()
294 class SystemEnclosure(SmbiosBaseStructure):
295 smbios_structure_type = 3
297 def __init__(self, u, sm):
298 super(SystemEnclosure, self).__init__(u, sm)
301 self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr)
302 self.add_field('enumerated_type', u.unpack_one("B"))
303 self.add_field('chassis_lock_present', bool(bitfields.getbits(self.enumerated_type, 7)), "enumerated_type[7]={}")
308 0x04: 'Low Profile Desktop',
316 0x0C: 'Docking Station',
318 0x0E: 'Sub Notebook',
319 0x0F: 'Space-saving',
321 0x11: 'Main Server Chassis',
322 0x12: 'Expansion Chassis',
324 0x14: 'Bus Expansion Chassis',
325 0x15: 'Peripheral Chassis',
326 0x16: 'RAID Chassis',
327 0x17: 'Rack Mount Chassis',
328 0x18: 'Sealed-case PC',
329 0x19: 'Multi-system chassis W',
331 0x1B: 'Advanced TCA',
333 0x1D: 'Blade Enclosure',
335 self.add_field('system_enclosure_type', bitfields.getbits(self.enumerated_type, 6, 0), unpack.format_table("enumerated_type[6:0]={}", board_types))
336 self.add_field('version', u.unpack_one("B"), self.fmtstr)
337 self.add_field('serial_number', u.unpack_one("B"), self.fmtstr)
338 self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr)
339 minor_version_str = str(sm.header.minor_version) # 34 is .34, 4 is .4, 41 is .41; compare ASCIIbetically to compare initial digits rather than numeric value
347 0x06: 'Non-recoverable',
349 self.add_field('bootup_state', u.unpack_one("B"), unpack.format_table("{}", chassis_states))
350 self.add_field('power_supply_state', u.unpack_one("B"), unpack.format_table("{}", chassis_states))
351 self.add_field('thermal_state', u.unpack_one("B"), unpack.format_table("{}", chassis_states))
356 0x04: 'External interface locked out',
357 0x05: 'External interface enabled',
359 self.add_field('security_status', u.unpack_one("B"), unpack.format_table("{}", security_states))
360 if self.length > 0xd:
361 self.add_field('oem_defined', u.unpack_one("<I"))
362 if self.length > 0x11:
363 self.add_field('height', u.unpack_one("B"))
364 self.add_field('num_power_cords', u.unpack_one("B"))
365 self.add_field('contained_element_count', u.unpack_one("B"))
366 self.add_field('contained_element_length', u.unpack_one("B"))
367 if getattr(self, 'contained_element_count', 0):
368 self.add_field('contained_elements', tuple(SystemEnclosureContainedElement(u, self.contained_element_length) for i in range(self.contained_element_count)))
369 if self.length > (0x15 + (getattr(self, 'contained_element_count', 0) * getattr(self, 'contained_element_length', 0))):
370 self.add_field('sku_number', u.unpack_one("B"), self.fmtstr)
372 self.decode_failure = True
373 print "Error parsing SystemEnclosure"
375 traceback.print_exc()
378 class SystemEnclosureContainedElement(unpack.Struct):
379 def __init__(self, u, length):
380 super(SystemEnclosureContainedElement, self).__init__()
381 self.start_offset = u.offset
382 self.raw_data = u.unpack_raw(length)
383 self.u = unpack.Unpackable(self.raw_data)
385 self.add_field('contained_element_type', u.unpack_one("B"))
387 0: 'SMBIOS baseboard type enumeration',
388 1: 'SMBIOS structure type enumeration',
390 self.add_field('type_select', bitfields.getbits(self.contained_element_type, 7), unpack.format_table("contained_element_type[7]={}", type_selections))
391 self.add_field('type', bitfields.getbits(self.contained_element_type, 6, 0))
392 if self.type_select == 0:
393 self.add_field('smbios_board_type', self.type, unpack.format_table("{}", _board_types))
395 self.add_field('smbios_structure_type', self.type)
396 self.add_field('minimum', u.unpack_one("B"))
397 self.add_field('maximum', u.unpack_one("B"))
399 self.add_field('data', u.unpack_rest())
402 class ProcessorInformation(SmbiosBaseStructure):
403 smbios_structure_type = 4
405 def __init__(self, u, sm):
406 super(ProcessorInformation, self).__init__(u, sm)
409 self.add_field('socket_designation', u.unpack_one("B"), self.fmtstr)
413 0x03: 'Central Processor',
414 0x04: 'Math Processor',
415 0x05: 'DSP Processor',
416 0x06: 'Video Processor',
418 self.add_field('processor_type', u.unpack_one("B"), unpack.format_table("{}", processor_types))
419 self.add_field('processor_family', u.unpack_one("B"))
420 self.add_field('processor_manufacturer', u.unpack_one("B"), self.fmtstr)
421 self.add_field('processor_id', u.unpack_one("<Q"))
422 self.add_field('processor_version', u.unpack_one("B"), self.fmtstr)
423 self.add_field('voltage', u.unpack_one("B"))
424 self.add_field('external_clock', u.unpack_one("<H"))
425 self.add_field('max_speed', u.unpack_one("<H"))
426 self.add_field('current_speed', u.unpack_one("<H"))
427 self.add_field('status', u.unpack_one("B"))
428 processor_upgrades = {
431 0x03: 'Daughter Board',
433 0x05: 'Replaceable Piggy Back',
438 0x0A: '370-pin socket',
442 0x0E: 'Socket A (Socket 462)',
447 0x13: 'Socket mPGA604',
448 0x14: 'Socket LGA771',
449 0x15: 'Socket LGA775',
452 0x18: 'Socket F (1207)',
453 0x19: 'Socket LGA1366',
457 0x1D: 'Socket LGA1156',
458 0x1E: 'Socket LGA1567',
459 0x1F: 'Socket PGA988A',
460 0x20: 'Socket BGA1288',
461 0x21: 'Socket rPGA988B',
462 0x22: 'Socket BGA1023',
463 0x23: 'Socket BGA1224',
464 0x24: 'Socket BGA1155',
465 0x25: 'Socket LGA1356',
466 0x26: 'Socket LGA2011',
472 self.add_field('processor_upgrade', u.unpack_one("B"), unpack.format_table("{}", processor_upgrades))
473 if self.length > 0x1A:
474 self.add_field('l1_cache_handle', u.unpack_one("<H"))
475 self.add_field('l2_cache_handle', u.unpack_one("<H"))
476 self.add_field('l3_cache_handle', u.unpack_one("<H"))
477 if self.length > 0x20:
478 self.add_field('serial_number', u.unpack_one("B"), self.fmtstr)
479 self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr)
480 self.add_field('part_number', u.unpack_one("B"), self.fmtstr)
481 if self.length > 0x24:
482 self.add_field('core_count', u.unpack_one("B"))
483 self.add_field('core_enabled', u.unpack_one("B"))
484 self.add_field('thread_count', u.unpack_one("B"))
485 self.add_field('processor_characteristics', u.unpack_one("<H"))
486 if self.length > 0x28:
487 self.add_field('processor_family_2', u.unpack_one("<H"))
488 if self.length > 0x2A:
489 self.add_field('core_count2', u.unpack_one("<H"))
490 self.add_field('core_enabled2', u.unpack_one("<H"))
491 self.add_field('thread_count2', u.unpack_one("<H"))
493 self.decode_failure = True
494 print "Error parsing Processor Information"
496 traceback.print_exc()
499 class MemoryControllerInformation(SmbiosBaseStructure): #obsolete starting with v2.1
500 smbios_structure_type = 5
502 def __init__(self, u, sm):
503 super(MemoryControllerInformation, self).__init__(u, sm)
506 _error_detecting_method = {
510 0x04: '8-bit Parity',
516 self.add_field('error_detecting_method', u.unpack_one("B"), unpack.format_table("{}", _error_detecting_method))
517 self.add_field('error_correcting_capability', u.unpack_one("B"))
521 0x03: 'One-Way Interleave',
522 0x04: 'Two-Way Interleave',
523 0x05: 'Four-Way Interleave',
524 0x06: 'Eight-Way Interleave',
525 0x07: 'Sixteen-Way Interleave'
527 self.add_field('supported_interleave', u.unpack_one("B"), unpack.format_table("{}", _interleaves))
528 self.add_field('current_interleave', u.unpack_one("B"), unpack.format_table("{}", _interleaves))
529 self.add_field('max_memory_module_size', u.unpack_one("B"), self.fmtstr)
530 self.add_field('supported_speeds', u.unpack_one("<H"))
531 self.add_field('supported_memory_types', u.unpack_one("<H"))
532 self.add_field('memory_module_voltage', u.unpack_one("B"))
533 self.add_field('req_voltage_b2', bitfields.getbits(self.memory_module_voltage, 2), "memory_module_voltage[2]={}")
534 self.add_field('req_voltage_b1', bitfields.getbits(self.memory_module_voltage, 1), "memory_module_voltage[1]={}")
535 self.add_field('req_voltage_b0', bitfields.getbits(self.memory_module_voltage, 0), "memory_module_voltage[0]={}")
536 self.add_field('num_associated_memory_slots', u.unpack_one("B"))
537 self.add_field('memory_module_configuration_handles', u.unpack_one("<(self.num_associated_memory_slots)H"))
538 self.add_field('enabled_error_correcting_capabilities', u.unpack_one("B"))
540 self.decode_failure = True
541 print "Error parsing MemoryControllerInformation"
543 traceback.print_exc()
546 class MemoryModuleInformation(SmbiosBaseStructure): #obsolete starting with v2.1
547 smbios_structure_type = 6
549 def __init__(self, u, sm):
550 super(MemoryModuleInformation, self).__init__(u, sm)
553 self.add_field('socket_designation', u.unpack_one("B"), self.fmtstr)
554 self.add_field('bank_connections', u.unpack_one("B"))
555 self.add_field('current_speed', u.unpack_one("B"))
556 self.add_field('current_memory_type', u.unpack_one("<H"))
561 self.add_field('installed_mem', u.unpack_one("B"))
562 self.add_field('installed_size', bitfields.getbits(self.installed_mem, 6, 0), "installed_mem[6:0]={}")
563 self.add_field('installed_memory_module_connection', bitfields.getbits(self.installed_mem, 7), unpack.format_table("installed_mem[7]={}", _mem_connection))
564 self.add_field('enabled_mem', u.unpack_one("B"))
565 self.add_field('enabled_size', bitfields.getbits(self.installed_mem, 6, 0), "enabled_mem[6:0]={}")
566 self.add_field('enabled_memory_module_connection', bitfields.getbits(self.installed_mem, 7), unpack.format_table("enabled_mem[7]={}", _mem_connection))
567 self.add_field('error_status', u.unpack_one("B"))
568 self.add_field('error_status_info_obstained_from_event_log', bool(bitfields.getbits(self.error_status, 2)), unpack.format_table("error_status[2]={}", _mem_connection))
569 self.add_field('correctable_errors_received', bool(bitfields.getbits(self.error_status, 1)), unpack.format_table("error_status[1]={}", _mem_connection))
570 self.add_field('uncorrectable_errors_received', bool(bitfields.getbits(self.error_status, 0)), unpack.format_table("error_status[0]={}", _mem_connection))
572 self.decode_failure = True
573 print "Error parsing MemoryModuleInformation"
575 traceback.print_exc()
578 class CacheInformation(SmbiosBaseStructure):
579 smbios_structure_type = 7
581 def __init__(self, u, sm):
582 super(CacheInformation, self).__init__(u, sm)
585 self.add_field('socket_designation', u.unpack_one("B"), self.fmtstr)
589 0x03: 'Central Processor',
590 0x04: 'Math Processor',
591 0x05: 'DSP Processor',
592 0x06: 'Video Processor',
594 self.add_field('cache_configuration', u.unpack_one("<H"))
595 _operational_mode = {
596 0b00: 'Write Through',
598 0b10: 'Varies with Memory Address',
601 self.add_field('operational_mode', bitfields.getbits(self.cache_configuration, 9, 8), unpack.format_table("cache_configuration[9:8]={}", _operational_mode))
602 self.add_field('enabled_at_boot_time', bool(bitfields.getbits(self.cache_configuration, 7)), "cache_configuration[7]={}")
609 self.add_field('location_relative_to_cpu_module', bitfields.getbits(self.cache_configuration, 6, 5), unpack.format_table("cache_configuration[6:5]={}", _location))
610 self.add_field('cache_socketed', bool(bitfields.getbits(self.cache_configuration, 3)), "cache_configuration[3]={}")
611 self.add_field('cache_level', bitfields.getbits(self.cache_configuration, 2, 0), "cache_configuration[2:0]={}")
612 self.add_field('max_cache_size', u.unpack_one("<H"))
617 self.add_field('max_granularity', bitfields.getbits(self.cache_configuration, 15), unpack.format_table("max_cache_size[15]={}", _granularity))
618 self.add_field('max_size_in_granularity', bitfields.getbits(self.cache_configuration, 14, 0), "max_cache_size[14, 0]={}")
619 self.add_field('installed_size', u.unpack_one("<H"))
620 if self.installed_size != 0:
621 self.add_field('installed_granularity', bitfields.getbits(self.cache_configuration, 15), unpack.format_table("installed_size[15]={}", _granularity))
622 self.add_field('installed_size_in_granularity', bitfields.getbits(self.cache_configuration, 14, 0), "installed_size[14, 0]={}")
623 self.add_field('supported_sram_type', u.unpack_one("<H"))
624 self.add_field('current_sram_type', u.unpack_one("<H"))
625 if self.length > 0x0F:
626 self.add_field('cache_speed', u.unpack_one("B"))
627 if self.length > 0x10:
628 _error_correction = {
633 0x05: 'Single-bit ECC',
634 0x06: 'Multi-bit ECC'
636 self.add_field('error_correction', u.unpack_one("B"), unpack.format_table("{}", _error_correction))
637 if self.length > 0x10:
638 _system_cache_type = {
645 self.add_field('system_cache_type', u.unpack_one("B"), unpack.format_table("{}", _system_cache_type))
646 if self.length > 0x12:
650 0x03: 'Direct Mapped',
651 0x04: '2-way Set-Associative',
652 0x05: '4-way Set-Associative',
653 0x06: 'Fully Associative',
654 0x07: '8-way Set-Associative',
655 0x08: '16-way Set-Associative',
656 0x09: '12-way Set-Associative',
657 0x0A: '24-way Set-Associative',
658 0x0B: '32-way Set-Associative',
659 0x0C: '48-way Set-Associative',
660 0x0D: '64-way Set-Associative',
661 0x0E: '20-way Set-Associative'
663 self.add_field('associativity', u.unpack_one("B"), unpack.format_table("{}", _associativity))
666 self.decode_failure = True
667 print "Error parsing CacheInformation"
669 traceback.print_exc()
672 class PortConnectorInfo(SmbiosBaseStructure):
673 smbios_structure_type = 8
675 def __init__(self, u, sm):
676 super(PortConnectorInfo, self).__init__(u, sm)
679 self.add_field('internal_reference_designator', u.unpack_one("B"), self.fmtstr)
683 0x02: 'Mini Centronics',
685 0x04: 'DB-25 pin male',
686 0x05: 'DB-25 pin female',
687 0x06: 'DB-15 pin male',
688 0x07: 'DB-15 pin female',
689 0x08: 'DB-9 pin male',
690 0x09: 'DB-9 pin female',
693 0x0C: '50-pin MiniSCSI',
699 0x12: 'Access Bus (USB)',
701 0x14: 'Circular DIN-8 male',
702 0x15: 'Circular DIN-8 female',
703 0x16: 'On Board IDE',
704 0x17: 'On Board Floppy',
705 0x18: '9-pin Dual Inline (pin 10 cut)',
706 0x19: '25-pin Dual Inline (pin 26 cut)',
707 0x1A: '50-pin Dual Inline',
708 0x1B: '68-pin Dual Inline',
709 0x1C: 'On Board Sound Input from CD-ROM',
710 0x1D: 'Mini-Centronics Type-14',
711 0x1E: 'Mini-Centronics Type-26',
712 0x1F: 'Mini-jack (headphones)',
715 0x22: 'SAS/SATA Plug Receptacle',
723 self.add_field('internal_connector_type', u.unpack_one("B"), unpack.format_table("{}", connector_types))
724 self.add_field('external_reference_designator', u.unpack_one("B"), self.fmtstr)
725 self.add_field('external_connector_type', u.unpack_one("B"), unpack.format_table("{}", connector_types))
728 0x01: 'Parallel Port XT/AT Compatible',
729 0x02: 'Parallel Port PS/2',
730 0x03: 'Parallel Port ECP',
731 0x04: 'Parallel Port EPP',
732 0x05: 'Parallel Port ECP/EPP',
733 0x06: 'Serial Port XT/AT Compatible',
734 0x07: 'Serial Port 16450 Compatible',
735 0x08: 'Serial Port 16550 Compatible',
736 0x09: 'Serial Port 16550A Compatible',
739 0x0C: 'Joy Stick Port',
740 0x0D: 'Keyboard Port',
744 0x11: 'FireWire (IEEE P1394)',
745 0x12: 'PCMCIA Type I2',
746 0x13: 'PCMCIA Type II',
747 0x14: 'PCMCIA Type III',
749 0x16: 'Access Bus Port',
753 0x1A: 'PC-98-Hireso',
758 0x1F: 'Network Port',
761 0xA0: '8251 Compatible',
762 0xA1: '8251 FIFO Compatible',
765 self.add_field('port_type', u.unpack_one("B"), unpack.format_table("{}", port_types))
767 self.decodeFailure = True
768 print "Error parsing PortConnectorInfo"
770 traceback.print_exc()
773 class SystemSlots(SmbiosBaseStructure):
774 smbios_structure_type = 9
776 def __init__(self, u, sm):
777 super(SystemSlots, self).__init__(u, sm)
780 self.add_field('designation', u.unpack_one("B"), self.fmtstr)
788 0x07: 'PC Card (PCMCIA)',
791 0x0A: 'Processor Card Slot',
792 0x0B: 'Proprietary Memory Card Slot',
793 0x0C: 'I/O Riser Card Slot',
795 0x0E: 'PCI 66MHz Capable',
804 0xA3: 'PC-98/Local Bus',
807 0xA6: 'PCI Express x1',
808 0xA7: 'PCI Express x2',
809 0xA8: 'PCI Express x4',
810 0xA9: 'PCI Express x8',
811 0xAA: 'PCI Express x16',
812 0xAB: 'PCI Express Gen 2',
813 0xAC: 'PCI Express Gen 2 x1',
814 0xAD: 'PCI Express Gen 2 x2',
815 0xAE: 'PCI Express Gen 2 x4',
816 0xAF: 'PCI Express Gen 2 x8',
817 0xB0: 'PCI Express Gen 2 x16',
818 0xB1: 'PCI Express Gen 3',
819 0xB2: 'PCI Express Gen 3 x1',
820 0xB3: 'PCI Express Gen 3 x2',
821 0xB4: 'PCI Express Gen 3 x4',
822 0xB5: 'PCI Express Gen 3 x8',
823 0xB6: 'PCI Express Gen 3 x16',
825 self.add_field('slot_type', u.unpack_one("B"), unpack.format_table("{}", _slot_types))
826 _slot_data_bus_widths = {
842 self.add_field('slot_data_bus_width', u.unpack_one('B'), unpack.format_table("{}", _slot_data_bus_widths))
849 self.add_field('current_usage', u.unpack_one('B'), unpack.format_table("{}", _current_usages))
853 0x03: 'Short Length',
856 self.add_field('slot_length', u.unpack_one('B'), unpack.format_table("{}", _slot_lengths))
857 self.add_field('slot_id', u.unpack_one('<H'))
858 self.add_field('characteristics1', u.unpack_one('B'))
859 self.add_field('characteristics_unknown', bool(bitfields.getbits(self.characteristics1, 0)), "characteristics1[0]={}")
860 self.add_field('provides_5_0_volts', bool(bitfields.getbits(self.characteristics1, 1)), "characteristics1[1]={}")
861 self.add_field('provides_3_3_volts', bool(bitfields.getbits(self.characteristics1, 2)), "characteristics1[2]={}")
862 self.add_field('shared_slot', bool(bitfields.getbits(self.characteristics1, 3)), "characteristics1[3]={}")
863 self.add_field('supports_pc_card_16', bool(bitfields.getbits(self.characteristics1, 4)), "characteristics1[4]={}")
864 self.add_field('supports_cardbus', bool(bitfields.getbits(self.characteristics1, 5)), "characteristics1[5]={}")
865 self.add_field('supports_zoom_video', bool(bitfields.getbits(self.characteristics1, 6)), "characteristics1[6]={}")
866 self.add_field('supports_modem_ring_resume', bool(bitfields.getbits(self.characteristics1, 7)), "characteristics1[7]={}")
867 if self.length > 0x0C:
868 self.add_field('characteristics2', u.unpack_one('B'))
869 self.add_field('supports_PME', bool(bitfields.getbits(self.characteristics2, 0)), "characteristics2[0]={}")
870 self.add_field('supports_hot_plug', bool(bitfields.getbits(self.characteristics2, 1)), "characteristics2[1]={}")
871 self.add_field('supports_smbus', bool(bitfields.getbits(self.characteristics2, 2)), "characteristics2[2]={}")
872 if self.length > 0x0D:
873 self.add_field('segment_group_number', u.unpack_one('<H'))
874 self.add_field('bus_number', u.unpack_one('B'))
875 self.add_field('device_function_number', u.unpack_one('B'))
876 self.add_field('device_number', bitfields.getbits(self.device_function_number, 7, 3), "device_function_number[7:3]={}")
877 self.add_field('function_number', bitfields.getbits(self.device_function_number, 2, 0), "device_function_number[2:0]={}")
879 self.decodeFailure = True
880 print "Error parsing SystemSlots"
882 traceback.print_exc()
885 class OnBoardDevicesInformation(SmbiosBaseStructure):
886 smbios_structure_type = 10
888 def __init__(self, u, sm):
889 super(OnBoardDevicesInformation, self).__init__(u, sm)
892 self.add_field('device_type', u.unpack_one("B"))
893 self.add_field('device_enabled', bool(bitfields.getbits(self.device_type, 7)), "device_type[7]={}")
898 0x04: 'SCSI Controller',
902 0x08: 'PATA Controller',
903 0x09: 'SATA Controller',
904 0x0A: 'SAS Controller'
906 self.add_field('type_of_device', bitfields.getbits(self.device_type, 6, 0), unpack.format_table("device_type[6:0]={}", _device_types))
907 self.add_field('description_string', u.unpack_one("B"), self.fmtstr)
909 self.decodeFailure = True
910 print "Error parsing OnBoardDevicesInformation"
912 traceback.print_exc()
915 class OEMStrings(SmbiosBaseStructure):
916 smbios_structure_type = 11
918 def __init__(self, u, sm):
919 super(OEMStrings, self).__init__(u, sm)
922 self.add_field('count', u.unpack_one("B"))
924 self.decodeFailure = True
925 print "Error parsing OEMStrings"
927 traceback.print_exc()
930 class SystemConfigOptions(SmbiosBaseStructure):
931 smbios_structure_type = 12
933 def __init__(self, u, sm):
934 super(SystemConfigOptions, self).__init__(u, sm)
937 self.add_field('count', u.unpack_one("B"))
939 self.decodeFailure = True
940 print "Error parsing SystemConfigOptions"
942 traceback.print_exc()
945 class BIOSLanguageInformation(SmbiosBaseStructure):
946 smbios_structure_type = 13
948 def __init__(self, u, sm):
949 super(BIOSLanguageInformation, self).__init__(u, sm)
952 self.add_field('installable_languages', u.unpack_one("B"))
953 if self.length > 0x05:
954 self.add_field('flags', u.unpack_one('B'))
955 self.add_field('abbreviated_format', bool(bitfields.getbits(self.flags, 0)), "flags[0]={}")
956 if self.length > 0x6:
958 self.add_field('current_language', u.unpack_one('B'), self.fmtstr)
960 self.decodeFailure = True
961 print "Error parsing BIOSLanguageInformation"
963 traceback.print_exc()
966 class GroupAssociations(SmbiosBaseStructure):
967 smbios_structure_type = 14
969 def __init__(self, u, sm):
970 super(GroupAssociations, self).__init__(u, sm)
973 self.add_field('group_name', u.unpack_one("B"), self.fmtstr)
974 self.add_field('item_type', u.unpack_one('B'))
975 self.add_field('item_handle', u.unpack_one('<H'))
977 self.decodeFailure = True
978 print "Error parsing GroupAssociations"
980 traceback.print_exc()
983 class SystemEventLog(SmbiosBaseStructure):
984 smbios_structure_type = 15
986 def __init__(self, u, sm):
987 super(SystemEventLog, self).__init__(u, sm)
990 self.add_field('log_area_length', u.unpack_one("<H"))
991 self.add_field('log_header_start_offset', u.unpack_one('<H'))
992 self.add_field('log_data_start_offset', u.unpack_one('<H'))
994 0x00: 'Indexed I/O: 1 8-bit index port, 1 8-bit data port',
995 0x01: 'Indexed I/O: 2 8-bit index ports, 1 8-bit data port',
996 0x02: 'Indexed I/O: 1 16-bit index port, 1 8-bit data port',
997 0x03: 'Memory-mapped physical 32-bit address',
998 0x04: 'Available through General-Purpose NonVolatile Data functions',
999 xrange(0x05, 0x07F): 'Available for future assignment',
1000 xrange(0x80, 0xFF): 'BIOS Vendor/OEM-specific'
1002 self.add_field('access_method', u.unpack_one('B'), unpack.format_table("{}", _access_method))
1003 self.add_field('log_status', u.unpack_one('B'))
1004 self.add_field('log_area_full', bool(bitfields.getbits(self.log_status, 1)), "log_status[1]={}")
1005 self.add_field('log_area_valid', bool(bitfields.getbits(self.log_status, 0)), "log_status[0]={}")
1006 self.add_field('log_change_token', u.unpack_one('<I'))
1007 self.add_field('access_method_address', u.unpack_one('<I'))
1008 if self.length > 0x14:
1009 _log_header_formats = {
1011 1: 'Type 1 log header',
1012 xrange(2, 0x7f): 'Available for future assignment',
1013 xrange(0x80, 0xff): 'BIOS vendor or OEM-specific format'
1015 self.add_field('log_header_format', u.unpack_one("B"), unpack.format_table("{}", _log_header_formats))
1016 if self.length > 0x15:
1017 self.add_field('num_supported_log_type_descriptors', u.unpack_one('B'))
1018 if self.length > 0x16:
1019 self.add_field('length_log_type_descriptor', u.unpack_one('B'))
1020 if self.length != (0x17 + (self.num_supported_log_type_descriptors * self.length_log_type_descriptor)):
1021 print "Error: structure length ({}) != 0x17 + (num_supported_log_type_descriptors ({}) * length_log_type_descriptor({}))".format(self.length, self.num_supported_log_type_descriptors, self.length_log_type_descriptor)
1022 print "structure length = {}".format(self.length)
1023 print "num_supported_log_type_descriptors = {}".format(self.num_supported_log_type_descriptors)
1024 print "length_log_type_descriptor = {}".format(self.length_log_type_descriptor)
1025 self.decodeFailure = True
1026 self.add_field('descriptors', tuple(EventLogDescriptor.unpack(u) for i in range(self.num_supported_log_type_descriptors)), unpack.format_each("\n{!r}"))
1028 self.decodeFailure = True
1029 print "Error parsing SystemEventLog"
1031 traceback.print_exc()
1034 class EventLogDescriptor(unpack.Struct):
1037 _event_log_type_descriptors = {
1039 0x01: 'Single-bit ECC memory error',
1040 0x02: 'Multi-bit ECC memory error',
1041 0x03: 'Parity memory error',
1042 0x04: 'Bus time-out',
1043 0x05: 'I/O Channel Check',
1044 0x06: 'Software NMI',
1045 0x07: 'POST Memory Resize',
1047 0x09: 'PCI Parity Error',
1048 0x0A: 'PCI System Error',
1049 0x0B: 'CPU Failure',
1050 0x0C: 'EISA FailSafe Timer time-out',
1051 0x0D: 'Correctable memory log disabled',
1052 0x0E: 'Logging disabled for a specific Event Type - too many errors of the same type received in a short amount of time',
1054 0x10: 'System Limit Exceeded',
1055 0x11: 'Asynchronous hardware timer expired and issued a system reset',
1056 0x12: 'System configuration information',
1057 0x13: 'Hard-disk information',
1058 0x14: 'System reconfigured',
1059 0x15: 'Uncorrectable CPU-complex error',
1060 0x16: 'Log Area Reset/Cleared',
1061 0x17: 'System boot',
1062 xrange(0x18, 0x7F): 'Unused, available for assignment',
1063 xrange(0x80, 0xFE): 'Availalbe for system- and OEM-specific assignments',
1066 yield 'log_type', u.unpack_one('B'), unpack.format_table("{}", _event_log_type_descriptors)
1067 _event_log_format = {
1070 0x02: 'Multiple-Event',
1071 0x03: 'Multiple-Event Handle',
1072 0x04: 'POST Results Bitmap',
1073 0x05: 'System Management Type',
1074 0x06: 'Multiple-Event System Management Type',
1075 xrange(0x80, 0xFF): 'OEM assigned'
1077 yield 'variable_data_format_type', u.unpack_one('B'), unpack.format_table("{}", _event_log_format)
1079 class PhysicalMemoryArray(SmbiosBaseStructure):
1080 smbios_structure_type = 16
1082 def __init__(self, u, sm):
1083 super(PhysicalMemoryArray, self).__init__(u, sm)
1086 if self.length > 0x4:
1090 0x03: "System board or motherboard",
1091 0x04: "ISA add-on card",
1092 0x05: "EISA add-on card",
1093 0x06: "PCI add-on card",
1094 0x07: "MCA add-on card",
1095 0x08: "PCMCIA add-on card",
1096 0x09: "Proprietary add-on card",
1098 0xA0: "PC-98/C20 add-on card",
1099 0xA1: "PC-98/C24 add-on card",
1100 0xA2: "PC-98/E add-on card",
1101 0xA3: "PC-98/Local bus add-on card"
1103 self.add_field('location', u.unpack_one("B"), unpack.format_table("{}", _location_field))
1104 if self.length > 0x05:
1108 0x03: "System memory",
1109 0x04: "Video memory",
1110 0x05: "Flash memory",
1111 0x06: "Non-volatile RAM",
1112 0x07: "Cache memory"
1114 self.add_field('use', u.unpack_one('B'), unpack.format_table("{}", _use))
1115 if self.length > 0x06:
1116 _error_correction = {
1121 0x05: "Single-bit ECC",
1122 0x06: "Multi-bit ECC",
1125 self.add_field('memory_error_correction', u.unpack_one('B'), unpack.format_table("{}", _error_correction))
1126 if self.length > 0x07:
1127 self.add_field('maximum_capacity', u.unpack_one('<I'))
1128 if self.length > 0x0B:
1129 self.add_field('memory_error_information_handle', u.unpack_one('<H'))
1130 if self.length > 0x0D:
1131 self.add_field('num_memory_devices', u.unpack_one('<H'))
1132 if self.length > 0x0F:
1133 self.add_field('extended_maximum_capacity', u.unpack_one('<Q'))
1135 self.decodeFailure = True
1136 print "Error parsing PhysicalMemoryArray"
1138 traceback.print_exc()
1141 class MemoryDevice(SmbiosBaseStructure):
1142 smbios_structure_type = 17
1144 def __init__(self, u, sm):
1145 super(MemoryDevice, self).__init__(u, sm)
1148 if self.length > 0x4:
1149 self.add_field('physical_memory_array_handle', u.unpack_one("<H"))
1150 if self.length > 0x6:
1151 self.add_field('memory_error_information_handle', u.unpack_one("<H"))
1152 if self.length > 0x8:
1153 self.add_field('total_width', u.unpack_one("<H"))
1154 if self.length > 0xA:
1155 self.add_field('data_width', u.unpack_one("<H"))
1156 if self.length > 0xC:
1157 self.add_field('size', u.unpack_one("<H"))
1158 if self.length > 0xE:
1167 0x08: 'Proprietary Card',
1170 0x0B: 'Row of chips',
1176 self.add_field('form_factor', u.unpack_one("B"), unpack.format_table("{}", _form_factors))
1177 if self.length > 0xF:
1178 self.add_field('device_set', u.unpack_one("B"))
1179 if self.length > 0x10:
1180 self.add_field('device_locator', u.unpack_one("B"), self.fmtstr)
1181 if self.length > 0x11:
1182 self.add_field('bank_locator', u.unpack_one("B"), self.fmtstr)
1183 if self.length > 0x12:
1204 0x14: 'DDR2 FB-DIMM',
1205 xrange(0x15, 0x17): 'Reserved',
1209 self.add_field('memory_type', u.unpack_one("B"), unpack.format_table("{}", _memory_types))
1210 if self.length > 0x13:
1211 self.add_field('type_detail', u.unpack_one('<H'))
1212 if self.length > 0x15:
1213 self.add_field('speed', u.unpack_one("<H"))
1214 if self.length > 0x17:
1215 self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr)
1216 if self.length > 0x18:
1217 self.add_field('serial_number', u.unpack_one("B"), self.fmtstr)
1218 if self.length > 0x19:
1219 self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr)
1220 if self.length > 0x1A:
1221 self.add_field('part_number', u.unpack_one("B"), self.fmtstr)
1222 if self.length > 0x1B:
1223 self.add_field('attributes', u.unpack_one("B"))
1224 self.add_field('rank', bitfields.getbits(self.attributes, 3, 0), "attributes[3:0]={}")
1225 if self.length > 0x1C:
1226 if self.size == 0x7FFF:
1227 self.add_field('extended_size', u.unpack_one('<I'))
1228 self.add_field('mem_size', bitfields.getbits(self.type_detail, 30, 0), "type_detail[30:0]={}")
1231 if self.length > 0x20:
1232 self.add_field('configured_memory_clock_speed', u.unpack_one("<H"))
1233 if self.length > 0x22:
1234 self.add_field('minimum_voltage', u.unpack_one("<H"))
1235 if self.length > 0x24:
1236 self.add_field('maximum_voltage', u.unpack_one("<H"))
1237 if self.length > 0x26:
1238 self.add_field('configured_voltage', u.unpack_one("<H"))
1240 self.decodeFailure = True
1241 print "Error parsing MemoryDevice"
1243 traceback.print_exc()
1246 class MemoryErrorInfo32Bit(SmbiosBaseStructure):
1247 smbios_structure_type = 18
1249 def __init__(self, u, sm):
1250 super(MemoryErrorInfo32Bit, self).__init__(u, sm)
1253 if self.length > 0x4:
1259 0x05: 'Parity error',
1260 0x06: 'Single-bit error',
1261 0x07: 'Double-bit error',
1262 0x08: 'Multi-bit error',
1263 0x09: 'Nibble error',
1264 0x0A: 'Checksum error',
1266 0x0C: 'Corrected single-bit error',
1267 0x0D: 'Corrected error',
1268 0x0E: 'Uncorrectable error'
1270 self.add_field('error_type', u.unpack_one("B"), unpack.format_table("{}", _error_types))
1271 if self.length > 0x5:
1272 _error_granularity_field = {
1275 0x03: 'Device level',
1276 0x04: 'Memory partition level'
1278 self.add_field('error_granularity', u.unpack_one("B"), unpack.format_table("{}", _error_granularity_field))
1279 if self.length > 0x6:
1280 _error_operation_field = {
1285 0x05: 'Partial write'
1287 self.add_field('error_operation', u.unpack_one("B"), unpack.format_table("{}", _error_operation_field))
1288 if self.length > 0x7:
1289 self.add_field('vendor_syndrome', u.unpack_one("<I"))
1290 if self.length > 0xB:
1291 self.add_field('memory_array_error_address', u.unpack_one("<I"))
1292 if self.length > 0xF:
1293 self.add_field('device_error_address', u.unpack_one("<I"))
1294 if self.length > 0x13:
1295 self.add_field('error_resolution', u.unpack_one("<I"))
1297 self.decodeFailure = True
1298 print "Error parsing MemoryErrorInfo32Bit"
1300 traceback.print_exc()
1303 class MemoryArrayMappedAddress(SmbiosBaseStructure):
1304 smbios_structure_type = 19
1306 def __init__(self, u, sm):
1307 super(MemoryArrayMappedAddress, self).__init__(u, sm)
1310 if self.length > 0x4:
1311 self.add_field('starting_address', u.unpack_one("<I"))
1312 # if FFFF FFFF: address stored in Extended Starting Address
1313 if self.length > 0x8:
1314 self.add_field('ending_address', u.unpack_one("<I"))
1315 if self.length > 0xC:
1316 self.add_field('memory_array_handle', u.unpack_one("<H"))
1317 if self.length > 0xE:
1318 self.add_field('partition_width', u.unpack_one("B"))
1319 if self.length > 0xF:
1320 # valid if starting_address = FFFF FFFF
1321 if self.starting_address == 0xFFFFFFFF:
1322 self.add_field('extended_starting_address', u.unpack_one("<Q"))
1323 if self.length > 0x17:
1324 self.add_field('extended_ending_address', u.unpack_one("<Q"))
1329 self.decodeFailure = True
1330 print "Error parsing MemoryArrayMappedAddress"
1332 traceback.print_exc()
1335 class MemoryDeviceMappedAddress(SmbiosBaseStructure):
1336 smbios_structure_type = 20
1338 def __init__(self, u, sm):
1339 super(MemoryDeviceMappedAddress, self).__init__(u, sm)
1342 if self.length > 0x4:
1343 self.add_field('starting_address', u.unpack_one("<I"))
1344 # if FFFF FFFF: address stored in Extended Starting Address
1345 if self.length > 0x8:
1346 self.add_field('ending_address', u.unpack_one("<I"))
1347 if self.length > 0xC:
1348 self.add_field('memory_device_handle', u.unpack_one("<H"))
1349 if self.length > 0xE:
1350 self.add_field('memory_array_mapped_address_handle', u.unpack_one("<H"))
1351 if self.length > 0x10:
1352 self.add_field('partition_row_position', u.unpack_one("B"))
1353 if self.length > 0x11:
1354 self.add_field('interleave_position', u.unpack_one("B"))
1355 if self.length > 0x12:
1356 self.add_field('interleave_data_depth', u.unpack_one("B"))
1357 if self.length > 0x13:
1358 # valid if starting_address = FFFF FFFF
1359 if self.starting_address == 0xFFFFFFFF:
1360 self.add_field('extended_starting_address', u.unpack_one("<Q"))
1361 if self.length > 0x1B:
1362 self.add_field('extended_ending_address', u.unpack_one("<Q"))
1366 self.decodeFailure = True
1367 print "Error parsing MemoryDeviceMappedAddress"
1369 traceback.print_exc()
1372 class BuiltInPointingDevice(SmbiosBaseStructure):
1373 smbios_structure_type = 21
1375 def __init__(self, u, sm):
1376 super(BuiltInPointingDevice, self).__init__(u, sm)
1379 if self.length > 0x4:
1380 _pointing_device_types = {
1385 0x05: 'Track Point',
1386 0x06: 'Glide Point',
1388 0x08: 'Touch Screen',
1389 0x09: 'Optical Sensor'
1391 self.add_field('pointing_device_type', u.unpack_one("B"), unpack.format_table("{}", _pointing_device_types))
1392 if self.length > 0x5:
1401 0x08: 'ADB (Apple Desktop Bus)',
1402 0x09: 'Bus mouse DB-9',
1403 0x0A: 'Bus mouse micro-DIN',
1406 self.add_field('interface', u.unpack_one("B"), unpack.format_table("{}", _interfaces))
1407 if self.length > 0x6:
1408 self.add_field('num_buttons', u.unpack_one("B"))
1410 self.decodeFailure = True
1411 print "Error parsing BuiltInPointingDevice"
1413 traceback.print_exc()
1416 class PortableBattery(SmbiosBaseStructure):
1417 smbios_structure_type = 22
1419 def __init__(self, u, sm):
1420 super(PortableBattery, self).__init__(u, sm)
1423 if self.length > 0x4:
1424 self.add_field('location', u.unpack_one("B"), self.fmtstr)
1425 if self.length > 0x5:
1426 self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr)
1427 if self.length > 0x6:
1428 self.add_field('manufacturer_date', u.unpack_one("B"), self.fmtstr)
1429 if self.length > 0x7:
1430 self.add_field('serial_number', u.unpack_one("B"), self.fmtstr)
1431 if self.length > 0x8:
1432 self.add_field('device_name', u.unpack_one("B"), self.fmtstr)
1433 if self.length > 0x9:
1434 _device_chemistry = {
1438 0x04: 'Nickel Cadmium',
1439 0x05: 'Nickel metal hydride',
1440 0x06: 'Lithium-ion',
1442 0x08: 'Lithium Polymer'
1444 self.add_field('device_chemistry', u.unpack_one("B"), unpack.format_table("{}", _device_chemistry))
1445 if self.length > 0xA:
1446 self.add_field('design_capacity', u.unpack_one("<H"))
1447 if self.length > 0xC:
1448 self.add_field('design_voltage', u.unpack_one("<H"))
1449 if self.length > 0xE:
1450 self.add_field('sbds_version_number', u.unpack_one("B"), self.fmtstr)
1451 if self.length > 0xF:
1452 self.add_field('max_error_battery_data', u.unpack_one("B"), self.fmtstr)
1453 if self.length > 0x10:
1454 if self.serial_number == 0:
1455 self.add_field('sbds_serial_number', u.unpack_one("<H"))
1458 if self.length > 0x12:
1459 if self.manufacturer_date == 0:
1460 self.add_field('sbds_manufacture_date', u.unpack_one("<H"))
1461 self.add_field('year_biased_by_1980', bitfields.getbits(self.sbds_manufacture_date, 15, 9), "sbds_manufacture_date[15:9]={}")
1462 self.add_field('month', bitfields.getbits(self.sbds_manufacture_date, 8, 5), "sbds_manufacture_date[8:5]={}")
1463 self.add_field('date', bitfields.getbits(self.sbds_manufacture_date, 4, 0), "sbds_manufacture_date[4:0]={}")
1466 if self.length > 0x14:
1467 if self.device_chemistry == 0x02:
1468 self.add_field('sbds_device_chemistry', u.unpack_one("B"), self.fmtstr)
1471 if self.length > 0x15:
1472 self.add_field('design_capacity_multiplier', u.unpack_one("B"))
1473 if self.length > 0x16:
1474 self.add_field('oem_specific', u.unpack_one("<I"))
1476 self.decodeFailure = True
1477 print "Error parsing PortableBattery"
1479 traceback.print_exc()
1482 class SystemReset(SmbiosBaseStructure):
1483 smbios_structure_type = 23
1485 def __init__(self, u, sm):
1486 super(SystemReset, self).__init__(u, sm)
1489 if self.length > 0x4:
1490 self.add_field('capabilities', u.unpack_one("B"))
1491 self.add_field('contains_watchdog_timer', bool(bitfields.getbits(self.capabilities, 5)), "capabilities[5]={}")
1493 0b00: 'Reserved, do not use',
1494 0b01: 'Operating System',
1495 0b10: 'System utilities',
1496 0b11: 'Do not reboot'
1498 self.add_field('boot_option_on_limit', bitfields.getbits(self.capabilities, 4, 3), unpack.format_table("capabilities[4:3]={}", _boot_option))
1499 self.add_field('boot_option_after_watchdog_reset', bitfields.getbits(self.capabilities, 2, 1), unpack.format_table("capabilities[2:1]={}", _boot_option))
1500 self.add_field('system_reset_enabled_by_user', bool(bitfields.getbits(self.capabilities, 0)), "capabilities[0]={}")
1501 if self.length > 0x5:
1502 self.add_field('reset_count', u.unpack_one("<H"))
1503 if self.length > 0x5:
1504 self.add_field('reset_limit', u.unpack_one("<H"))
1505 if self.length > 0x9:
1506 self.add_field('timer_interval', u.unpack_one("<H"))
1507 if self.length > 0xB:
1508 self.add_field('timeout', u.unpack_one("<H"))
1510 self.decodeFailure = True
1511 print "Error parsing SystemReset"
1513 traceback.print_exc()
1516 class HardwareSecurity(SmbiosBaseStructure):
1517 smbios_structure_type = 24
1519 def __init__(self, u, sm):
1520 super(HardwareSecurity, self).__init__(u, sm)
1523 if self.length > 0x4:
1524 self.add_field('hardware_security_settings', u.unpack_one("B"))
1528 0x02: 'Not Implemented',
1531 self.add_field('power_on_password_status', bitfields.getbits(self.hardware_security_settings, 7, 6), unpack.format_table("hardware_security_settings[7:6]={}", _status))
1532 self.add_field('keyboard_password_status', bitfields.getbits(self.hardware_security_settings, 5, 4), unpack.format_table("hardware_security_settings[5:4]={}", _status))
1533 self.add_field('admin_password_status', bitfields.getbits(self.hardware_security_settings, 3, 2), unpack.format_table("hardware_security_settings0[3:2]={}", _status))
1534 self.add_field('front_panel_reset_status', bitfields.getbits(self.hardware_security_settings, 1, 0), unpack.format_table("hardware_security_settings[1:0]={}", _status))
1536 self.decodeFailure = True
1537 print "Error parsing HardwareSecurity"
1539 traceback.print_exc()
1542 class SystemPowerControls(SmbiosBaseStructure):
1543 smbios_structure_type = 25
1545 def __init__(self, u, sm):
1546 super(SystemPowerControls, self).__init__(u, sm)
1549 if self.length > 0x4:
1550 self.add_field('next_scheduled_poweron_month', u.unpack_one("B"))
1551 self.add_field('next_scheduled_poweron_day_of_month', u.unpack_one("B"))
1552 self.add_field('next_scheduled_poweron_hour', u.unpack_one("B"))
1553 self.add_field('next_scheduled_poweron_minute', u.unpack_one("B"))
1554 self.add_field('next_scheduled_poweron_second', u.unpack_one("B"))
1556 self.decodeFailure = True
1557 print "Error parsing SystemPowerControls"
1559 traceback.print_exc()
1562 class VoltageProbe(SmbiosBaseStructure):
1563 smbios_structure_type = 26
1565 def __init__(self, u, sm):
1566 super(VoltageProbe, self).__init__(u, sm)
1569 if self.length > 0x4:
1570 self.add_field('description', u.unpack_one("B"), self.fmtstr)
1571 if self.length > 0x5:
1572 self.add_field('location_and_status', u.unpack_one("B"))
1577 0b100: 'Non-critical',
1579 0b110: 'Non-recoverable'
1584 0b00011: 'Processor',
1586 0b00101: 'Peripheral Bay',
1587 0b00110: 'System Management Module',
1588 0b00111: 'Motherboard',
1589 0b01000: 'Memory Module',
1590 0b01001: 'Processor Module',
1591 0b01010: 'Power Unit',
1592 0b01011: 'Add-in Card'
1594 self.add_field('status', bitfields.getbits(self.location_and_status, 7, 5), unpack.format_table("location_and_status[7:5]={}", _status))
1595 self.add_field('location', bitfields.getbits(self.location_and_status, 4, 0), unpack.format_table("location_and_status[4:0]={}", _location))
1596 if self.length > 0x6:
1597 self.add_field('max_value', u.unpack_one("<H"))
1598 if self.length > 0x8:
1599 self.add_field('min_value', u.unpack_one("<H"))
1600 if self.length > 0xA:
1601 self.add_field('resolution', u.unpack_one("<H"))
1602 if self.length > 0xC:
1603 self.add_field('tolerance', u.unpack_one("<H"))
1604 if self.length > 0xE:
1605 self.add_field('accuracy', u.unpack_one("<H"))
1606 if self.length > 0x10:
1607 self.add_field('oem_defined', u.unpack_one("<I"))
1608 if self.length > 0x14:
1609 self.add_field('nominal_value', u.unpack_one("<H"))
1611 self.decodeFailure = True
1612 print "Error parsing VoltageProbe"
1614 traceback.print_exc()
1617 class CoolingDevice(SmbiosBaseStructure):
1618 smbios_structure_type = 27
1620 def __init__(self, u, sm):
1621 super(CoolingDevice, self).__init__(u, sm)
1624 if self.length > 0x4:
1625 self.add_field('temperature_probe_handle', u.unpack_one("<H"))
1626 if self.length > 0x6:
1627 self.add_field('device_type_and_status', u.unpack_one("B"))
1632 0b100: 'Non-critical',
1634 0b110: 'Non-recoverable'
1640 0b00100: 'Centrifugal Blower',
1641 0b00101: 'Chip Fan',
1642 0b00110: 'Cabinet Fan',
1643 0b00111: 'Power Supply Fan',
1644 0b01000: 'Heat Pipe',
1645 0b01001: 'Integrated Refrigeration',
1646 0b10000: 'Active Cooling',
1647 0b10001: 'Passive Cooling'
1649 self.add_field('status', bitfields.getbits(self.device_type_and_status, 7, 5), unpack.format_table("device_type_and_status[7:5]={}", _status))
1650 self.add_field('device_type', bitfields.getbits(self.device_type_and_status, 4, 0), unpack.format_table("device_type_and_status[4:0]={}", _type))
1651 if self.length > 0x7:
1652 self.add_field('cooling_unit_group', u.unpack_one("B"))
1653 if self.length > 0x8:
1654 self.add_field('OEM_defined', u.unpack_one("<I"))
1655 if self.length > 0xC:
1656 self.add_field('nominal_speed', u.unpack_one("<H"))
1657 if self.length > 0xE:
1658 self.add_field('description', u.unpack_one("B"), self.fmtstr)
1660 self.decodeFailure = True
1661 print "Error parsing CoolingDevice"
1663 traceback.print_exc()
1666 class TemperatureProbe(SmbiosBaseStructure):
1667 smbios_structure_type = 28
1669 def __init__(self, u, sm):
1670 super(TemperatureProbe, self).__init__(u, sm)
1673 if self.length > 0x4:
1674 self.add_field('description', u.unpack_one("B"), self.fmtstr)
1675 if self.length > 0x5:
1676 self.add_field('location_and_status', u.unpack_one("B"))
1681 0b100: 'Non-critical',
1683 0b110: 'Non-recoverable'
1688 0b00011: 'Processor',
1690 0b00101: 'Peripheral Bay',
1691 0b00110: 'System Management Module',
1692 0b00111: 'Motherboard',
1693 0b01000: 'Memory Module',
1694 0b01001: 'Processor Module',
1695 0b01010: 'Power Unit',
1696 0b01011: 'Add-in Card',
1697 0b01100: 'Front Panel Board',
1698 0b01101: 'Back Panel Board',
1699 0b01110: 'Power System Board',
1700 0b01111: 'Drive Back Plane'
1702 self.add_field('status', bitfields.getbits(self.location_and_status, 7, 5), unpack.format_table("location_and_status[7:5]={}", _status))
1703 self.add_field('location', bitfields.getbits(self.location_and_status, 4, 0), unpack.format_table("location_and_status[4:0]={}", _location))
1704 if self.length > 0x6:
1705 self.add_field('maximum_value', u.unpack_one("<H"))
1706 if self.length > 0x8:
1707 self.add_field('minimum_value', u.unpack_one("<H"))
1708 if self.length > 0xA:
1709 self.add_field('resolution', u.unpack_one("<H"))
1710 if self.length > 0xC:
1711 self.add_field('tolerance', u.unpack_one("<H"))
1712 if self.length > 0xE:
1713 self.add_field('accuracy', u.unpack_one("<H"))
1714 if self.length > 0x10:
1715 self.add_field('OEM_defined', u.unpack_one("<I"))
1716 if self.length > 0x14:
1717 self.add_field('nominal_value', u.unpack_one("<H"))
1719 self.decodeFailure = True
1720 print "Error parsing TemperatureProbe"
1722 traceback.print_exc()
1725 class ElectricalCurrentProbe(SmbiosBaseStructure):
1726 smbios_structure_type = 29
1728 def __init__(self, u, sm):
1729 super(ElectricalCurrentProbe, self).__init__(u, sm)
1732 if self.length > 0x4:
1733 self.add_field('description', u.unpack_one("B"), self.fmtstr)
1734 if self.length > 0x5:
1735 self.add_field('location_and_status', u.unpack_one("B"))
1740 0b100: 'Non-critical',
1742 0b110: 'Non-recoverable'
1747 0b00011: 'Processor',
1749 0b00101: 'Peripheral Bay',
1750 0b00110: 'System Management Module',
1751 0b00111: 'Motherboard',
1752 0b01000: 'Memory Module',
1753 0b01001: 'Processor Module',
1754 0b01010: 'Power Unit',
1755 0b01011: 'Add-in Card',
1756 0b01100: 'Front Panel Board',
1757 0b01101: 'Back Panel Board',
1758 0b01110: 'Power System Board',
1759 0b01111: 'Drive Back Plane'
1761 self.add_field('status', bitfields.getbits(self.location_and_status, 7, 5), unpack.format_table("location_and_status[7:5]={}", _status))
1762 self.add_field('location', bitfields.getbits(self.location_and_status, 4, 0), unpack.format_table("location_and_status[4:0]={}", _location))
1763 if self.length > 0x6:
1764 self.add_field('maximum_value', u.unpack_one("<H"))
1765 if self.length > 0x8:
1766 self.add_field('minimum_value', u.unpack_one("<H"))
1767 if self.length > 0xA:
1768 self.add_field('resolution', u.unpack_one("<H"))
1769 if self.length > 0xC:
1770 self.add_field('tolerance', u.unpack_one("<H"))
1771 if self.length > 0xE:
1772 self.add_field('accuracy', u.unpack_one("<H"))
1773 if self.length > 0x10:
1774 self.add_field('OEM_defined', u.unpack_one("<I"))
1775 if self.length > 0x14:
1776 self.add_field('nominal_value', u.unpack_one("<H"))
1778 self.decodeFailure = True
1779 print "Error parsing ElectricalCurrentProbe"
1781 traceback.print_exc()
1784 class OutOfBandRemoteAccess(SmbiosBaseStructure):
1785 smbios_structure_type = 30
1787 def __init__(self, u, sm):
1788 super(OutOfBandRemoteAccess, self).__init__(u, sm)
1791 if self.length > 0x4:
1792 self.add_field('manufacturer_name', u.unpack_one("B"), self.fmtstr)
1793 if self.length > 0x5:
1794 self.add_field('connections', u.unpack_one("B"))
1795 self.add_field('outbound_connection_enabled', bool(bitfields.getbits(self.connections, 1)), "connections[1]={}")
1796 self.add_field('inbound_connection_enabled', bool(bitfields.getbits(self.connections, 0)), "connections[0]={}")
1798 self.decodeFailure = True
1799 print "Error parsing OutOfBandRemoteAccess"
1801 traceback.print_exc()
1804 class BootIntegrityServicesEntryPoint(SmbiosBaseStructure):
1805 smbios_structure_type = 31
1807 class SystemBootInformation(SmbiosBaseStructure):
1808 smbios_structure_type = 32
1810 def __init__(self, u, sm):
1811 super(SystemBootInformation, self).__init__(u, sm)
1814 if self.length > 0xA:
1817 0: 'No errors detected',
1818 1: 'No bootable media',
1819 2: '"normal" operating system failed to load',
1820 3: 'Firmware-detected hardware failure, including "unknown" failure types',
1821 4: 'Operating system-detected hardware failure',
1822 5: 'User-requested boot, usually through a keystroke',
1823 6: 'System security violation',
1824 7: 'Previously-requested image',
1825 8: 'System watchdog timer expired, causing the system to reboot',
1826 xrange(9,127): 'Reserved for future assignment',
1827 xrange(128, 191): 'Vendor/OEM-specific implementations',
1828 xrange(192, 255): 'Product-specific implementations'
1830 self.add_field('boot_status', u.unpack_one("B"), unpack.format_table("{}", _boot_status))
1832 self.decodeFailure = True
1833 print "Error parsing SystemBootInformation"
1835 traceback.print_exc()
1838 class MemoryErrorInfo64Bit(SmbiosBaseStructure):
1839 smbios_structure_type = 33
1841 def __init__(self, u, sm):
1842 super(MemoryErrorInfo64Bit, self).__init__(u, sm)
1845 if self.length > 0x4:
1851 0x05: 'Parity error',
1852 0x06: 'Single-bit error',
1853 0x07: 'Double-bit error',
1854 0x08: 'Multi-bit error',
1855 0x09: 'Nibble error',
1856 0x0A: 'Checksum error',
1858 0x0C: 'Corrected single-bit error',
1859 0x0D: 'Corrected error',
1860 0x0E: 'Uncorrectable error'
1862 self.add_field('error_type', u.unpack_one("B"), unpack.format_table("{}", _error_types))
1863 if self.length > 0x5:
1864 _error_granularity_field = {
1867 0x03: 'Device level',
1868 0x04: 'Memory partition level'
1870 self.add_field('error_granularity', u.unpack_one("B"), unpack.format_table("{}", _error_granularity_field))
1871 if self.length > 0x6:
1872 _error_operation_field = {
1877 0x05: 'Partial write'
1879 self.add_field('error_operation', u.unpack_one("B"), unpack.format_table("{}", _error_operation_field))
1880 if self.length > 0x7:
1881 self.add_field('vendor_syndrome', u.unpack_one("<I"))
1882 if self.length > 0xB:
1883 self.add_field('memory_array_error_address', u.unpack_one("<Q"))
1884 if self.length > 0xF:
1885 self.add_field('device_error_address', u.unpack_one("<Q"))
1886 if self.length > 0x13:
1887 self.add_field('error_resolution', u.unpack_one("<Q"))
1889 self.decodeFailure = True
1890 print "Error parsing MemoryErrorInfo64Bit"
1892 traceback.print_exc()
1895 class ManagementDevice(SmbiosBaseStructure):
1896 smbios_structure_type = 34
1898 def __init__(self, u, sm):
1899 super(ManagementDevice, self).__init__(u, sm)
1902 if self.length > 0x4:
1903 self.add_field('description', u.unpack_one("B"), self.fmtstr)
1904 if self.length > 0x5:
1908 0x03: 'National Semiconductor LM75',
1909 0x04: 'National Semiconductor LM78',
1910 0x05: 'National Semiconductor LM79',
1911 0x06: 'National Semiconductor LM80',
1912 0x07: 'National Semiconductor LM81',
1913 0x08: 'Analog Devices ADM9240',
1914 0x09: 'Dallas Semiconductor DS1780',
1916 0x0B: 'Genesys GL518SM',
1917 0x0C: 'Winbond W83781D',
1918 0x0D: 'Holtek HT82H791'
1920 self.add_field('device_type', u.unpack_one("B"), unpack.format_table("{}", _type))
1921 if self.length > 0x6:
1922 self.add_field('address', u.unpack_one("<I"))
1923 if self.length > 0xA:
1931 self.add_field('address_type', u.unpack_one("B"), unpack.format_table("{}", _address_type))
1933 self.decodeFailure = True
1934 print "Error parsing ManagementDevice"
1936 traceback.print_exc()
1939 class ManagementDeviceComponent(SmbiosBaseStructure):
1940 smbios_structure_type = 35
1942 def __init__(self, u, sm):
1943 super(ManagementDeviceComponent, self).__init__(u, sm)
1946 if self.length > 0x4:
1947 self.add_field('description', u.unpack_one("B"), self.fmtstr)
1948 if self.length > 0x5:
1949 self.add_field('management_device_handle', u.unpack_one("<H"))
1950 if self.length > 0x7:
1951 self.add_field('component_handle', u.unpack_one("<H"))
1952 if self.length > 0x9:
1953 self.add_field('threshold_handle', u.unpack_one("<H"))
1955 self.decodeFailure = True
1956 print "Error parsing ManagementDeviceComponent"
1958 traceback.print_exc()
1961 class ManagementDeviceThresholdData(SmbiosBaseStructure):
1962 smbios_structure_type = 36
1964 def __init__(self, u, sm):
1965 super(ManagementDeviceThresholdData, self).__init__(u, sm)
1968 if self.length > 0x4:
1969 self.add_field('lower_threshold_noncritical', u.unpack_one("<H"))
1970 if self.length > 0x6:
1971 self.add_field('upper_threshold_noncritical', u.unpack_one("<H"))
1972 if self.length > 0x8:
1973 self.add_field('lower_threshold_critical', u.unpack_one("<H"))
1974 if self.length > 0xA:
1975 self.add_field('upper_threshold_critical', u.unpack_one("<H"))
1976 if self.length > 0xC:
1977 self.add_field('lower_threshold_nonrecoverable', u.unpack_one("<H"))
1978 if self.length > 0xE:
1979 self.add_field('upper_threshold_nonrecoverable', u.unpack_one("<H"))
1981 self.decodeFailure = True
1982 print "Error parsing ManagementDeviceThresholdData"
1984 traceback.print_exc()
1987 class MemoryChannel(SmbiosBaseStructure):
1988 smbios_structure_type = 37
1990 def __init__(self, u, sm):
1991 super(MemoryChannel, self).__init__(u, sm)
1994 if self.length > 0x4:
2001 self.add_field('channel_type', u.unpack_one("B"), unpack.format_table("{}", _channel_type))
2002 if self.length > 0x6:
2003 self.add_field('max_channel_load', u.unpack_one("B"))
2004 if self.length > 0x8:
2005 self.add_field('memory_device_count', u.unpack_one("B"))
2006 if self.length > 0xA:
2007 self.add_field('memory_device_load', u.unpack_one("B"))
2008 if self.length > 0xC:
2009 self.add_field('memory_device_handle', u.unpack_one("<H"))
2011 self.decodeFailure = True
2012 print "Error parsing MemoryChannel"
2014 traceback.print_exc()
2017 class IPMIDeviceInformation(SmbiosBaseStructure):
2018 smbios_structure_type = 38
2020 def __init__(self, u, sm):
2021 super(IPMIDeviceInformation, self).__init__(u, sm)
2026 0x01: 'KCS: Keyboard Controller Style',
2027 0x02: 'SMIC: Server Management Interface Chip',
2028 0x03: 'BT: Block Transfer',
2029 xrange(0x04, 0xFF): 'Reserved'
2031 self.add_field('interface_type', u.unpack_one("B"), unpack.format_table("{}", _interface_type))
2032 self.add_field('ipmi_specification_revision', u.unpack_one("B"))
2033 self.add_field('msd_revision', bitfields.getbits(self.ipmi_specification_revision, 7, 4), "ipmi_specification_revision[7:4]={}")
2034 self.add_field('lsd_revision', bitfields.getbits(self.ipmi_specification_revision, 3, 0), "ipmi_specification_revision[3:0]={}")
2036 self.add_field('i2c_slave_address', u.unpack_one("B"))
2037 self.add_field('nv_storage_device_address', u.unpack_one("B"))
2038 self.add_field('base_address', u.unpack_one("<Q"))
2039 # if lsb is 1, address is in IO space. otherwise, memory-mapped
2040 self.add_field('base_address_modifier_interrupt_info', u.unpack_one("B"))
2042 0b00: 'Interface registers are on successive byte boundaries',
2043 0b01: 'Interface registers are on 32-bit boundaries',
2044 0b10: 'Interface registers are on 16-byte boundaries',
2047 self.add_field('register_spacing', bitfields.getbits(self.base_address_modifier_interrupt_info, 7, 6), unpack.format_table("base_address_modifier_interrupt_info[7:6]={}", _reg_spacing))
2048 self.add_field('ls_bit_for_addresses', bitfields.getbits(self.base_address_modifier_interrupt_info, 4), "base_address_modifier_interrupt_info[4]={}")
2049 self.add_field('interrupt_info_specified', bool(bitfields.getbits(self.base_address_modifier_interrupt_info, 3)), "base_address_modifier_interrupt_info[3]={}")
2054 self.add_field('interrupt_polarity', bitfields.getbits(self.base_address_modifier_interrupt_info, 1), unpack.format_table("base_address_modifier_interrupt_info[1]={}", _polarity))
2055 _interrupt_trigger = {
2059 self.add_field('interrupt_trigger_mode', bitfields.getbits(self.base_address_modifier_interrupt_info, 0), unpack.format_table("base_address_modifier_interrupt_info[0]={}", _interrupt_trigger))
2060 self.add_field('interrupt_number', u.unpack_one("B"))
2062 self.decodeFailure = True
2063 print "Error parsing IPMIDeviceInformation"
2065 traceback.print_exc()
2068 class SystemPowerSupply(SmbiosBaseStructure):
2069 smbios_structure_type = 39
2071 def __init__(self, u, sm):
2072 super(SystemPowerSupply, self).__init__(u, sm)
2075 if self.length > 0x4:
2076 self.add_field('power_unit_group', u.unpack_one("B"))
2077 if self.length > 0x5:
2078 self.add_field('location', u.unpack_one("B"), self.fmtstr)
2079 if self.length > 0x6:
2080 self.add_field('device_name', u.unpack_one("B"), self.fmtstr)
2081 if self.length > 0x7:
2082 self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr)
2083 if self.length > 0x8:
2084 self.add_field('serial_number', u.unpack_one("B"), self.fmtstr)
2085 if self.length > 0x9:
2086 self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr)
2087 if self.length > 0xA:
2088 self.add_field('model_part_number', u.unpack_one("B"), self.fmtstr)
2089 if self.length > 0xB:
2090 self.add_field('revision_level', u.unpack_one("B"), self.fmtstr)
2091 if self.length > 0xC:
2092 self.add_field('max_power_capacity', u.unpack_one("<H"))
2093 if self.length > 0xE:
2094 self.add_field('power_supply_characteristics', u.unpack_one("<H"))
2095 _dmtf_power_supply_type = {
2103 0b1000: 'Regulator',
2104 xrange(0b1001, 0b1111): 'Reserved'
2106 self.add_field('dmtf_power_supply_type', bitfields.getbits(self.power_supply_characteristics, 13, 10), unpack.format_table("power_supply_characteristics[13:10]={}", _dmtf_power_supply_type))
2111 0b100: 'Non-critical',
2112 0b101: 'Critical; power supply has failed and has been taken off-line'
2114 self.add_field('status', bitfields.getbits(self.power_supply_characteristics, 9, 7), unpack.format_table("power_supply_characteristics[9:7]={}", _status))
2115 _dmtf_input_voltage_range_switching = {
2119 0b100: 'Auto-switch',
2120 0b101: 'Wide range',
2121 0b110: 'Not applicable',
2122 xrange(0b0111, 0b1111): 'Reserved'
2124 self.add_field('dmtf_input_voltage_range_switching', bitfields.getbits(self.power_supply_characteristics, 6, 3), unpack.format_table("power_supply_characteristics[6:3]={}", _dmtf_input_voltage_range_switching))
2125 self.add_field('power_supply_unplugged', bool(bitfields.getbits(self.power_supply_characteristics, 2)), "power_supply_characteristics[2]={}")
2126 self.add_field('power_supply_present', bool(bitfields.getbits(self.power_supply_characteristics, 1)), "power_supply_characteristics[1]={}")
2127 self.add_field('power_supply_hot_replaceable', bool(bitfields.getbits(self.power_supply_characteristics, 0)), "power_supply_characteristics[0]={}")
2128 if self.length > 0x10:
2129 self.add_field('input_voltage_probe_handle', u.unpack_one("<H"))
2130 if self.length > 0x12:
2131 self.add_field('cooling_device_handle', u.unpack_one("<H"))
2132 if self.length > 0x14:
2133 self.add_field('input_current_probe_handle', u.unpack_one("<H"))
2135 self.decodeFailure = True
2136 print "Error parsing SystemPowerSupply"
2138 traceback.print_exc()
2141 class AdditionalInformation(SmbiosBaseStructure):
2142 smbios_structure_type = 40
2144 def __init__(self, u, sm):
2145 super(AdditionalInformation, self).__init__(u, sm)
2148 if self.length > 0x4:
2149 self.add_field('num_additional_information_entries', u.unpack_one("B"))
2150 if self.length > 0x5:
2151 self.add_field('additional_information_entry_length', u.unpack_one("B"))
2152 self.add_field('referenced_handle', u.unpack_one("<H"))
2153 self.add_field('referenced_offset', u.unpack_one("B"))
2154 self.add_field('string', u.unpack_one("B"), self.fmtstr)
2155 self.add_field('value', u.unpack_rest())
2157 self.decodeFailure = True
2158 print "Error parsing AdditionalInformation"
2160 traceback.print_exc()
2163 class OnboardDevicesExtendedInformation(SmbiosBaseStructure):
2164 smbios_structure_type = 41
2166 def __init__(self, u, sm):
2167 super(OnboardDevicesExtendedInformation, self).__init__(u, sm)
2170 if self.length > 0x4:
2171 self.add_field('reference_designation', u.unpack_one("B"), self.fmtstr)
2172 if self.length > 0x5:
2173 self.add_field('device_type', u.unpack_one("B"))
2174 self.add_field('device_enabled', bool(bitfields.getbits(self.device_type, 7)), "device_type[7]={}")
2179 0x04: 'SCSI Controller',
2183 0x08: 'PATA Controller',
2184 0x09: 'SATA Controller',
2185 0x0A: 'SAS Controller'
2187 self.add_field('type_of_device', bitfields.getbits(self.device_type, 6, 0), unpack.format_table("device_type[6:0]={}", _device_types))
2188 if self.length > 0x6:
2189 self.add_field('device_type_instance', u.unpack_one("B"))
2190 if self.length > 0x7:
2191 self.add_field('segment_group_number', u.unpack_one("<H"))
2192 if self.length > 0x9:
2193 self.add_field('bus_number', u.unpack_one("B"), self.fmtstr)
2194 if self.length > 0xA:
2195 self.add_field('device_and_function_number', u.unpack_one("B"))
2196 self.add_field('device_number', bitfields.getbits(self.device_type, 7, 3), "device_and_function_number[7:3]={}")
2197 self.add_field('function_number', bitfields.getbits(self.device_type, 2, 0), "device_and_function_number[2:0]={}")
2199 self.decodeFailure = True
2200 print "Error parsing OnboardDevicesExtendedInformation"
2202 traceback.print_exc()
2205 class ManagementControllerHostInterface(SmbiosBaseStructure):
2206 smbios_structure_type = 42
2208 def __init__(self, u, sm):
2209 super(ManagementControllerHostInterface, self).__init__(u, sm)
2212 if self.length > 0x4:
2213 _interface_types = {
2216 0x02: 'KCS: Keyboard Controller Style',
2217 0x03: '8250 UART Register Compatible',
2218 0x04: '16450 UART Register Compatible',
2219 0x05: '16550/16550A UART Register Compatible',
2220 0x06: '16650/16650A UART Register Compatible',
2221 0x07: '16750/16750A UART Register Compatible',
2222 0x08: '16850/16850A UART Register Compatible',
2225 self.add_field('interface_type', u.unpack_one("B"), unpack.format_table("{}", _interface_types))
2226 if self.length > 0x5:
2227 self.add_field('mc_host_interface_data', u.unpack_rest(), self.fmtstr)
2229 self.decodeFailure = True
2230 print "Error parsing ManagementControllerHostInterface"
2232 traceback.print_exc()
2235 class Inactive(SmbiosBaseStructure):
2236 smbios_structure_type = 126
2238 def __init__(self, u, sm):
2239 super(Inactive, self).__init__(u, sm)
2242 class EndOfTable(SmbiosBaseStructure):
2243 smbios_structure_type = 127
2245 def __init__(self, u, sm):
2246 super(EndOfTable, self).__init__(u, sm)
2249 class SmbiosStructureUnknown(SmbiosBaseStructure):
2250 smbios_structure_type = None
2252 def __init__(self, u, sm):
2253 super(SmbiosStructureUnknown, self).__init__(u, sm)
2256 _smbios_structures = [
2259 BaseboardInformation,
2261 ProcessorInformation,
2262 MemoryControllerInformation,
2263 MemoryModuleInformation,
2267 OnBoardDevicesInformation,
2269 SystemConfigOptions,
2270 BIOSLanguageInformation,
2273 PhysicalMemoryArray,
2275 MemoryErrorInfo32Bit,
2276 MemoryArrayMappedAddress,
2277 MemoryDeviceMappedAddress,
2278 BuiltInPointingDevice,
2282 SystemPowerControls,
2286 ElectricalCurrentProbe,
2287 OutOfBandRemoteAccess,
2288 BootIntegrityServicesEntryPoint,
2289 SystemBootInformation,
2290 MemoryErrorInfo64Bit,
2292 ManagementDeviceComponent,
2293 ManagementDeviceThresholdData,
2295 IPMIDeviceInformation,
2297 AdditionalInformation,
2298 OnboardDevicesExtendedInformation,
2299 ManagementControllerHostInterface,
2302 SmbiosStructureUnknown, # Must always come last
2305 def log_smbios_info():
2306 with redirect.logonly():
2311 print "No SMBIOS structures found"
2314 known_types = (0, 1)
2315 for sm_struct in sm.structures:
2316 if sm_struct.type in known_types:
2317 output.setdefault(sm_struct.type, []).append(sm_struct)
2318 if len(output) == len(known_types):
2321 print "SMBIOS information:"
2322 for key in sorted(known_types):
2323 for s in output.get(key, ["No structure of type {} found".format(key)]):
2324 print ttypager._wrap("{}: {}".format(key, s))
2326 print "Error parsing SMBIOS information:"
2328 traceback.print_exc()
2334 s = "SMBIOS -- Raw bytes and structure decode.\n\n"
2336 s += str(sm.header) + '\n'
2337 s += bits.dumpmem(sm._header_memory) + '\n'
2339 s += "Raw bytes for the SMBIOS structures\n"
2340 s += bits.dumpmem(sm._structure_memory) + '\n'
2342 for sm_struct in sm.structures:
2343 s += str(sm_struct) + '\n'
2344 s += bits.dumpmem(sm_struct.raw_data)
2347 for n in range(1, len(getattr(sm_struct, "strings", [])) + 1):
2348 s += str(sm_struct.fmtstr(n)) + '\n'
2349 s += bits.dumpmem(sm_struct.raw_strings) + '\n'
2351 s = "No SMBIOS structures found"
2352 ttypager.ttypager_wrap(s, indent=False)
2354 print "Error parsing SMBIOS information:"
2356 traceback.print_exc()
2364 s = "No SMBIOS structures found"
2365 ttypager.ttypager_wrap(s, indent=False)
2367 print "Error parsing SMBIOS information:"
2369 traceback.print_exc()
2371 def annex_a_conformance():
2375 # check: 1. The table anchor string "_SM_" is present in the address range 0xF0000 to 0xFFFFF on a 16-byte bound
2377 def table_entry_point_verification():
2378 ''' Verify table entry-point'''
2379 if (sm.header.length < 0x1F):
2380 print "Failure: Table entry-point - The entry-point Length must be at least 0x1F"
2381 if sm.header.checksum != 0:
2382 print "Failure: Table entry-point - The entry-point checksum must evaluate to 0"
2383 if ((sm.header.major_version < 2) and (sm.header.minor_version < 4)):
2384 print "Failure: Table entry-point - SMBIOS version must be at least 2.4"
2385 if (sm.header.intermediate_anchor_string == '_DMI_'):
2386 print "Failure: Table entry-point - The Intermediate Anchor String must be '_DMI_'"
2387 if (sm.header.intermediate_checksum != 0):
2388 print "Failure: Table entry-point - The Intermediate checksum must evaluate to 0"
2390 #check: 3. The structure-table is traversable and conforms to the entry-point specifications:
2392 def req_structures():
2393 '''Checks for required structures and corresponding data'''
2394 types_present = [sm.structures[x].smbios_structure_type for x in range(len(sm.structures))]
2395 required = [0, 1, 4, 7, 9, 16, 17, 19, 31, 32]
2397 if s not in set(types_present):
2398 print "Failure: Type {} required but not found".format(s)
2402 if types_present.count(s) > 1:
2403 print "Failure: Type {} - One and only one structure of this type must be present.".format(s)
2404 if sm.structure_type(s).length < 0x18:
2405 print "Failure: Type {} - The structure Length field must be at least 0x18".format(s)
2406 if sm.structure_type(s).version is None:
2407 print "Failure: Type {} - BIOS Version string must be present and non-null.".format(s)
2408 if sm.structure_type(s).release_date is None:
2409 print "Failure: Type {} - BIOS Release Date string must be present, non-null, and include a 4-digit year".format(s)
2410 if bitfields.getbits(sm.structure_type(s).characteristics, 3, 0) != 0 or bitfields.getbits(sm.structure_type(s).characteristics, 31, 4) == 0:
2411 print "Failure: Type {} - BIOS Characteristics: bits 3:0 must all be 0, and at least one of bits 31:4 must be set to 1.".format(s)
2413 if types_present.count(s) > 1:
2414 print "Failure: Type {} - One and only one structure of this type must be present.".format(s)
2415 if sm.structure_type(s).length < 0x1B:
2416 print "Failure: Type {} - The structure Length field must be at least 0x1B".format(s)
2417 if sm.structure_type(s).manufacturer == None:
2418 print "Failure: Type {} - Manufacturer string must be present and non-null.".format(s)
2419 if sm.structure_type(s).product_name == None:
2420 print "Failure: Type {} - Product Name string must be present and non-null".format(s)
2421 if sm.structure_type(s).uuid == '00000000 00000000' and sm.structure_type(s).uuid == 'FFFFFFFF FFFFFFFF':
2422 print "Failure: Type {} - UUID field must be neither 00000000 00000000 nor FFFFFFFF FFFFFFFF.".format(s)
2423 if sm.structure_type(s).wakeup_type == 00 and sm.structure_type(s).wakeup_type == 0x02:
2424 print "Failure: Type {} - Wake-up Type field must be neither 00h (Reserved) nor 02h (Unknown).".format(s)
2425 # continue for remaining required types
2427 # check remaining conformance guidelines
2429 table_entry_point_verification()
2432 print "Error checking ANNEX A conformance guidelines"
2434 traceback.print_exc()