mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-10-11 23:48:07 +00:00
category based on different log levels: 1) If the board inspector show CRITICAL error messages, it means that the board inspector tool exit instantly and generate no file. 2) If the board inspector show ERROR messages, it means that the board inspector will generate the board XML file successfully, but several conditions may result in ACRN build or boot failure cannot continue execution due to the error. 3) If the board inspector show WARNING messages, this means that the board inspector generate the board XML file successfully, but this board XML file is lack of some feature which could still boot ACRN but loss some features. 4) If the board inspector show INFO messages, this means that board inspector printed out some normal information. 5) If the board inspector show DEBUG messages, this means that it is used to debug board inspector workflow. v1->v2 1. Keep the assertions or exceptions under the acpiparser, inspectorlib and smbiosparser directory. 2. Exit after all check_deps() completes instead of any unsatisfied dep is identified. 3. As Amy's advice, Replace the message "{board_xml} saved successfully" with the message "SUCCESS: Board configuration file <file name> generated successfully and saved to <path>." To do: Print all messages using the colored font. Tracked-On: #6689 Reviewed-by: Junjie Mao <junjie.mao@intel.com> Signed-off-by: Kunhui-Li <kunhuix.li@intel.com>
2284 lines
101 KiB
Python
2284 lines
101 KiB
Python
# Copyright (C) 2021 Intel Corporation. All rights reserved.
|
|
#
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
#
|
|
|
|
"""SMBIOS/DMI module."""
|
|
|
|
import sys
|
|
import ctypes
|
|
import struct
|
|
import uuid
|
|
import logging
|
|
import inspectorlib.bitfields as bitfields
|
|
import inspectorlib.unpack as unpack
|
|
|
|
class SMBIOS(unpack.Struct):
|
|
def __new__(cls):
|
|
sm = super(SMBIOS, cls).__new__(cls)
|
|
with open("/sys/firmware/dmi/tables/smbios_entry_point", "rb") as f:
|
|
sm._header_memory = f.read()
|
|
return sm
|
|
|
|
def __init__(self):
|
|
super(SMBIOS, self).__init__()
|
|
u = unpack.Unpackable(self._header_memory)
|
|
if self._header_memory[:4] == b"_SM_":
|
|
self.add_field('header', Header_2_1(u))
|
|
elif self._header_memory[:5] == b"_SM3_":
|
|
self.add_field('header', Header_3_0(u))
|
|
else:
|
|
assert False, "Unknown SMBIOS entry point structure"
|
|
with open("/sys/firmware/dmi/tables/DMI", "rb") as f:
|
|
self._structure_memory = f.read()
|
|
u = unpack.Unpackable(self._structure_memory)
|
|
self.add_field('structures', unpack.unpack_all(u, _smbios_structures, self), unpack.format_each("\n\n{!r}"))
|
|
|
|
def structure_type(self, num):
|
|
'''Dumps structure of given Type if present'''
|
|
try:
|
|
types_present = [self.structures[x].smbios_structure_type for x in range(len(self.structures))]
|
|
matrix = dict()
|
|
for index in range(len(types_present)):
|
|
if types_present.count(types_present[index]) == 1:
|
|
matrix[types_present[index]] = self.structures[index]
|
|
else: # if multiple structures of the same type, return a list of structures for the type number
|
|
if matrix.has_key(types_present[index]):
|
|
matrix[types_present[index]].append(self.structures[index])
|
|
else:
|
|
matrix[types_present[index]] = [self.structures[index]]
|
|
return matrix[num]
|
|
except:
|
|
logging.debug("Failure: Type {} - not found".format(num))
|
|
|
|
class Header_2_1(unpack.Struct):
|
|
def __new__(cls, u):
|
|
return super(Header_2_1, cls).__new__(cls)
|
|
|
|
def __init__(self, u):
|
|
super(Header_2_1, self).__init__()
|
|
self.raw_data = u.unpack_rest()
|
|
u = unpack.Unpackable(self.raw_data)
|
|
self.add_field('anchor_string', u.unpack_one("4s"))
|
|
self.add_field('checksum', u.unpack_one("B"))
|
|
self.add_field('length', u.unpack_one("B"))
|
|
self.add_field('major_version', u.unpack_one("B"))
|
|
self.add_field('minor_version', u.unpack_one("B"))
|
|
self.add_field('max_structure_size', u.unpack_one("<H"))
|
|
self.add_field('entry_point_revision', u.unpack_one("B"))
|
|
self.add_field('formatted_area', u.unpack_one("5s"))
|
|
self.add_field('intermediate_anchor_string', u.unpack_one("5s"))
|
|
self.add_field('intermediate_checksum', u.unpack_one("B"))
|
|
self.add_field('structure_table_length', u.unpack_one("<H"))
|
|
self.add_field('structure_table_address', u.unpack_one("<I"))
|
|
self.add_field('number_structures', u.unpack_one("<H"))
|
|
self.add_field('bcd_revision', u.unpack_one("B"))
|
|
if not u.at_end():
|
|
self.add_field('data', u.unpack_rest())
|
|
|
|
class Header_3_0(unpack.Struct):
|
|
def __new__(cls, u):
|
|
return super(Header_3_0, cls).__new__(cls)
|
|
|
|
def __init__(self, u):
|
|
super(Header_3_0, self).__init__()
|
|
self.raw_data = u.unpack_rest()
|
|
u = unpack.Unpackable(self.raw_data)
|
|
self.add_field('anchor_string', u.unpack_one("5s"))
|
|
self.add_field('checksum', u.unpack_one("B"))
|
|
self.add_field('length', u.unpack_one("B"))
|
|
self.add_field('major_version', u.unpack_one("B"))
|
|
self.add_field('minor_version', u.unpack_one("B"))
|
|
self.add_field('doc_revision', u.unpack_one("B"))
|
|
self.add_field('entry_point_revision', u.unpack_one("B"))
|
|
self.add_field('reserved', u.unpack_one("B"))
|
|
self.add_field('max_structure_size', u.unpack_one("<I"))
|
|
self.add_field('structure_table_address', u.unpack_one("<Q"))
|
|
if not u.at_end():
|
|
self.add_field('data', u.unpack_rest())
|
|
|
|
class SmbiosBaseStructure(unpack.Struct):
|
|
def __new__(cls, u, sm):
|
|
t = u.unpack_peek_one("B")
|
|
if cls.smbios_structure_type is not None and t != cls.smbios_structure_type:
|
|
return None
|
|
return super(SmbiosBaseStructure, cls).__new__(cls)
|
|
|
|
def __init__(self, u, sm):
|
|
super(SmbiosBaseStructure, self).__init__()
|
|
self.start_offset = u.offset
|
|
length = u.unpack_peek_one("<xB")
|
|
self.raw_data = u.unpack_raw(length)
|
|
self.u = unpack.Unpackable(self.raw_data)
|
|
|
|
self.strings_offset = u.offset
|
|
def unpack_string():
|
|
return b"".join(iter(lambda: u.unpack_one("c"), b"\x00"))
|
|
strings = list(iter(unpack_string, b""))
|
|
if not strings:
|
|
u.skip(1)
|
|
|
|
self.strings_length = u.offset - self.strings_offset
|
|
|
|
if len(strings):
|
|
self.strings = strings
|
|
|
|
self.add_field('type', self.u.unpack_one("B"))
|
|
self.add_field('length', self.u.unpack_one("B"))
|
|
self.add_field('handle', self.u.unpack_one("<H"))
|
|
|
|
def fini(self):
|
|
if not self.u.at_end():
|
|
self.add_field('data', self.u.unpack_rest())
|
|
del self.u
|
|
|
|
def fmtstr(self, i):
|
|
"""Format the specified index and the associated string"""
|
|
return "{} '{}'".format(i, self.getstr(i))
|
|
|
|
def getstr(self, i):
|
|
"""Get the string associated with the given index"""
|
|
if i == 0:
|
|
return "(none)"
|
|
if not hasattr(self, "strings"):
|
|
return "(error: structure has no strings)"
|
|
if i > len(self.strings):
|
|
return "(error: string index out of range)"
|
|
return self.strings[i - 1]
|
|
|
|
class BIOSInformation(SmbiosBaseStructure):
|
|
smbios_structure_type = 0
|
|
|
|
def __init__(self, u, sm):
|
|
super(BIOSInformation, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
self.add_field('vendor', u.unpack_one("B"), self.fmtstr)
|
|
self.add_field('version', u.unpack_one("B"), self.fmtstr)
|
|
self.add_field('starting_address_segment', u.unpack_one("<H"))
|
|
self.add_field('release_date', u.unpack_one("B"), self.fmtstr)
|
|
self.add_field('rom_size', u.unpack_one("B"))
|
|
self.add_field('characteristics', u.unpack_one("<Q"))
|
|
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
|
|
if (sm.header.major_version, minor_version_str) >= (2,"4"):
|
|
characteristic_bytes = 2
|
|
else:
|
|
characteristic_bytes = self.length - 0x12
|
|
self.add_field('characteristics_extensions', [u.unpack_one("B") for b in range(characteristic_bytes)])
|
|
if (sm.header.major_version, minor_version_str) >= (2,"4"):
|
|
self.add_field('major_release', u.unpack_one("B"))
|
|
self.add_field('minor_release', u.unpack_one("B"))
|
|
self.add_field('ec_major_release', u.unpack_one("B"))
|
|
self.add_field('ec_minor_release', u.unpack_one("B"))
|
|
except:
|
|
self.decode_failure = True
|
|
logging.debug("Error parsing BIOSInformation")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class SystemInformation(SmbiosBaseStructure):
|
|
smbios_structure_type = 1
|
|
|
|
def __init__(self, u, sm):
|
|
super(SystemInformation, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr)
|
|
self.add_field('product_name', u.unpack_one("B"), self.fmtstr)
|
|
self.add_field('version', u.unpack_one("B"), self.fmtstr)
|
|
self.add_field('serial_number', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x8:
|
|
self.add_field('uuid', uuid.UUID(bytes_le=u.unpack_one("16s")))
|
|
wakeup_types = {
|
|
0: 'Reserved',
|
|
1: 'Other',
|
|
2: 'Unknown',
|
|
3: 'APM Timer',
|
|
4: 'Modem Ring',
|
|
5: 'LAN Remote',
|
|
6: 'Power Switch',
|
|
7: 'PCI PME#',
|
|
8: 'AC Power Restored'
|
|
}
|
|
self.add_field('wakeup_type', u.unpack_one("B"), unpack.format_table("{}", wakeup_types))
|
|
if self.length > 0x19:
|
|
self.add_field('sku_number', u.unpack_one("B"), self.fmtstr)
|
|
self.add_field('family', u.unpack_one("B"), self.fmtstr)
|
|
except:
|
|
self.decode_failure = True
|
|
logging.debug("Error parsing SystemInformation")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
_board_types = {
|
|
1: 'Unknown',
|
|
2: 'Other',
|
|
3: 'Server Blade',
|
|
4: 'Connectivity Switch',
|
|
5: 'System Management Module',
|
|
6: 'Processor Module',
|
|
7: 'I/O Module',
|
|
8: 'Memory Module',
|
|
9: 'Daughter Board',
|
|
0xA: 'Motherboard',
|
|
0xB: 'Processor/Memory Module',
|
|
0xC: 'Processor/IO Module',
|
|
0xD: 'Interconnect Board'
|
|
}
|
|
|
|
class BaseboardInformation(SmbiosBaseStructure):
|
|
smbios_structure_type = 2
|
|
|
|
def __init__(self, u, sm):
|
|
super(BaseboardInformation, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr)
|
|
self.add_field('product', u.unpack_one("B"), self.fmtstr)
|
|
self.add_field('version', u.unpack_one("B"), self.fmtstr)
|
|
self.add_field('serial_number', u.unpack_one("B"), self.fmtstr)
|
|
|
|
if self.length > 0x8:
|
|
self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr)
|
|
|
|
if self.length > 0x9:
|
|
self.add_field('feature_flags', u.unpack_one("B"))
|
|
self.add_field('hosting_board', bool(bitfields.getbits(self.feature_flags, 0)), "feature_flags[0]={}")
|
|
self.add_field('requires_daughter_card', bool(bitfields.getbits(self.feature_flags, 1)), "feature_flags[1]={}")
|
|
self.add_field('removable', bool(bitfields.getbits(self.feature_flags, 2)), "feature_flags[2]={}")
|
|
self.add_field('replaceable', bool(bitfields.getbits(self.feature_flags, 3)), "feature_flags[3]={}")
|
|
self.add_field('hot_swappable', bool(bitfields.getbits(self.feature_flags, 4)), "feature_flags[4]={}")
|
|
|
|
if self.length > 0xA:
|
|
self.add_field('location', u.unpack_one("B"), self.fmtstr)
|
|
|
|
if self.length > 0xB:
|
|
self.add_field('chassis_handle', u.unpack_one("<H"))
|
|
|
|
if self.length > 0xD:
|
|
self.add_field('board_type', u.unpack_one("B"), unpack.format_table("{}", _board_types))
|
|
|
|
if self.length > 0xE:
|
|
self.add_field('handle_count', u.unpack_one("B"))
|
|
if self.handle_count > 0:
|
|
self.add_field('contained_object_handles', tuple(u.unpack_one("<H") for i in range(self.handle_count)))
|
|
except:
|
|
self.decode_failure = True
|
|
logging.debug("Error parsing BaseboardInformation")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class SystemEnclosure(SmbiosBaseStructure):
|
|
smbios_structure_type = 3
|
|
|
|
def __init__(self, u, sm):
|
|
super(SystemEnclosure, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr)
|
|
self.add_field('enumerated_type', u.unpack_one("B"))
|
|
self.add_field('chassis_lock_present', bool(bitfields.getbits(self.enumerated_type, 7)), "enumerated_type[7]={}")
|
|
board_types = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'Desktop',
|
|
0x04: 'Low Profile Desktop',
|
|
0x05: 'Pizza Box',
|
|
0x06: 'Mini Tower',
|
|
0x07: 'Tower',
|
|
0x08: 'Portable',
|
|
0x09: 'Laptop',
|
|
0x0A: 'Notebook',
|
|
0x0B: 'Hand Held',
|
|
0x0C: 'Docking Station',
|
|
0x0D: 'All in One',
|
|
0x0E: 'Sub Notebook',
|
|
0x0F: 'Space-saving',
|
|
0x10: 'Lunch Box',
|
|
0x11: 'Main Server Chassis',
|
|
0x12: 'Expansion Chassis',
|
|
0x13: 'SubChassis',
|
|
0x14: 'Bus Expansion Chassis',
|
|
0x15: 'Peripheral Chassis',
|
|
0x16: 'RAID Chassis',
|
|
0x17: 'Rack Mount Chassis',
|
|
0x18: 'Sealed-case PC',
|
|
0x19: 'Multi-system chassis W',
|
|
0x1A: 'Compact PCI',
|
|
0x1B: 'Advanced TCA',
|
|
0x1C: 'Blade',
|
|
0x1D: 'Blade Enclosure',
|
|
}
|
|
self.add_field('system_enclosure_type', bitfields.getbits(self.enumerated_type, 6, 0), unpack.format_table("enumerated_type[6:0]={}", board_types))
|
|
self.add_field('version', u.unpack_one("B"), self.fmtstr)
|
|
self.add_field('serial_number', u.unpack_one("B"), self.fmtstr)
|
|
self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr)
|
|
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
|
|
if self.length > 9:
|
|
chassis_states = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'Safe',
|
|
0x04: 'Warning',
|
|
0x05: 'Critical',
|
|
0x06: 'Non-recoverable',
|
|
}
|
|
self.add_field('bootup_state', u.unpack_one("B"), unpack.format_table("{}", chassis_states))
|
|
self.add_field('power_supply_state', u.unpack_one("B"), unpack.format_table("{}", chassis_states))
|
|
self.add_field('thermal_state', u.unpack_one("B"), unpack.format_table("{}", chassis_states))
|
|
security_states = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'None',
|
|
0x04: 'External interface locked out',
|
|
0x05: 'External interface enabled',
|
|
}
|
|
self.add_field('security_status', u.unpack_one("B"), unpack.format_table("{}", security_states))
|
|
if self.length > 0xd:
|
|
self.add_field('oem_defined', u.unpack_one("<I"))
|
|
if self.length > 0x11:
|
|
self.add_field('height', u.unpack_one("B"))
|
|
self.add_field('num_power_cords', u.unpack_one("B"))
|
|
self.add_field('contained_element_count', u.unpack_one("B"))
|
|
self.add_field('contained_element_length', u.unpack_one("B"))
|
|
if getattr(self, 'contained_element_count', 0):
|
|
self.add_field('contained_elements', tuple(SystemEnclosureContainedElement(u, self.contained_element_length) for i in range(self.contained_element_count)))
|
|
if self.length > (0x15 + (getattr(self, 'contained_element_count', 0) * getattr(self, 'contained_element_length', 0))):
|
|
self.add_field('sku_number', u.unpack_one("B"), self.fmtstr)
|
|
except:
|
|
self.decode_failure = True
|
|
logging.debug("Error parsing SystemEnclosure")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class SystemEnclosureContainedElement(unpack.Struct):
|
|
def __init__(self, u, length):
|
|
super(SystemEnclosureContainedElement, self).__init__()
|
|
self.start_offset = u.offset
|
|
self.raw_data = u.unpack_raw(length)
|
|
self.u = unpack.Unpackable(self.raw_data)
|
|
u = self.u
|
|
self.add_field('contained_element_type', u.unpack_one("B"))
|
|
type_selections = {
|
|
0: 'SMBIOS baseboard type enumeration',
|
|
1: 'SMBIOS structure type enumeration',
|
|
}
|
|
self.add_field('type_select', bitfields.getbits(self.contained_element_type, 7), unpack.format_table("contained_element_type[7]={}", type_selections))
|
|
self.add_field('type', bitfields.getbits(self.contained_element_type, 6, 0))
|
|
if self.type_select == 0:
|
|
self.add_field('smbios_board_type', self.type, unpack.format_table("{}", _board_types))
|
|
else:
|
|
self.add_field('smbios_structure_type', self.type)
|
|
self.add_field('minimum', u.unpack_one("B"))
|
|
self.add_field('maximum', u.unpack_one("B"))
|
|
if not u.at_end():
|
|
self.add_field('data', u.unpack_rest())
|
|
del self.u
|
|
|
|
class ProcessorInformation(SmbiosBaseStructure):
|
|
smbios_structure_type = 4
|
|
|
|
def __init__(self, u, sm):
|
|
super(ProcessorInformation, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
self.add_field('socket_designation', u.unpack_one("B"), self.fmtstr)
|
|
processor_types = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'Central Processor',
|
|
0x04: 'Math Processor',
|
|
0x05: 'DSP Processor',
|
|
0x06: 'Video Processor',
|
|
}
|
|
self.add_field('processor_type', u.unpack_one("B"), unpack.format_table("{}", processor_types))
|
|
self.add_field('processor_family', u.unpack_one("B"))
|
|
self.add_field('processor_manufacturer', u.unpack_one("B"), self.fmtstr)
|
|
self.add_field('processor_id', u.unpack_one("<Q"))
|
|
self.add_field('processor_version', u.unpack_one("B"), self.fmtstr)
|
|
self.add_field('voltage', u.unpack_one("B"))
|
|
self.add_field('external_clock', u.unpack_one("<H"))
|
|
self.add_field('max_speed', u.unpack_one("<H"))
|
|
self.add_field('current_speed', u.unpack_one("<H"))
|
|
self.add_field('status', u.unpack_one("B"))
|
|
processor_upgrades = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'Daughter Board',
|
|
0x04: 'ZIF Socket',
|
|
0x05: 'Replaceable Piggy Back',
|
|
0x06: 'None',
|
|
0x07: 'LIF Socket',
|
|
0x08: 'Slot 1',
|
|
0x09: 'Slot 2',
|
|
0x0A: '370-pin socket',
|
|
0x0B: 'Slot A',
|
|
0x0C: 'Slot M',
|
|
0x0D: 'Socket 423',
|
|
0x0E: 'Socket A (Socket 462)',
|
|
0x0F: 'Socket 478',
|
|
0x10: 'Socket 754',
|
|
0x11: 'Socket 940',
|
|
0x12: 'Socket 939',
|
|
0x13: 'Socket mPGA604',
|
|
0x14: 'Socket LGA771',
|
|
0x15: 'Socket LGA775',
|
|
0x16: 'Socket S1',
|
|
0x17: 'Socket AM2',
|
|
0x18: 'Socket F (1207)',
|
|
0x19: 'Socket LGA1366',
|
|
0x1A: 'Socket G34',
|
|
0x1B: 'Socket AM3',
|
|
0x1C: 'Socket C32',
|
|
0x1D: 'Socket LGA1156',
|
|
0x1E: 'Socket LGA1567',
|
|
0x1F: 'Socket PGA988A',
|
|
0x20: 'Socket BGA1288',
|
|
0x21: 'Socket rPGA988B',
|
|
0x22: 'Socket BGA1023',
|
|
0x23: 'Socket BGA1224',
|
|
0x24: 'Socket BGA1155',
|
|
0x25: 'Socket LGA1356',
|
|
0x26: 'Socket LGA2011',
|
|
0x27: 'Socket FS1',
|
|
0x28: 'Socket FS2',
|
|
0x29: 'Socket FM1',
|
|
0x2A: 'Socket FM2',
|
|
}
|
|
self.add_field('processor_upgrade', u.unpack_one("B"), unpack.format_table("{}", processor_upgrades))
|
|
if self.length > 0x1A:
|
|
self.add_field('l1_cache_handle', u.unpack_one("<H"))
|
|
self.add_field('l2_cache_handle', u.unpack_one("<H"))
|
|
self.add_field('l3_cache_handle', u.unpack_one("<H"))
|
|
if self.length > 0x20:
|
|
self.add_field('serial_number', u.unpack_one("B"), self.fmtstr)
|
|
self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr)
|
|
self.add_field('part_number', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x24:
|
|
self.add_field('core_count', u.unpack_one("B"))
|
|
self.add_field('core_enabled', u.unpack_one("B"))
|
|
self.add_field('thread_count', u.unpack_one("B"))
|
|
self.add_field('processor_characteristics', u.unpack_one("<H"))
|
|
if self.length > 0x28:
|
|
self.add_field('processor_family_2', u.unpack_one("<H"))
|
|
if self.length > 0x2A:
|
|
self.add_field('core_count2', u.unpack_one("<H"))
|
|
self.add_field('core_enabled2', u.unpack_one("<H"))
|
|
self.add_field('thread_count2', u.unpack_one("<H"))
|
|
except:
|
|
self.decode_failure = True
|
|
logging.debug("Error parsing Processor Information")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class MemoryControllerInformation(SmbiosBaseStructure): #obsolete starting with v2.1
|
|
smbios_structure_type = 5
|
|
|
|
def __init__(self, u, sm):
|
|
super(MemoryControllerInformation, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
_error_detecting_method = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'None',
|
|
0x04: '8-bit Parity',
|
|
0x05: '32-bit ECC',
|
|
0x06: '64-bit ECC',
|
|
0x07: '128-bit ECC',
|
|
0x08: 'CRC'
|
|
}
|
|
self.add_field('error_detecting_method', u.unpack_one("B"), unpack.format_table("{}", _error_detecting_method))
|
|
self.add_field('error_correcting_capability', u.unpack_one("B"))
|
|
_interleaves = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'One-Way Interleave',
|
|
0x04: 'Two-Way Interleave',
|
|
0x05: 'Four-Way Interleave',
|
|
0x06: 'Eight-Way Interleave',
|
|
0x07: 'Sixteen-Way Interleave'
|
|
}
|
|
self.add_field('supported_interleave', u.unpack_one("B"), unpack.format_table("{}", _interleaves))
|
|
self.add_field('current_interleave', u.unpack_one("B"), unpack.format_table("{}", _interleaves))
|
|
self.add_field('max_memory_module_size', u.unpack_one("B"), self.fmtstr)
|
|
self.add_field('supported_speeds', u.unpack_one("<H"))
|
|
self.add_field('supported_memory_types', u.unpack_one("<H"))
|
|
self.add_field('memory_module_voltage', u.unpack_one("B"))
|
|
self.add_field('req_voltage_b2', bitfields.getbits(self.memory_module_voltage, 2), "memory_module_voltage[2]={}")
|
|
self.add_field('req_voltage_b1', bitfields.getbits(self.memory_module_voltage, 1), "memory_module_voltage[1]={}")
|
|
self.add_field('req_voltage_b0', bitfields.getbits(self.memory_module_voltage, 0), "memory_module_voltage[0]={}")
|
|
self.add_field('num_associated_memory_slots', u.unpack_one("B"))
|
|
self.add_field('memory_module_configuration_handles', u.unpack_one("<(self.num_associated_memory_slots)H"))
|
|
self.add_field('enabled_error_correcting_capabilities', u.unpack_one("B"))
|
|
except:
|
|
self.decode_failure = True
|
|
logging.debug("Error parsing MemoryControllerInformation")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class MemoryModuleInformation(SmbiosBaseStructure): #obsolete starting with v2.1
|
|
smbios_structure_type = 6
|
|
|
|
def __init__(self, u, sm):
|
|
super(MemoryModuleInformation, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
self.add_field('socket_designation', u.unpack_one("B"), self.fmtstr)
|
|
self.add_field('bank_connections', u.unpack_one("B"))
|
|
self.add_field('current_speed', u.unpack_one("B"))
|
|
self.add_field('current_memory_type', u.unpack_one("<H"))
|
|
_mem_connection = {
|
|
0: 'single',
|
|
1: 'double-bank'
|
|
}
|
|
self.add_field('installed_mem', u.unpack_one("B"))
|
|
self.add_field('installed_size', bitfields.getbits(self.installed_mem, 6, 0), "installed_mem[6:0]={}")
|
|
self.add_field('installed_memory_module_connection', bitfields.getbits(self.installed_mem, 7), unpack.format_table("installed_mem[7]={}", _mem_connection))
|
|
self.add_field('enabled_mem', u.unpack_one("B"))
|
|
self.add_field('enabled_size', bitfields.getbits(self.installed_mem, 6, 0), "enabled_mem[6:0]={}")
|
|
self.add_field('enabled_memory_module_connection', bitfields.getbits(self.installed_mem, 7), unpack.format_table("enabled_mem[7]={}", _mem_connection))
|
|
self.add_field('error_status', u.unpack_one("B"))
|
|
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))
|
|
self.add_field('correctable_errors_received', bool(bitfields.getbits(self.error_status, 1)), unpack.format_table("error_status[1]={}", _mem_connection))
|
|
self.add_field('uncorrectable_errors_received', bool(bitfields.getbits(self.error_status, 0)), unpack.format_table("error_status[0]={}", _mem_connection))
|
|
except:
|
|
self.decode_failure = True
|
|
logging.debug("Error parsing MemoryModuleInformation")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class CacheInformation(SmbiosBaseStructure):
|
|
smbios_structure_type = 7
|
|
|
|
def __init__(self, u, sm):
|
|
super(CacheInformation, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
self.add_field('socket_designation', u.unpack_one("B"), self.fmtstr)
|
|
processor_types = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'Central Processor',
|
|
0x04: 'Math Processor',
|
|
0x05: 'DSP Processor',
|
|
0x06: 'Video Processor',
|
|
}
|
|
self.add_field('cache_configuration', u.unpack_one("<H"))
|
|
_operational_mode = {
|
|
0b00: 'Write Through',
|
|
0b01: 'Write Back',
|
|
0b10: 'Varies with Memory Address',
|
|
0b11: 'Unknown'
|
|
}
|
|
self.add_field('operational_mode', bitfields.getbits(self.cache_configuration, 9, 8), unpack.format_table("cache_configuration[9:8]={}", _operational_mode))
|
|
self.add_field('enabled_at_boot_time', bool(bitfields.getbits(self.cache_configuration, 7)), "cache_configuration[7]={}")
|
|
_location = {
|
|
0b00: 'Internal',
|
|
0b01: 'External',
|
|
0b10: 'Reserved',
|
|
0b11: 'Unknown'
|
|
}
|
|
self.add_field('location_relative_to_cpu_module', bitfields.getbits(self.cache_configuration, 6, 5), unpack.format_table("cache_configuration[6:5]={}", _location))
|
|
self.add_field('cache_socketed', bool(bitfields.getbits(self.cache_configuration, 3)), "cache_configuration[3]={}")
|
|
self.add_field('cache_level', bitfields.getbits(self.cache_configuration, 2, 0), "cache_configuration[2:0]={}")
|
|
self.add_field('max_cache_size', u.unpack_one("<H"))
|
|
_granularity = {
|
|
0: '1K granularity',
|
|
1: '64K granularity'
|
|
}
|
|
self.add_field('max_granularity', bitfields.getbits(self.cache_configuration, 15), unpack.format_table("max_cache_size[15]={}", _granularity))
|
|
self.add_field('max_size_in_granularity', bitfields.getbits(self.cache_configuration, 14, 0), "max_cache_size[14, 0]={}")
|
|
self.add_field('installed_size', u.unpack_one("<H"))
|
|
if self.installed_size != 0:
|
|
self.add_field('installed_granularity', bitfields.getbits(self.cache_configuration, 15), unpack.format_table("installed_size[15]={}", _granularity))
|
|
self.add_field('installed_size_in_granularity', bitfields.getbits(self.cache_configuration, 14, 0), "installed_size[14, 0]={}")
|
|
self.add_field('supported_sram_type', u.unpack_one("<H"))
|
|
self.add_field('current_sram_type', u.unpack_one("<H"))
|
|
if self.length > 0x0F:
|
|
self.add_field('cache_speed', u.unpack_one("B"))
|
|
if self.length > 0x10:
|
|
_error_correction = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'None',
|
|
0x04: 'Parity',
|
|
0x05: 'Single-bit ECC',
|
|
0x06: 'Multi-bit ECC'
|
|
}
|
|
self.add_field('error_correction', u.unpack_one("B"), unpack.format_table("{}", _error_correction))
|
|
if self.length > 0x10:
|
|
_system_cache_type = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'Instruction',
|
|
0x04: 'Data',
|
|
0x05: 'Unified'
|
|
}
|
|
self.add_field('system_cache_type', u.unpack_one("B"), unpack.format_table("{}", _system_cache_type))
|
|
if self.length > 0x12:
|
|
_associativity = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'Direct Mapped',
|
|
0x04: '2-way Set-Associative',
|
|
0x05: '4-way Set-Associative',
|
|
0x06: 'Fully Associative',
|
|
0x07: '8-way Set-Associative',
|
|
0x08: '16-way Set-Associative',
|
|
0x09: '12-way Set-Associative',
|
|
0x0A: '24-way Set-Associative',
|
|
0x0B: '32-way Set-Associative',
|
|
0x0C: '48-way Set-Associative',
|
|
0x0D: '64-way Set-Associative',
|
|
0x0E: '20-way Set-Associative'
|
|
}
|
|
self.add_field('associativity', u.unpack_one("B"), unpack.format_table("{}", _associativity))
|
|
|
|
except:
|
|
self.decode_failure = True
|
|
logging.debug("Error parsing CacheInformation")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class PortConnectorInfo(SmbiosBaseStructure):
|
|
smbios_structure_type = 8
|
|
|
|
def __init__(self, u, sm):
|
|
super(PortConnectorInfo, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
self.add_field('internal_reference_designator', u.unpack_one("B"), self.fmtstr)
|
|
connector_types = {
|
|
0x00: 'None',
|
|
0x01: 'Centronics',
|
|
0x02: 'Mini Centronics',
|
|
0x03: 'Proprietary',
|
|
0x04: 'DB-25 pin male',
|
|
0x05: 'DB-25 pin female',
|
|
0x06: 'DB-15 pin male',
|
|
0x07: 'DB-15 pin female',
|
|
0x08: 'DB-9 pin male',
|
|
0x09: 'DB-9 pin female',
|
|
0x0A: 'RJ-11',
|
|
0x0B: 'RJ-45',
|
|
0x0C: '50-pin MiniSCSI',
|
|
0x0D: 'Mini-DIN',
|
|
0x0E: 'Micro-DIN',
|
|
0x0F: 'PS/2',
|
|
0x10: 'Infrared',
|
|
0x11: 'HP-HIL',
|
|
0x12: 'Access Bus (USB)',
|
|
0x13: 'SSA SCSI',
|
|
0x14: 'Circular DIN-8 male',
|
|
0x15: 'Circular DIN-8 female',
|
|
0x16: 'On Board IDE',
|
|
0x17: 'On Board Floppy',
|
|
0x18: '9-pin Dual Inline (pin 10 cut)',
|
|
0x19: '25-pin Dual Inline (pin 26 cut)',
|
|
0x1A: '50-pin Dual Inline',
|
|
0x1B: '68-pin Dual Inline',
|
|
0x1C: 'On Board Sound Input from CD-ROM',
|
|
0x1D: 'Mini-Centronics Type-14',
|
|
0x1E: 'Mini-Centronics Type-26',
|
|
0x1F: 'Mini-jack (headphones)',
|
|
0x20: 'BNC',
|
|
0x21: '1394',
|
|
0x22: 'SAS/SATA Plug Receptacle',
|
|
0xA0: 'PC-98',
|
|
0xA1: 'PC-98Hireso',
|
|
0xA2: 'PC-H98',
|
|
0xA3: 'PC-98Note',
|
|
0xA4: 'PC-98Full',
|
|
0xFF: 'Other',
|
|
}
|
|
self.add_field('internal_connector_type', u.unpack_one("B"), unpack.format_table("{}", connector_types))
|
|
self.add_field('external_reference_designator', u.unpack_one("B"), self.fmtstr)
|
|
self.add_field('external_connector_type', u.unpack_one("B"), unpack.format_table("{}", connector_types))
|
|
port_types = {
|
|
0x00: 'None',
|
|
0x01: 'Parallel Port XT/AT Compatible',
|
|
0x02: 'Parallel Port PS/2',
|
|
0x03: 'Parallel Port ECP',
|
|
0x04: 'Parallel Port EPP',
|
|
0x05: 'Parallel Port ECP/EPP',
|
|
0x06: 'Serial Port XT/AT Compatible',
|
|
0x07: 'Serial Port 16450 Compatible',
|
|
0x08: 'Serial Port 16550 Compatible',
|
|
0x09: 'Serial Port 16550A Compatible',
|
|
0x0A: 'SCSI Port',
|
|
0x0B: 'MIDI Port',
|
|
0x0C: 'Joy Stick Port',
|
|
0x0D: 'Keyboard Port',
|
|
0x0E: 'Mouse Port',
|
|
0x0F: 'SSA SCSI',
|
|
0x10: 'USB',
|
|
0x11: 'FireWire (IEEE P1394)',
|
|
0x12: 'PCMCIA Type I2',
|
|
0x13: 'PCMCIA Type II',
|
|
0x14: 'PCMCIA Type III',
|
|
0x15: 'Cardbus',
|
|
0x16: 'Access Bus Port',
|
|
0x17: 'SCSI II',
|
|
0x18: 'SCSI Wide',
|
|
0x19: 'PC-98',
|
|
0x1A: 'PC-98-Hireso',
|
|
0x1B: 'PC-H98',
|
|
0x1C: 'Video Port',
|
|
0x1D: 'Audio Port',
|
|
0x1E: 'Modem Port',
|
|
0x1F: 'Network Port',
|
|
0x20: 'SATA',
|
|
0x21: 'SAS',
|
|
0xA0: '8251 Compatible',
|
|
0xA1: '8251 FIFO Compatible',
|
|
0xFF: 'Other',
|
|
}
|
|
self.add_field('port_type', u.unpack_one("B"), unpack.format_table("{}", port_types))
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing PortConnectorInfo")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class SystemSlots(SmbiosBaseStructure):
|
|
smbios_structure_type = 9
|
|
|
|
def __init__(self, u, sm):
|
|
super(SystemSlots, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
self.add_field('designation', u.unpack_one("B"), self.fmtstr)
|
|
_slot_types = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'ISA',
|
|
0x04: 'MCA',
|
|
0x05: 'EISA',
|
|
0x06: 'PCI',
|
|
0x07: 'PC Card (PCMCIA)',
|
|
0x08: 'VL-VESA',
|
|
0x09: 'Proprietary',
|
|
0x0A: 'Processor Card Slot',
|
|
0x0B: 'Proprietary Memory Card Slot',
|
|
0x0C: 'I/O Riser Card Slot',
|
|
0x0D: 'NuBus',
|
|
0x0E: 'PCI 66MHz Capable',
|
|
0x0F: 'AGP',
|
|
0x10: 'AGP 2X',
|
|
0x11: 'AGP 4X',
|
|
0x12: 'PCI-X',
|
|
0x13: 'AGP 8X',
|
|
0xA0: 'PC-98/C20',
|
|
0xA1: 'PC-98/C24',
|
|
0xA2: 'PC-98/E',
|
|
0xA3: 'PC-98/Local Bus',
|
|
0xA4: 'PC-98/Card',
|
|
0xA5: 'PCI Express',
|
|
0xA6: 'PCI Express x1',
|
|
0xA7: 'PCI Express x2',
|
|
0xA8: 'PCI Express x4',
|
|
0xA9: 'PCI Express x8',
|
|
0xAA: 'PCI Express x16',
|
|
0xAB: 'PCI Express Gen 2',
|
|
0xAC: 'PCI Express Gen 2 x1',
|
|
0xAD: 'PCI Express Gen 2 x2',
|
|
0xAE: 'PCI Express Gen 2 x4',
|
|
0xAF: 'PCI Express Gen 2 x8',
|
|
0xB0: 'PCI Express Gen 2 x16',
|
|
0xB1: 'PCI Express Gen 3',
|
|
0xB2: 'PCI Express Gen 3 x1',
|
|
0xB3: 'PCI Express Gen 3 x2',
|
|
0xB4: 'PCI Express Gen 3 x4',
|
|
0xB5: 'PCI Express Gen 3 x8',
|
|
0xB6: 'PCI Express Gen 3 x16',
|
|
}
|
|
self.add_field('slot_type', u.unpack_one("B"), unpack.format_table("{}", _slot_types))
|
|
_slot_data_bus_widths = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: '8 bit',
|
|
0x04: '16 bit',
|
|
0x05: '32 bit',
|
|
0x06: '64 bit',
|
|
0x07: '128 bit',
|
|
0x08: '1x or x1',
|
|
0x09: '2x or x2',
|
|
0x0A: '4x or x4',
|
|
0x0B: '8x or x8',
|
|
0x0C: '12x or x12',
|
|
0x0D: '16x or x16',
|
|
0x0E: '32x or x32',
|
|
}
|
|
self.add_field('slot_data_bus_width', u.unpack_one('B'), unpack.format_table("{}", _slot_data_bus_widths))
|
|
_current_usages = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'Available',
|
|
0x04: 'In use',
|
|
}
|
|
self.add_field('current_usage', u.unpack_one('B'), unpack.format_table("{}", _current_usages))
|
|
_slot_lengths = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'Short Length',
|
|
0x04: 'Long Length',
|
|
}
|
|
self.add_field('slot_length', u.unpack_one('B'), unpack.format_table("{}", _slot_lengths))
|
|
self.add_field('slot_id', u.unpack_one('<H'))
|
|
self.add_field('characteristics1', u.unpack_one('B'))
|
|
self.add_field('characteristics_unknown', bool(bitfields.getbits(self.characteristics1, 0)), "characteristics1[0]={}")
|
|
self.add_field('provides_5_0_volts', bool(bitfields.getbits(self.characteristics1, 1)), "characteristics1[1]={}")
|
|
self.add_field('provides_3_3_volts', bool(bitfields.getbits(self.characteristics1, 2)), "characteristics1[2]={}")
|
|
self.add_field('shared_slot', bool(bitfields.getbits(self.characteristics1, 3)), "characteristics1[3]={}")
|
|
self.add_field('supports_pc_card_16', bool(bitfields.getbits(self.characteristics1, 4)), "characteristics1[4]={}")
|
|
self.add_field('supports_cardbus', bool(bitfields.getbits(self.characteristics1, 5)), "characteristics1[5]={}")
|
|
self.add_field('supports_zoom_video', bool(bitfields.getbits(self.characteristics1, 6)), "characteristics1[6]={}")
|
|
self.add_field('supports_modem_ring_resume', bool(bitfields.getbits(self.characteristics1, 7)), "characteristics1[7]={}")
|
|
if self.length > 0x0C:
|
|
self.add_field('characteristics2', u.unpack_one('B'))
|
|
self.add_field('supports_PME', bool(bitfields.getbits(self.characteristics2, 0)), "characteristics2[0]={}")
|
|
self.add_field('supports_hot_plug', bool(bitfields.getbits(self.characteristics2, 1)), "characteristics2[1]={}")
|
|
self.add_field('supports_smbus', bool(bitfields.getbits(self.characteristics2, 2)), "characteristics2[2]={}")
|
|
if self.length > 0x0D:
|
|
self.add_field('segment_group_number', u.unpack_one('<H'))
|
|
self.add_field('bus_number', u.unpack_one('B'))
|
|
self.add_field('device_function_number', u.unpack_one('B'))
|
|
self.add_field('device_number', bitfields.getbits(self.device_function_number, 7, 3), "device_function_number[7:3]={}")
|
|
self.add_field('function_number', bitfields.getbits(self.device_function_number, 2, 0), "device_function_number[2:0]={}")
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing SystemSlots")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class OnBoardDevicesInformation(SmbiosBaseStructure):
|
|
smbios_structure_type = 10
|
|
|
|
def __init__(self, u, sm):
|
|
super(OnBoardDevicesInformation, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
self.add_field('device_type', u.unpack_one("B"))
|
|
self.add_field('device_enabled', bool(bitfields.getbits(self.device_type, 7)), "device_type[7]={}")
|
|
_device_types = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'Video',
|
|
0x04: 'SCSI Controller',
|
|
0x05: 'Ethernet',
|
|
0x06: 'Token Ring',
|
|
0x07: 'Sound',
|
|
0x08: 'PATA Controller',
|
|
0x09: 'SATA Controller',
|
|
0x0A: 'SAS Controller'
|
|
}
|
|
self.add_field('type_of_device', bitfields.getbits(self.device_type, 6, 0), unpack.format_table("device_type[6:0]={}", _device_types))
|
|
self.add_field('description_string', u.unpack_one("B"), self.fmtstr)
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing OnBoardDevicesInformation")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class OEMStrings(SmbiosBaseStructure):
|
|
smbios_structure_type = 11
|
|
|
|
def __init__(self, u, sm):
|
|
super(OEMStrings, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
self.add_field('count', u.unpack_one("B"))
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing OEMStrings")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class SystemConfigOptions(SmbiosBaseStructure):
|
|
smbios_structure_type = 12
|
|
|
|
def __init__(self, u, sm):
|
|
super(SystemConfigOptions, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
self.add_field('count', u.unpack_one("B"))
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing SystemConfigOptions")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class BIOSLanguageInformation(SmbiosBaseStructure):
|
|
smbios_structure_type = 13
|
|
|
|
def __init__(self, u, sm):
|
|
super(BIOSLanguageInformation, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
self.add_field('installable_languages', u.unpack_one("B"))
|
|
if self.length > 0x05:
|
|
self.add_field('flags', u.unpack_one('B'))
|
|
self.add_field('abbreviated_format', bool(bitfields.getbits(self.flags, 0)), "flags[0]={}")
|
|
if self.length > 0x6:
|
|
u.skip(15)
|
|
self.add_field('current_language', u.unpack_one('B'), self.fmtstr)
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing BIOSLanguageInformation")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class GroupAssociations(SmbiosBaseStructure):
|
|
smbios_structure_type = 14
|
|
|
|
def __init__(self, u, sm):
|
|
super(GroupAssociations, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
self.add_field('group_name', u.unpack_one("B"), self.fmtstr)
|
|
self.add_field('item_type', u.unpack_one('B'))
|
|
self.add_field('item_handle', u.unpack_one('<H'))
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing GroupAssociations")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class SystemEventLog(SmbiosBaseStructure):
|
|
smbios_structure_type = 15
|
|
|
|
def __init__(self, u, sm):
|
|
super(SystemEventLog, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
self.add_field('log_area_length', u.unpack_one("<H"))
|
|
self.add_field('log_header_start_offset', u.unpack_one('<H'))
|
|
self.add_field('log_data_start_offset', u.unpack_one('<H'))
|
|
_access_method = {
|
|
0x00: 'Indexed I/O: 1 8-bit index port, 1 8-bit data port',
|
|
0x01: 'Indexed I/O: 2 8-bit index ports, 1 8-bit data port',
|
|
0x02: 'Indexed I/O: 1 16-bit index port, 1 8-bit data port',
|
|
0x03: 'Memory-mapped physical 32-bit address',
|
|
0x04: 'Available through General-Purpose NonVolatile Data functions',
|
|
range(0x05, 0x07F): 'Available for future assignment',
|
|
range(0x80, 0xFF): 'BIOS Vendor/OEM-specific'
|
|
}
|
|
self.add_field('access_method', u.unpack_one('B'), unpack.format_table("{}", _access_method))
|
|
self.add_field('log_status', u.unpack_one('B'))
|
|
self.add_field('log_area_full', bool(bitfields.getbits(self.log_status, 1)), "log_status[1]={}")
|
|
self.add_field('log_area_valid', bool(bitfields.getbits(self.log_status, 0)), "log_status[0]={}")
|
|
self.add_field('log_change_token', u.unpack_one('<I'))
|
|
self.add_field('access_method_address', u.unpack_one('<I'))
|
|
if self.length > 0x14:
|
|
_log_header_formats = {
|
|
0: 'No header',
|
|
1: 'Type 1 log header',
|
|
range(2, 0x7f): 'Available for future assignment',
|
|
range(0x80, 0xff): 'BIOS vendor or OEM-specific format'
|
|
}
|
|
self.add_field('log_header_format', u.unpack_one("B"), unpack.format_table("{}", _log_header_formats))
|
|
if self.length > 0x15:
|
|
self.add_field('num_supported_log_type_descriptors', u.unpack_one('B'))
|
|
if self.length > 0x16:
|
|
self.add_field('length_log_type_descriptor', u.unpack_one('B'))
|
|
if self.length != (0x17 + (self.num_supported_log_type_descriptors * self.length_log_type_descriptor)):
|
|
logging.debug(f"Error: structure length ({self.length}) != 0x17 + (num_supported_log_type_descriptors ({self.num_supported_log_type_descriptors}) * length_log_type_descriptor({self.length_log_type_descriptor}))")
|
|
logging.debug("structure length = {}".format(self.length))
|
|
logging.debug("num_supported_log_type_descriptors = {}".format(self.num_supported_log_type_descriptors))
|
|
logging.debug("length_log_type_descriptor = {}".format(self.length_log_type_descriptor))
|
|
self.decodeFailure = True
|
|
self.add_field('descriptors', tuple(EventLogDescriptor.unpack(u) for i in range(self.num_supported_log_type_descriptors)), unpack.format_each("\n{!r}"))
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing SystemEventLog")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class EventLogDescriptor(unpack.Struct):
|
|
@staticmethod
|
|
def _unpack(u):
|
|
_event_log_type_descriptors = {
|
|
0x00: 'Reserved',
|
|
0x01: 'Single-bit ECC memory error',
|
|
0x02: 'Multi-bit ECC memory error',
|
|
0x03: 'Parity memory error',
|
|
0x04: 'Bus time-out',
|
|
0x05: 'I/O Channel Check',
|
|
0x06: 'Software NMI',
|
|
0x07: 'POST Memory Resize',
|
|
0x08: 'POST Error',
|
|
0x09: 'PCI Parity Error',
|
|
0x0A: 'PCI System Error',
|
|
0x0B: 'CPU Failure',
|
|
0x0C: 'EISA FailSafe Timer time-out',
|
|
0x0D: 'Correctable memory log disabled',
|
|
0x0E: 'Logging disabled for a specific Event Type - too many errors of the same type received in a short amount of time',
|
|
0x0F: 'Reserved',
|
|
0x10: 'System Limit Exceeded',
|
|
0x11: 'Asynchronous hardware timer expired and issued a system reset',
|
|
0x12: 'System configuration information',
|
|
0x13: 'Hard-disk information',
|
|
0x14: 'System reconfigured',
|
|
0x15: 'Uncorrectable CPU-complex error',
|
|
0x16: 'Log Area Reset/Cleared',
|
|
0x17: 'System boot',
|
|
range(0x18, 0x7F): 'Unused, available for assignment',
|
|
range(0x80, 0xFE): 'Availalbe for system- and OEM-specific assignments',
|
|
0xFF: 'End of log'
|
|
}
|
|
yield 'log_type', u.unpack_one('B'), unpack.format_table("{}", _event_log_type_descriptors)
|
|
_event_log_format = {
|
|
0x00: 'None',
|
|
0x01: 'Handle',
|
|
0x02: 'Multiple-Event',
|
|
0x03: 'Multiple-Event Handle',
|
|
0x04: 'POST Results Bitmap',
|
|
0x05: 'System Management Type',
|
|
0x06: 'Multiple-Event System Management Type',
|
|
range(0x80, 0xFF): 'OEM assigned'
|
|
}
|
|
yield 'variable_data_format_type', u.unpack_one('B'), unpack.format_table("{}", _event_log_format)
|
|
|
|
class PhysicalMemoryArray(SmbiosBaseStructure):
|
|
smbios_structure_type = 16
|
|
|
|
def __init__(self, u, sm):
|
|
super(PhysicalMemoryArray, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0x4:
|
|
_location_field = {
|
|
0x01: "Other",
|
|
0x02: "Unknown",
|
|
0x03: "System board or motherboard",
|
|
0x04: "ISA add-on card",
|
|
0x05: "EISA add-on card",
|
|
0x06: "PCI add-on card",
|
|
0x07: "MCA add-on card",
|
|
0x08: "PCMCIA add-on card",
|
|
0x09: "Proprietary add-on card",
|
|
0x0A: "NuBus",
|
|
0xA0: "PC-98/C20 add-on card",
|
|
0xA1: "PC-98/C24 add-on card",
|
|
0xA2: "PC-98/E add-on card",
|
|
0xA3: "PC-98/Local bus add-on card"
|
|
}
|
|
self.add_field('location', u.unpack_one("B"), unpack.format_table("{}", _location_field))
|
|
if self.length > 0x05:
|
|
_use = {
|
|
0x01: "Other",
|
|
0x02: "Unknown",
|
|
0x03: "System memory",
|
|
0x04: "Video memory",
|
|
0x05: "Flash memory",
|
|
0x06: "Non-volatile RAM",
|
|
0x07: "Cache memory"
|
|
}
|
|
self.add_field('use', u.unpack_one('B'), unpack.format_table("{}", _use))
|
|
if self.length > 0x06:
|
|
_error_correction = {
|
|
0x01: "Other",
|
|
0x02: "Unknown",
|
|
0x03: "None",
|
|
0x04: "Parity",
|
|
0x05: "Single-bit ECC",
|
|
0x06: "Multi-bit ECC",
|
|
0x07: "CRC"
|
|
}
|
|
self.add_field('memory_error_correction', u.unpack_one('B'), unpack.format_table("{}", _error_correction))
|
|
if self.length > 0x07:
|
|
self.add_field('maximum_capacity', u.unpack_one('<I'))
|
|
if self.length > 0x0B:
|
|
self.add_field('memory_error_information_handle', u.unpack_one('<H'))
|
|
if self.length > 0x0D:
|
|
self.add_field('num_memory_devices', u.unpack_one('<H'))
|
|
if self.length > 0x0F:
|
|
self.add_field('extended_maximum_capacity', u.unpack_one('<Q'))
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing PhysicalMemoryArray")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class MemoryDevice(SmbiosBaseStructure):
|
|
smbios_structure_type = 17
|
|
|
|
def __init__(self, u, sm):
|
|
super(MemoryDevice, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0x4:
|
|
self.add_field('physical_memory_array_handle', u.unpack_one("<H"))
|
|
if self.length > 0x6:
|
|
self.add_field('memory_error_information_handle', u.unpack_one("<H"))
|
|
if self.length > 0x8:
|
|
self.add_field('total_width', u.unpack_one("<H"))
|
|
if self.length > 0xA:
|
|
self.add_field('data_width', u.unpack_one("<H"))
|
|
if self.length > 0xC:
|
|
self.add_field('size', u.unpack_one("<H"))
|
|
if self.length > 0xE:
|
|
_form_factors = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'SIMM',
|
|
0x04: 'SIP',
|
|
0x05: 'Chip',
|
|
0x06: 'DIP',
|
|
0x07: 'ZIP',
|
|
0x08: 'Proprietary Card',
|
|
0x09: 'DIMM',
|
|
0x0A: 'TSOP',
|
|
0x0B: 'Row of chips',
|
|
0x0C: 'RIMM',
|
|
0x0D: 'SODIMM',
|
|
0x0E: 'SRIMM',
|
|
0x0F: 'FB-DIMM'
|
|
}
|
|
self.add_field('form_factor', u.unpack_one("B"), unpack.format_table("{}", _form_factors))
|
|
if self.length > 0xF:
|
|
self.add_field('device_set', u.unpack_one("B"))
|
|
if self.length > 0x10:
|
|
self.add_field('device_locator', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x11:
|
|
self.add_field('bank_locator', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x12:
|
|
_memory_types = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'DRAM',
|
|
0x04: 'EDRAM',
|
|
0x05: 'VRAM',
|
|
0x06: 'SRAM',
|
|
0x07: 'RAM',
|
|
0x08: 'ROM',
|
|
0x09: 'FLASH',
|
|
0x0A: 'EEPROM',
|
|
0x0B: 'FEPROM',
|
|
0x0C: 'EPROM',
|
|
0x0D: 'CDRAM',
|
|
0x0E: '3DRAM',
|
|
0x0F: 'SDRAM',
|
|
0x10: 'SGRAM',
|
|
0x11: 'RDRAM',
|
|
0x12: 'DDR',
|
|
0x13: 'DDR2',
|
|
0x14: 'DDR2 FB-DIMM',
|
|
range(0x15, 0x17): 'Reserved',
|
|
0x18: 'DDR3',
|
|
0x19: 'FBD2'
|
|
}
|
|
self.add_field('memory_type', u.unpack_one("B"), unpack.format_table("{}", _memory_types))
|
|
if self.length > 0x13:
|
|
self.add_field('type_detail', u.unpack_one('<H'))
|
|
if self.length > 0x15:
|
|
self.add_field('speed', u.unpack_one("<H"))
|
|
if self.length > 0x17:
|
|
self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x18:
|
|
self.add_field('serial_number', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x19:
|
|
self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x1A:
|
|
self.add_field('part_number', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x1B:
|
|
self.add_field('attributes', u.unpack_one("B"))
|
|
self.add_field('rank', bitfields.getbits(self.attributes, 3, 0), "attributes[3:0]={}")
|
|
if self.length > 0x1C:
|
|
if self.size == 0x7FFF:
|
|
self.add_field('extended_size', u.unpack_one('<I'))
|
|
self.add_field('mem_size', bitfields.getbits(self.type_detail, 30, 0), "type_detail[30:0]={}")
|
|
else:
|
|
u.skip(4)
|
|
if self.length > 0x20:
|
|
self.add_field('configured_memory_clock_speed', u.unpack_one("<H"))
|
|
if self.length > 0x22:
|
|
self.add_field('minimum_voltage', u.unpack_one("<H"))
|
|
if self.length > 0x24:
|
|
self.add_field('maximum_voltage', u.unpack_one("<H"))
|
|
if self.length > 0x26:
|
|
self.add_field('configured_voltage', u.unpack_one("<H"))
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing MemoryDevice")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class MemoryErrorInfo32Bit(SmbiosBaseStructure):
|
|
smbios_structure_type = 18
|
|
|
|
def __init__(self, u, sm):
|
|
super(MemoryErrorInfo32Bit, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0x4:
|
|
_error_types = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'OK',
|
|
0x04: 'Bad read',
|
|
0x05: 'Parity error',
|
|
0x06: 'Single-bit error',
|
|
0x07: 'Double-bit error',
|
|
0x08: 'Multi-bit error',
|
|
0x09: 'Nibble error',
|
|
0x0A: 'Checksum error',
|
|
0x0B: 'CRC error',
|
|
0x0C: 'Corrected single-bit error',
|
|
0x0D: 'Corrected error',
|
|
0x0E: 'Uncorrectable error'
|
|
}
|
|
self.add_field('error_type', u.unpack_one("B"), unpack.format_table("{}", _error_types))
|
|
if self.length > 0x5:
|
|
_error_granularity_field = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'Device level',
|
|
0x04: 'Memory partition level'
|
|
}
|
|
self.add_field('error_granularity', u.unpack_one("B"), unpack.format_table("{}", _error_granularity_field))
|
|
if self.length > 0x6:
|
|
_error_operation_field = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'Read',
|
|
0x04: 'Write',
|
|
0x05: 'Partial write'
|
|
}
|
|
self.add_field('error_operation', u.unpack_one("B"), unpack.format_table("{}", _error_operation_field))
|
|
if self.length > 0x7:
|
|
self.add_field('vendor_syndrome', u.unpack_one("<I"))
|
|
if self.length > 0xB:
|
|
self.add_field('memory_array_error_address', u.unpack_one("<I"))
|
|
if self.length > 0xF:
|
|
self.add_field('device_error_address', u.unpack_one("<I"))
|
|
if self.length > 0x13:
|
|
self.add_field('error_resolution', u.unpack_one("<I"))
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing MemoryErrorInfo32Bit")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class MemoryArrayMappedAddress(SmbiosBaseStructure):
|
|
smbios_structure_type = 19
|
|
|
|
def __init__(self, u, sm):
|
|
super(MemoryArrayMappedAddress, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0x4:
|
|
self.add_field('starting_address', u.unpack_one("<I"))
|
|
# if FFFF FFFF: address stored in Extended Starting Address
|
|
if self.length > 0x8:
|
|
self.add_field('ending_address', u.unpack_one("<I"))
|
|
if self.length > 0xC:
|
|
self.add_field('memory_array_handle', u.unpack_one("<H"))
|
|
if self.length > 0xE:
|
|
self.add_field('partition_width', u.unpack_one("B"))
|
|
if self.length > 0xF:
|
|
# valid if starting_address = FFFF FFFF
|
|
if self.starting_address == 0xFFFFFFFF:
|
|
self.add_field('extended_starting_address', u.unpack_one("<Q"))
|
|
if self.length > 0x17:
|
|
self.add_field('extended_ending_address', u.unpack_one("<Q"))
|
|
else:
|
|
u.skip(16)
|
|
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing MemoryArrayMappedAddress")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class MemoryDeviceMappedAddress(SmbiosBaseStructure):
|
|
smbios_structure_type = 20
|
|
|
|
def __init__(self, u, sm):
|
|
super(MemoryDeviceMappedAddress, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0x4:
|
|
self.add_field('starting_address', u.unpack_one("<I"))
|
|
# if FFFF FFFF: address stored in Extended Starting Address
|
|
if self.length > 0x8:
|
|
self.add_field('ending_address', u.unpack_one("<I"))
|
|
if self.length > 0xC:
|
|
self.add_field('memory_device_handle', u.unpack_one("<H"))
|
|
if self.length > 0xE:
|
|
self.add_field('memory_array_mapped_address_handle', u.unpack_one("<H"))
|
|
if self.length > 0x10:
|
|
self.add_field('partition_row_position', u.unpack_one("B"))
|
|
if self.length > 0x11:
|
|
self.add_field('interleave_position', u.unpack_one("B"))
|
|
if self.length > 0x12:
|
|
self.add_field('interleave_data_depth', u.unpack_one("B"))
|
|
if self.length > 0x13:
|
|
# valid if starting_address = FFFF FFFF
|
|
if self.starting_address == 0xFFFFFFFF:
|
|
self.add_field('extended_starting_address', u.unpack_one("<Q"))
|
|
if self.length > 0x1B:
|
|
self.add_field('extended_ending_address', u.unpack_one("<Q"))
|
|
else:
|
|
u.skip(16)
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing MemoryDeviceMappedAddress")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class BuiltInPointingDevice(SmbiosBaseStructure):
|
|
smbios_structure_type = 21
|
|
|
|
def __init__(self, u, sm):
|
|
super(BuiltInPointingDevice, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0x4:
|
|
_pointing_device_types = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'Mouse',
|
|
0x04: 'Track Ball',
|
|
0x05: 'Track Point',
|
|
0x06: 'Glide Point',
|
|
0x07: 'Touch Pad',
|
|
0x08: 'Touch Screen',
|
|
0x09: 'Optical Sensor'
|
|
}
|
|
self.add_field('pointing_device_type', u.unpack_one("B"), unpack.format_table("{}", _pointing_device_types))
|
|
if self.length > 0x5:
|
|
_interfaces = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'Serial',
|
|
0x04: 'PS/2',
|
|
0x05: 'Infared',
|
|
0x06: 'HP-HIL',
|
|
0x07: 'Bus mouse',
|
|
0x08: 'ADB (Apple Desktop Bus)',
|
|
0x09: 'Bus mouse DB-9',
|
|
0x0A: 'Bus mouse micro-DIN',
|
|
0x0B: 'USB'
|
|
}
|
|
self.add_field('interface', u.unpack_one("B"), unpack.format_table("{}", _interfaces))
|
|
if self.length > 0x6:
|
|
self.add_field('num_buttons', u.unpack_one("B"))
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing BuiltInPointingDevice")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class PortableBattery(SmbiosBaseStructure):
|
|
smbios_structure_type = 22
|
|
|
|
def __init__(self, u, sm):
|
|
super(PortableBattery, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0x4:
|
|
self.add_field('location', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x5:
|
|
self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x6:
|
|
self.add_field('manufacturer_date', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x7:
|
|
self.add_field('serial_number', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x8:
|
|
self.add_field('device_name', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x9:
|
|
_device_chemistry = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'Lead Acid',
|
|
0x04: 'Nickel Cadmium',
|
|
0x05: 'Nickel metal hydride',
|
|
0x06: 'Lithium-ion',
|
|
0x07: 'Zinc air',
|
|
0x08: 'Lithium Polymer'
|
|
}
|
|
self.add_field('device_chemistry', u.unpack_one("B"), unpack.format_table("{}", _device_chemistry))
|
|
if self.length > 0xA:
|
|
self.add_field('design_capacity', u.unpack_one("<H"))
|
|
if self.length > 0xC:
|
|
self.add_field('design_voltage', u.unpack_one("<H"))
|
|
if self.length > 0xE:
|
|
self.add_field('sbds_version_number', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0xF:
|
|
self.add_field('max_error_battery_data', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x10:
|
|
if self.serial_number == 0:
|
|
self.add_field('sbds_serial_number', u.unpack_one("<H"))
|
|
else:
|
|
u.skip(2)
|
|
if self.length > 0x12:
|
|
if self.manufacturer_date == 0:
|
|
self.add_field('sbds_manufacture_date', u.unpack_one("<H"))
|
|
self.add_field('year_biased_by_1980', bitfields.getbits(self.sbds_manufacture_date, 15, 9), "sbds_manufacture_date[15:9]={}")
|
|
self.add_field('month', bitfields.getbits(self.sbds_manufacture_date, 8, 5), "sbds_manufacture_date[8:5]={}")
|
|
self.add_field('date', bitfields.getbits(self.sbds_manufacture_date, 4, 0), "sbds_manufacture_date[4:0]={}")
|
|
else:
|
|
u.skip(2)
|
|
if self.length > 0x14:
|
|
if self.device_chemistry == 0x02:
|
|
self.add_field('sbds_device_chemistry', u.unpack_one("B"), self.fmtstr)
|
|
else:
|
|
u.skip(1)
|
|
if self.length > 0x15:
|
|
self.add_field('design_capacity_multiplier', u.unpack_one("B"))
|
|
if self.length > 0x16:
|
|
self.add_field('oem_specific', u.unpack_one("<I"))
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing PortableBattery")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class SystemReset(SmbiosBaseStructure):
|
|
smbios_structure_type = 23
|
|
|
|
def __init__(self, u, sm):
|
|
super(SystemReset, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0x4:
|
|
self.add_field('capabilities', u.unpack_one("B"))
|
|
self.add_field('contains_watchdog_timer', bool(bitfields.getbits(self.capabilities, 5)), "capabilities[5]={}")
|
|
_boot_option = {
|
|
0b00: 'Reserved, do not use',
|
|
0b01: 'Operating System',
|
|
0b10: 'System utilities',
|
|
0b11: 'Do not reboot'
|
|
}
|
|
self.add_field('boot_option_on_limit', bitfields.getbits(self.capabilities, 4, 3), unpack.format_table("capabilities[4:3]={}", _boot_option))
|
|
self.add_field('boot_option_after_watchdog_reset', bitfields.getbits(self.capabilities, 2, 1), unpack.format_table("capabilities[2:1]={}", _boot_option))
|
|
self.add_field('system_reset_enabled_by_user', bool(bitfields.getbits(self.capabilities, 0)), "capabilities[0]={}")
|
|
if self.length > 0x5:
|
|
self.add_field('reset_count', u.unpack_one("<H"))
|
|
if self.length > 0x5:
|
|
self.add_field('reset_limit', u.unpack_one("<H"))
|
|
if self.length > 0x9:
|
|
self.add_field('timer_interval', u.unpack_one("<H"))
|
|
if self.length > 0xB:
|
|
self.add_field('timeout', u.unpack_one("<H"))
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing SystemReset")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class HardwareSecurity(SmbiosBaseStructure):
|
|
smbios_structure_type = 24
|
|
|
|
def __init__(self, u, sm):
|
|
super(HardwareSecurity, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0x4:
|
|
self.add_field('hardware_security_settings', u.unpack_one("B"))
|
|
_status = {
|
|
0x00: 'Disabled',
|
|
0x01: 'Enabled',
|
|
0x02: 'Not Implemented',
|
|
0x03: 'Unknown'
|
|
}
|
|
self.add_field('power_on_password_status', bitfields.getbits(self.hardware_security_settings, 7, 6), unpack.format_table("hardware_security_settings[7:6]={}", _status))
|
|
self.add_field('keyboard_password_status', bitfields.getbits(self.hardware_security_settings, 5, 4), unpack.format_table("hardware_security_settings[5:4]={}", _status))
|
|
self.add_field('admin_password_status', bitfields.getbits(self.hardware_security_settings, 3, 2), unpack.format_table("hardware_security_settings0[3:2]={}", _status))
|
|
self.add_field('front_panel_reset_status', bitfields.getbits(self.hardware_security_settings, 1, 0), unpack.format_table("hardware_security_settings[1:0]={}", _status))
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing HardwareSecurity")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class SystemPowerControls(SmbiosBaseStructure):
|
|
smbios_structure_type = 25
|
|
|
|
def __init__(self, u, sm):
|
|
super(SystemPowerControls, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0x4:
|
|
self.add_field('next_scheduled_poweron_month', u.unpack_one("B"))
|
|
self.add_field('next_scheduled_poweron_day_of_month', u.unpack_one("B"))
|
|
self.add_field('next_scheduled_poweron_hour', u.unpack_one("B"))
|
|
self.add_field('next_scheduled_poweron_minute', u.unpack_one("B"))
|
|
self.add_field('next_scheduled_poweron_second', u.unpack_one("B"))
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing SystemPowerControls")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class VoltageProbe(SmbiosBaseStructure):
|
|
smbios_structure_type = 26
|
|
|
|
def __init__(self, u, sm):
|
|
super(VoltageProbe, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0x4:
|
|
self.add_field('description', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x5:
|
|
self.add_field('location_and_status', u.unpack_one("B"))
|
|
_status = {
|
|
0b001: 'Other',
|
|
0b010: 'Unknown',
|
|
0b011: 'OK',
|
|
0b100: 'Non-critical',
|
|
0b101: 'Critical',
|
|
0b110: 'Non-recoverable'
|
|
}
|
|
_location = {
|
|
0b00001: 'Other',
|
|
0b00010: 'Unknown',
|
|
0b00011: 'Processor',
|
|
0b00100: 'Disk',
|
|
0b00101: 'Peripheral Bay',
|
|
0b00110: 'System Management Module',
|
|
0b00111: 'Motherboard',
|
|
0b01000: 'Memory Module',
|
|
0b01001: 'Processor Module',
|
|
0b01010: 'Power Unit',
|
|
0b01011: 'Add-in Card'
|
|
}
|
|
self.add_field('status', bitfields.getbits(self.location_and_status, 7, 5), unpack.format_table("location_and_status[7:5]={}", _status))
|
|
self.add_field('location', bitfields.getbits(self.location_and_status, 4, 0), unpack.format_table("location_and_status[4:0]={}", _location))
|
|
if self.length > 0x6:
|
|
self.add_field('max_value', u.unpack_one("<H"))
|
|
if self.length > 0x8:
|
|
self.add_field('min_value', u.unpack_one("<H"))
|
|
if self.length > 0xA:
|
|
self.add_field('resolution', u.unpack_one("<H"))
|
|
if self.length > 0xC:
|
|
self.add_field('tolerance', u.unpack_one("<H"))
|
|
if self.length > 0xE:
|
|
self.add_field('accuracy', u.unpack_one("<H"))
|
|
if self.length > 0x10:
|
|
self.add_field('oem_defined', u.unpack_one("<I"))
|
|
if self.length > 0x14:
|
|
self.add_field('nominal_value', u.unpack_one("<H"))
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing VoltageProbe")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class CoolingDevice(SmbiosBaseStructure):
|
|
smbios_structure_type = 27
|
|
|
|
def __init__(self, u, sm):
|
|
super(CoolingDevice, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0x4:
|
|
self.add_field('temperature_probe_handle', u.unpack_one("<H"))
|
|
if self.length > 0x6:
|
|
self.add_field('device_type_and_status', u.unpack_one("B"))
|
|
_status = {
|
|
0b001: 'Other',
|
|
0b010: 'Unknown',
|
|
0b011: 'OK',
|
|
0b100: 'Non-critical',
|
|
0b101: 'Critical',
|
|
0b110: 'Non-recoverable'
|
|
}
|
|
_type = {
|
|
0b00001: 'Other',
|
|
0b00010: 'Unknown',
|
|
0b00011: 'Fan',
|
|
0b00100: 'Centrifugal Blower',
|
|
0b00101: 'Chip Fan',
|
|
0b00110: 'Cabinet Fan',
|
|
0b00111: 'Power Supply Fan',
|
|
0b01000: 'Heat Pipe',
|
|
0b01001: 'Integrated Refrigeration',
|
|
0b10000: 'Active Cooling',
|
|
0b10001: 'Passive Cooling'
|
|
}
|
|
self.add_field('status', bitfields.getbits(self.device_type_and_status, 7, 5), unpack.format_table("device_type_and_status[7:5]={}", _status))
|
|
self.add_field('device_type', bitfields.getbits(self.device_type_and_status, 4, 0), unpack.format_table("device_type_and_status[4:0]={}", _type))
|
|
if self.length > 0x7:
|
|
self.add_field('cooling_unit_group', u.unpack_one("B"))
|
|
if self.length > 0x8:
|
|
self.add_field('OEM_defined', u.unpack_one("<I"))
|
|
if self.length > 0xC:
|
|
self.add_field('nominal_speed', u.unpack_one("<H"))
|
|
if self.length > 0xE:
|
|
self.add_field('description', u.unpack_one("B"), self.fmtstr)
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing CoolingDevice")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class TemperatureProbe(SmbiosBaseStructure):
|
|
smbios_structure_type = 28
|
|
|
|
def __init__(self, u, sm):
|
|
super(TemperatureProbe, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0x4:
|
|
self.add_field('description', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x5:
|
|
self.add_field('location_and_status', u.unpack_one("B"))
|
|
_status = {
|
|
0b001: 'Other',
|
|
0b010: 'Unknown',
|
|
0b011: 'OK',
|
|
0b100: 'Non-critical',
|
|
0b101: 'Critical',
|
|
0b110: 'Non-recoverable'
|
|
}
|
|
_location = {
|
|
0b00001: 'Other',
|
|
0b00010: 'Unknown',
|
|
0b00011: 'Processor',
|
|
0b00100: 'Disk',
|
|
0b00101: 'Peripheral Bay',
|
|
0b00110: 'System Management Module',
|
|
0b00111: 'Motherboard',
|
|
0b01000: 'Memory Module',
|
|
0b01001: 'Processor Module',
|
|
0b01010: 'Power Unit',
|
|
0b01011: 'Add-in Card',
|
|
0b01100: 'Front Panel Board',
|
|
0b01101: 'Back Panel Board',
|
|
0b01110: 'Power System Board',
|
|
0b01111: 'Drive Back Plane'
|
|
}
|
|
self.add_field('status', bitfields.getbits(self.location_and_status, 7, 5), unpack.format_table("location_and_status[7:5]={}", _status))
|
|
self.add_field('location', bitfields.getbits(self.location_and_status, 4, 0), unpack.format_table("location_and_status[4:0]={}", _location))
|
|
if self.length > 0x6:
|
|
self.add_field('maximum_value', u.unpack_one("<H"))
|
|
if self.length > 0x8:
|
|
self.add_field('minimum_value', u.unpack_one("<H"))
|
|
if self.length > 0xA:
|
|
self.add_field('resolution', u.unpack_one("<H"))
|
|
if self.length > 0xC:
|
|
self.add_field('tolerance', u.unpack_one("<H"))
|
|
if self.length > 0xE:
|
|
self.add_field('accuracy', u.unpack_one("<H"))
|
|
if self.length > 0x10:
|
|
self.add_field('OEM_defined', u.unpack_one("<I"))
|
|
if self.length > 0x14:
|
|
self.add_field('nominal_value', u.unpack_one("<H"))
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing TemperatureProbe")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class ElectricalCurrentProbe(SmbiosBaseStructure):
|
|
smbios_structure_type = 29
|
|
|
|
def __init__(self, u, sm):
|
|
super(ElectricalCurrentProbe, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0x4:
|
|
self.add_field('description', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x5:
|
|
self.add_field('location_and_status', u.unpack_one("B"))
|
|
_status = {
|
|
0b001: 'Other',
|
|
0b010: 'Unknown',
|
|
0b011: 'OK',
|
|
0b100: 'Non-critical',
|
|
0b101: 'Critical',
|
|
0b110: 'Non-recoverable'
|
|
}
|
|
_location = {
|
|
0b00001: 'Other',
|
|
0b00010: 'Unknown',
|
|
0b00011: 'Processor',
|
|
0b00100: 'Disk',
|
|
0b00101: 'Peripheral Bay',
|
|
0b00110: 'System Management Module',
|
|
0b00111: 'Motherboard',
|
|
0b01000: 'Memory Module',
|
|
0b01001: 'Processor Module',
|
|
0b01010: 'Power Unit',
|
|
0b01011: 'Add-in Card',
|
|
0b01100: 'Front Panel Board',
|
|
0b01101: 'Back Panel Board',
|
|
0b01110: 'Power System Board',
|
|
0b01111: 'Drive Back Plane'
|
|
}
|
|
self.add_field('status', bitfields.getbits(self.location_and_status, 7, 5), unpack.format_table("location_and_status[7:5]={}", _status))
|
|
self.add_field('location', bitfields.getbits(self.location_and_status, 4, 0), unpack.format_table("location_and_status[4:0]={}", _location))
|
|
if self.length > 0x6:
|
|
self.add_field('maximum_value', u.unpack_one("<H"))
|
|
if self.length > 0x8:
|
|
self.add_field('minimum_value', u.unpack_one("<H"))
|
|
if self.length > 0xA:
|
|
self.add_field('resolution', u.unpack_one("<H"))
|
|
if self.length > 0xC:
|
|
self.add_field('tolerance', u.unpack_one("<H"))
|
|
if self.length > 0xE:
|
|
self.add_field('accuracy', u.unpack_one("<H"))
|
|
if self.length > 0x10:
|
|
self.add_field('OEM_defined', u.unpack_one("<I"))
|
|
if self.length > 0x14:
|
|
self.add_field('nominal_value', u.unpack_one("<H"))
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing ElectricalCurrentProbe")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class OutOfBandRemoteAccess(SmbiosBaseStructure):
|
|
smbios_structure_type = 30
|
|
|
|
def __init__(self, u, sm):
|
|
super(OutOfBandRemoteAccess, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0x4:
|
|
self.add_field('manufacturer_name', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x5:
|
|
self.add_field('connections', u.unpack_one("B"))
|
|
self.add_field('outbound_connection_enabled', bool(bitfields.getbits(self.connections, 1)), "connections[1]={}")
|
|
self.add_field('inbound_connection_enabled', bool(bitfields.getbits(self.connections, 0)), "connections[0]={}")
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing OutOfBandRemoteAccess")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class BootIntegrityServicesEntryPoint(SmbiosBaseStructure):
|
|
smbios_structure_type = 31
|
|
|
|
class SystemBootInformation(SmbiosBaseStructure):
|
|
smbios_structure_type = 32
|
|
|
|
def __init__(self, u, sm):
|
|
super(SystemBootInformation, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0xA:
|
|
u.skip(6)
|
|
_boot_status = {
|
|
0: 'No errors detected',
|
|
1: 'No bootable media',
|
|
2: '"normal" operating system failed to load',
|
|
3: 'Firmware-detected hardware failure, including "unknown" failure types',
|
|
4: 'Operating system-detected hardware failure',
|
|
5: 'User-requested boot, usually through a keystroke',
|
|
6: 'System security violation',
|
|
7: 'Previously-requested image',
|
|
8: 'System watchdog timer expired, causing the system to reboot',
|
|
range(9,127): 'Reserved for future assignment',
|
|
range(128, 191): 'Vendor/OEM-specific implementations',
|
|
range(192, 255): 'Product-specific implementations'
|
|
}
|
|
self.add_field('boot_status', u.unpack_one("B"), unpack.format_table("{}", _boot_status))
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing SystemBootInformation")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class MemoryErrorInfo64Bit(SmbiosBaseStructure):
|
|
smbios_structure_type = 33
|
|
|
|
def __init__(self, u, sm):
|
|
super(MemoryErrorInfo64Bit, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0x4:
|
|
_error_types = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'OK',
|
|
0x04: 'Bad read',
|
|
0x05: 'Parity error',
|
|
0x06: 'Single-bit error',
|
|
0x07: 'Double-bit error',
|
|
0x08: 'Multi-bit error',
|
|
0x09: 'Nibble error',
|
|
0x0A: 'Checksum error',
|
|
0x0B: 'CRC error',
|
|
0x0C: 'Corrected single-bit error',
|
|
0x0D: 'Corrected error',
|
|
0x0E: 'Uncorrectable error'
|
|
}
|
|
self.add_field('error_type', u.unpack_one("B"), unpack.format_table("{}", _error_types))
|
|
if self.length > 0x5:
|
|
_error_granularity_field = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'Device level',
|
|
0x04: 'Memory partition level'
|
|
}
|
|
self.add_field('error_granularity', u.unpack_one("B"), unpack.format_table("{}", _error_granularity_field))
|
|
if self.length > 0x6:
|
|
_error_operation_field = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'Read',
|
|
0x04: 'Write',
|
|
0x05: 'Partial write'
|
|
}
|
|
self.add_field('error_operation', u.unpack_one("B"), unpack.format_table("{}", _error_operation_field))
|
|
if self.length > 0x7:
|
|
self.add_field('vendor_syndrome', u.unpack_one("<I"))
|
|
if self.length > 0xB:
|
|
self.add_field('memory_array_error_address', u.unpack_one("<Q"))
|
|
if self.length > 0xF:
|
|
self.add_field('device_error_address', u.unpack_one("<Q"))
|
|
if self.length > 0x13:
|
|
self.add_field('error_resolution', u.unpack_one("<Q"))
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing MemoryErrorInfo64Bit")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class ManagementDevice(SmbiosBaseStructure):
|
|
smbios_structure_type = 34
|
|
|
|
def __init__(self, u, sm):
|
|
super(ManagementDevice, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0x4:
|
|
self.add_field('description', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x5:
|
|
_type = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'National Semiconductor LM75',
|
|
0x04: 'National Semiconductor LM78',
|
|
0x05: 'National Semiconductor LM79',
|
|
0x06: 'National Semiconductor LM80',
|
|
0x07: 'National Semiconductor LM81',
|
|
0x08: 'Analog Devices ADM9240',
|
|
0x09: 'Dallas Semiconductor DS1780',
|
|
0x0A: 'Maxim 1617',
|
|
0x0B: 'Genesys GL518SM',
|
|
0x0C: 'Winbond W83781D',
|
|
0x0D: 'Holtek HT82H791'
|
|
}
|
|
self.add_field('device_type', u.unpack_one("B"), unpack.format_table("{}", _type))
|
|
if self.length > 0x6:
|
|
self.add_field('address', u.unpack_one("<I"))
|
|
if self.length > 0xA:
|
|
_address_type = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'I/O Port',
|
|
0x04: 'Memory',
|
|
0x05: 'SM Bus'
|
|
}
|
|
self.add_field('address_type', u.unpack_one("B"), unpack.format_table("{}", _address_type))
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing ManagementDevice")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class ManagementDeviceComponent(SmbiosBaseStructure):
|
|
smbios_structure_type = 35
|
|
|
|
def __init__(self, u, sm):
|
|
super(ManagementDeviceComponent, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0x4:
|
|
self.add_field('description', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x5:
|
|
self.add_field('management_device_handle', u.unpack_one("<H"))
|
|
if self.length > 0x7:
|
|
self.add_field('component_handle', u.unpack_one("<H"))
|
|
if self.length > 0x9:
|
|
self.add_field('threshold_handle', u.unpack_one("<H"))
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing ManagementDeviceComponent")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class ManagementDeviceThresholdData(SmbiosBaseStructure):
|
|
smbios_structure_type = 36
|
|
|
|
def __init__(self, u, sm):
|
|
super(ManagementDeviceThresholdData, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0x4:
|
|
self.add_field('lower_threshold_noncritical', u.unpack_one("<H"))
|
|
if self.length > 0x6:
|
|
self.add_field('upper_threshold_noncritical', u.unpack_one("<H"))
|
|
if self.length > 0x8:
|
|
self.add_field('lower_threshold_critical', u.unpack_one("<H"))
|
|
if self.length > 0xA:
|
|
self.add_field('upper_threshold_critical', u.unpack_one("<H"))
|
|
if self.length > 0xC:
|
|
self.add_field('lower_threshold_nonrecoverable', u.unpack_one("<H"))
|
|
if self.length > 0xE:
|
|
self.add_field('upper_threshold_nonrecoverable', u.unpack_one("<H"))
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing ManagementDeviceThresholdData")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class MemoryChannel(SmbiosBaseStructure):
|
|
smbios_structure_type = 37
|
|
|
|
def __init__(self, u, sm):
|
|
super(MemoryChannel, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0x4:
|
|
_channel_type = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'RamBus',
|
|
0x04: 'SyncLink'
|
|
}
|
|
self.add_field('channel_type', u.unpack_one("B"), unpack.format_table("{}", _channel_type))
|
|
if self.length > 0x6:
|
|
self.add_field('max_channel_load', u.unpack_one("B"))
|
|
if self.length > 0x8:
|
|
self.add_field('memory_device_count', u.unpack_one("B"))
|
|
if self.length > 0xA:
|
|
self.add_field('memory_device_load', u.unpack_one("B"))
|
|
if self.length > 0xC:
|
|
self.add_field('memory_device_handle', u.unpack_one("<H"))
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing MemoryChannel")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class IPMIDeviceInformation(SmbiosBaseStructure):
|
|
smbios_structure_type = 38
|
|
|
|
def __init__(self, u, sm):
|
|
super(IPMIDeviceInformation, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
_interface_type = {
|
|
0x00: 'Unknown',
|
|
0x01: 'KCS: Keyboard Controller Style',
|
|
0x02: 'SMIC: Server Management Interface Chip',
|
|
0x03: 'BT: Block Transfer',
|
|
range(0x04, 0xFF): 'Reserved'
|
|
}
|
|
self.add_field('interface_type', u.unpack_one("B"), unpack.format_table("{}", _interface_type))
|
|
self.add_field('ipmi_specification_revision', u.unpack_one("B"))
|
|
self.add_field('msd_revision', bitfields.getbits(self.ipmi_specification_revision, 7, 4), "ipmi_specification_revision[7:4]={}")
|
|
self.add_field('lsd_revision', bitfields.getbits(self.ipmi_specification_revision, 3, 0), "ipmi_specification_revision[3:0]={}")
|
|
|
|
self.add_field('i2c_slave_address', u.unpack_one("B"))
|
|
self.add_field('nv_storage_device_address', u.unpack_one("B"))
|
|
self.add_field('base_address', u.unpack_one("<Q"))
|
|
# if lsb is 1, address is in IO space. otherwise, memory-mapped
|
|
self.add_field('base_address_modifier_interrupt_info', u.unpack_one("B"))
|
|
_reg_spacing = {
|
|
0b00: 'Interface registers are on successive byte boundaries',
|
|
0b01: 'Interface registers are on 32-bit boundaries',
|
|
0b10: 'Interface registers are on 16-byte boundaries',
|
|
0b11: 'Reserved'
|
|
}
|
|
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))
|
|
self.add_field('ls_bit_for_addresses', bitfields.getbits(self.base_address_modifier_interrupt_info, 4), "base_address_modifier_interrupt_info[4]={}")
|
|
self.add_field('interrupt_info_specified', bool(bitfields.getbits(self.base_address_modifier_interrupt_info, 3)), "base_address_modifier_interrupt_info[3]={}")
|
|
_polarity = {
|
|
0: 'active low',
|
|
1: 'active high'
|
|
}
|
|
self.add_field('interrupt_polarity', bitfields.getbits(self.base_address_modifier_interrupt_info, 1), unpack.format_table("base_address_modifier_interrupt_info[1]={}", _polarity))
|
|
_interrupt_trigger = {
|
|
0: 'edge',
|
|
1: 'level'
|
|
}
|
|
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))
|
|
self.add_field('interrupt_number', u.unpack_one("B"))
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing IPMIDeviceInformation")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class SystemPowerSupply(SmbiosBaseStructure):
|
|
smbios_structure_type = 39
|
|
|
|
def __init__(self, u, sm):
|
|
super(SystemPowerSupply, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0x4:
|
|
self.add_field('power_unit_group', u.unpack_one("B"))
|
|
if self.length > 0x5:
|
|
self.add_field('location', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x6:
|
|
self.add_field('device_name', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x7:
|
|
self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x8:
|
|
self.add_field('serial_number', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x9:
|
|
self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0xA:
|
|
self.add_field('model_part_number', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0xB:
|
|
self.add_field('revision_level', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0xC:
|
|
self.add_field('max_power_capacity', u.unpack_one("<H"))
|
|
if self.length > 0xE:
|
|
self.add_field('power_supply_characteristics', u.unpack_one("<H"))
|
|
_dmtf_power_supply_type = {
|
|
0b001: 'Other',
|
|
0b010: 'Unknown',
|
|
0b011: 'Linear',
|
|
0b100: 'Switching',
|
|
0b101: 'Battery',
|
|
0b110: 'UPS',
|
|
0b111: 'Converter',
|
|
0b1000: 'Regulator',
|
|
range(0b1001, 0b1111): 'Reserved'
|
|
}
|
|
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))
|
|
_status = {
|
|
0b001: 'Other',
|
|
0b010: 'Unknown',
|
|
0b011: 'OK',
|
|
0b100: 'Non-critical',
|
|
0b101: 'Critical; power supply has failed and has been taken off-line'
|
|
}
|
|
self.add_field('status', bitfields.getbits(self.power_supply_characteristics, 9, 7), unpack.format_table("power_supply_characteristics[9:7]={}", _status))
|
|
_dmtf_input_voltage_range_switching = {
|
|
0b001: 'Other',
|
|
0b010: 'Unknown',
|
|
0b011: 'Manual',
|
|
0b100: 'Auto-switch',
|
|
0b101: 'Wide range',
|
|
0b110: 'Not applicable',
|
|
range(0b0111, 0b1111): 'Reserved'
|
|
}
|
|
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))
|
|
self.add_field('power_supply_unplugged', bool(bitfields.getbits(self.power_supply_characteristics, 2)), "power_supply_characteristics[2]={}")
|
|
self.add_field('power_supply_present', bool(bitfields.getbits(self.power_supply_characteristics, 1)), "power_supply_characteristics[1]={}")
|
|
self.add_field('power_supply_hot_replaceable', bool(bitfields.getbits(self.power_supply_characteristics, 0)), "power_supply_characteristics[0]={}")
|
|
if self.length > 0x10:
|
|
self.add_field('input_voltage_probe_handle', u.unpack_one("<H"))
|
|
if self.length > 0x12:
|
|
self.add_field('cooling_device_handle', u.unpack_one("<H"))
|
|
if self.length > 0x14:
|
|
self.add_field('input_current_probe_handle', u.unpack_one("<H"))
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing SystemPowerSupply")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class AdditionalInformation(SmbiosBaseStructure):
|
|
smbios_structure_type = 40
|
|
|
|
def __init__(self, u, sm):
|
|
super(AdditionalInformation, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0x4:
|
|
self.add_field('num_additional_information_entries', u.unpack_one("B"))
|
|
if self.length > 0x5:
|
|
self.add_field('additional_information_entry_length', u.unpack_one("B"))
|
|
self.add_field('referenced_handle', u.unpack_one("<H"))
|
|
self.add_field('referenced_offset', u.unpack_one("B"))
|
|
self.add_field('string', u.unpack_one("B"), self.fmtstr)
|
|
self.add_field('value', u.unpack_rest())
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing AdditionalInformation")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class OnboardDevicesExtendedInformation(SmbiosBaseStructure):
|
|
smbios_structure_type = 41
|
|
|
|
def __init__(self, u, sm):
|
|
super(OnboardDevicesExtendedInformation, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0x4:
|
|
self.add_field('reference_designation', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0x5:
|
|
self.add_field('device_type', u.unpack_one("B"))
|
|
self.add_field('device_enabled', bool(bitfields.getbits(self.device_type, 7)), "device_type[7]={}")
|
|
_device_types = {
|
|
0x01: 'Other',
|
|
0x02: 'Unknown',
|
|
0x03: 'Video',
|
|
0x04: 'SCSI Controller',
|
|
0x05: 'Ethernet',
|
|
0x06: 'Token Ring',
|
|
0x07: 'Sound',
|
|
0x08: 'PATA Controller',
|
|
0x09: 'SATA Controller',
|
|
0x0A: 'SAS Controller'
|
|
}
|
|
self.add_field('type_of_device', bitfields.getbits(self.device_type, 6, 0), unpack.format_table("device_type[6:0]={}", _device_types))
|
|
if self.length > 0x6:
|
|
self.add_field('device_type_instance', u.unpack_one("B"))
|
|
if self.length > 0x7:
|
|
self.add_field('segment_group_number', u.unpack_one("<H"))
|
|
if self.length > 0x9:
|
|
self.add_field('bus_number', u.unpack_one("B"), self.fmtstr)
|
|
if self.length > 0xA:
|
|
self.add_field('device_and_function_number', u.unpack_one("B"))
|
|
self.add_field('device_number', bitfields.getbits(self.device_type, 7, 3), "device_and_function_number[7:3]={}")
|
|
self.add_field('function_number', bitfields.getbits(self.device_type, 2, 0), "device_and_function_number[2:0]={}")
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing OnboardDevicesExtendedInformation")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class ManagementControllerHostInterface(SmbiosBaseStructure):
|
|
smbios_structure_type = 42
|
|
|
|
def __init__(self, u, sm):
|
|
super(ManagementControllerHostInterface, self).__init__(u, sm)
|
|
u = self.u
|
|
try:
|
|
if self.length > 0x4:
|
|
_interface_types = {
|
|
0x00: 'Reserved',
|
|
0x01: 'Reserved',
|
|
0x02: 'KCS: Keyboard Controller Style',
|
|
0x03: '8250 UART Register Compatible',
|
|
0x04: '16450 UART Register Compatible',
|
|
0x05: '16550/16550A UART Register Compatible',
|
|
0x06: '16650/16650A UART Register Compatible',
|
|
0x07: '16750/16750A UART Register Compatible',
|
|
0x08: '16850/16850A UART Register Compatible',
|
|
0xF0: 'OEM'
|
|
}
|
|
self.add_field('interface_type', u.unpack_one("B"), unpack.format_table("{}", _interface_types))
|
|
if self.length > 0x5:
|
|
self.add_field('mc_host_interface_data', u.unpack_rest(), self.fmtstr)
|
|
except:
|
|
self.decodeFailure = True
|
|
logging.debug("Error parsing ManagementControllerHostInterface")
|
|
import traceback
|
|
traceback.print_exc()
|
|
self.fini()
|
|
|
|
class Inactive(SmbiosBaseStructure):
|
|
smbios_structure_type = 126
|
|
|
|
def __init__(self, u, sm):
|
|
super(Inactive, self).__init__(u, sm)
|
|
self.fini()
|
|
|
|
class EndOfTable(SmbiosBaseStructure):
|
|
smbios_structure_type = 127
|
|
|
|
def __init__(self, u, sm):
|
|
super(EndOfTable, self).__init__(u, sm)
|
|
self.fini()
|
|
|
|
class SmbiosStructureUnknown(SmbiosBaseStructure):
|
|
smbios_structure_type = None
|
|
|
|
def __init__(self, u, sm):
|
|
super(SmbiosStructureUnknown, self).__init__(u, sm)
|
|
self.fini()
|
|
|
|
_smbios_structures = [
|
|
BIOSInformation,
|
|
SystemInformation,
|
|
BaseboardInformation,
|
|
SystemEnclosure,
|
|
ProcessorInformation,
|
|
MemoryControllerInformation,
|
|
MemoryModuleInformation,
|
|
CacheInformation,
|
|
PortConnectorInfo,
|
|
SystemSlots,
|
|
OnBoardDevicesInformation,
|
|
OEMStrings,
|
|
SystemConfigOptions,
|
|
BIOSLanguageInformation,
|
|
GroupAssociations,
|
|
SystemEventLog,
|
|
PhysicalMemoryArray,
|
|
MemoryDevice,
|
|
MemoryErrorInfo32Bit,
|
|
MemoryArrayMappedAddress,
|
|
MemoryDeviceMappedAddress,
|
|
BuiltInPointingDevice,
|
|
PortableBattery,
|
|
SystemReset,
|
|
HardwareSecurity,
|
|
SystemPowerControls,
|
|
VoltageProbe,
|
|
CoolingDevice,
|
|
TemperatureProbe,
|
|
ElectricalCurrentProbe,
|
|
OutOfBandRemoteAccess,
|
|
BootIntegrityServicesEntryPoint,
|
|
SystemBootInformation,
|
|
MemoryErrorInfo64Bit,
|
|
ManagementDevice,
|
|
ManagementDeviceComponent,
|
|
ManagementDeviceThresholdData,
|
|
MemoryChannel,
|
|
IPMIDeviceInformation,
|
|
SystemPowerSupply,
|
|
AdditionalInformation,
|
|
OnboardDevicesExtendedInformation,
|
|
ManagementControllerHostInterface,
|
|
Inactive,
|
|
EndOfTable,
|
|
SmbiosStructureUnknown, # Must always come last
|
|
]
|