Serenity Operating System
1/*
2 * Copyright (c) 2020, Liav A. <liavalb@hotmail.co.il>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. 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 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#pragma once
28
29#include <AK/SinglyLinkedList.h>
30#include <AK/Types.h>
31#include <AK/Vector.h>
32#include <Kernel/VM/Region.h>
33#include <LibBareMetal/Memory/PhysicalAddress.h>
34#include <LibBareMetal/Memory/VirtualAddress.h>
35
36namespace Kernel {
37
38namespace SMBIOS {
39struct [[gnu::packed]] LegacyEntryPoint32bit
40{
41 char legacy_sig[5];
42 u8 checksum2;
43 u16 smboios_table_length;
44 u32 smbios_table_ptr;
45 u16 smbios_tables_count;
46 u8 smbios_bcd_revision;
47};
48
49struct [[gnu::packed]] EntryPoint32bit
50{
51 char sig[4];
52 u8 checksum;
53 u8 length;
54 u8 major_version;
55 u8 minor_version;
56 u16 maximum_structure_size;
57 u8 implementation_revision;
58 char formatted_area[5];
59 LegacyEntryPoint32bit legacy_structure;
60};
61
62struct [[gnu::packed]] EntryPoint64bit
63{
64 char sig[5];
65 u8 checksum;
66 u8 length;
67 u8 major_version;
68 u8 minor_version;
69 u8 document_revision;
70 u8 revision;
71 u8 reserved;
72 u32 table_maximum_size;
73 u64 table_ptr;
74};
75
76struct [[gnu::packed]] TableHeader
77{
78 u8 type;
79 u8 length;
80 u16 handle;
81};
82
83enum class TableType {
84 BIOSInfo = 0,
85 SysInfo = 1,
86 ModuleInfo = 2,
87 SysEnclosure = 3,
88 ProcessorInfo = 4,
89 CacheInfo = 7,
90 PortConnectorInfo = 8,
91 SystemSlots = 9,
92 OEMStrings = 11,
93 SysConfigOptions = 12,
94 BIOSLanguageInfo = 13,
95 GroupAssociations = 14,
96 SysEventLog = 15,
97 PhysicalMemoryArray = 16,
98 MemoryDevice = 17,
99 MemoryErrorInfo32Bit = 18,
100 MemoryArrayMappedAddress = 19,
101 MemoryDeviceMappedAddress = 20,
102 BuiltinPointingDevice = 21,
103 PortableBattery = 22,
104 SysReset = 23,
105 HardwareSecurity = 24,
106 SysPowerControls = 25,
107 VoltageProbe = 26,
108 CoolingDevice = 27,
109 TemperatureProbe = 28,
110 ElectricalCurrentProbe = 29,
111 OutOfBandRemoteAccess = 30,
112 SystemBootInfo = 32,
113 MemoryErrorInfo64Bit = 33,
114 ManagementDevice = 34,
115 ManagementDeviceComponent = 35,
116 ManagementDeviceThresholdData = 36,
117 MemoryChannel = 37,
118 IPMIDeviceInfo = 38,
119 SysPowerSupply = 39,
120 AdditionalInfo = 40,
121 OnboardDevicesExtendedInfo = 41,
122 ManagementControllerHostInterface = 42,
123 TPMDevice = 43,
124 ProcessorAdditionalInfo = 44,
125 Inactive = 126,
126 EndOfTable = 127
127};
128
129struct [[gnu::packed]] BIOSInfo
130{ // Type 0
131 TableHeader h;
132 u8 bios_vendor_str_number;
133 u8 bios_version_str_number;
134 u16 bios_segment;
135 u8 bios_release_date_str_number;
136 u8 bios_rom_size;
137 u64 bios_characteristics;
138 u8 ext_bios_characteristics[];
139};
140
141enum class BIOSCharacteristics {
142 Unknown = (1 << 2),
143 NotSupported = (1 << 3),
144 ISA_support = (1 << 4),
145 MCA_support = (1 << 5),
146 EISA_support = (1 << 6),
147 PCI_support = (1 << 7),
148 PCMCIA_support = (1 << 8),
149 PnP_support = (1 << 9),
150 APM_support = (1 << 10),
151 UpgradeableBIOS = (1 << 11),
152 Shadowing_BIOS = (1 << 12),
153 VL_VESA_support = (1 << 13),
154 ESCD_support = (1 << 14),
155 CD_boot_support = (1 << 15),
156 select_boot_support = (1 << 16),
157 BIOS_ROM_socketed = (1 << 17),
158 PCMCIA_boot_support = (1 << 18),
159 EDD_spec_support = (1 << 19),
160 floppy_nec98_1200k_support = (1 << 20),
161 floppy_toshiba_1200k_support = (1 << 21),
162 floppy_360k_support = (1 << 22),
163 floppy_1200k_services_support = (1 << 23),
164 floppy_720k_services_support = (1 << 24),
165 floppy_2880k_services_support = (1 << 25),
166 int5_print_screen_support = (1 << 26),
167 int9_8042_keyboard_support = (1 << 27),
168 int14_serial_support = (1 << 28),
169 int17_printer_support = (1 << 29),
170 int10_video_support = (1 << 30),
171 nec_pc98 = (1 << 31)
172};
173
174struct [[gnu::packed]] ExtBIOSInfo
175{
176 u8 bios_major_release;
177 u8 bios_minor_release;
178 u8 embedded_controller_firmware_major_release;
179 u8 embedded_controller_firmware_minor_release;
180 u16 ext_bios_rom_size;
181};
182
183struct [[gnu::packed]] SysInfo
184{ // Type 1
185 TableHeader h;
186 u8 manufacturer_str_number;
187 u8 product_name_str_number;
188 u8 version_str_number;
189 u8 serial_number_str_number;
190 u64 uuid[2];
191 u8 wake_up_type;
192 u8 sku_str_number;
193 u8 family_str_number;
194};
195
196enum class WakeUpType {
197 Reserved = 0,
198 Other = 1,
199 Unknown = 2,
200 APM_TIMER = 3,
201 MODEM_RING = 4,
202 LAN_REMOTE = 5,
203 POWER_SWTCH = 6,
204 PCI_PME = 7,
205 AC_RESTORE = 8,
206};
207
208struct [[gnu::packed]] ModuleInfo
209{ // Type 2
210 TableHeader h;
211 u8 manufacturer_str_number;
212 u8 product_name_str_number;
213 u8 version_str_number;
214 u8 serial_number_str_number;
215 u8 asset_tag_str_number;
216 u8 feature_flags;
217 u8 chassis_location;
218 u16 chassis_handle;
219 u8 board_type;
220 u8 contained_object_handles_count;
221 u16 contained_object_handles[];
222};
223
224enum class BoardType {
225 Unkown = 0x1,
226 Other = 0x2,
227 Server_Blade = 0x3,
228 Connectivity_Switch = 0x4,
229 System_Management_Module = 0x5,
230 Processor_Module = 0x6,
231 IO_Module = 0x7,
232 Memory_Module = 0x8,
233 Daughter_Board = 0x9,
234 Motherboard = 0xA,
235 Processor_Memory_Module = 0xB,
236 Processor_IO_Module = 0xC,
237 Interconnect_Board = 0xD,
238};
239
240struct [[gnu::packed]] SysEnclosure
241{ // Type 3
242 TableHeader h;
243 u8 manufacturer_str_number;
244 u8 type;
245 u8 version_str_number;
246 u8 serial_number_str_number;
247 u8 asset_tag_str_number;
248 u8 boot_up_state;
249 u8 power_supply_state;
250 u8 thermal_state;
251 u8 security_status;
252 u32 vendor_specific_info;
253 u8 height;
254 u8 power_cords_number;
255 u8 contained_element_count;
256 u8 contained_element_record_length;
257};
258
259struct [[gnu::packed]] ExtSysEnclosure
260{
261 u8 sku_str_number;
262};
263
264enum class SysEnclosureType {
265 Other = 0x1,
266 Unknown = 0x2,
267 Desktop = 0x3,
268 Low_Profile_Desktop = 0x4,
269 Pizza_Box = 0x5,
270 Mini_Tower = 0x6,
271 Tower = 0x7,
272 Portable = 0x8,
273 Laptop = 0x9,
274 Notebook = 0xA,
275 Hand_Held = 0xB,
276 Docking_Station = 0xC,
277 AIO = 0xD,
278 Sub_Notebook = 0xE,
279 Space_Saving = 0xF,
280 Lunch_Box = 0x10,
281 Main_Server_Chassis = 0x11,
282 Expansion_Chassis = 0x12,
283 Sub_Chassis = 0x13,
284 Bus_Expansion_Chassis = 0x14,
285 Peripheral_Chassis = 0x15,
286 RAID_Chassis = 0x16,
287 Rack_MOunt_Chassis = 0x17,
288 Sealed_case_PC = 0x18,
289 Multi_System_Chasis = 0x19,
290 Compact_PCI = 0x1A,
291 Advanced_TCA = 0x1B,
292 Blade = 0x1C,
293 Blade_Enclosure = 0x1D,
294 Tablet = 0x1E,
295 Convertible = 0x1F,
296 Detachable = 0x20,
297 IoT_Gateway = 0x21,
298 Embedded_PC = 0x22,
299 Mini_PC = 0x23,
300 Stick_PC = 0x24,
301};
302
303enum class SysEnclosureState {
304 Other = 0x1,
305 Unknown = 0x2,
306 Safe = 0x3,
307 Warning = 0x4,
308 Critical = 0x5,
309 Non_Recoverable = 0x6,
310};
311
312enum class SysEnclosureSecurityStatus {
313 Other = 0x1,
314 Unknown = 0x2,
315 None = 0x3,
316 External_Interface_Locked_Out = 0x4,
317 External_Interface_Enabled = 0x5,
318};
319
320struct [[gnu::packed]] SysEnclosureContainedElement
321{
322 u8 type;
323 u8 min_contained_element_count;
324 u8 max_contained_element_count;
325};
326
327struct [[gnu::packed]] ProcessorInfo
328{ // Type 4
329 TableHeader h;
330 u8 socket_designation_str_number;
331 u8 processor_type;
332 u8 processor_family;
333 u8 processor_manufacturer_str_number;
334 u64 processor_id;
335 u8 processor_version_str_number;
336 u8 voltage;
337 u16 external_clock;
338 u16 max_speed;
339 u16 current_speed;
340 u8 status;
341 u8 processor_upgrade;
342 u16 l1_cache_handle;
343 u16 l2_cache_handle;
344 u16 l3_cache_handle;
345 u8 serial_number_str_number;
346 u8 asset_tag_str_number;
347 u8 part_number_str_number;
348 u8 core_count;
349 u8 core_enabled;
350 u8 thread_count;
351 u16 processor_characteristics;
352 u16 processor_family2;
353 u16 core_count2;
354 u16 core_enabled2;
355 u16 thread_count2;
356};
357
358enum class ProcessorType {
359 Other = 0x1,
360 Unknown = 0x2,
361 Central_Processor = 0x3,
362 Math_Processor = 0x4,
363 DSP_Processor = 0x5,
364 Video_Processor = 0x6,
365};
366
367enum class ProcessorUpgrade {
368 Other = 0x1,
369 Unknown = 0x2,
370 Daughter_Board = 0x3,
371 ZIF_Socket = 0x4,
372 Replaceable_Piggy_Back = 0x5,
373 None = 0x6,
374 LIF_Sokcet = 0x7,
375 Slot_1 = 0x8,
376 Slot_2 = 0x9,
377 Socket_370_pin = 0xA,
378 Slot_A = 0xB,
379 Slot_M = 0xC,
380 Socket_423 = 0xD,
381 Socket_A_462 = 0xE,
382 Socket_478 = 0xF,
383 Socket_754 = 0x10,
384 Socket_940 = 0x11,
385 Socket_939 = 0x12,
386 Socket_mPGA604 = 0x13,
387 Socket_LGA771 = 0x14,
388 Socket_LGA775 = 0x15,
389 Socket_S1 = 0x16,
390 Socket_AM2 = 0x17,
391 Socket_F_1207 = 0x18,
392 Socket_LGA1366 = 0x19,
393 Socket_G34 = 0x1A,
394 Socket_AM3 = 0x1B,
395 Socket_C32 = 0x1C,
396 Socket_LGA1156 = 0x1D,
397 Socket_LGA1567 = 0x1E,
398 Socket_PGA988A = 0x1F,
399 Socket_BGA1288 = 0x20,
400 Socket_rPGA988B = 0x21,
401 Socket_BGA1023 = 0x22,
402 Socket_BGA1224 = 0x23,
403 Socket_LGA1155 = 0x24,
404 Socket_LGA1356 = 0x25,
405 Socket_LGA2011 = 0x26,
406 Socket_FS1 = 0x27,
407 Socket_FS2 = 0x28,
408 Socket_FM1 = 0x29,
409 Socket_FM2 = 0x2A,
410 Socket_LGA2011_3 = 0x2B,
411 Socket_LGA1356_3 = 0x2C,
412 Socket_LGA1150 = 0x2D,
413 Socket_BGA1168 = 0x2E,
414 Socket_BGA1234 = 0x2F,
415 Socket_BGA1364 = 0x30,
416 Socket_AM4 = 0x31,
417 Socket_LGA1151 = 0x32,
418 Socket_BGA1356 = 0x33,
419 Socket_BGA1440 = 0x34,
420 Socket_BGA1515 = 0x35,
421 Socket_LGA3647_1 = 0x36,
422 Socket_SP3 = 0x37,
423 Socket_SP3r2 = 0x38,
424 Socket_LGA2066 = 0x39,
425 Socket_BGA1392 = 0x3A,
426 Socket_BGA1510 = 0x3B,
427 Socket_BGA1528 = 0x3C
428};
429
430struct [[gnu::packed]] CacheInfo
431{ // Type 7
432 TableHeader h;
433 u8 socket_designation_str_number;
434 u16 cache_config;
435 u16 max_cache_size;
436 u16 installed_size;
437 u16 supported_sram_type;
438 u16 current_sram_type;
439 u8 cache_speed;
440 u8 error_correction_type;
441 u8 system_cache_type;
442 u8 associativity;
443 u32 max_cache_size2;
444 u32 installed_size2;
445};
446
447struct [[gnu::packed]] PortConnectorInfo
448{ // Type 8
449 TableHeader h;
450 u8 internal_reference_designator_str_number;
451 u8 internal_connector_type;
452 u8 external_reference_designator_str_number;
453 u8 external_connector_type;
454 u8 port_type;
455};
456
457enum class ConnectorType {
458 None = 0x0,
459 Centronics = 0x1,
460 Mini_Centronics = 0x2,
461 Proprietary = 0x3,
462 DB_25_pin_male = 0x4,
463 DB_25_pin_female = 0x5,
464 DB_15_pin_male = 0x6,
465 DB_15_pin_female = 0x7,
466 DB_9_pin_male = 0x8,
467 DB_9_pin_female = 0x9,
468 RJ_11 = 0xA,
469 RJ_45 = 0xB,
470 MiniSCSI_50_pin = 0xC,
471 MiniDIN = 0xD,
472 MicroDIN = 0xE,
473 PS2 = 0xF,
474 Infrared = 0x10,
475 HP_HIL = 0x11,
476 AccessBus_USB = 0x12,
477 SSA_SCSI = 0x13,
478 Circular_DIN8_male = 0x14,
479 Circular_DIN8_female = 0x15,
480 OnBoard_IDE = 0x16,
481 OnBoard_Floppy = 0x17,
482 Dual_Inline_9pin = 0x18,
483 Dual_Inline_25pin = 0x19,
484 Dual_Inline_50pin = 0x1A,
485 Dual_Inline_68pin = 0x1B,
486 OnBoard_SoundInput_CDROM = 0x1C,
487 Mini_Centronics_Type14 = 0x1D,
488 Mini_Centronics_Type26 = 0x1E,
489 Mini_Jack_Headphones = 0x1F,
490 BNC = 0x20,
491 Connector_1394 = 0x21,
492 SAS_SATA_Plug_Receptacle = 0x22,
493 USB_TypeC_Receptacle = 0x23,
494 PC98 = 0xA0,
495 PC98_Hireso = 0xA1,
496 PC_H98 = 0xA2,
497 PC98_Note = 0xA3,
498 PC98_Full = 0xA4,
499 Other = 0xFF
500};
501
502enum class PortType {
503 None = 0x0,
504 Parallel_Port_XT_AT_Compatible = 0x1,
505 Parallel_Port_PS2 = 0x2,
506 Parallel_Port_ECP = 0x3,
507 Parallel_Port_EPP = 0x4,
508 Parallel_Port_ECP_EPP = 0x5,
509 Serial_Port_XT_AT_Compatible = 0x6,
510 Serial_Port_16450_Compatible = 0x7,
511 Serial_Port_16550_Compatible = 0x8,
512 Serial_Port_16550A_Compatible = 0x9,
513 SCSI_Port = 0xA,
514 MIDI_Port = 0xB,
515 Joy_Stick_Port = 0xC,
516 Keyboard_Port = 0xD,
517 Mouse_Port = 0xE,
518 SSA_SCSI = 0xF,
519 USB = 0x10,
520 FireWire = 0x11,
521 PCMCIA_Type1 = 0x12,
522 PCMCIA_Type2 = 0x13,
523 PCMCIA_Type3 = 0x14,
524 Cardbus = 0x15,
525 AccessBus_Port = 0x16,
526 SCSI_2 = 0x17,
527 SCSI_Wide = 0x18,
528 PC98 = 0x19,
529 PC98_Hireso = 0x1A,
530 PC_H98 = 0x1B,
531 Video_Port = 0x1C,
532 Audio_Port = 0x1D,
533 Modem_Port = 0x1E,
534 Network_Port = 0x1F,
535 SATA = 0x20,
536 SAS = 0x21,
537 MFDP = 0x22,
538 Thunderbolt = 0x23,
539 Intel_8251_Compatible = 0xA0,
540 Intel_8251_FIFO_Compatible = 0xA1,
541 Other = 0xFF
542};
543
544struct [[gnu::packed]] SystemSlotPeerGroup
545{
546 u16 segment_group_number;
547 u8 bus_number;
548 u8 device_function_number;
549 u8 data_bus_width;
550};
551
552struct [[gnu::packed]] SystemSlots
553{ // Type 9
554 TableHeader h;
555 u8 slot_designation_str_number;
556 u8 slot_type;
557 u8 slot_data_bus_width;
558 u8 current_stage;
559 u8 slot_length;
560 u16 slot_id;
561 u8 slot_characteristics_1;
562 u8 slot_characteristics_2;
563 u16 segment_group_number;
564 u8 bus_number;
565 u8 device_function_number;
566 u8 data_bus_width;
567 u8 peer_grouping_count;
568 SystemSlotPeerGroup peer_groups[];
569};
570
571enum class SlotType {
572 Other = 0x1,
573 Unknown = 0x2,
574 ISA = 0x3,
575 MCA = 0x4,
576 EISA = 0x5,
577 PCI = 0x6,
578 PCMCIA = 0x7,
579 VL_VESA = 0x8,
580 Proprietary = 0x9,
581 Processor_Card_Slot = 0xA,
582 Proprietary_Memory_Card_Slot = 0xB,
583 IO_Riser_Card_Slot = 0xC,
584 NuBus = 0xD,
585 PCI_66MHZ_Capable = 0xE,
586 AGP = 0xF,
587 AGP_2X = 0x10,
588 AGP_4X = 0x11,
589 PCI_X = 0x12,
590 AGP_8X = 0x13,
591 M_Dot_2_Socket_1_DP = 0x14,
592 M_Dot_2_Socket_1_SD = 0x15,
593 M_Dot_2_Socket_2 = 0x16,
594 M_Dot_2_Socket_3 = 0x17,
595 MXM_Type1 = 0x18,
596 MXM_Type2 = 0x19,
597 MXM_Type3_Standard = 0x1A,
598 MXM_Type3_HE = 0x1B,
599 MXM_Type4 = 0x1C,
600 MXM_3_Type_A = 0x1D,
601 MXM_3_Type_B = 0x1E,
602 PCI_Express_Gen2 = 0x1F,
603 PCI_Express_Gen3 = 0x20,
604 PCI_Express_Mini_52pin_Type1 = 0x21,
605 PCI_Express_Mini_52pin_Type2 = 0x22,
606 PCI_Express_Mini_76pin = 0x23,
607 CXL_Flexbus_1_0 = 0x30,
608 PC98_C20 = 0xA0,
609 PC98_C24 = 0xA1,
610 PC98_E = 0xA2,
611 PC98_Local_Bus = 0xA3,
612 PC98_Card = 0xA4,
613 PCI_Express = 0xA5,
614 PCI_Express_x1 = 0xA6,
615 PCI_Express_x2 = 0xA7,
616 PCI_Express_x4 = 0xA8,
617 PCI_Express_x8 = 0xA9,
618 PCI_Express_x16 = 0xAA,
619 PCI_Express_Gen_2 = 0xAB,
620 PCI_Express_Gen_2_x1 = 0xAC,
621 PCI_Express_Gen_2_x2 = 0xAD,
622 PCI_Express_Gen_2_x4 = 0xAE,
623 PCI_Express_Gen_2_x8 = 0xAF,
624 PCI_Express_Gen_2_x16 = 0xB0,
625 PCI_Express_Gen_3 = 0xB1,
626 PCI_Express_Gen_3_x1 = 0xB2,
627 PCI_Express_Gen_3_x2 = 0xB3,
628 PCI_Express_Gen_3_x4 = 0xB4,
629 PCI_Express_Gen_3_x8 = 0xB5,
630 PCI_Express_Gen_3_x16 = 0xB6,
631 PCI_Express_Gen_4 = 0xB8,
632 PCI_Express_Gen_4_x1 = 0xB9,
633 PCI_Express_Gen_4_x2 = 0xBA,
634 PCI_Express_Gen_4_x4 = 0xBB,
635 PCI_Express_Gen_4_x8 = 0xBC,
636 PCI_Express_Gen_4_x16 = 0xBD
637};
638
639enum class SlotDataBusWidth {
640 Other = 0x1,
641 Unknown = 0x2,
642 _8_bit = 0x3,
643 _16_bit = 0x4,
644 _32_bit = 0x5,
645 _64_bit = 0x6,
646 _128_bit = 0x7,
647 _1x_x1 = 0x8,
648 _2x_x2 = 0x9,
649 _4x_x4 = 0xA,
650 _8x_x8 = 0xB,
651 _12x_x12 = 0xC,
652 _16x_x16 = 0xD,
653 _32x_x32 = 0xE
654};
655
656enum class SlotCurrentUsage {
657 Other = 0x1,
658 Unknown = 0x2,
659 Available = 0x3,
660 In_Use = 0x4,
661 Unavailable = 0x5
662};
663
664enum class SlotLength {
665 Other = 0x1,
666 Unknown = 0x2,
667 Short_Length = 0x3,
668 Long_Length = 0x4,
669 _2_5_Drive_Form_Factor = 0x5,
670 _3_5_Drive_Form_Factor = 0x6
671};
672
673enum class SlotCharacteristics1 {
674 Unknown = (1 << 0),
675 Provides_5volt = (1 << 1),
676 Provides_3_3volt = (1 << 2),
677 Shared_Slot = (1 << 3),
678 Support_PC_Card_16 = (1 << 4),
679 Support_CardBus = (1 << 5),
680 Support_Zoom_Video = (1 << 6),
681 Support_Modem_Ring_Resume = (1 << 7)
682};
683
684enum class SlotCharacteristics2 {
685 Support_PCI_PME = (1 << 0),
686 Support_Hot_Plug = (1 << 1),
687 Support_SMBus = (1 << 2),
688 Support_Bifurcation = (1 << 3),
689};
690
691struct [[gnu::packed]] OEMStrings
692{ // Type 11
693 TableHeader h;
694 u8 strings_count;
695};
696
697struct [[gnu::packed]] SysConfigOptions
698{ // Type 12
699 TableHeader h;
700 u8 strings_count;
701};
702
703struct [[gnu::packed]] BIOSLanguageInfo
704{ // Type 13
705 TableHeader h;
706 u8 installable_langs_counts;
707 u8 flags;
708 u8 reserved[15];
709 u8 current_lang_str_number; // String number (one-based) of the currently installed language
710};
711
712struct [[gnu::packed]] GroupAssociations
713{ // Type 14
714 TableHeader h;
715 u8 group_name_str_number;
716 u8 item_type;
717 u16 item_handle;
718};
719
720struct [[gnu::packed]] SysEventLog
721{ // Type 15
722 TableHeader h;
723 u16 log_area_length;
724 u16 log_header_start_offset;
725 u16 log_data_start_offset;
726 u8 access_method;
727 u8 log_status;
728 u32 log_change_token;
729 u32 access_method_address;
730 u8 log_header_format;
731 u8 supported_log_type_descriptors_count;
732 u8 log_type_descriptor_length;
733 u8 supported_event_log_type_descriptor_list[];
734};
735
736struct [[gnu::packed]] PhysicalMemoryArray
737{ // Type 16
738 TableHeader h;
739 u8 location;
740 u8 use;
741 u8 memory_error_correction;
742 u32 max_capacity;
743 u16 memory_error_info_handle;
744 u16 memory_devices_count;
745 u64 ext_max_capacity;
746};
747
748enum class MemoryArrayLocation {
749 Other = 0x1,
750 Unknown = 0x2,
751 Motherboard = 0x3,
752 ISA_addon_card = 0x4,
753 EISA_addon_card = 0x5,
754 PCI_addon_card = 0x6,
755 MCA_addon_card = 0x7,
756 PCMCIA_addon_card = 0x8,
757 Proprietary_addon_card = 0x9,
758 NuBus = 0xA,
759 PC98_C20_addon_card = 0xA0,
760 PC98_C24_addon_card = 0xA1,
761 PC98_E_addon_card = 0xA2,
762 PC98_Local_Bus_addon_card = 0xA3,
763 CXL_Flexbus_1_0_addon_card = 0xA4
764};
765
766enum class MemoryArrayUse {
767 Other = 0x1,
768 Unknown = 0x2,
769 System_Memory = 0x3,
770 Video_Memory = 0x4,
771 Flash_Memory = 0x5,
772 Non_Volatile_RAM = 0x6,
773 Cache_Memory = 0x7
774};
775
776enum class MemoryArrayErrorCorrectionType {
777 Other = 0x1,
778 Unknown = 0x2,
779 None = 0x3,
780 Parity = 0x4,
781 SingleBit_ECC = 0x5,
782 MultiBit_ECC = 0x6,
783 CRC = 0x7
784};
785
786struct [[gnu::packed]] MemoryDevice
787{ // Type 17
788 TableHeader h;
789 u16 physical_memory_array_handle;
790 u16 memory_error_info_handle;
791 u16 total_width;
792 u16 data_width;
793 u16 size;
794 u8 form_factor;
795 u8 device_set;
796 u8 device_locator_str_number;
797 u8 bank_locator_str_number;
798 u8 memory_type;
799 u16 type_detail;
800 u16 speed;
801 u8 manufacturer_str_number;
802 u8 serial_number_str_number;
803 u8 asset_tag_str_number;
804 u8 part_number_str_number;
805 u8 attributes;
806 u32 ext_size;
807 u16 configured_memory_speed;
808 u16 min_voltage;
809 u16 max_voltage;
810 u16 configured_voltage;
811 u8 memory_technology;
812 u16 memory_operating_mode_capability;
813 u8 firmware_version_str_number;
814 u16 module_manufacturer_id;
815 u16 module_product_id;
816 u16 memory_subsystem_controller_manufacturer_id;
817 u16 memory_subsystem_controller_product_id;
818 u64 non_volatile_size;
819 u64 volatile_size;
820 u64 cache_size;
821 u64 logical_size;
822 u32 ext_speed;
823 u32 ext_configured_memory_speed;
824};
825
826enum class MemoryDeviceFormFactor {
827 Other = 0x1,
828 Unknown = 0x2,
829 SIMM = 0x3,
830 SIP = 0x4,
831 Chip = 0x5,
832 DIP = 0x6,
833 ZIP = 0x7,
834 ProprietaryCard = 0x8,
835 DIMM = 0x9,
836 TSOP = 0xA,
837 Chips_Row = 0xB,
838 RIMM = 0xC,
839 SODIMM = 0xD,
840 SRIMM = 0xE,
841 FB_DIMM = 0xF,
842 Die = 0x10
843};
844
845enum class MemoryDeviceType {
846 Other = 0x1,
847 Unknown = 0x2,
848 DRAM = 0x3,
849 EDRAM = 0x4,
850 VRAM = 0x5,
851 SRAM = 0x6,
852 RAM = 0x7,
853 ROM = 0x8,
854 FLASH = 0x9,
855 EEPROM = 0xA,
856 FEPROM = 0xB,
857 EPROM = 0xC,
858 CDRAM = 0xD,
859 _3DRAM = 0xE,
860 SDRAM = 0xF,
861 SGRAM = 0x10,
862 RDRAM = 0x11,
863 DDR = 0x12,
864 DDR2 = 0x13,
865 DDR2_FB_DIMM = 0x14,
866 DDR3 = 0x18,
867 FBD2 = 0x19,
868 DDR4 = 0x1A,
869 LPDDR = 0x1B,
870 LPDDR2 = 0x1C,
871 LPDDR3 = 0x1D,
872 LPDDR4 = 0x1E,
873 Logical_Non_Volatile_Device = 0x1F,
874 HBM = 0x20, // (High Bandwidth Memory)
875 HBM2 = 0x21, // (High Bandwidth Memory Generation 2)
876};
877
878enum class MemoryDeviceTypeDetail {
879 Other = (1 << 1),
880 Unknown = (1 << 2),
881 Fast_paged = (1 << 3),
882 Static_Column = (1 << 4),
883 Pseudo_Static = (1 << 5),
884 RAMBUS = (1 << 6),
885 Synchronous = (1 << 7),
886 CMOS = (1 << 8),
887 EDO = (1 << 9),
888 Window_DRAM = (1 << 10),
889 Cache_DRAM = (1 << 11),
890 Non_volatile = (1 << 12),
891 Registered_Buffered = (1 << 13),
892 Unbuffered_Unregistered = (1 << 14),
893 LRDIMM = (1 << 15)
894};
895
896enum class MemoryDeviceTechnology {
897 Other = 0x1,
898 Unknown = 0x2,
899 DRAM = 0x3,
900 NVDIMM_N = 0x4,
901 NVDIMM_F = 0x5,
902 NVDIMM_P = 0x6,
903 Intel_Optane_DC_Persistent_Memory = 0x7
904};
905
906enum class MemoryDeviceOperatingModeCapability {
907 Other = (1 << 1),
908 Unknown = (1 << 2),
909 Volatile_Memory = (1 << 3),
910 Byte_accessible_persistent_memory = (1 << 4),
911 Block_accessible_persistent_memory = (1 << 5),
912};
913
914struct MemoryErrorInfo32Bit { // Type 18
915 TableHeader h;
916 u8 error_type;
917 u8 error_granularity;
918 u8 error_operation;
919 u32 vendor_syndrome;
920 u32 memory_array_error_address;
921 u32 device_error_address;
922 u32 error_resolution;
923};
924
925enum class MemoryErrorType {
926 Other = 0x1,
927 Unknown = 0x2,
928 OK = 0x3,
929 Bad_read = 0x4,
930 Parity_error = 0x5,
931 SingleBit_error = 0x6,
932 DoubleBit_error = 0x7,
933 MultiBit_error = 0x8,
934 Nibble_error = 0x9,
935 Checksum_error = 0xA,
936 CRC_error = 0xB,
937 Corrected_SingleBit_error = 0xC,
938 Corrected_error = 0xD,
939 Uncorrectable_error = 0xE
940};
941
942enum class MemoryErrorGranularity {
943 Other = 0x1,
944 Unknown = 0x2,
945 Device_level = 0x3,
946 Memory_partition_level = 0x4
947};
948
949enum class MemoryErrorOperation {
950 Other = 0x1,
951 Unknown = 0x2,
952 Read = 0x3,
953 Write = 0x4,
954 Partial_Write = 0x5
955};
956
957struct [[gnu::packed]] MemoryArrayMappedAddress
958{ // Type 19
959 TableHeader h;
960 u32 starting_address;
961 u32 ending_address;
962 u16 memory_array_handle;
963 u8 partition_width;
964 u64 ext_starting_address;
965 u64 ext_ending_address;
966};
967
968struct [[gnu::packed]] MemoryDeviceMappedAddress
969{ // Type 20
970 TableHeader h;
971 u32 starting_address;
972 u32 ending_address;
973 u16 memory_device_handle;
974 u16 memory_array_mapped_handle;
975 u8 partition_row_position;
976 u8 interleave_position;
977 u8 interleaved_data_depth;
978 u64 ext_starting_address;
979 u64 ext_ending_address;
980};
981
982struct [[gnu::packed]] BuiltinPointingDevice
983{ // Type 21
984 TableHeader h;
985 u8 type;
986 u8 interface;
987 u8 buttons_count;
988};
989
990enum class PointingDeviceType {
991 Other = 0x1,
992 Unknown = 0x2,
993 Mouse = 0x3,
994 Track_Ball = 0x4,
995 Track_Point = 0x5,
996 Glide_Point = 0x6,
997 Touch_Pad = 0x7,
998 Touch_Screen = 0x8,
999 Optical_Sensor = 0x9
1000};
1001
1002enum class PointingDeviceInterface {
1003 Other = 0x1,
1004 Unknown = 0x2,
1005 Serial = 0x3,
1006 PS2 = 0x4,
1007 Infrared = 0x5,
1008 HP_HIL = 0x6,
1009 Bus_mouse = 0x7,
1010 AppleDesktopBus = 0x8,
1011 Bus_mouse_DB9 = 0xA0,
1012 Bus_mouse_microDIN = 0xA1,
1013 USB = 0xA2
1014};
1015
1016struct [[gnu::packed]] PortableBattery
1017{ // Type 22
1018 TableHeader h;
1019 u8 location_str_number;
1020 u8 manufacturer_str_number;
1021 u8 manufacture_date_str_number;
1022 u8 serial_number_str_number;
1023 u8 device_name_str_number;
1024 u8 device_chemistry;
1025 u16 design_capacity;
1026 u16 design_voltage;
1027 u8 sbds_version_number;
1028 u8 max_error_battery_data;
1029 u16 sbds_serial_number;
1030 u16 sbds_manufacture_date;
1031 u8 sbds_device_chemistry_str_number;
1032 u8 design_capacity_multiplier;
1033 u32 oem_specific;
1034};
1035
1036enum class PortableBatteryChemistry {
1037 Other = 0x1,
1038 Unknown = 0x2,
1039 Lead_Acid = 0x3,
1040 Nickel_Cadmium = 0x4,
1041 Nickel_metal_hydride = 0x5,
1042 Lithium_ion = 0x6,
1043 Zinc_air = 0x7,
1044 Lithium_polymer = 0x8
1045};
1046
1047struct [[gnu::packed]] SysReset
1048{ // Type 23
1049 TableHeader h;
1050 u8 capabilities;
1051 u16 reset_count;
1052 u16 reset_limit;
1053 u16 timer_interval;
1054 u16 timeout;
1055};
1056
1057struct [[gnu::packed]] HardwareSecurity
1058{ // Type 24
1059 TableHeader h;
1060 u8 hardware_security_settings;
1061};
1062
1063struct [[gnu::packed]] SysPowerControls
1064{ // Type 25
1065 TableHeader h;
1066 u8 next_scheduled_power_on_month;
1067 u8 next_scheduled_power_on_day_of_month;
1068 u8 next_scheduled_power_on_hour;
1069 u8 next_scheduled_power_on_minute;
1070 u8 next_scheduled_power_on_second;
1071};
1072
1073struct [[gnu::packed]] VoltageProbe
1074{ // Type 26
1075 TableHeader h;
1076 u8 description_str_number;
1077 u8 location_and_status;
1078 u16 max_value;
1079 u16 min_value;
1080 u16 resolution;
1081 u16 tolerance;
1082 u16 accuracy;
1083 u32 oem_defined;
1084 u16 nominal_value;
1085};
1086
1087struct [[gnu::packed]] CoolingDevice
1088{ // Type 27
1089 TableHeader h;
1090 u16 temperature_probe_handle;
1091 u8 device_type_and_status;
1092 u8 cooling_unit_group;
1093 u32 oem_defined;
1094 u16 nominal_speed;
1095 u8 description_str_number;
1096};
1097
1098struct [[gnu::packed]] TemperatureProbe
1099{ // Type 28
1100 TableHeader h;
1101 u8 description_str_number;
1102 u8 location_and_status;
1103 u16 max_value;
1104 u16 min_value;
1105 u16 resolution;
1106 u16 tolerance;
1107 u16 accuracy;
1108 u32 oem_defined;
1109 u16 nominal_value;
1110};
1111
1112struct [[gnu::packed]] ElectricalCurrentProbe
1113{ // Type 29
1114 TableHeader h;
1115 u8 description_str_number;
1116 u8 location_and_status;
1117 u16 max_value;
1118 u16 min_value;
1119 u16 resolution;
1120 u16 tolerance;
1121 u16 accuracy;
1122 u32 oem_defined;
1123 u16 nominal_value;
1124};
1125
1126struct [[gnu::packed]] OutOfBandRemoteAccess
1127{ // Type 30
1128 TableHeader h;
1129 u8 manufacturer_name_str_number;
1130 u8 connections;
1131};
1132
1133struct [[gnu::packed]] SystemBootInfo
1134{ // Type 32
1135 TableHeader h;
1136 u8 reserved[6];
1137 u8 boot_status[10];
1138};
1139
1140struct [[gnu::packed]] MemoryErrorInfo64Bit
1141{ // Type 33
1142 TableHeader h;
1143 u8 error_type;
1144 u8 error_granularity;
1145 u8 error_operation;
1146 u32 vendor_syndrome;
1147 u64 memory_array_error_address;
1148 u64 device_error_address;
1149 u32 error_resolution;
1150};
1151
1152struct [[gnu::packed]] ManagementDevice
1153{ // Type 34
1154 TableHeader h;
1155 u8 description_str_number;
1156 u8 type;
1157 u32 address;
1158 u8 address_type;
1159};
1160
1161enum class ManagementDeviceType {
1162 Other = 0x1,
1163 Unknown = 0x2,
1164 LM75 = 0x3,
1165 LM78 = 0x4,
1166 LM79 = 0x5,
1167 LM80 = 0x6,
1168 LM81 = 0x7,
1169 ADM9240 = 0x8,
1170 DS1780 = 0x9,
1171 Maxim_1617 = 0xA,
1172 GL518SM = 0xB, // Genesys GL518SM
1173 W83781D = 0xC, // Winbond W83781D
1174 HT82H791 = 0xD // Holtek HT82H791
1175};
1176
1177enum class ManagementDeviceAddressType {
1178 Other = 0x1,
1179 Unknown = 0x2,
1180 IO_Port = 0x3,
1181 Memory = 0x4,
1182 SMBus = 0x5
1183};
1184
1185struct [[gnu::packed]] ManagementDeviceComponent
1186{ // Type 35
1187 TableHeader h;
1188 u8 description_str_number;
1189 u16 management_device_handle;
1190 u16 component_handle;
1191 u16 threshold_handle;
1192};
1193
1194struct [[gnu::packed]] ManagementDeviceThresholdData
1195{ // Type 36
1196 TableHeader h;
1197 u16 lower_threshold_non_critical;
1198 u16 upper_threshold_non_critical;
1199 u16 lower_threshold_critical;
1200 u16 upper_threshold_critical;
1201 u16 lower_threshold_non_recoverable;
1202 u16 upper_threshold_non_recoverable;
1203};
1204
1205struct [[gnu::packed]] MemoryDeviceDescriptor
1206{
1207 u8 device_load;
1208 u16 device_handle;
1209};
1210
1211struct [[gnu::packed]] MemoryChannel
1212{ // Type 37
1213 TableHeader h;
1214 u8 channel_type;
1215 u8 memory_device_count;
1216 MemoryDeviceDescriptor memory_devices_descriptors[];
1217};
1218
1219enum class MemroryChannelType {
1220 Other = 0x1,
1221 Unknown = 0x2,
1222 RamBus = 0x3,
1223 SyncLink = 0x4
1224};
1225
1226struct [[gnu::packed]] IPMIDeviceInfo
1227{ // Type 38
1228 TableHeader h;
1229 u8 interface_type;
1230 u8 ipmi_spec_revision;
1231 u8 i2c_slave_address;
1232 u8 nv_storage_device_address;
1233 u64 base_address;
1234 u8 base_address_modifier;
1235 u8 interrupt_number;
1236};
1237
1238enum class IPMIDeviceInfoBMCInterfaceType {
1239 Unknown = 0x1,
1240 KCS = 0x2, // KCS: Keyboard Controller Style
1241 SMIC = 0x3, // SMIC: Server Management Interface Chip
1242 BT = 0x4, // BT: Block Transfer
1243 SSIF = 0x5 // SSIF: SMBus System Interface
1244};
1245
1246struct [[gnu::packed]] SysPowerSupply
1247{ // Type 39
1248 TableHeader h;
1249 u8 power_unit_group;
1250 u8 location_str_number;
1251 u8 device_name_str_number;
1252 u8 manufacturer_str_number;
1253 u8 serial_number_str_number;
1254 u8 asset_tag_number_str_number;
1255 u8 model_part_number_str_number;
1256 u8 revision_level_str_number;
1257 u16 max_power_capacity;
1258 u16 power_supply_characteristics;
1259 u16 input_voltage_probe_handle;
1260 u16 cooling_device_handle;
1261 u16 input_current_probe_handle;
1262};
1263
1264struct [[gnu::packed]] AdditionalInfoEntry
1265{
1266 u8 entry_length;
1267 u16 referenced_handle;
1268 u8 referenced_offset;
1269 u8 string_number;
1270 u8 value[];
1271};
1272
1273struct [[gnu::packed]] AdditionalInfo
1274{ // Type 40
1275 TableHeader h;
1276 u8 additional_info_entries_count;
1277 AdditionalInfoEntry entries[];
1278};
1279
1280struct [[gnu::packed]] OnboardDevicesExtendedInfo
1281{ // Type 41
1282 TableHeader h;
1283 u8 reference_designation_str_number;
1284 u8 device_type;
1285 u8 device_type_instance;
1286 u16 segment_group_number;
1287 u8 bus_number;
1288 u8 device_function_number;
1289};
1290
1291enum class OnboardDeviceType {
1292 Other = 0x1,
1293 Unknown = 0x2,
1294 Video = 0x3,
1295 SCSI_Controller = 0x4,
1296 Ethernet = 0x5,
1297 Token_Ring = 0x6,
1298 Sound = 0x7,
1299 PATA_Controller = 0x8,
1300 SATA_Controller = 0x9,
1301 SAS_Controller = 0xA
1302};
1303
1304struct [[gnu::packed]] ManagementControllerHostInterface
1305{ // Type 42
1306 TableHeader h;
1307 u8 interface_type;
1308 u8 interface_type_specific_data_length;
1309 u8 interface_type_specific_data[];
1310};
1311
1312struct [[gnu::packed]] ProtocolRecordData
1313{
1314 u8 protocol_type;
1315 u8 protocol_type_specific_data_length;
1316 u8 protocol_type_specific_data[];
1317};
1318
1319struct [[gnu::packed]] ExtManagementControllerHostInterface
1320{ // Type 42 Ext
1321 u8 protocol_records_count;
1322 ProtocolRecordData protocol_records[];
1323};
1324
1325enum class ManagementControllerHostInterfaceProtocolType {
1326 IPMI = 0x2,
1327 MCTP = 0x3,
1328 RedfishOverIP = 0x4
1329};
1330
1331struct [[gnu::packed]] TPMDevice
1332{ // Type 43
1333 TableHeader h;
1334 char vendor_id[4];
1335 u8 major_spec_version;
1336 u8 minor_spec_version;
1337 u32 firmware_version_1;
1338 u32 firmware_version_2;
1339 u8 description_str_number;
1340 u64 characteristics;
1341 u32 oem_defined;
1342};
1343
1344enum class TPMDeviceCharacteristics {
1345 Characteristics_not_supported = (1 << 2),
1346 Family_Configurable_1 = (1 << 3), // Family configurable via firmware update; for example, switching between TPM 1.2 and TPM 2.0.
1347 Family_Configurable_2 = (1 << 4), // Family configurable via platform software support, such as BIOS Setup; for example, switching between TPM 1.2 and TPM 2.0.
1348 Family_Configurable_3 = (1 << 5), // Family configurable via OEM proprietary mechanism; for example, switching between TPM 1.2 and TPM 2.0.
1349};
1350
1351struct [[gnu::packed]] ProcessorSpecificBlock
1352{
1353 u8 block_length;
1354 u8 processor_type;
1355 u8 processor_specific_data[];
1356};
1357
1358struct [[gnu::packed]] ProcessorAdditionalInfo
1359{ // Type 44
1360 TableHeader h;
1361 u16 referenced_handle;
1362 ProcessorSpecificBlock blocks[];
1363};
1364
1365enum class ProcessorArchitectureType {
1366 IA32 = 0x1,
1367 x86_64 = 0x2,
1368 Itanium = 0x3,
1369 ARM32bit = 0x4,
1370 ARM64bit = 0x5,
1371 RISC_V_32bit = 0x6,
1372 RISC_V_64bit = 0x7,
1373 RISC_V_128bit = 0x8
1374};
1375
1376struct [[gnu::packed]] Inactive
1377{ // Type 126
1378 TableHeader h;
1379};
1380
1381struct [[gnu::packed]] EndOfTable
1382{ // Type 127
1383 TableHeader h;
1384};
1385}
1386
1387class DMIDecoder {
1388public:
1389 static DMIDecoder& the();
1390 static void initialize();
1391 static void initialize_untrusted();
1392 Vector<SMBIOS::PhysicalMemoryArray*>& get_physical_memory_areas();
1393 bool is_reliable();
1394 u64 get_bios_characteristics();
1395
1396private:
1397 void enumerate_smbios_tables();
1398 PhysicalAddress get_next_physical_table(PhysicalAddress p_table);
1399 PhysicalAddress get_smbios_physical_table_by_handle(u16 handle);
1400 PhysicalAddress get_smbios_physical_table_by_type(u8 table_type);
1401 char* get_smbios_string(PhysicalAddress, u8 string_number);
1402 size_t get_table_size(PhysicalAddress);
1403
1404 explicit DMIDecoder(bool trusted);
1405 void initialize_parser();
1406
1407 void set_64_bit_entry_initialization_values(PhysicalAddress);
1408 void set_32_bit_entry_initialization_values(PhysicalAddress);
1409
1410 PhysicalAddress find_entry32bit_point();
1411 PhysicalAddress find_entry64bit_point();
1412
1413 PhysicalAddress m_entry32bit_point;
1414 PhysicalAddress m_entry64bit_point;
1415 PhysicalAddress m_structure_table;
1416 u32 m_structures_count;
1417 u32 m_table_length;
1418 bool m_use_64bit_entry;
1419 bool m_operable;
1420 bool m_untrusted;
1421
1422 SinglyLinkedList<PhysicalAddress> m_smbios_tables;
1423};
1424
1425}