|
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() |