1# Copyright (c) 2015, Intel Corporation 2# All rights reserved. 3# 4# Redistribution and use in source and binary forms, with or without 5# modification, are permitted provided that the following conditions are met: 6# 7# * Redistributions of source code must retain the above copyright notice, 8# this list of conditions and the following disclaimer. 9# * Redistributions in binary form must reproduce the above copyright notice, 10# this list of conditions and the following disclaimer in the documentation 11# and/or other materials provided with the distribution. 12# * Neither the name of Intel Corporation nor the names of its contributors 13# may be used to endorse or promote products derived from this software 14# without specific prior written permission. 15# 16# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 20# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 23# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 27"""SMBIOS/DMI module.""" 28 29import bits 30import bitfields 31import ctypes 32import redirect 33import struct 34import uuid 35import unpack 36import ttypager 37import sys 38 39class SMBIOS(unpack.Struct): 40 def __new__(cls): 41 if sys.platform == "BITS-EFI": 42 import efi 43 sm_ptr = efi.system_table.ConfigurationTableDict.get(efi.SMBIOS_TABLE_GUID) 44 else: 45 address = 0xF0000 46 mem = bits.memory(0xF0000, 0x10000) 47 for offset in range(0, len(mem), 16): 48 signature = (ctypes.c_char * 4).from_address(address + offset).value 49 if signature == "_SM_": 50 entry_point_length = ctypes.c_ubyte.from_address(address + offset + 5).value 51 csum = sum(map(ord, mem[offset:offset + entry_point_length])) & 0xff 52 if csum == 0: 53 sm_ptr = address + offset 54 break 55 else: 56 return None 57 58 if not sm_ptr: 59 return None 60 61 sm = super(SMBIOS, cls).__new__(cls) 62 sm._header_memory = bits.memory(sm_ptr, 0x1f) 63 return sm 64 65 def __init__(self): 66 super(SMBIOS, self).__init__() 67 u = unpack.Unpackable(self._header_memory) 68 self.add_field('header', Header(u)) 69 self._structure_memory = bits.memory(self.header.structure_table_address, self.header.structure_table_length) 70 u = unpack.Unpackable(self._structure_memory) 71 self.add_field('structures', unpack.unpack_all(u, _smbios_structures, self), unpack.format_each("\n\n{!r}")) 72 73 def structure_type(self, num): 74 '''Dumps structure of given Type if present''' 75 try: 76 types_present = [self.structures[x].smbios_structure_type for x in range(len(self.structures))] 77 matrix = dict() 78 for index in range(len(types_present)): 79 if types_present.count(types_present[index]) == 1: 80 matrix[types_present[index]] = self.structures[index] 81 else: # if multiple structures of the same type, return a list of structures for the type number 82 if matrix.has_key(types_present[index]): 83 matrix[types_present[index]].append(self.structures[index]) 84 else: 85 matrix[types_present[index]] = [self.structures[index]] 86 return matrix[num] 87 except: 88 print "Failure: Type {} - not found".format(num) 89 90class Header(unpack.Struct): 91 def __new__(cls, u): 92 return super(Header, cls).__new__(cls) 93 94 def __init__(self, u): 95 super(Header, self).__init__() 96 self.raw_data = u.unpack_rest() 97 u = unpack.Unpackable(self.raw_data) 98 self.add_field('anchor_string', u.unpack_one("4s")) 99 self.add_field('checksum', u.unpack_one("B")) 100 self.add_field('length', u.unpack_one("B")) 101 self.add_field('major_version', u.unpack_one("B")) 102 self.add_field('minor_version', u.unpack_one("B")) 103 self.add_field('max_structure_size', u.unpack_one("<H")) 104 self.add_field('entry_point_revision', u.unpack_one("B")) 105 self.add_field('formatted_area', u.unpack_one("5s")) 106 self.add_field('intermediate_anchor_string', u.unpack_one("5s")) 107 self.add_field('intermediate_checksum', u.unpack_one("B")) 108 self.add_field('structure_table_length', u.unpack_one("<H")) 109 self.add_field('structure_table_address', u.unpack_one("<I")) 110 self.add_field('number_structures', u.unpack_one("<H")) 111 self.add_field('bcd_revision', u.unpack_one("B")) 112 if not u.at_end(): 113 self.add_field('data', u.unpack_rest()) 114 115class SmbiosBaseStructure(unpack.Struct): 116 def __new__(cls, u, sm): 117 t = u.unpack_peek_one("B") 118 if cls.smbios_structure_type is not None and t != cls.smbios_structure_type: 119 return None 120 return super(SmbiosBaseStructure, cls).__new__(cls) 121 122 def __init__(self, u, sm): 123 super(SmbiosBaseStructure, self).__init__() 124 self.start_offset = u.offset 125 length = u.unpack_peek_one("<xB") 126 self.raw_data = u.unpack_raw(length) 127 self.u = unpack.Unpackable(self.raw_data) 128 129 self.strings_offset = u.offset 130 def unpack_string(): 131 return "".join(iter(lambda: u.unpack_one("c"), "\x00")) 132 strings = list(iter(unpack_string, "")) 133 if not strings: 134 u.skip(1) 135 136 self.strings_length = u.offset - self.strings_offset 137 self.raw_strings = str(bits.memory(sm.header.structure_table_address + self.strings_offset, self.strings_length)) 138 139 if len(strings): 140 self.strings = strings 141 142 self.add_field('type', self.u.unpack_one("B")) 143 self.add_field('length', self.u.unpack_one("B")) 144 self.add_field('handle', self.u.unpack_one("<H")) 145 146 def fini(self): 147 if not self.u.at_end(): 148 self.add_field('data', self.u.unpack_rest()) 149 del self.u 150 151 def fmtstr(self, i): 152 """Format the specified index and the associated string""" 153 return "{} '{}'".format(i, self.getstr(i)) 154 155 def getstr(self, i): 156 """Get the string associated with the given index""" 157 if i == 0: 158 return "(none)" 159 if not hasattr(self, "strings"): 160 return "(error: structure has no strings)" 161 if i > len(self.strings): 162 return "(error: string index out of range)" 163 return self.strings[i - 1] 164 165class BIOSInformation(SmbiosBaseStructure): 166 smbios_structure_type = 0 167 168 def __init__(self, u, sm): 169 super(BIOSInformation, self).__init__(u, sm) 170 u = self.u 171 try: 172 self.add_field('vendor', u.unpack_one("B"), self.fmtstr) 173 self.add_field('version', u.unpack_one("B"), self.fmtstr) 174 self.add_field('starting_address_segment', u.unpack_one("<H")) 175 self.add_field('release_date', u.unpack_one("B"), self.fmtstr) 176 self.add_field('rom_size', u.unpack_one("B")) 177 self.add_field('characteristics', u.unpack_one("<Q")) 178 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 179 if (sm.header.major_version, minor_version_str) >= (2,"4"): 180 characteristic_bytes = 2 181 else: 182 characteristic_bytes = self.length - 0x12 183 self.add_field('characteristics_extensions', [u.unpack_one("B") for b in range(characteristic_bytes)]) 184 if (sm.header.major_version, minor_version_str) >= (2,"4"): 185 self.add_field('major_release', u.unpack_one("B")) 186 self.add_field('minor_release', u.unpack_one("B")) 187 self.add_field('ec_major_release', u.unpack_one("B")) 188 self.add_field('ec_minor_release', u.unpack_one("B")) 189 except: 190 self.decode_failure = True 191 print "Error parsing BIOSInformation" 192 import traceback 193 traceback.print_exc() 194 self.fini() 195 196class SystemInformation(SmbiosBaseStructure): 197 smbios_structure_type = 1 198 199 def __init__(self, u, sm): 200 super(SystemInformation, self).__init__(u, sm) 201 u = self.u 202 try: 203 self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr) 204 self.add_field('product_name', u.unpack_one("B"), self.fmtstr) 205 self.add_field('version', u.unpack_one("B"), self.fmtstr) 206 self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) 207 if self.length > 0x8: 208 self.add_field('uuid', uuid.UUID(bytes_le=u.unpack_one("16s"))) 209 wakeup_types = { 210 0: 'Reserved', 211 1: 'Other', 212 2: 'Unknown', 213 3: 'APM Timer', 214 4: 'Modem Ring', 215 5: 'LAN Remote', 216 6: 'Power Switch', 217 7: 'PCI PME#', 218 8: 'AC Power Restored' 219 } 220 self.add_field('wakeup_type', u.unpack_one("B"), unpack.format_table("{}", wakeup_types)) 221 if self.length > 0x19: 222 self.add_field('sku_number', u.unpack_one("B"), self.fmtstr) 223 self.add_field('family', u.unpack_one("B"), self.fmtstr) 224 except: 225 self.decode_failure = True 226 print "Error parsing SystemInformation" 227 import traceback 228 traceback.print_exc() 229 self.fini() 230 231_board_types = { 232 1: 'Unknown', 233 2: 'Other', 234 3: 'Server Blade', 235 4: 'Connectivity Switch', 236 5: 'System Management Module', 237 6: 'Processor Module', 238 7: 'I/O Module', 239 8: 'Memory Module', 240 9: 'Daughter Board', 241 0xA: 'Motherboard', 242 0xB: 'Processor/Memory Module', 243 0xC: 'Processor/IO Module', 244 0xD: 'Interconnect Board' 245} 246 247class BaseboardInformation(SmbiosBaseStructure): 248 smbios_structure_type = 2 249 250 def __init__(self, u, sm): 251 super(BaseboardInformation, self).__init__(u, sm) 252 u = self.u 253 try: 254 self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr) 255 self.add_field('product', u.unpack_one("B"), self.fmtstr) 256 self.add_field('version', u.unpack_one("B"), self.fmtstr) 257 self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) 258 259 if self.length > 0x8: 260 self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr) 261 262 if self.length > 0x9: 263 self.add_field('feature_flags', u.unpack_one("B")) 264 self.add_field('hosting_board', bool(bitfields.getbits(self.feature_flags, 0)), "feature_flags[0]={}") 265 self.add_field('requires_daughter_card', bool(bitfields.getbits(self.feature_flags, 1)), "feature_flags[1]={}") 266 self.add_field('removable', bool(bitfields.getbits(self.feature_flags, 2)), "feature_flags[2]={}") 267 self.add_field('replaceable', bool(bitfields.getbits(self.feature_flags, 3)), "feature_flags[3]={}") 268 self.add_field('hot_swappable', bool(bitfields.getbits(self.feature_flags, 4)), "feature_flags[4]={}") 269 270 if self.length > 0xA: 271 self.add_field('location', u.unpack_one("B"), self.fmtstr) 272 273 if self.length > 0xB: 274 self.add_field('chassis_handle', u.unpack_one("<H")) 275 276 if self.length > 0xD: 277 self.add_field('board_type', u.unpack_one("B"), unpack.format_table("{}", _board_types)) 278 279 if self.length > 0xE: 280 self.add_field('handle_count', u.unpack_one("B")) 281 if self.handle_count > 0: 282 self.add_field('contained_object_handles', tuple(u.unpack_one("<H") for i in range(self.handle_count))) 283 except: 284 self.decode_failure = True 285 print "Error parsing BaseboardInformation" 286 import traceback 287 traceback.print_exc() 288 self.fini() 289 290class SystemEnclosure(SmbiosBaseStructure): 291 smbios_structure_type = 3 292 293 def __init__(self, u, sm): 294 super(SystemEnclosure, self).__init__(u, sm) 295 u = self.u 296 try: 297 self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr) 298 self.add_field('enumerated_type', u.unpack_one("B")) 299 self.add_field('chassis_lock_present', bool(bitfields.getbits(self.enumerated_type, 7)), "enumerated_type[7]={}") 300 board_types = { 301 0x01: 'Other', 302 0x02: 'Unknown', 303 0x03: 'Desktop', 304 0x04: 'Low Profile Desktop', 305 0x05: 'Pizza Box', 306 0x06: 'Mini Tower', 307 0x07: 'Tower', 308 0x08: 'Portable', 309 0x09: 'Laptop', 310 0x0A: 'Notebook', 311 0x0B: 'Hand Held', 312 0x0C: 'Docking Station', 313 0x0D: 'All in One', 314 0x0E: 'Sub Notebook', 315 0x0F: 'Space-saving', 316 0x10: 'Lunch Box', 317 0x11: 'Main Server Chassis', 318 0x12: 'Expansion Chassis', 319 0x13: 'SubChassis', 320 0x14: 'Bus Expansion Chassis', 321 0x15: 'Peripheral Chassis', 322 0x16: 'RAID Chassis', 323 0x17: 'Rack Mount Chassis', 324 0x18: 'Sealed-case PC', 325 0x19: 'Multi-system chassis W', 326 0x1A: 'Compact PCI', 327 0x1B: 'Advanced TCA', 328 0x1C: 'Blade', 329 0x1D: 'Blade Enclosure', 330 } 331 self.add_field('system_enclosure_type', bitfields.getbits(self.enumerated_type, 6, 0), unpack.format_table("enumerated_type[6:0]={}", board_types)) 332 self.add_field('version', u.unpack_one("B"), self.fmtstr) 333 self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) 334 self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr) 335 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 336 if self.length > 9: 337 chassis_states = { 338 0x01: 'Other', 339 0x02: 'Unknown', 340 0x03: 'Safe', 341 0x04: 'Warning', 342 0x05: 'Critical', 343 0x06: 'Non-recoverable', 344 } 345 self.add_field('bootup_state', u.unpack_one("B"), unpack.format_table("{}", chassis_states)) 346 self.add_field('power_supply_state', u.unpack_one("B"), unpack.format_table("{}", chassis_states)) 347 self.add_field('thermal_state', u.unpack_one("B"), unpack.format_table("{}", chassis_states)) 348 security_states = { 349 0x01: 'Other', 350 0x02: 'Unknown', 351 0x03: 'None', 352 0x04: 'External interface locked out', 353 0x05: 'External interface enabled', 354 } 355 self.add_field('security_status', u.unpack_one("B"), unpack.format_table("{}", security_states)) 356 if self.length > 0xd: 357 self.add_field('oem_defined', u.unpack_one("<I")) 358 if self.length > 0x11: 359 self.add_field('height', u.unpack_one("B")) 360 self.add_field('num_power_cords', u.unpack_one("B")) 361 self.add_field('contained_element_count', u.unpack_one("B")) 362 self.add_field('contained_element_length', u.unpack_one("B")) 363 if getattr(self, 'contained_element_count', 0): 364 self.add_field('contained_elements', tuple(SystemEnclosureContainedElement(u, self.contained_element_length) for i in range(self.contained_element_count))) 365 if self.length > (0x15 + (getattr(self, 'contained_element_count', 0) * getattr(self, 'contained_element_length', 0))): 366 self.add_field('sku_number', u.unpack_one("B"), self.fmtstr) 367 except: 368 self.decode_failure = True 369 print "Error parsing SystemEnclosure" 370 import traceback 371 traceback.print_exc() 372 self.fini() 373 374class SystemEnclosureContainedElement(unpack.Struct): 375 def __init__(self, u, length): 376 super(SystemEnclosureContainedElement, self).__init__() 377 self.start_offset = u.offset 378 self.raw_data = u.unpack_raw(length) 379 self.u = unpack.Unpackable(self.raw_data) 380 u = self.u 381 self.add_field('contained_element_type', u.unpack_one("B")) 382 type_selections = { 383 0: 'SMBIOS baseboard type enumeration', 384 1: 'SMBIOS structure type enumeration', 385 } 386 self.add_field('type_select', bitfields.getbits(self.contained_element_type, 7), unpack.format_table("contained_element_type[7]={}", type_selections)) 387 self.add_field('type', bitfields.getbits(self.contained_element_type, 6, 0)) 388 if self.type_select == 0: 389 self.add_field('smbios_board_type', self.type, unpack.format_table("{}", _board_types)) 390 else: 391 self.add_field('smbios_structure_type', self.type) 392 self.add_field('minimum', u.unpack_one("B")) 393 self.add_field('maximum', u.unpack_one("B")) 394 if not u.at_end(): 395 self.add_field('data', u.unpack_rest()) 396 del self.u 397 398class ProcessorInformation(SmbiosBaseStructure): 399 smbios_structure_type = 4 400 401 def __init__(self, u, sm): 402 super(ProcessorInformation, self).__init__(u, sm) 403 u = self.u 404 try: 405 self.add_field('socket_designation', u.unpack_one("B"), self.fmtstr) 406 processor_types = { 407 0x01: 'Other', 408 0x02: 'Unknown', 409 0x03: 'Central Processor', 410 0x04: 'Math Processor', 411 0x05: 'DSP Processor', 412 0x06: 'Video Processor', 413 } 414 self.add_field('processor_type', u.unpack_one("B"), unpack.format_table("{}", processor_types)) 415 self.add_field('processor_family', u.unpack_one("B")) 416 self.add_field('processor_manufacturer', u.unpack_one("B"), self.fmtstr) 417 self.add_field('processor_id', u.unpack_one("<Q")) 418 self.add_field('processor_version', u.unpack_one("B"), self.fmtstr) 419 self.add_field('voltage', u.unpack_one("B")) 420 self.add_field('external_clock', u.unpack_one("<H")) 421 self.add_field('max_speed', u.unpack_one("<H")) 422 self.add_field('current_speed', u.unpack_one("<H")) 423 self.add_field('status', u.unpack_one("B")) 424 processor_upgrades = { 425 0x01: 'Other', 426 0x02: 'Unknown', 427 0x03: 'Daughter Board', 428 0x04: 'ZIF Socket', 429 0x05: 'Replaceable Piggy Back', 430 0x06: 'None', 431 0x07: 'LIF Socket', 432 0x08: 'Slot 1', 433 0x09: 'Slot 2', 434 0x0A: '370-pin socket', 435 0x0B: 'Slot A', 436 0x0C: 'Slot M', 437 0x0D: 'Socket 423', 438 0x0E: 'Socket A (Socket 462)', 439 0x0F: 'Socket 478', 440 0x10: 'Socket 754', 441 0x11: 'Socket 940', 442 0x12: 'Socket 939', 443 0x13: 'Socket mPGA604', 444 0x14: 'Socket LGA771', 445 0x15: 'Socket LGA775', 446 0x16: 'Socket S1', 447 0x17: 'Socket AM2', 448 0x18: 'Socket F (1207)', 449 0x19: 'Socket LGA1366', 450 0x1A: 'Socket G34', 451 0x1B: 'Socket AM3', 452 0x1C: 'Socket C32', 453 0x1D: 'Socket LGA1156', 454 0x1E: 'Socket LGA1567', 455 0x1F: 'Socket PGA988A', 456 0x20: 'Socket BGA1288', 457 0x21: 'Socket rPGA988B', 458 0x22: 'Socket BGA1023', 459 0x23: 'Socket BGA1224', 460 0x24: 'Socket BGA1155', 461 0x25: 'Socket LGA1356', 462 0x26: 'Socket LGA2011', 463 0x27: 'Socket FS1', 464 0x28: 'Socket FS2', 465 0x29: 'Socket FM1', 466 0x2A: 'Socket FM2', 467 } 468 self.add_field('processor_upgrade', u.unpack_one("B"), unpack.format_table("{}", processor_upgrades)) 469 if self.length > 0x1A: 470 self.add_field('l1_cache_handle', u.unpack_one("<H")) 471 self.add_field('l2_cache_handle', u.unpack_one("<H")) 472 self.add_field('l3_cache_handle', u.unpack_one("<H")) 473 if self.length > 0x20: 474 self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) 475 self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr) 476 self.add_field('part_number', u.unpack_one("B"), self.fmtstr) 477 if self.length > 0x24: 478 self.add_field('core_count', u.unpack_one("B")) 479 self.add_field('core_enabled', u.unpack_one("B")) 480 self.add_field('thread_count', u.unpack_one("B")) 481 self.add_field('processor_characteristics', u.unpack_one("<H")) 482 if self.length > 0x28: 483 self.add_field('processor_family_2', u.unpack_one("<H")) 484 if self.length > 0x2A: 485 self.add_field('core_count2', u.unpack_one("<H")) 486 self.add_field('core_enabled2', u.unpack_one("<H")) 487 self.add_field('thread_count2', u.unpack_one("<H")) 488 except: 489 self.decode_failure = True 490 print "Error parsing Processor Information" 491 import traceback 492 traceback.print_exc() 493 self.fini() 494 495class MemoryControllerInformation(SmbiosBaseStructure): #obsolete starting with v2.1 496 smbios_structure_type = 5 497 498 def __init__(self, u, sm): 499 super(MemoryControllerInformation, self).__init__(u, sm) 500 u = self.u 501 try: 502 _error_detecting_method = { 503 0x01: 'Other', 504 0x02: 'Unknown', 505 0x03: 'None', 506 0x04: '8-bit Parity', 507 0x05: '32-bit ECC', 508 0x06: '64-bit ECC', 509 0x07: '128-bit ECC', 510 0x08: 'CRC' 511 } 512 self.add_field('error_detecting_method', u.unpack_one("B"), unpack.format_table("{}", _error_detecting_method)) 513 self.add_field('error_correcting_capability', u.unpack_one("B")) 514 _interleaves = { 515 0x01: 'Other', 516 0x02: 'Unknown', 517 0x03: 'One-Way Interleave', 518 0x04: 'Two-Way Interleave', 519 0x05: 'Four-Way Interleave', 520 0x06: 'Eight-Way Interleave', 521 0x07: 'Sixteen-Way Interleave' 522 } 523 self.add_field('supported_interleave', u.unpack_one("B"), unpack.format_table("{}", _interleaves)) 524 self.add_field('current_interleave', u.unpack_one("B"), unpack.format_table("{}", _interleaves)) 525 self.add_field('max_memory_module_size', u.unpack_one("B"), self.fmtstr) 526 self.add_field('supported_speeds', u.unpack_one("<H")) 527 self.add_field('supported_memory_types', u.unpack_one("<H")) 528 self.add_field('memory_module_voltage', u.unpack_one("B")) 529 self.add_field('req_voltage_b2', bitfields.getbits(self.memory_module_voltage, 2), "memory_module_voltage[2]={}") 530 self.add_field('req_voltage_b1', bitfields.getbits(self.memory_module_voltage, 1), "memory_module_voltage[1]={}") 531 self.add_field('req_voltage_b0', bitfields.getbits(self.memory_module_voltage, 0), "memory_module_voltage[0]={}") 532 self.add_field('num_associated_memory_slots', u.unpack_one("B")) 533 self.add_field('memory_module_configuration_handles', u.unpack_one("<(self.num_associated_memory_slots)H")) 534 self.add_field('enabled_error_correcting_capabilities', u.unpack_one("B")) 535 except: 536 self.decode_failure = True 537 print "Error parsing MemoryControllerInformation" 538 import traceback 539 traceback.print_exc() 540 self.fini() 541 542class MemoryModuleInformation(SmbiosBaseStructure): #obsolete starting with v2.1 543 smbios_structure_type = 6 544 545 def __init__(self, u, sm): 546 super(MemoryModuleInformation, self).__init__(u, sm) 547 u = self.u 548 try: 549 self.add_field('socket_designation', u.unpack_one("B"), self.fmtstr) 550 self.add_field('bank_connections', u.unpack_one("B")) 551 self.add_field('current_speed', u.unpack_one("B")) 552 self.add_field('current_memory_type', u.unpack_one("<H")) 553 _mem_connection = { 554 0: 'single', 555 1: 'double-bank' 556 } 557 self.add_field('installed_mem', u.unpack_one("B")) 558 self.add_field('installed_size', bitfields.getbits(self.installed_mem, 6, 0), "installed_mem[6:0]={}") 559 self.add_field('installed_memory_module_connection', bitfields.getbits(self.installed_mem, 7), unpack.format_table("installed_mem[7]={}", _mem_connection)) 560 self.add_field('enabled_mem', u.unpack_one("B")) 561 self.add_field('enabled_size', bitfields.getbits(self.installed_mem, 6, 0), "enabled_mem[6:0]={}") 562 self.add_field('enabled_memory_module_connection', bitfields.getbits(self.installed_mem, 7), unpack.format_table("enabled_mem[7]={}", _mem_connection)) 563 self.add_field('error_status', u.unpack_one("B")) 564 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)) 565 self.add_field('correctable_errors_received', bool(bitfields.getbits(self.error_status, 1)), unpack.format_table("error_status[1]={}", _mem_connection)) 566 self.add_field('uncorrectable_errors_received', bool(bitfields.getbits(self.error_status, 0)), unpack.format_table("error_status[0]={}", _mem_connection)) 567 except: 568 self.decode_failure = True 569 print "Error parsing MemoryModuleInformation" 570 import traceback 571 traceback.print_exc() 572 self.fini() 573 574class CacheInformation(SmbiosBaseStructure): 575 smbios_structure_type = 7 576 577 def __init__(self, u, sm): 578 super(CacheInformation, self).__init__(u, sm) 579 u = self.u 580 try: 581 self.add_field('socket_designation', u.unpack_one("B"), self.fmtstr) 582 processor_types = { 583 0x01: 'Other', 584 0x02: 'Unknown', 585 0x03: 'Central Processor', 586 0x04: 'Math Processor', 587 0x05: 'DSP Processor', 588 0x06: 'Video Processor', 589 } 590 self.add_field('cache_configuration', u.unpack_one("<H")) 591 _operational_mode = { 592 0b00: 'Write Through', 593 0b01: 'Write Back', 594 0b10: 'Varies with Memory Address', 595 0b11: 'Unknown' 596 } 597 self.add_field('operational_mode', bitfields.getbits(self.cache_configuration, 9, 8), unpack.format_table("cache_configuration[9:8]={}", _operational_mode)) 598 self.add_field('enabled_at_boot_time', bool(bitfields.getbits(self.cache_configuration, 7)), "cache_configuration[7]={}") 599 _location = { 600 0b00: 'Internal', 601 0b01: 'External', 602 0b10: 'Reserved', 603 0b11: 'Unknown' 604 } 605 self.add_field('location_relative_to_cpu_module', bitfields.getbits(self.cache_configuration, 6, 5), unpack.format_table("cache_configuration[6:5]={}", _location)) 606 self.add_field('cache_socketed', bool(bitfields.getbits(self.cache_configuration, 3)), "cache_configuration[3]={}") 607 self.add_field('cache_level', bitfields.getbits(self.cache_configuration, 2, 0), "cache_configuration[2:0]={}") 608 self.add_field('max_cache_size', u.unpack_one("<H")) 609 _granularity = { 610 0: '1K granularity', 611 1: '64K granularity' 612 } 613 self.add_field('max_granularity', bitfields.getbits(self.cache_configuration, 15), unpack.format_table("max_cache_size[15]={}", _granularity)) 614 self.add_field('max_size_in_granularity', bitfields.getbits(self.cache_configuration, 14, 0), "max_cache_size[14, 0]={}") 615 self.add_field('installed_size', u.unpack_one("<H")) 616 if self.installed_size != 0: 617 self.add_field('installed_granularity', bitfields.getbits(self.cache_configuration, 15), unpack.format_table("installed_size[15]={}", _granularity)) 618 self.add_field('installed_size_in_granularity', bitfields.getbits(self.cache_configuration, 14, 0), "installed_size[14, 0]={}") 619 self.add_field('supported_sram_type', u.unpack_one("<H")) 620 self.add_field('current_sram_type', u.unpack_one("<H")) 621 if self.length > 0x0F: 622 self.add_field('cache_speed', u.unpack_one("B")) 623 if self.length > 0x10: 624 _error_correction = { 625 0x01: 'Other', 626 0x02: 'Unknown', 627 0x03: 'None', 628 0x04: 'Parity', 629 0x05: 'Single-bit ECC', 630 0x06: 'Multi-bit ECC' 631 } 632 self.add_field('error_correction', u.unpack_one("B"), unpack.format_table("{}", _error_correction)) 633 if self.length > 0x10: 634 _system_cache_type = { 635 0x01: 'Other', 636 0x02: 'Unknown', 637 0x03: 'Instruction', 638 0x04: 'Data', 639 0x05: 'Unified' 640 } 641 self.add_field('system_cache_type', u.unpack_one("B"), unpack.format_table("{}", _system_cache_type)) 642 if self.length > 0x12: 643 _associativity = { 644 0x01: 'Other', 645 0x02: 'Unknown', 646 0x03: 'Direct Mapped', 647 0x04: '2-way Set-Associative', 648 0x05: '4-way Set-Associative', 649 0x06: 'Fully Associative', 650 0x07: '8-way Set-Associative', 651 0x08: '16-way Set-Associative', 652 0x09: '12-way Set-Associative', 653 0x0A: '24-way Set-Associative', 654 0x0B: '32-way Set-Associative', 655 0x0C: '48-way Set-Associative', 656 0x0D: '64-way Set-Associative', 657 0x0E: '20-way Set-Associative' 658 } 659 self.add_field('associativity', u.unpack_one("B"), unpack.format_table("{}", _associativity)) 660 661 except: 662 self.decode_failure = True 663 print "Error parsing CacheInformation" 664 import traceback 665 traceback.print_exc() 666 self.fini() 667 668class PortConnectorInfo(SmbiosBaseStructure): 669 smbios_structure_type = 8 670 671 def __init__(self, u, sm): 672 super(PortConnectorInfo, self).__init__(u, sm) 673 u = self.u 674 try: 675 self.add_field('internal_reference_designator', u.unpack_one("B"), self.fmtstr) 676 connector_types = { 677 0x00: 'None', 678 0x01: 'Centronics', 679 0x02: 'Mini Centronics', 680 0x03: 'Proprietary', 681 0x04: 'DB-25 pin male', 682 0x05: 'DB-25 pin female', 683 0x06: 'DB-15 pin male', 684 0x07: 'DB-15 pin female', 685 0x08: 'DB-9 pin male', 686 0x09: 'DB-9 pin female', 687 0x0A: 'RJ-11', 688 0x0B: 'RJ-45', 689 0x0C: '50-pin MiniSCSI', 690 0x0D: 'Mini-DIN', 691 0x0E: 'Micro-DIN', 692 0x0F: 'PS/2', 693 0x10: 'Infrared', 694 0x11: 'HP-HIL', 695 0x12: 'Access Bus (USB)', 696 0x13: 'SSA SCSI', 697 0x14: 'Circular DIN-8 male', 698 0x15: 'Circular DIN-8 female', 699 0x16: 'On Board IDE', 700 0x17: 'On Board Floppy', 701 0x18: '9-pin Dual Inline (pin 10 cut)', 702 0x19: '25-pin Dual Inline (pin 26 cut)', 703 0x1A: '50-pin Dual Inline', 704 0x1B: '68-pin Dual Inline', 705 0x1C: 'On Board Sound Input from CD-ROM', 706 0x1D: 'Mini-Centronics Type-14', 707 0x1E: 'Mini-Centronics Type-26', 708 0x1F: 'Mini-jack (headphones)', 709 0x20: 'BNC', 710 0x21: '1394', 711 0x22: 'SAS/SATA Plug Receptacle', 712 0xA0: 'PC-98', 713 0xA1: 'PC-98Hireso', 714 0xA2: 'PC-H98', 715 0xA3: 'PC-98Note', 716 0xA4: 'PC-98Full', 717 0xFF: 'Other', 718 } 719 self.add_field('internal_connector_type', u.unpack_one("B"), unpack.format_table("{}", connector_types)) 720 self.add_field('external_reference_designator', u.unpack_one("B"), self.fmtstr) 721 self.add_field('external_connector_type', u.unpack_one("B"), unpack.format_table("{}", connector_types)) 722 port_types = { 723 0x00: 'None', 724 0x01: 'Parallel Port XT/AT Compatible', 725 0x02: 'Parallel Port PS/2', 726 0x03: 'Parallel Port ECP', 727 0x04: 'Parallel Port EPP', 728 0x05: 'Parallel Port ECP/EPP', 729 0x06: 'Serial Port XT/AT Compatible', 730 0x07: 'Serial Port 16450 Compatible', 731 0x08: 'Serial Port 16550 Compatible', 732 0x09: 'Serial Port 16550A Compatible', 733 0x0A: 'SCSI Port', 734 0x0B: 'MIDI Port', 735 0x0C: 'Joy Stick Port', 736 0x0D: 'Keyboard Port', 737 0x0E: 'Mouse Port', 738 0x0F: 'SSA SCSI', 739 0x10: 'USB', 740 0x11: 'FireWire (IEEE P1394)', 741 0x12: 'PCMCIA Type I2', 742 0x13: 'PCMCIA Type II', 743 0x14: 'PCMCIA Type III', 744 0x15: 'Cardbus', 745 0x16: 'Access Bus Port', 746 0x17: 'SCSI II', 747 0x18: 'SCSI Wide', 748 0x19: 'PC-98', 749 0x1A: 'PC-98-Hireso', 750 0x1B: 'PC-H98', 751 0x1C: 'Video Port', 752 0x1D: 'Audio Port', 753 0x1E: 'Modem Port', 754 0x1F: 'Network Port', 755 0x20: 'SATA', 756 0x21: 'SAS', 757 0xA0: '8251 Compatible', 758 0xA1: '8251 FIFO Compatible', 759 0xFF: 'Other', 760 } 761 self.add_field('port_type', u.unpack_one("B"), unpack.format_table("{}", port_types)) 762 except: 763 self.decodeFailure = True 764 print "Error parsing PortConnectorInfo" 765 import traceback 766 traceback.print_exc() 767 self.fini() 768 769class SystemSlots(SmbiosBaseStructure): 770 smbios_structure_type = 9 771 772 def __init__(self, u, sm): 773 super(SystemSlots, self).__init__(u, sm) 774 u = self.u 775 try: 776 self.add_field('designation', u.unpack_one("B"), self.fmtstr) 777 _slot_types = { 778 0x01: 'Other', 779 0x02: 'Unknown', 780 0x03: 'ISA', 781 0x04: 'MCA', 782 0x05: 'EISA', 783 0x06: 'PCI', 784 0x07: 'PC Card (PCMCIA)', 785 0x08: 'VL-VESA', 786 0x09: 'Proprietary', 787 0x0A: 'Processor Card Slot', 788 0x0B: 'Proprietary Memory Card Slot', 789 0x0C: 'I/O Riser Card Slot', 790 0x0D: 'NuBus', 791 0x0E: 'PCI 66MHz Capable', 792 0x0F: 'AGP', 793 0x10: 'AGP 2X', 794 0x11: 'AGP 4X', 795 0x12: 'PCI-X', 796 0x13: 'AGP 8X', 797 0xA0: 'PC-98/C20', 798 0xA1: 'PC-98/C24', 799 0xA2: 'PC-98/E', 800 0xA3: 'PC-98/Local Bus', 801 0xA4: 'PC-98/Card', 802 0xA5: 'PCI Express', 803 0xA6: 'PCI Express x1', 804 0xA7: 'PCI Express x2', 805 0xA8: 'PCI Express x4', 806 0xA9: 'PCI Express x8', 807 0xAA: 'PCI Express x16', 808 0xAB: 'PCI Express Gen 2', 809 0xAC: 'PCI Express Gen 2 x1', 810 0xAD: 'PCI Express Gen 2 x2', 811 0xAE: 'PCI Express Gen 2 x4', 812 0xAF: 'PCI Express Gen 2 x8', 813 0xB0: 'PCI Express Gen 2 x16', 814 0xB1: 'PCI Express Gen 3', 815 0xB2: 'PCI Express Gen 3 x1', 816 0xB3: 'PCI Express Gen 3 x2', 817 0xB4: 'PCI Express Gen 3 x4', 818 0xB5: 'PCI Express Gen 3 x8', 819 0xB6: 'PCI Express Gen 3 x16', 820 } 821 self.add_field('slot_type', u.unpack_one("B"), unpack.format_table("{}", _slot_types)) 822 _slot_data_bus_widths = { 823 0x01: 'Other', 824 0x02: 'Unknown', 825 0x03: '8 bit', 826 0x04: '16 bit', 827 0x05: '32 bit', 828 0x06: '64 bit', 829 0x07: '128 bit', 830 0x08: '1x or x1', 831 0x09: '2x or x2', 832 0x0A: '4x or x4', 833 0x0B: '8x or x8', 834 0x0C: '12x or x12', 835 0x0D: '16x or x16', 836 0x0E: '32x or x32', 837 } 838 self.add_field('slot_data_bus_width', u.unpack_one('B'), unpack.format_table("{}", _slot_data_bus_widths)) 839 _current_usages = { 840 0x01: 'Other', 841 0x02: 'Unknown', 842 0x03: 'Available', 843 0x04: 'In use', 844 } 845 self.add_field('current_usage', u.unpack_one('B'), unpack.format_table("{}", _current_usages)) 846 _slot_lengths = { 847 0x01: 'Other', 848 0x02: 'Unknown', 849 0x03: 'Short Length', 850 0x04: 'Long Length', 851 } 852 self.add_field('slot_length', u.unpack_one('B'), unpack.format_table("{}", _slot_lengths)) 853 self.add_field('slot_id', u.unpack_one('<H')) 854 self.add_field('characteristics1', u.unpack_one('B')) 855 self.add_field('characteristics_unknown', bool(bitfields.getbits(self.characteristics1, 0)), "characteristics1[0]={}") 856 self.add_field('provides_5_0_volts', bool(bitfields.getbits(self.characteristics1, 1)), "characteristics1[1]={}") 857 self.add_field('provides_3_3_volts', bool(bitfields.getbits(self.characteristics1, 2)), "characteristics1[2]={}") 858 self.add_field('shared_slot', bool(bitfields.getbits(self.characteristics1, 3)), "characteristics1[3]={}") 859 self.add_field('supports_pc_card_16', bool(bitfields.getbits(self.characteristics1, 4)), "characteristics1[4]={}") 860 self.add_field('supports_cardbus', bool(bitfields.getbits(self.characteristics1, 5)), "characteristics1[5]={}") 861 self.add_field('supports_zoom_video', bool(bitfields.getbits(self.characteristics1, 6)), "characteristics1[6]={}") 862 self.add_field('supports_modem_ring_resume', bool(bitfields.getbits(self.characteristics1, 7)), "characteristics1[7]={}") 863 if self.length > 0x0C: 864 self.add_field('characteristics2', u.unpack_one('B')) 865 self.add_field('supports_PME', bool(bitfields.getbits(self.characteristics2, 0)), "characteristics2[0]={}") 866 self.add_field('supports_hot_plug', bool(bitfields.getbits(self.characteristics2, 1)), "characteristics2[1]={}") 867 self.add_field('supports_smbus', bool(bitfields.getbits(self.characteristics2, 2)), "characteristics2[2]={}") 868 if self.length > 0x0D: 869 self.add_field('segment_group_number', u.unpack_one('<H')) 870 self.add_field('bus_number', u.unpack_one('B')) 871 self.add_field('device_function_number', u.unpack_one('B')) 872 self.add_field('device_number', bitfields.getbits(self.device_function_number, 7, 3), "device_function_number[7:3]={}") 873 self.add_field('function_number', bitfields.getbits(self.device_function_number, 2, 0), "device_function_number[2:0]={}") 874 except: 875 self.decodeFailure = True 876 print "Error parsing SystemSlots" 877 import traceback 878 traceback.print_exc() 879 self.fini() 880 881class OnBoardDevicesInformation(SmbiosBaseStructure): 882 smbios_structure_type = 10 883 884 def __init__(self, u, sm): 885 super(OnBoardDevicesInformation, self).__init__(u, sm) 886 u = self.u 887 try: 888 self.add_field('device_type', u.unpack_one("B")) 889 self.add_field('device_enabled', bool(bitfields.getbits(self.device_type, 7)), "device_type[7]={}") 890 _device_types = { 891 0x01: 'Other', 892 0x02: 'Unknown', 893 0x03: 'Video', 894 0x04: 'SCSI Controller', 895 0x05: 'Ethernet', 896 0x06: 'Token Ring', 897 0x07: 'Sound', 898 0x08: 'PATA Controller', 899 0x09: 'SATA Controller', 900 0x0A: 'SAS Controller' 901 } 902 self.add_field('type_of_device', bitfields.getbits(self.device_type, 6, 0), unpack.format_table("device_type[6:0]={}", _device_types)) 903 self.add_field('description_string', u.unpack_one("B"), self.fmtstr) 904 except: 905 self.decodeFailure = True 906 print "Error parsing OnBoardDevicesInformation" 907 import traceback 908 traceback.print_exc() 909 self.fini() 910 911class OEMStrings(SmbiosBaseStructure): 912 smbios_structure_type = 11 913 914 def __init__(self, u, sm): 915 super(OEMStrings, self).__init__(u, sm) 916 u = self.u 917 try: 918 self.add_field('count', u.unpack_one("B")) 919 except: 920 self.decodeFailure = True 921 print "Error parsing OEMStrings" 922 import traceback 923 traceback.print_exc() 924 self.fini() 925 926class SystemConfigOptions(SmbiosBaseStructure): 927 smbios_structure_type = 12 928 929 def __init__(self, u, sm): 930 super(SystemConfigOptions, self).__init__(u, sm) 931 u = self.u 932 try: 933 self.add_field('count', u.unpack_one("B")) 934 except: 935 self.decodeFailure = True 936 print "Error parsing SystemConfigOptions" 937 import traceback 938 traceback.print_exc() 939 self.fini() 940 941class BIOSLanguageInformation(SmbiosBaseStructure): 942 smbios_structure_type = 13 943 944 def __init__(self, u, sm): 945 super(BIOSLanguageInformation, self).__init__(u, sm) 946 u = self.u 947 try: 948 self.add_field('installable_languages', u.unpack_one("B")) 949 if self.length > 0x05: 950 self.add_field('flags', u.unpack_one('B')) 951 self.add_field('abbreviated_format', bool(bitfields.getbits(self.flags, 0)), "flags[0]={}") 952 if self.length > 0x6: 953 u.skip(15) 954 self.add_field('current_language', u.unpack_one('B'), self.fmtstr) 955 except: 956 self.decodeFailure = True 957 print "Error parsing BIOSLanguageInformation" 958 import traceback 959 traceback.print_exc() 960 self.fini() 961 962class GroupAssociations(SmbiosBaseStructure): 963 smbios_structure_type = 14 964 965 def __init__(self, u, sm): 966 super(GroupAssociations, self).__init__(u, sm) 967 u = self.u 968 try: 969 self.add_field('group_name', u.unpack_one("B"), self.fmtstr) 970 self.add_field('item_type', u.unpack_one('B')) 971 self.add_field('item_handle', u.unpack_one('<H')) 972 except: 973 self.decodeFailure = True 974 print "Error parsing GroupAssociations" 975 import traceback 976 traceback.print_exc() 977 self.fini() 978 979class SystemEventLog(SmbiosBaseStructure): 980 smbios_structure_type = 15 981 982 def __init__(self, u, sm): 983 super(SystemEventLog, self).__init__(u, sm) 984 u = self.u 985 try: 986 self.add_field('log_area_length', u.unpack_one("<H")) 987 self.add_field('log_header_start_offset', u.unpack_one('<H')) 988 self.add_field('log_data_start_offset', u.unpack_one('<H')) 989 _access_method = { 990 0x00: 'Indexed I/O: 1 8-bit index port, 1 8-bit data port', 991 0x01: 'Indexed I/O: 2 8-bit index ports, 1 8-bit data port', 992 0x02: 'Indexed I/O: 1 16-bit index port, 1 8-bit data port', 993 0x03: 'Memory-mapped physical 32-bit address', 994 0x04: 'Available through General-Purpose NonVolatile Data functions', 995 xrange(0x05, 0x07F): 'Available for future assignment', 996 xrange(0x80, 0xFF): 'BIOS Vendor/OEM-specific' 997 } 998 self.add_field('access_method', u.unpack_one('B'), unpack.format_table("{}", _access_method)) 999 self.add_field('log_status', u.unpack_one('B')) 1000 self.add_field('log_area_full', bool(bitfields.getbits(self.log_status, 1)), "log_status[1]={}") 1001 self.add_field('log_area_valid', bool(bitfields.getbits(self.log_status, 0)), "log_status[0]={}") 1002 self.add_field('log_change_token', u.unpack_one('<I')) 1003 self.add_field('access_method_address', u.unpack_one('<I')) 1004 if self.length > 0x14: 1005 _log_header_formats = { 1006 0: 'No header', 1007 1: 'Type 1 log header', 1008 xrange(2, 0x7f): 'Available for future assignment', 1009 xrange(0x80, 0xff): 'BIOS vendor or OEM-specific format' 1010 } 1011 self.add_field('log_header_format', u.unpack_one("B"), unpack.format_table("{}", _log_header_formats)) 1012 if self.length > 0x15: 1013 self.add_field('num_supported_log_type_descriptors', u.unpack_one('B')) 1014 if self.length > 0x16: 1015 self.add_field('length_log_type_descriptor', u.unpack_one('B')) 1016 if self.length != (0x17 + (self.num_supported_log_type_descriptors * self.length_log_type_descriptor)): 1017 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) 1018 print "structure length = {}".format(self.length) 1019 print "num_supported_log_type_descriptors = {}".format(self.num_supported_log_type_descriptors) 1020 print "length_log_type_descriptor = {}".format(self.length_log_type_descriptor) 1021 self.decodeFailure = True 1022 self.add_field('descriptors', tuple(EventLogDescriptor.unpack(u) for i in range(self.num_supported_log_type_descriptors)), unpack.format_each("\n{!r}")) 1023 except: 1024 self.decodeFailure = True 1025 print "Error parsing SystemEventLog" 1026 import traceback 1027 traceback.print_exc() 1028 self.fini() 1029 1030class EventLogDescriptor(unpack.Struct): 1031 @staticmethod 1032 def _unpack(u): 1033 _event_log_type_descriptors = { 1034 0x00: 'Reserved', 1035 0x01: 'Single-bit ECC memory error', 1036 0x02: 'Multi-bit ECC memory error', 1037 0x03: 'Parity memory error', 1038 0x04: 'Bus time-out', 1039 0x05: 'I/O Channel Check', 1040 0x06: 'Software NMI', 1041 0x07: 'POST Memory Resize', 1042 0x08: 'POST Error', 1043 0x09: 'PCI Parity Error', 1044 0x0A: 'PCI System Error', 1045 0x0B: 'CPU Failure', 1046 0x0C: 'EISA FailSafe Timer time-out', 1047 0x0D: 'Correctable memory log disabled', 1048 0x0E: 'Logging disabled for a specific Event Type - too many errors of the same type received in a short amount of time', 1049 0x0F: 'Reserved', 1050 0x10: 'System Limit Exceeded', 1051 0x11: 'Asynchronous hardware timer expired and issued a system reset', 1052 0x12: 'System configuration information', 1053 0x13: 'Hard-disk information', 1054 0x14: 'System reconfigured', 1055 0x15: 'Uncorrectable CPU-complex error', 1056 0x16: 'Log Area Reset/Cleared', 1057 0x17: 'System boot', 1058 xrange(0x18, 0x7F): 'Unused, available for assignment', 1059 xrange(0x80, 0xFE): 'Availalbe for system- and OEM-specific assignments', 1060 0xFF: 'End of log' 1061 } 1062 yield 'log_type', u.unpack_one('B'), unpack.format_table("{}", _event_log_type_descriptors) 1063 _event_log_format = { 1064 0x00: 'None', 1065 0x01: 'Handle', 1066 0x02: 'Multiple-Event', 1067 0x03: 'Multiple-Event Handle', 1068 0x04: 'POST Results Bitmap', 1069 0x05: 'System Management Type', 1070 0x06: 'Multiple-Event System Management Type', 1071 xrange(0x80, 0xFF): 'OEM assigned' 1072 } 1073 yield 'variable_data_format_type', u.unpack_one('B'), unpack.format_table("{}", _event_log_format) 1074 1075class PhysicalMemoryArray(SmbiosBaseStructure): 1076 smbios_structure_type = 16 1077 1078 def __init__(self, u, sm): 1079 super(PhysicalMemoryArray, self).__init__(u, sm) 1080 u = self.u 1081 try: 1082 if self.length > 0x4: 1083 _location_field = { 1084 0x01: "Other", 1085 0x02: "Unknown", 1086 0x03: "System board or motherboard", 1087 0x04: "ISA add-on card", 1088 0x05: "EISA add-on card", 1089 0x06: "PCI add-on card", 1090 0x07: "MCA add-on card", 1091 0x08: "PCMCIA add-on card", 1092 0x09: "Proprietary add-on card", 1093 0x0A: "NuBus", 1094 0xA0: "PC-98/C20 add-on card", 1095 0xA1: "PC-98/C24 add-on card", 1096 0xA2: "PC-98/E add-on card", 1097 0xA3: "PC-98/Local bus add-on card" 1098 } 1099 self.add_field('location', u.unpack_one("B"), unpack.format_table("{}", _location_field)) 1100 if self.length > 0x05: 1101 _use = { 1102 0x01: "Other", 1103 0x02: "Unknown", 1104 0x03: "System memory", 1105 0x04: "Video memory", 1106 0x05: "Flash memory", 1107 0x06: "Non-volatile RAM", 1108 0x07: "Cache memory" 1109 } 1110 self.add_field('use', u.unpack_one('B'), unpack.format_table("{}", _use)) 1111 if self.length > 0x06: 1112 _error_correction = { 1113 0x01: "Other", 1114 0x02: "Unknown", 1115 0x03: "None", 1116 0x04: "Parity", 1117 0x05: "Single-bit ECC", 1118 0x06: "Multi-bit ECC", 1119 0x07: "CRC" 1120 } 1121 self.add_field('memory_error_correction', u.unpack_one('B'), unpack.format_table("{}", _error_correction)) 1122 if self.length > 0x07: 1123 self.add_field('maximum_capacity', u.unpack_one('<I')) 1124 if self.length > 0x0B: 1125 self.add_field('memory_error_information_handle', u.unpack_one('<H')) 1126 if self.length > 0x0D: 1127 self.add_field('num_memory_devices', u.unpack_one('<H')) 1128 if self.length > 0x0F: 1129 self.add_field('extended_maximum_capacity', u.unpack_one('<Q')) 1130 except: 1131 self.decodeFailure = True 1132 print "Error parsing PhysicalMemoryArray" 1133 import traceback 1134 traceback.print_exc() 1135 self.fini() 1136 1137class MemoryDevice(SmbiosBaseStructure): 1138 smbios_structure_type = 17 1139 1140 def __init__(self, u, sm): 1141 super(MemoryDevice, self).__init__(u, sm) 1142 u = self.u 1143 try: 1144 if self.length > 0x4: 1145 self.add_field('physical_memory_array_handle', u.unpack_one("<H")) 1146 if self.length > 0x6: 1147 self.add_field('memory_error_information_handle', u.unpack_one("<H")) 1148 if self.length > 0x8: 1149 self.add_field('total_width', u.unpack_one("<H")) 1150 if self.length > 0xA: 1151 self.add_field('data_width', u.unpack_one("<H")) 1152 if self.length > 0xC: 1153 self.add_field('size', u.unpack_one("<H")) 1154 if self.length > 0xE: 1155 _form_factors = { 1156 0x01: 'Other', 1157 0x02: 'Unknown', 1158 0x03: 'SIMM', 1159 0x04: 'SIP', 1160 0x05: 'Chip', 1161 0x06: 'DIP', 1162 0x07: 'ZIP', 1163 0x08: 'Proprietary Card', 1164 0x09: 'DIMM', 1165 0x0A: 'TSOP', 1166 0x0B: 'Row of chips', 1167 0x0C: 'RIMM', 1168 0x0D: 'SODIMM', 1169 0x0E: 'SRIMM', 1170 0x0F: 'FB-DIMM' 1171 } 1172 self.add_field('form_factor', u.unpack_one("B"), unpack.format_table("{}", _form_factors)) 1173 if self.length > 0xF: 1174 self.add_field('device_set', u.unpack_one("B")) 1175 if self.length > 0x10: 1176 self.add_field('device_locator', u.unpack_one("B"), self.fmtstr) 1177 if self.length > 0x11: 1178 self.add_field('bank_locator', u.unpack_one("B"), self.fmtstr) 1179 if self.length > 0x12: 1180 _memory_types = { 1181 0x01: 'Other', 1182 0x02: 'Unknown', 1183 0x03: 'DRAM', 1184 0x04: 'EDRAM', 1185 0x05: 'VRAM', 1186 0x06: 'SRAM', 1187 0x07: 'RAM', 1188 0x08: 'ROM', 1189 0x09: 'FLASH', 1190 0x0A: 'EEPROM', 1191 0x0B: 'FEPROM', 1192 0x0C: 'EPROM', 1193 0x0D: 'CDRAM', 1194 0x0E: '3DRAM', 1195 0x0F: 'SDRAM', 1196 0x10: 'SGRAM', 1197 0x11: 'RDRAM', 1198 0x12: 'DDR', 1199 0x13: 'DDR2', 1200 0x14: 'DDR2 FB-DIMM', 1201 xrange(0x15, 0x17): 'Reserved', 1202 0x18: 'DDR3', 1203 0x19: 'FBD2' 1204 } 1205 self.add_field('memory_type', u.unpack_one("B"), unpack.format_table("{}", _memory_types)) 1206 if self.length > 0x13: 1207 self.add_field('type_detail', u.unpack_one('<H')) 1208 if self.length > 0x15: 1209 self.add_field('speed', u.unpack_one("<H")) 1210 if self.length > 0x17: 1211 self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr) 1212 if self.length > 0x18: 1213 self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) 1214 if self.length > 0x19: 1215 self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr) 1216 if self.length > 0x1A: 1217 self.add_field('part_number', u.unpack_one("B"), self.fmtstr) 1218 if self.length > 0x1B: 1219 self.add_field('attributes', u.unpack_one("B")) 1220 self.add_field('rank', bitfields.getbits(self.attributes, 3, 0), "attributes[3:0]={}") 1221 if self.length > 0x1C: 1222 if self.size == 0x7FFF: 1223 self.add_field('extended_size', u.unpack_one('<I')) 1224 self.add_field('mem_size', bitfields.getbits(self.type_detail, 30, 0), "type_detail[30:0]={}") 1225 else: 1226 u.skip(4) 1227 if self.length > 0x20: 1228 self.add_field('configured_memory_clock_speed', u.unpack_one("<H")) 1229 if self.length > 0x22: 1230 self.add_field('minimum_voltage', u.unpack_one("<H")) 1231 if self.length > 0x24: 1232 self.add_field('maximum_voltage', u.unpack_one("<H")) 1233 if self.length > 0x26: 1234 self.add_field('configured_voltage', u.unpack_one("<H")) 1235 except: 1236 self.decodeFailure = True 1237 print "Error parsing MemoryDevice" 1238 import traceback 1239 traceback.print_exc() 1240 self.fini() 1241 1242class MemoryErrorInfo32Bit(SmbiosBaseStructure): 1243 smbios_structure_type = 18 1244 1245 def __init__(self, u, sm): 1246 super(MemoryErrorInfo32Bit, self).__init__(u, sm) 1247 u = self.u 1248 try: 1249 if self.length > 0x4: 1250 _error_types = { 1251 0x01: 'Other', 1252 0x02: 'Unknown', 1253 0x03: 'OK', 1254 0x04: 'Bad read', 1255 0x05: 'Parity error', 1256 0x06: 'Single-bit error', 1257 0x07: 'Double-bit error', 1258 0x08: 'Multi-bit error', 1259 0x09: 'Nibble error', 1260 0x0A: 'Checksum error', 1261 0x0B: 'CRC error', 1262 0x0C: 'Corrected single-bit error', 1263 0x0D: 'Corrected error', 1264 0x0E: 'Uncorrectable error' 1265 } 1266 self.add_field('error_type', u.unpack_one("B"), unpack.format_table("{}", _error_types)) 1267 if self.length > 0x5: 1268 _error_granularity_field = { 1269 0x01: 'Other', 1270 0x02: 'Unknown', 1271 0x03: 'Device level', 1272 0x04: 'Memory partition level' 1273 } 1274 self.add_field('error_granularity', u.unpack_one("B"), unpack.format_table("{}", _error_granularity_field)) 1275 if self.length > 0x6: 1276 _error_operation_field = { 1277 0x01: 'Other', 1278 0x02: 'Unknown', 1279 0x03: 'Read', 1280 0x04: 'Write', 1281 0x05: 'Partial write' 1282 } 1283 self.add_field('error_operation', u.unpack_one("B"), unpack.format_table("{}", _error_operation_field)) 1284 if self.length > 0x7: 1285 self.add_field('vendor_syndrome', u.unpack_one("<I")) 1286 if self.length > 0xB: 1287 self.add_field('memory_array_error_address', u.unpack_one("<I")) 1288 if self.length > 0xF: 1289 self.add_field('device_error_address', u.unpack_one("<I")) 1290 if self.length > 0x13: 1291 self.add_field('error_resolution', u.unpack_one("<I")) 1292 except: 1293 self.decodeFailure = True 1294 print "Error parsing MemoryErrorInfo32Bit" 1295 import traceback 1296 traceback.print_exc() 1297 self.fini() 1298 1299class MemoryArrayMappedAddress(SmbiosBaseStructure): 1300 smbios_structure_type = 19 1301 1302 def __init__(self, u, sm): 1303 super(MemoryArrayMappedAddress, self).__init__(u, sm) 1304 u = self.u 1305 try: 1306 if self.length > 0x4: 1307 self.add_field('starting_address', u.unpack_one("<I")) 1308 # if FFFF FFFF: address stored in Extended Starting Address 1309 if self.length > 0x8: 1310 self.add_field('ending_address', u.unpack_one("<I")) 1311 if self.length > 0xC: 1312 self.add_field('memory_array_handle', u.unpack_one("<H")) 1313 if self.length > 0xE: 1314 self.add_field('partition_width', u.unpack_one("B")) 1315 if self.length > 0xF: 1316 # valid if starting_address = FFFF FFFF 1317 if self.starting_address == 0xFFFFFFFF: 1318 self.add_field('extended_starting_address', u.unpack_one("<Q")) 1319 if self.length > 0x17: 1320 self.add_field('extended_ending_address', u.unpack_one("<Q")) 1321 else: 1322 u.skip(16) 1323 1324 except: 1325 self.decodeFailure = True 1326 print "Error parsing MemoryArrayMappedAddress" 1327 import traceback 1328 traceback.print_exc() 1329 self.fini() 1330 1331class MemoryDeviceMappedAddress(SmbiosBaseStructure): 1332 smbios_structure_type = 20 1333 1334 def __init__(self, u, sm): 1335 super(MemoryDeviceMappedAddress, self).__init__(u, sm) 1336 u = self.u 1337 try: 1338 if self.length > 0x4: 1339 self.add_field('starting_address', u.unpack_one("<I")) 1340 # if FFFF FFFF: address stored in Extended Starting Address 1341 if self.length > 0x8: 1342 self.add_field('ending_address', u.unpack_one("<I")) 1343 if self.length > 0xC: 1344 self.add_field('memory_device_handle', u.unpack_one("<H")) 1345 if self.length > 0xE: 1346 self.add_field('memory_array_mapped_address_handle', u.unpack_one("<H")) 1347 if self.length > 0x10: 1348 self.add_field('partition_row_position', u.unpack_one("B")) 1349 if self.length > 0x11: 1350 self.add_field('interleave_position', u.unpack_one("B")) 1351 if self.length > 0x12: 1352 self.add_field('interleave_data_depth', u.unpack_one("B")) 1353 if self.length > 0x13: 1354 # valid if starting_address = FFFF FFFF 1355 if self.starting_address == 0xFFFFFFFF: 1356 self.add_field('extended_starting_address', u.unpack_one("<Q")) 1357 if self.length > 0x1B: 1358 self.add_field('extended_ending_address', u.unpack_one("<Q")) 1359 else: 1360 u.skip(16) 1361 except: 1362 self.decodeFailure = True 1363 print "Error parsing MemoryDeviceMappedAddress" 1364 import traceback 1365 traceback.print_exc() 1366 self.fini() 1367 1368class BuiltInPointingDevice(SmbiosBaseStructure): 1369 smbios_structure_type = 21 1370 1371 def __init__(self, u, sm): 1372 super(BuiltInPointingDevice, self).__init__(u, sm) 1373 u = self.u 1374 try: 1375 if self.length > 0x4: 1376 _pointing_device_types = { 1377 0x01: 'Other', 1378 0x02: 'Unknown', 1379 0x03: 'Mouse', 1380 0x04: 'Track Ball', 1381 0x05: 'Track Point', 1382 0x06: 'Glide Point', 1383 0x07: 'Touch Pad', 1384 0x08: 'Touch Screen', 1385 0x09: 'Optical Sensor' 1386 } 1387 self.add_field('pointing_device_type', u.unpack_one("B"), unpack.format_table("{}", _pointing_device_types)) 1388 if self.length > 0x5: 1389 _interfaces = { 1390 0x01: 'Other', 1391 0x02: 'Unknown', 1392 0x03: 'Serial', 1393 0x04: 'PS/2', 1394 0x05: 'Infared', 1395 0x06: 'HP-HIL', 1396 0x07: 'Bus mouse', 1397 0x08: 'ADB (Apple Desktop Bus)', 1398 0x09: 'Bus mouse DB-9', 1399 0x0A: 'Bus mouse micro-DIN', 1400 0x0B: 'USB' 1401 } 1402 self.add_field('interface', u.unpack_one("B"), unpack.format_table("{}", _interfaces)) 1403 if self.length > 0x6: 1404 self.add_field('num_buttons', u.unpack_one("B")) 1405 except: 1406 self.decodeFailure = True 1407 print "Error parsing BuiltInPointingDevice" 1408 import traceback 1409 traceback.print_exc() 1410 self.fini() 1411 1412class PortableBattery(SmbiosBaseStructure): 1413 smbios_structure_type = 22 1414 1415 def __init__(self, u, sm): 1416 super(PortableBattery, self).__init__(u, sm) 1417 u = self.u 1418 try: 1419 if self.length > 0x4: 1420 self.add_field('location', u.unpack_one("B"), self.fmtstr) 1421 if self.length > 0x5: 1422 self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr) 1423 if self.length > 0x6: 1424 self.add_field('manufacturer_date', u.unpack_one("B"), self.fmtstr) 1425 if self.length > 0x7: 1426 self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) 1427 if self.length > 0x8: 1428 self.add_field('device_name', u.unpack_one("B"), self.fmtstr) 1429 if self.length > 0x9: 1430 _device_chemistry = { 1431 0x01: 'Other', 1432 0x02: 'Unknown', 1433 0x03: 'Lead Acid', 1434 0x04: 'Nickel Cadmium', 1435 0x05: 'Nickel metal hydride', 1436 0x06: 'Lithium-ion', 1437 0x07: 'Zinc air', 1438 0x08: 'Lithium Polymer' 1439 } 1440 self.add_field('device_chemistry', u.unpack_one("B"), unpack.format_table("{}", _device_chemistry)) 1441 if self.length > 0xA: 1442 self.add_field('design_capacity', u.unpack_one("<H")) 1443 if self.length > 0xC: 1444 self.add_field('design_voltage', u.unpack_one("<H")) 1445 if self.length > 0xE: 1446 self.add_field('sbds_version_number', u.unpack_one("B"), self.fmtstr) 1447 if self.length > 0xF: 1448 self.add_field('max_error_battery_data', u.unpack_one("B"), self.fmtstr) 1449 if self.length > 0x10: 1450 if self.serial_number == 0: 1451 self.add_field('sbds_serial_number', u.unpack_one("<H")) 1452 else: 1453 u.skip(2) 1454 if self.length > 0x12: 1455 if self.manufacturer_date == 0: 1456 self.add_field('sbds_manufacture_date', u.unpack_one("<H")) 1457 self.add_field('year_biased_by_1980', bitfields.getbits(self.sbds_manufacture_date, 15, 9), "sbds_manufacture_date[15:9]={}") 1458 self.add_field('month', bitfields.getbits(self.sbds_manufacture_date, 8, 5), "sbds_manufacture_date[8:5]={}") 1459 self.add_field('date', bitfields.getbits(self.sbds_manufacture_date, 4, 0), "sbds_manufacture_date[4:0]={}") 1460 else: 1461 u.skip(2) 1462 if self.length > 0x14: 1463 if self.device_chemistry == 0x02: 1464 self.add_field('sbds_device_chemistry', u.unpack_one("B"), self.fmtstr) 1465 else: 1466 u.skip(1) 1467 if self.length > 0x15: 1468 self.add_field('design_capacity_multiplier', u.unpack_one("B")) 1469 if self.length > 0x16: 1470 self.add_field('oem_specific', u.unpack_one("<I")) 1471 except: 1472 self.decodeFailure = True 1473 print "Error parsing PortableBattery" 1474 import traceback 1475 traceback.print_exc() 1476 self.fini() 1477 1478class SystemReset(SmbiosBaseStructure): 1479 smbios_structure_type = 23 1480 1481 def __init__(self, u, sm): 1482 super(SystemReset, self).__init__(u, sm) 1483 u = self.u 1484 try: 1485 if self.length > 0x4: 1486 self.add_field('capabilities', u.unpack_one("B")) 1487 self.add_field('contains_watchdog_timer', bool(bitfields.getbits(self.capabilities, 5)), "capabilities[5]={}") 1488 _boot_option = { 1489 0b00: 'Reserved, do not use', 1490 0b01: 'Operating System', 1491 0b10: 'System utilities', 1492 0b11: 'Do not reboot' 1493 } 1494 self.add_field('boot_option_on_limit', bitfields.getbits(self.capabilities, 4, 3), unpack.format_table("capabilities[4:3]={}", _boot_option)) 1495 self.add_field('boot_option_after_watchdog_reset', bitfields.getbits(self.capabilities, 2, 1), unpack.format_table("capabilities[2:1]={}", _boot_option)) 1496 self.add_field('system_reset_enabled_by_user', bool(bitfields.getbits(self.capabilities, 0)), "capabilities[0]={}") 1497 if self.length > 0x5: 1498 self.add_field('reset_count', u.unpack_one("<H")) 1499 if self.length > 0x5: 1500 self.add_field('reset_limit', u.unpack_one("<H")) 1501 if self.length > 0x9: 1502 self.add_field('timer_interval', u.unpack_one("<H")) 1503 if self.length > 0xB: 1504 self.add_field('timeout', u.unpack_one("<H")) 1505 except: 1506 self.decodeFailure = True 1507 print "Error parsing SystemReset" 1508 import traceback 1509 traceback.print_exc() 1510 self.fini() 1511 1512class HardwareSecurity(SmbiosBaseStructure): 1513 smbios_structure_type = 24 1514 1515 def __init__(self, u, sm): 1516 super(HardwareSecurity, self).__init__(u, sm) 1517 u = self.u 1518 try: 1519 if self.length > 0x4: 1520 self.add_field('hardware_security_settings', u.unpack_one("B")) 1521 _status = { 1522 0x00: 'Disabled', 1523 0x01: 'Enabled', 1524 0x02: 'Not Implemented', 1525 0x03: 'Unknown' 1526 } 1527 self.add_field('power_on_password_status', bitfields.getbits(self.hardware_security_settings, 7, 6), unpack.format_table("hardware_security_settings[7:6]={}", _status)) 1528 self.add_field('keyboard_password_status', bitfields.getbits(self.hardware_security_settings, 5, 4), unpack.format_table("hardware_security_settings[5:4]={}", _status)) 1529 self.add_field('admin_password_status', bitfields.getbits(self.hardware_security_settings, 3, 2), unpack.format_table("hardware_security_settings0[3:2]={}", _status)) 1530 self.add_field('front_panel_reset_status', bitfields.getbits(self.hardware_security_settings, 1, 0), unpack.format_table("hardware_security_settings[1:0]={}", _status)) 1531 except: 1532 self.decodeFailure = True 1533 print "Error parsing HardwareSecurity" 1534 import traceback 1535 traceback.print_exc() 1536 self.fini() 1537 1538class SystemPowerControls(SmbiosBaseStructure): 1539 smbios_structure_type = 25 1540 1541 def __init__(self, u, sm): 1542 super(SystemPowerControls, self).__init__(u, sm) 1543 u = self.u 1544 try: 1545 if self.length > 0x4: 1546 self.add_field('next_scheduled_poweron_month', u.unpack_one("B")) 1547 self.add_field('next_scheduled_poweron_day_of_month', u.unpack_one("B")) 1548 self.add_field('next_scheduled_poweron_hour', u.unpack_one("B")) 1549 self.add_field('next_scheduled_poweron_minute', u.unpack_one("B")) 1550 self.add_field('next_scheduled_poweron_second', u.unpack_one("B")) 1551 except: 1552 self.decodeFailure = True 1553 print "Error parsing SystemPowerControls" 1554 import traceback 1555 traceback.print_exc() 1556 self.fini() 1557 1558class VoltageProbe(SmbiosBaseStructure): 1559 smbios_structure_type = 26 1560 1561 def __init__(self, u, sm): 1562 super(VoltageProbe, self).__init__(u, sm) 1563 u = self.u 1564 try: 1565 if self.length > 0x4: 1566 self.add_field('description', u.unpack_one("B"), self.fmtstr) 1567 if self.length > 0x5: 1568 self.add_field('location_and_status', u.unpack_one("B")) 1569 _status = { 1570 0b001: 'Other', 1571 0b010: 'Unknown', 1572 0b011: 'OK', 1573 0b100: 'Non-critical', 1574 0b101: 'Critical', 1575 0b110: 'Non-recoverable' 1576 } 1577 _location = { 1578 0b00001: 'Other', 1579 0b00010: 'Unknown', 1580 0b00011: 'Processor', 1581 0b00100: 'Disk', 1582 0b00101: 'Peripheral Bay', 1583 0b00110: 'System Management Module', 1584 0b00111: 'Motherboard', 1585 0b01000: 'Memory Module', 1586 0b01001: 'Processor Module', 1587 0b01010: 'Power Unit', 1588 0b01011: 'Add-in Card' 1589 } 1590 self.add_field('status', bitfields.getbits(self.location_and_status, 7, 5), unpack.format_table("location_and_status[7:5]={}", _status)) 1591 self.add_field('location', bitfields.getbits(self.location_and_status, 4, 0), unpack.format_table("location_and_status[4:0]={}", _location)) 1592 if self.length > 0x6: 1593 self.add_field('max_value', u.unpack_one("<H")) 1594 if self.length > 0x8: 1595 self.add_field('min_value', u.unpack_one("<H")) 1596 if self.length > 0xA: 1597 self.add_field('resolution', u.unpack_one("<H")) 1598 if self.length > 0xC: 1599 self.add_field('tolerance', u.unpack_one("<H")) 1600 if self.length > 0xE: 1601 self.add_field('accuracy', u.unpack_one("<H")) 1602 if self.length > 0x10: 1603 self.add_field('oem_defined', u.unpack_one("<I")) 1604 if self.length > 0x14: 1605 self.add_field('nominal_value', u.unpack_one("<H")) 1606 except: 1607 self.decodeFailure = True 1608 print "Error parsing VoltageProbe" 1609 import traceback 1610 traceback.print_exc() 1611 self.fini() 1612 1613class CoolingDevice(SmbiosBaseStructure): 1614 smbios_structure_type = 27 1615 1616 def __init__(self, u, sm): 1617 super(CoolingDevice, self).__init__(u, sm) 1618 u = self.u 1619 try: 1620 if self.length > 0x4: 1621 self.add_field('temperature_probe_handle', u.unpack_one("<H")) 1622 if self.length > 0x6: 1623 self.add_field('device_type_and_status', u.unpack_one("B")) 1624 _status = { 1625 0b001: 'Other', 1626 0b010: 'Unknown', 1627 0b011: 'OK', 1628 0b100: 'Non-critical', 1629 0b101: 'Critical', 1630 0b110: 'Non-recoverable' 1631 } 1632 _type = { 1633 0b00001: 'Other', 1634 0b00010: 'Unknown', 1635 0b00011: 'Fan', 1636 0b00100: 'Centrifugal Blower', 1637 0b00101: 'Chip Fan', 1638 0b00110: 'Cabinet Fan', 1639 0b00111: 'Power Supply Fan', 1640 0b01000: 'Heat Pipe', 1641 0b01001: 'Integrated Refrigeration', 1642 0b10000: 'Active Cooling', 1643 0b10001: 'Passive Cooling' 1644 } 1645 self.add_field('status', bitfields.getbits(self.device_type_and_status, 7, 5), unpack.format_table("device_type_and_status[7:5]={}", _status)) 1646 self.add_field('device_type', bitfields.getbits(self.device_type_and_status, 4, 0), unpack.format_table("device_type_and_status[4:0]={}", _type)) 1647 if self.length > 0x7: 1648 self.add_field('cooling_unit_group', u.unpack_one("B")) 1649 if self.length > 0x8: 1650 self.add_field('OEM_defined', u.unpack_one("<I")) 1651 if self.length > 0xC: 1652 self.add_field('nominal_speed', u.unpack_one("<H")) 1653 if self.length > 0xE: 1654 self.add_field('description', u.unpack_one("B"), self.fmtstr) 1655 except: 1656 self.decodeFailure = True 1657 print "Error parsing CoolingDevice" 1658 import traceback 1659 traceback.print_exc() 1660 self.fini() 1661 1662class TemperatureProbe(SmbiosBaseStructure): 1663 smbios_structure_type = 28 1664 1665 def __init__(self, u, sm): 1666 super(TemperatureProbe, self).__init__(u, sm) 1667 u = self.u 1668 try: 1669 if self.length > 0x4: 1670 self.add_field('description', u.unpack_one("B"), self.fmtstr) 1671 if self.length > 0x5: 1672 self.add_field('location_and_status', u.unpack_one("B")) 1673 _status = { 1674 0b001: 'Other', 1675 0b010: 'Unknown', 1676 0b011: 'OK', 1677 0b100: 'Non-critical', 1678 0b101: 'Critical', 1679 0b110: 'Non-recoverable' 1680 } 1681 _location = { 1682 0b00001: 'Other', 1683 0b00010: 'Unknown', 1684 0b00011: 'Processor', 1685 0b00100: 'Disk', 1686 0b00101: 'Peripheral Bay', 1687 0b00110: 'System Management Module', 1688 0b00111: 'Motherboard', 1689 0b01000: 'Memory Module', 1690 0b01001: 'Processor Module', 1691 0b01010: 'Power Unit', 1692 0b01011: 'Add-in Card', 1693 0b01100: 'Front Panel Board', 1694 0b01101: 'Back Panel Board', 1695 0b01110: 'Power System Board', 1696 0b01111: 'Drive Back Plane' 1697 } 1698 self.add_field('status', bitfields.getbits(self.location_and_status, 7, 5), unpack.format_table("location_and_status[7:5]={}", _status)) 1699 self.add_field('location', bitfields.getbits(self.location_and_status, 4, 0), unpack.format_table("location_and_status[4:0]={}", _location)) 1700 if self.length > 0x6: 1701 self.add_field('maximum_value', u.unpack_one("<H")) 1702 if self.length > 0x8: 1703 self.add_field('minimum_value', u.unpack_one("<H")) 1704 if self.length > 0xA: 1705 self.add_field('resolution', u.unpack_one("<H")) 1706 if self.length > 0xC: 1707 self.add_field('tolerance', u.unpack_one("<H")) 1708 if self.length > 0xE: 1709 self.add_field('accuracy', u.unpack_one("<H")) 1710 if self.length > 0x10: 1711 self.add_field('OEM_defined', u.unpack_one("<I")) 1712 if self.length > 0x14: 1713 self.add_field('nominal_value', u.unpack_one("<H")) 1714 except: 1715 self.decodeFailure = True 1716 print "Error parsing TemperatureProbe" 1717 import traceback 1718 traceback.print_exc() 1719 self.fini() 1720 1721class ElectricalCurrentProbe(SmbiosBaseStructure): 1722 smbios_structure_type = 29 1723 1724 def __init__(self, u, sm): 1725 super(ElectricalCurrentProbe, self).__init__(u, sm) 1726 u = self.u 1727 try: 1728 if self.length > 0x4: 1729 self.add_field('description', u.unpack_one("B"), self.fmtstr) 1730 if self.length > 0x5: 1731 self.add_field('location_and_status', u.unpack_one("B")) 1732 _status = { 1733 0b001: 'Other', 1734 0b010: 'Unknown', 1735 0b011: 'OK', 1736 0b100: 'Non-critical', 1737 0b101: 'Critical', 1738 0b110: 'Non-recoverable' 1739 } 1740 _location = { 1741 0b00001: 'Other', 1742 0b00010: 'Unknown', 1743 0b00011: 'Processor', 1744 0b00100: 'Disk', 1745 0b00101: 'Peripheral Bay', 1746 0b00110: 'System Management Module', 1747 0b00111: 'Motherboard', 1748 0b01000: 'Memory Module', 1749 0b01001: 'Processor Module', 1750 0b01010: 'Power Unit', 1751 0b01011: 'Add-in Card', 1752 0b01100: 'Front Panel Board', 1753 0b01101: 'Back Panel Board', 1754 0b01110: 'Power System Board', 1755 0b01111: 'Drive Back Plane' 1756 } 1757 self.add_field('status', bitfields.getbits(self.location_and_status, 7, 5), unpack.format_table("location_and_status[7:5]={}", _status)) 1758 self.add_field('location', bitfields.getbits(self.location_and_status, 4, 0), unpack.format_table("location_and_status[4:0]={}", _location)) 1759 if self.length > 0x6: 1760 self.add_field('maximum_value', u.unpack_one("<H")) 1761 if self.length > 0x8: 1762 self.add_field('minimum_value', u.unpack_one("<H")) 1763 if self.length > 0xA: 1764 self.add_field('resolution', u.unpack_one("<H")) 1765 if self.length > 0xC: 1766 self.add_field('tolerance', u.unpack_one("<H")) 1767 if self.length > 0xE: 1768 self.add_field('accuracy', u.unpack_one("<H")) 1769 if self.length > 0x10: 1770 self.add_field('OEM_defined', u.unpack_one("<I")) 1771 if self.length > 0x14: 1772 self.add_field('nominal_value', u.unpack_one("<H")) 1773 except: 1774 self.decodeFailure = True 1775 print "Error parsing ElectricalCurrentProbe" 1776 import traceback 1777 traceback.print_exc() 1778 self.fini() 1779 1780class OutOfBandRemoteAccess(SmbiosBaseStructure): 1781 smbios_structure_type = 30 1782 1783 def __init__(self, u, sm): 1784 super(OutOfBandRemoteAccess, self).__init__(u, sm) 1785 u = self.u 1786 try: 1787 if self.length > 0x4: 1788 self.add_field('manufacturer_name', u.unpack_one("B"), self.fmtstr) 1789 if self.length > 0x5: 1790 self.add_field('connections', u.unpack_one("B")) 1791 self.add_field('outbound_connection_enabled', bool(bitfields.getbits(self.connections, 1)), "connections[1]={}") 1792 self.add_field('inbound_connection_enabled', bool(bitfields.getbits(self.connections, 0)), "connections[0]={}") 1793 except: 1794 self.decodeFailure = True 1795 print "Error parsing OutOfBandRemoteAccess" 1796 import traceback 1797 traceback.print_exc() 1798 self.fini() 1799 1800class BootIntegrityServicesEntryPoint(SmbiosBaseStructure): 1801 smbios_structure_type = 31 1802 1803class SystemBootInformation(SmbiosBaseStructure): 1804 smbios_structure_type = 32 1805 1806 def __init__(self, u, sm): 1807 super(SystemBootInformation, self).__init__(u, sm) 1808 u = self.u 1809 try: 1810 if self.length > 0xA: 1811 u.skip(6) 1812 _boot_status = { 1813 0: 'No errors detected', 1814 1: 'No bootable media', 1815 2: '"normal" operating system failed to load', 1816 3: 'Firmware-detected hardware failure, including "unknown" failure types', 1817 4: 'Operating system-detected hardware failure', 1818 5: 'User-requested boot, usually through a keystroke', 1819 6: 'System security violation', 1820 7: 'Previously-requested image', 1821 8: 'System watchdog timer expired, causing the system to reboot', 1822 xrange(9,127): 'Reserved for future assignment', 1823 xrange(128, 191): 'Vendor/OEM-specific implementations', 1824 xrange(192, 255): 'Product-specific implementations' 1825 } 1826 self.add_field('boot_status', u.unpack_one("B"), unpack.format_table("{}", _boot_status)) 1827 except: 1828 self.decodeFailure = True 1829 print "Error parsing SystemBootInformation" 1830 import traceback 1831 traceback.print_exc() 1832 self.fini() 1833 1834class MemoryErrorInfo64Bit(SmbiosBaseStructure): 1835 smbios_structure_type = 33 1836 1837 def __init__(self, u, sm): 1838 super(MemoryErrorInfo64Bit, self).__init__(u, sm) 1839 u = self.u 1840 try: 1841 if self.length > 0x4: 1842 _error_types = { 1843 0x01: 'Other', 1844 0x02: 'Unknown', 1845 0x03: 'OK', 1846 0x04: 'Bad read', 1847 0x05: 'Parity error', 1848 0x06: 'Single-bit error', 1849 0x07: 'Double-bit error', 1850 0x08: 'Multi-bit error', 1851 0x09: 'Nibble error', 1852 0x0A: 'Checksum error', 1853 0x0B: 'CRC error', 1854 0x0C: 'Corrected single-bit error', 1855 0x0D: 'Corrected error', 1856 0x0E: 'Uncorrectable error' 1857 } 1858 self.add_field('error_type', u.unpack_one("B"), unpack.format_table("{}", _error_types)) 1859 if self.length > 0x5: 1860 _error_granularity_field = { 1861 0x01: 'Other', 1862 0x02: 'Unknown', 1863 0x03: 'Device level', 1864 0x04: 'Memory partition level' 1865 } 1866 self.add_field('error_granularity', u.unpack_one("B"), unpack.format_table("{}", _error_granularity_field)) 1867 if self.length > 0x6: 1868 _error_operation_field = { 1869 0x01: 'Other', 1870 0x02: 'Unknown', 1871 0x03: 'Read', 1872 0x04: 'Write', 1873 0x05: 'Partial write' 1874 } 1875 self.add_field('error_operation', u.unpack_one("B"), unpack.format_table("{}", _error_operation_field)) 1876 if self.length > 0x7: 1877 self.add_field('vendor_syndrome', u.unpack_one("<I")) 1878 if self.length > 0xB: 1879 self.add_field('memory_array_error_address', u.unpack_one("<Q")) 1880 if self.length > 0xF: 1881 self.add_field('device_error_address', u.unpack_one("<Q")) 1882 if self.length > 0x13: 1883 self.add_field('error_resolution', u.unpack_one("<Q")) 1884 except: 1885 self.decodeFailure = True 1886 print "Error parsing MemoryErrorInfo64Bit" 1887 import traceback 1888 traceback.print_exc() 1889 self.fini() 1890 1891class ManagementDevice(SmbiosBaseStructure): 1892 smbios_structure_type = 34 1893 1894 def __init__(self, u, sm): 1895 super(ManagementDevice, self).__init__(u, sm) 1896 u = self.u 1897 try: 1898 if self.length > 0x4: 1899 self.add_field('description', u.unpack_one("B"), self.fmtstr) 1900 if self.length > 0x5: 1901 _type = { 1902 0x01: 'Other', 1903 0x02: 'Unknown', 1904 0x03: 'National Semiconductor LM75', 1905 0x04: 'National Semiconductor LM78', 1906 0x05: 'National Semiconductor LM79', 1907 0x06: 'National Semiconductor LM80', 1908 0x07: 'National Semiconductor LM81', 1909 0x08: 'Analog Devices ADM9240', 1910 0x09: 'Dallas Semiconductor DS1780', 1911 0x0A: 'Maxim 1617', 1912 0x0B: 'Genesys GL518SM', 1913 0x0C: 'Winbond W83781D', 1914 0x0D: 'Holtek HT82H791' 1915 } 1916 self.add_field('device_type', u.unpack_one("B"), unpack.format_table("{}", _type)) 1917 if self.length > 0x6: 1918 self.add_field('address', u.unpack_one("<I")) 1919 if self.length > 0xA: 1920 _address_type = { 1921 0x01: 'Other', 1922 0x02: 'Unknown', 1923 0x03: 'I/O Port', 1924 0x04: 'Memory', 1925 0x05: 'SM Bus' 1926 } 1927 self.add_field('address_type', u.unpack_one("B"), unpack.format_table("{}", _address_type)) 1928 except: 1929 self.decodeFailure = True 1930 print "Error parsing ManagementDevice" 1931 import traceback 1932 traceback.print_exc() 1933 self.fini() 1934 1935class ManagementDeviceComponent(SmbiosBaseStructure): 1936 smbios_structure_type = 35 1937 1938 def __init__(self, u, sm): 1939 super(ManagementDeviceComponent, self).__init__(u, sm) 1940 u = self.u 1941 try: 1942 if self.length > 0x4: 1943 self.add_field('description', u.unpack_one("B"), self.fmtstr) 1944 if self.length > 0x5: 1945 self.add_field('management_device_handle', u.unpack_one("<H")) 1946 if self.length > 0x7: 1947 self.add_field('component_handle', u.unpack_one("<H")) 1948 if self.length > 0x9: 1949 self.add_field('threshold_handle', u.unpack_one("<H")) 1950 except: 1951 self.decodeFailure = True 1952 print "Error parsing ManagementDeviceComponent" 1953 import traceback 1954 traceback.print_exc() 1955 self.fini() 1956 1957class ManagementDeviceThresholdData(SmbiosBaseStructure): 1958 smbios_structure_type = 36 1959 1960 def __init__(self, u, sm): 1961 super(ManagementDeviceThresholdData, self).__init__(u, sm) 1962 u = self.u 1963 try: 1964 if self.length > 0x4: 1965 self.add_field('lower_threshold_noncritical', u.unpack_one("<H")) 1966 if self.length > 0x6: 1967 self.add_field('upper_threshold_noncritical', u.unpack_one("<H")) 1968 if self.length > 0x8: 1969 self.add_field('lower_threshold_critical', u.unpack_one("<H")) 1970 if self.length > 0xA: 1971 self.add_field('upper_threshold_critical', u.unpack_one("<H")) 1972 if self.length > 0xC: 1973 self.add_field('lower_threshold_nonrecoverable', u.unpack_one("<H")) 1974 if self.length > 0xE: 1975 self.add_field('upper_threshold_nonrecoverable', u.unpack_one("<H")) 1976 except: 1977 self.decodeFailure = True 1978 print "Error parsing ManagementDeviceThresholdData" 1979 import traceback 1980 traceback.print_exc() 1981 self.fini() 1982 1983class MemoryChannel(SmbiosBaseStructure): 1984 smbios_structure_type = 37 1985 1986 def __init__(self, u, sm): 1987 super(MemoryChannel, self).__init__(u, sm) 1988 u = self.u 1989 try: 1990 if self.length > 0x4: 1991 _channel_type = { 1992 0x01: 'Other', 1993 0x02: 'Unknown', 1994 0x03: 'RamBus', 1995 0x04: 'SyncLink' 1996 } 1997 self.add_field('channel_type', u.unpack_one("B"), unpack.format_table("{}", _channel_type)) 1998 if self.length > 0x6: 1999 self.add_field('max_channel_load', u.unpack_one("B")) 2000 if self.length > 0x8: 2001 self.add_field('memory_device_count', u.unpack_one("B")) 2002 if self.length > 0xA: 2003 self.add_field('memory_device_load', u.unpack_one("B")) 2004 if self.length > 0xC: 2005 self.add_field('memory_device_handle', u.unpack_one("<H")) 2006 except: 2007 self.decodeFailure = True 2008 print "Error parsing MemoryChannel" 2009 import traceback 2010 traceback.print_exc() 2011 self.fini() 2012 2013class IPMIDeviceInformation(SmbiosBaseStructure): 2014 smbios_structure_type = 38 2015 2016 def __init__(self, u, sm): 2017 super(IPMIDeviceInformation, self).__init__(u, sm) 2018 u = self.u 2019 try: 2020 _interface_type = { 2021 0x00: 'Unknown', 2022 0x01: 'KCS: Keyboard Controller Style', 2023 0x02: 'SMIC: Server Management Interface Chip', 2024 0x03: 'BT: Block Transfer', 2025 xrange(0x04, 0xFF): 'Reserved' 2026 } 2027 self.add_field('interface_type', u.unpack_one("B"), unpack.format_table("{}", _interface_type)) 2028 self.add_field('ipmi_specification_revision', u.unpack_one("B")) 2029 self.add_field('msd_revision', bitfields.getbits(self.ipmi_specification_revision, 7, 4), "ipmi_specification_revision[7:4]={}") 2030 self.add_field('lsd_revision', bitfields.getbits(self.ipmi_specification_revision, 3, 0), "ipmi_specification_revision[3:0]={}") 2031 2032 self.add_field('i2c_slave_address', u.unpack_one("B")) 2033 self.add_field('nv_storage_device_address', u.unpack_one("B")) 2034 self.add_field('base_address', u.unpack_one("<Q")) 2035 # if lsb is 1, address is in IO space. otherwise, memory-mapped 2036 self.add_field('base_address_modifier_interrupt_info', u.unpack_one("B")) 2037 _reg_spacing = { 2038 0b00: 'Interface registers are on successive byte boundaries', 2039 0b01: 'Interface registers are on 32-bit boundaries', 2040 0b10: 'Interface registers are on 16-byte boundaries', 2041 0b11: 'Reserved' 2042 } 2043 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)) 2044 self.add_field('ls_bit_for_addresses', bitfields.getbits(self.base_address_modifier_interrupt_info, 4), "base_address_modifier_interrupt_info[4]={}") 2045 self.add_field('interrupt_info_specified', bool(bitfields.getbits(self.base_address_modifier_interrupt_info, 3)), "base_address_modifier_interrupt_info[3]={}") 2046 _polarity = { 2047 0: 'active low', 2048 1: 'active high' 2049 } 2050 self.add_field('interrupt_polarity', bitfields.getbits(self.base_address_modifier_interrupt_info, 1), unpack.format_table("base_address_modifier_interrupt_info[1]={}", _polarity)) 2051 _interrupt_trigger = { 2052 0: 'edge', 2053 1: 'level' 2054 } 2055 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)) 2056 self.add_field('interrupt_number', u.unpack_one("B")) 2057 except: 2058 self.decodeFailure = True 2059 print "Error parsing IPMIDeviceInformation" 2060 import traceback 2061 traceback.print_exc() 2062 self.fini() 2063 2064class SystemPowerSupply(SmbiosBaseStructure): 2065 smbios_structure_type = 39 2066 2067 def __init__(self, u, sm): 2068 super(SystemPowerSupply, self).__init__(u, sm) 2069 u = self.u 2070 try: 2071 if self.length > 0x4: 2072 self.add_field('power_unit_group', u.unpack_one("B")) 2073 if self.length > 0x5: 2074 self.add_field('location', u.unpack_one("B"), self.fmtstr) 2075 if self.length > 0x6: 2076 self.add_field('device_name', u.unpack_one("B"), self.fmtstr) 2077 if self.length > 0x7: 2078 self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr) 2079 if self.length > 0x8: 2080 self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) 2081 if self.length > 0x9: 2082 self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr) 2083 if self.length > 0xA: 2084 self.add_field('model_part_number', u.unpack_one("B"), self.fmtstr) 2085 if self.length > 0xB: 2086 self.add_field('revision_level', u.unpack_one("B"), self.fmtstr) 2087 if self.length > 0xC: 2088 self.add_field('max_power_capacity', u.unpack_one("<H")) 2089 if self.length > 0xE: 2090 self.add_field('power_supply_characteristics', u.unpack_one("<H")) 2091 _dmtf_power_supply_type = { 2092 0b001: 'Other', 2093 0b010: 'Unknown', 2094 0b011: 'Linear', 2095 0b100: 'Switching', 2096 0b101: 'Battery', 2097 0b110: 'UPS', 2098 0b111: 'Converter', 2099 0b1000: 'Regulator', 2100 xrange(0b1001, 0b1111): 'Reserved' 2101 } 2102 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)) 2103 _status = { 2104 0b001: 'Other', 2105 0b010: 'Unknown', 2106 0b011: 'OK', 2107 0b100: 'Non-critical', 2108 0b101: 'Critical; power supply has failed and has been taken off-line' 2109 } 2110 self.add_field('status', bitfields.getbits(self.power_supply_characteristics, 9, 7), unpack.format_table("power_supply_characteristics[9:7]={}", _status)) 2111 _dmtf_input_voltage_range_switching = { 2112 0b001: 'Other', 2113 0b010: 'Unknown', 2114 0b011: 'Manual', 2115 0b100: 'Auto-switch', 2116 0b101: 'Wide range', 2117 0b110: 'Not applicable', 2118 xrange(0b0111, 0b1111): 'Reserved' 2119 } 2120 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)) 2121 self.add_field('power_supply_unplugged', bool(bitfields.getbits(self.power_supply_characteristics, 2)), "power_supply_characteristics[2]={}") 2122 self.add_field('power_supply_present', bool(bitfields.getbits(self.power_supply_characteristics, 1)), "power_supply_characteristics[1]={}") 2123 self.add_field('power_supply_hot_replaceable', bool(bitfields.getbits(self.power_supply_characteristics, 0)), "power_supply_characteristics[0]={}") 2124 if self.length > 0x10: 2125 self.add_field('input_voltage_probe_handle', u.unpack_one("<H")) 2126 if self.length > 0x12: 2127 self.add_field('cooling_device_handle', u.unpack_one("<H")) 2128 if self.length > 0x14: 2129 self.add_field('input_current_probe_handle', u.unpack_one("<H")) 2130 except: 2131 self.decodeFailure = True 2132 print "Error parsing SystemPowerSupply" 2133 import traceback 2134 traceback.print_exc() 2135 self.fini() 2136 2137class AdditionalInformation(SmbiosBaseStructure): 2138 smbios_structure_type = 40 2139 2140 def __init__(self, u, sm): 2141 super(AdditionalInformation, self).__init__(u, sm) 2142 u = self.u 2143 try: 2144 if self.length > 0x4: 2145 self.add_field('num_additional_information_entries', u.unpack_one("B")) 2146 if self.length > 0x5: 2147 self.add_field('additional_information_entry_length', u.unpack_one("B")) 2148 self.add_field('referenced_handle', u.unpack_one("<H")) 2149 self.add_field('referenced_offset', u.unpack_one("B")) 2150 self.add_field('string', u.unpack_one("B"), self.fmtstr) 2151 self.add_field('value', u.unpack_rest()) 2152 except: 2153 self.decodeFailure = True 2154 print "Error parsing AdditionalInformation" 2155 import traceback 2156 traceback.print_exc() 2157 self.fini() 2158 2159class OnboardDevicesExtendedInformation(SmbiosBaseStructure): 2160 smbios_structure_type = 41 2161 2162 def __init__(self, u, sm): 2163 super(OnboardDevicesExtendedInformation, self).__init__(u, sm) 2164 u = self.u 2165 try: 2166 if self.length > 0x4: 2167 self.add_field('reference_designation', u.unpack_one("B"), self.fmtstr) 2168 if self.length > 0x5: 2169 self.add_field('device_type', u.unpack_one("B")) 2170 self.add_field('device_enabled', bool(bitfields.getbits(self.device_type, 7)), "device_type[7]={}") 2171 _device_types = { 2172 0x01: 'Other', 2173 0x02: 'Unknown', 2174 0x03: 'Video', 2175 0x04: 'SCSI Controller', 2176 0x05: 'Ethernet', 2177 0x06: 'Token Ring', 2178 0x07: 'Sound', 2179 0x08: 'PATA Controller', 2180 0x09: 'SATA Controller', 2181 0x0A: 'SAS Controller' 2182 } 2183 self.add_field('type_of_device', bitfields.getbits(self.device_type, 6, 0), unpack.format_table("device_type[6:0]={}", _device_types)) 2184 if self.length > 0x6: 2185 self.add_field('device_type_instance', u.unpack_one("B")) 2186 if self.length > 0x7: 2187 self.add_field('segment_group_number', u.unpack_one("<H")) 2188 if self.length > 0x9: 2189 self.add_field('bus_number', u.unpack_one("B"), self.fmtstr) 2190 if self.length > 0xA: 2191 self.add_field('device_and_function_number', u.unpack_one("B")) 2192 self.add_field('device_number', bitfields.getbits(self.device_type, 7, 3), "device_and_function_number[7:3]={}") 2193 self.add_field('function_number', bitfields.getbits(self.device_type, 2, 0), "device_and_function_number[2:0]={}") 2194 except: 2195 self.decodeFailure = True 2196 print "Error parsing OnboardDevicesExtendedInformation" 2197 import traceback 2198 traceback.print_exc() 2199 self.fini() 2200 2201class ManagementControllerHostInterface(SmbiosBaseStructure): 2202 smbios_structure_type = 42 2203 2204 def __init__(self, u, sm): 2205 super(ManagementControllerHostInterface, self).__init__(u, sm) 2206 u = self.u 2207 try: 2208 if self.length > 0x4: 2209 _interface_types = { 2210 0x00: 'Reserved', 2211 0x01: 'Reserved', 2212 0x02: 'KCS: Keyboard Controller Style', 2213 0x03: '8250 UART Register Compatible', 2214 0x04: '16450 UART Register Compatible', 2215 0x05: '16550/16550A UART Register Compatible', 2216 0x06: '16650/16650A UART Register Compatible', 2217 0x07: '16750/16750A UART Register Compatible', 2218 0x08: '16850/16850A UART Register Compatible', 2219 0xF0: 'OEM' 2220 } 2221 self.add_field('interface_type', u.unpack_one("B"), unpack.format_table("{}", _interface_types)) 2222 if self.length > 0x5: 2223 self.add_field('mc_host_interface_data', u.unpack_rest(), self.fmtstr) 2224 except: 2225 self.decodeFailure = True 2226 print "Error parsing ManagementControllerHostInterface" 2227 import traceback 2228 traceback.print_exc() 2229 self.fini() 2230 2231class Inactive(SmbiosBaseStructure): 2232 smbios_structure_type = 126 2233 2234 def __init__(self, u, sm): 2235 super(Inactive, self).__init__(u, sm) 2236 self.fini() 2237 2238class EndOfTable(SmbiosBaseStructure): 2239 smbios_structure_type = 127 2240 2241 def __init__(self, u, sm): 2242 super(EndOfTable, self).__init__(u, sm) 2243 self.fini() 2244 2245class SmbiosStructureUnknown(SmbiosBaseStructure): 2246 smbios_structure_type = None 2247 2248 def __init__(self, u, sm): 2249 super(SmbiosStructureUnknown, self).__init__(u, sm) 2250 self.fini() 2251 2252_smbios_structures = [ 2253 BIOSInformation, 2254 SystemInformation, 2255 BaseboardInformation, 2256 SystemEnclosure, 2257 ProcessorInformation, 2258 MemoryControllerInformation, 2259 MemoryModuleInformation, 2260 CacheInformation, 2261 PortConnectorInfo, 2262 SystemSlots, 2263 OnBoardDevicesInformation, 2264 OEMStrings, 2265 SystemConfigOptions, 2266 BIOSLanguageInformation, 2267 GroupAssociations, 2268 SystemEventLog, 2269 PhysicalMemoryArray, 2270 MemoryDevice, 2271 MemoryErrorInfo32Bit, 2272 MemoryArrayMappedAddress, 2273 MemoryDeviceMappedAddress, 2274 BuiltInPointingDevice, 2275 PortableBattery, 2276 SystemReset, 2277 HardwareSecurity, 2278 SystemPowerControls, 2279 VoltageProbe, 2280 CoolingDevice, 2281 TemperatureProbe, 2282 ElectricalCurrentProbe, 2283 OutOfBandRemoteAccess, 2284 BootIntegrityServicesEntryPoint, 2285 SystemBootInformation, 2286 MemoryErrorInfo64Bit, 2287 ManagementDevice, 2288 ManagementDeviceComponent, 2289 ManagementDeviceThresholdData, 2290 MemoryChannel, 2291 IPMIDeviceInformation, 2292 SystemPowerSupply, 2293 AdditionalInformation, 2294 OnboardDevicesExtendedInformation, 2295 ManagementControllerHostInterface, 2296 Inactive, 2297 EndOfTable, 2298 SmbiosStructureUnknown, # Must always come last 2299] 2300 2301def log_smbios_info(): 2302 with redirect.logonly(): 2303 try: 2304 sm = SMBIOS() 2305 print 2306 if sm is None: 2307 print "No SMBIOS structures found" 2308 return 2309 output = {} 2310 known_types = (0, 1) 2311 for sm_struct in sm.structures: 2312 if sm_struct.type in known_types: 2313 output.setdefault(sm_struct.type, []).append(sm_struct) 2314 if len(output) == len(known_types): 2315 break 2316 2317 print "SMBIOS information:" 2318 for key in sorted(known_types): 2319 for s in output.get(key, ["No structure of type {} found".format(key)]): 2320 print ttypager._wrap("{}: {}".format(key, s)) 2321 except: 2322 print "Error parsing SMBIOS information:" 2323 import traceback 2324 traceback.print_exc() 2325 2326def dump_raw(): 2327 try: 2328 sm = SMBIOS() 2329 if sm: 2330 s = "SMBIOS -- Raw bytes and structure decode.\n\n" 2331 2332 s += str(sm.header) + '\n' 2333 s += bits.dumpmem(sm._header_memory) + '\n' 2334 2335 s += "Raw bytes for the SMBIOS structures\n" 2336 s += bits.dumpmem(sm._structure_memory) + '\n' 2337 2338 for sm_struct in sm.structures: 2339 s += str(sm_struct) + '\n' 2340 s += bits.dumpmem(sm_struct.raw_data) 2341 2342 s += "Strings:\n" 2343 for n in range(1, len(getattr(sm_struct, "strings", [])) + 1): 2344 s += str(sm_struct.fmtstr(n)) + '\n' 2345 s += bits.dumpmem(sm_struct.raw_strings) + '\n' 2346 else: 2347 s = "No SMBIOS structures found" 2348 ttypager.ttypager_wrap(s, indent=False) 2349 except: 2350 print "Error parsing SMBIOS information:" 2351 import traceback 2352 traceback.print_exc() 2353 2354def dump(): 2355 try: 2356 sm = SMBIOS() 2357 if sm: 2358 s = str(sm) 2359 else: 2360 s = "No SMBIOS structures found" 2361 ttypager.ttypager_wrap(s, indent=False) 2362 except: 2363 print "Error parsing SMBIOS information:" 2364 import traceback 2365 traceback.print_exc() 2366 2367def annex_a_conformance(): 2368 try: 2369 sm = SMBIOS() 2370 2371 # check: 1. The table anchor string "_SM_" is present in the address range 0xF0000 to 0xFFFFF on a 16-byte bound 2372 2373 def table_entry_point_verification(): 2374 ''' Verify table entry-point''' 2375 if (sm.header.length < 0x1F): 2376 print "Failure: Table entry-point - The entry-point Length must be at least 0x1F" 2377 if sm.header.checksum != 0: 2378 print "Failure: Table entry-point - The entry-point checksum must evaluate to 0" 2379 if ((sm.header.major_version < 2) and (sm.header.minor_version < 4)): 2380 print "Failure: Table entry-point - SMBIOS version must be at least 2.4" 2381 if (sm.header.intermediate_anchor_string == '_DMI_'): 2382 print "Failure: Table entry-point - The Intermediate Anchor String must be '_DMI_'" 2383 if (sm.header.intermediate_checksum != 0): 2384 print "Failure: Table entry-point - The Intermediate checksum must evaluate to 0" 2385 2386 #check: 3. The structure-table is traversable and conforms to the entry-point specifications: 2387 2388 def req_structures(): 2389 '''Checks for required structures and corresponding data''' 2390 types_present = [sm.structures[x].smbios_structure_type for x in range(len(sm.structures))] 2391 required = [0, 1, 4, 7, 9, 16, 17, 19, 31, 32] 2392 for s in required: 2393 if s not in set(types_present): 2394 print "Failure: Type {} required but not found".format(s) 2395 2396 else: 2397 if s == 0: 2398 if types_present.count(s) > 1: 2399 print "Failure: Type {} - One and only one structure of this type must be present.".format(s) 2400 if sm.structure_type(s).length < 0x18: 2401 print "Failure: Type {} - The structure Length field must be at least 0x18".format(s) 2402 if sm.structure_type(s).version is None: 2403 print "Failure: Type {} - BIOS Version string must be present and non-null.".format(s) 2404 if sm.structure_type(s).release_date is None: 2405 print "Failure: Type {} - BIOS Release Date string must be present, non-null, and include a 4-digit year".format(s) 2406 if bitfields.getbits(sm.structure_type(s).characteristics, 3, 0) != 0 or bitfields.getbits(sm.structure_type(s).characteristics, 31, 4) == 0: 2407 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) 2408 elif s == 1: 2409 if types_present.count(s) > 1: 2410 print "Failure: Type {} - One and only one structure of this type must be present.".format(s) 2411 if sm.structure_type(s).length < 0x1B: 2412 print "Failure: Type {} - The structure Length field must be at least 0x1B".format(s) 2413 if sm.structure_type(s).manufacturer == None: 2414 print "Failure: Type {} - Manufacturer string must be present and non-null.".format(s) 2415 if sm.structure_type(s).product_name == None: 2416 print "Failure: Type {} - Product Name string must be present and non-null".format(s) 2417 if sm.structure_type(s).uuid == '00000000 00000000' and sm.structure_type(s).uuid == 'FFFFFFFF FFFFFFFF': 2418 print "Failure: Type {} - UUID field must be neither 00000000 00000000 nor FFFFFFFF FFFFFFFF.".format(s) 2419 if sm.structure_type(s).wakeup_type == 00 and sm.structure_type(s).wakeup_type == 0x02: 2420 print "Failure: Type {} - Wake-up Type field must be neither 00h (Reserved) nor 02h (Unknown).".format(s) 2421 # continue for remaining required types 2422 2423 # check remaining conformance guidelines 2424 2425 table_entry_point_verification() 2426 req_structures() 2427 except: 2428 print "Error checking ANNEX A conformance guidelines" 2429 import traceback 2430 traceback.print_exc() 2431