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