master
py2 2,434 lines 108 KB
Raw
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
33 import bits
34 import bitfields
35 import ctypes
36 import redirect
37 import struct
38 import uuid
39 import unpack
40 import ttypager
41 import sys
42
43 class 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
94 class 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
119 class SmbiosBaseStructure(unpack.Struct):
120 def __new__(cls, u, sm):
121 t = u.unpack_peek_one("B")
122 if cls.smbios_structure_type is not None and t != cls.smbios_structure_type:
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
169 class 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
200 class 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
251 class 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
294 class 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
378 class SystemEnclosureContainedElement(unpack.Struct):
379 def __init__(self, u, length):
380 super(SystemEnclosureContainedElement, self).__init__()
381 self.start_offset = u.offset
382 self.raw_data = u.unpack_raw(length)
383 self.u = unpack.Unpackable(self.raw_data)
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
402 class 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
499 class 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
546 class 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
578 class 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
672 class 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
773 class 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
885 class 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
915 class 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
930 class 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
945 class 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
966 class 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
983 class 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
1034 class 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): 'Available 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
1079 class 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
1141 class 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
1246 class 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
1303 class 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
1335 class 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
1372 class 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
1416 class 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
1482 class 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
1516 class 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
1542 class 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
1562 class 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
1617 class 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
1666 class 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
1725 class 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
1784 class 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
1804 class BootIntegrityServicesEntryPoint(SmbiosBaseStructure):
1805 smbios_structure_type = 31
1806
1807 class 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
1838 class 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
1895 class 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
1939 class 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
1961 class 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
1987 class 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
2017 class 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
2068 class 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
2141 class 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
2163 class 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
2205 class 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
2235 class 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
2242 class 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
2249 class 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
2305 def 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
2330 def 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
2358 def 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
2371 def 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()