ladybird/Kernel/ACPI/DMIDecoder.h
Liav A 325022cbd7 Kernel: DMIDecoder no longer depends on identity-mapping
DMIDecoder creates the mappings using the standard helpers, thus no
need to rely on the identity mapping in the first 1MB in memory.
2020-01-21 11:29:58 +01:00

1420 lines
33 KiB
C++

/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <AK/Types.h>
#include <AK/Vector.h>
#include <Kernel/VM/PhysicalAddress.h>
#include <Kernel/VM/Region.h>
#include <Kernel/VM/VirtualAddress.h>
namespace SMBIOS {
struct [[gnu::packed]] LegacyEntryPoint32bit
{
char legacy_sig[5];
u8 checksum2;
u16 smboios_table_length;
u32 smbios_table_ptr;
u16 smbios_tables_count;
u8 smbios_bcd_revision;
};
struct [[gnu::packed]] EntryPoint32bit
{
char sig[4];
u8 checksum;
u8 length;
u8 major_version;
u8 minor_version;
u16 maximum_structure_size;
u8 implementation_revision;
char formatted_area[5];
LegacyEntryPoint32bit legacy_structure;
};
struct [[gnu::packed]] EntryPoint64bit
{
char sig[5];
u8 checksum;
u8 length;
u8 major_version;
u8 minor_version;
u8 document_revision;
u8 revision;
u8 reserved;
u32 table_maximum_size;
u64 table_ptr;
};
struct [[gnu::packed]] TableHeader
{
u8 type;
u8 length;
u16 handle;
};
enum class TableType {
BIOSInfo = 0,
SysInfo = 1,
ModuleInfo = 2,
SysEnclosure = 3,
ProcessorInfo = 4,
CacheInfo = 7,
PortConnectorInfo = 8,
SystemSlots = 9,
OEMStrings = 11,
SysConfigOptions = 12,
BIOSLanguageInfo = 13,
GroupAssociations = 14,
SysEventLog = 15,
PhysicalMemoryArray = 16,
MemoryDevice = 17,
MemoryErrorInfo32Bit = 18,
MemoryArrayMappedAddress = 19,
MemoryDeviceMappedAddress = 20,
BuiltinPointingDevice = 21,
PortableBattery = 22,
SysReset = 23,
HardwareSecurity = 24,
SysPowerControls = 25,
VoltageProbe = 26,
CoolingDevice = 27,
TemperatureProbe = 28,
ElectricalCurrentProbe = 29,
OutOfBandRemoteAccess = 30,
SystemBootInfo = 32,
MemoryErrorInfo64Bit = 33,
ManagementDevice = 34,
ManagementDeviceComponent = 35,
ManagementDeviceThresholdData = 36,
MemoryChannel = 37,
IPMIDeviceInfo = 38,
SysPowerSupply = 39,
AdditionalInfo = 40,
OnboardDevicesExtendedInfo = 41,
ManagementControllerHostInterface = 42,
TPMDevice = 43,
ProcessorAdditionalInfo = 44,
Inactive = 126,
EndOfTable = 127
};
struct [[gnu::packed]] BIOSInfo
{ // Type 0
TableHeader h;
u8 bios_vendor_str_number;
u8 bios_version_str_number;
u16 bios_segment;
u8 bios_release_date_str_number;
u8 bios_rom_size;
u64 bios_characteristics;
u8 ext_bios_characteristics[];
};
enum class BIOSCharacteristics {
Unknown = (1 << 2),
NotSupported = (1 << 3),
ISA_support = (1 << 4),
MCA_support = (1 << 5),
EISA_support = (1 << 6),
PCI_support = (1 << 7),
PCMCIA_support = (1 << 8),
PnP_support = (1 << 9),
APM_support = (1 << 10),
UpgradeableBIOS = (1 << 11),
Shadowing_BIOS = (1 << 12),
VL_VESA_support = (1 << 13),
ESCD_support = (1 << 14),
CD_boot_support = (1 << 15),
select_boot_support = (1 << 16),
BIOS_ROM_socketed = (1 << 17),
PCMCIA_boot_support = (1 << 18),
EDD_spec_support = (1 << 19),
floppy_nec98_1200k_support = (1 << 20),
floppy_toshiba_1200k_support = (1 << 21),
floppy_360k_support = (1 << 22),
floppy_1200k_services_support = (1 << 23),
floppy_720k_services_support = (1 << 24),
floppy_2880k_services_support = (1 << 25),
int5_print_screen_support = (1 << 26),
int9_8042_keyboard_support = (1 << 27),
int14_serial_support = (1 << 28),
int17_printer_support = (1 << 29),
int10_video_support = (1 << 30),
nec_pc98 = (1 << 31)
};
struct [[gnu::packed]] ExtBIOSInfo
{
u8 bios_major_release;
u8 bios_minor_release;
u8 embedded_controller_firmware_major_release;
u8 embedded_controller_firmware_minor_release;
u16 ext_bios_rom_size;
};
struct [[gnu::packed]] SysInfo
{ // Type 1
TableHeader h;
u8 manufacturer_str_number;
u8 product_name_str_number;
u8 version_str_number;
u8 serial_number_str_number;
u64 uuid[2];
u8 wake_up_type;
u8 sku_str_number;
u8 family_str_number;
};
enum class WakeUpType {
Reserved = 0,
Other = 1,
Unknown = 2,
APM_TIMER = 3,
MODEM_RING = 4,
LAN_REMOTE = 5,
POWER_SWTCH = 6,
PCI_PME = 7,
AC_RESTORE = 8,
};
struct [[gnu::packed]] ModuleInfo
{ // Type 2
TableHeader h;
u8 manufacturer_str_number;
u8 product_name_str_number;
u8 version_str_number;
u8 serial_number_str_number;
u8 asset_tag_str_number;
u8 feature_flags;
u8 chassis_location;
u16 chassis_handle;
u8 board_type;
u8 contained_object_handles_count;
u16 contained_object_handles[];
};
enum class BoardType {
Unkown = 0x1,
Other = 0x2,
Server_Blade = 0x3,
Connectivity_Switch = 0x4,
System_Management_Module = 0x5,
Processor_Module = 0x6,
IO_Module = 0x7,
Memory_Module = 0x8,
Daughter_Board = 0x9,
Motherboard = 0xA,
Processor_Memory_Module = 0xB,
Processor_IO_Module = 0xC,
Interconnect_Board = 0xD,
};
struct [[gnu::packed]] SysEnclosure
{ // Type 3
TableHeader h;
u8 manufacturer_str_number;
u8 type;
u8 version_str_number;
u8 serial_number_str_number;
u8 asset_tag_str_number;
u8 boot_up_state;
u8 power_supply_state;
u8 thermal_state;
u8 security_status;
u32 vendor_specific_info;
u8 height;
u8 power_cords_number;
u8 contained_element_count;
u8 contained_element_record_length;
};
struct [[gnu::packed]] ExtSysEnclosure
{
u8 sku_str_number;
};
enum class SysEnclosureType {
Other = 0x1,
Unknown = 0x2,
Desktop = 0x3,
Low_Profile_Desktop = 0x4,
Pizza_Box = 0x5,
Mini_Tower = 0x6,
Tower = 0x7,
Portable = 0x8,
Laptop = 0x9,
Notebook = 0xA,
Hand_Held = 0xB,
Docking_Station = 0xC,
AIO = 0xD,
Sub_Notebook = 0xE,
Space_Saving = 0xF,
Lunch_Box = 0x10,
Main_Server_Chassis = 0x11,
Expansion_Chassis = 0x12,
Sub_Chassis = 0x13,
Bus_Expansion_Chassis = 0x14,
Peripheral_Chassis = 0x15,
RAID_Chassis = 0x16,
Rack_MOunt_Chassis = 0x17,
Sealed_case_PC = 0x18,
Multi_System_Chasis = 0x19,
Compact_PCI = 0x1A,
Advanced_TCA = 0x1B,
Blade = 0x1C,
Blade_Enclosure = 0x1D,
Tablet = 0x1E,
Convertible = 0x1F,
Detachable = 0x20,
IoT_Gateway = 0x21,
Embedded_PC = 0x22,
Mini_PC = 0x23,
Stick_PC = 0x24,
};
enum class SysEnclosureState {
Other = 0x1,
Unknown = 0x2,
Safe = 0x3,
Warning = 0x4,
Critical = 0x5,
Non_Recoverable = 0x6,
};
enum class SysEnclosureSecurityStatus {
Other = 0x1,
Unknown = 0x2,
None = 0x3,
External_Interface_Locked_Out = 0x4,
External_Interface_Enabled = 0x5,
};
struct [[gnu::packed]] SysEnclosureContainedElement
{
u8 type;
u8 min_contained_element_count;
u8 max_contained_element_count;
};
struct [[gnu::packed]] ProcessorInfo
{ // Type 4
TableHeader h;
u8 socket_designation_str_number;
u8 processor_type;
u8 processor_family;
u8 processor_manufacturer_str_number;
u64 processor_id;
u8 processor_version_str_number;
u8 voltage;
u16 external_clock;
u16 max_speed;
u16 current_speed;
u8 status;
u8 processor_upgrade;
u16 l1_cache_handle;
u16 l2_cache_handle;
u16 l3_cache_handle;
u8 serial_number_str_number;
u8 asset_tag_str_number;
u8 part_number_str_number;
u8 core_count;
u8 core_enabled;
u8 thread_count;
u16 processor_characteristics;
u16 processor_family2;
u16 core_count2;
u16 core_enabled2;
u16 thread_count2;
};
enum class ProcessorType {
Other = 0x1,
Unknown = 0x2,
Central_Processor = 0x3,
Math_Processor = 0x4,
DSP_Processor = 0x5,
Video_Processor = 0x6,
};
enum class ProcessorUpgrade {
Other = 0x1,
Unknown = 0x2,
Daughter_Board = 0x3,
ZIF_Socket = 0x4,
Replaceable_Piggy_Back = 0x5,
None = 0x6,
LIF_Sokcet = 0x7,
Slot_1 = 0x8,
Slot_2 = 0x9,
Socket_370_pin = 0xA,
Slot_A = 0xB,
Slot_M = 0xC,
Socket_423 = 0xD,
Socket_A_462 = 0xE,
Socket_478 = 0xF,
Socket_754 = 0x10,
Socket_940 = 0x11,
Socket_939 = 0x12,
Socket_mPGA604 = 0x13,
Socket_LGA771 = 0x14,
Socket_LGA775 = 0x15,
Socket_S1 = 0x16,
Socket_AM2 = 0x17,
Socket_F_1207 = 0x18,
Socket_LGA1366 = 0x19,
Socket_G34 = 0x1A,
Socket_AM3 = 0x1B,
Socket_C32 = 0x1C,
Socket_LGA1156 = 0x1D,
Socket_LGA1567 = 0x1E,
Socket_PGA988A = 0x1F,
Socket_BGA1288 = 0x20,
Socket_rPGA988B = 0x21,
Socket_BGA1023 = 0x22,
Socket_BGA1224 = 0x23,
Socket_LGA1155 = 0x24,
Socket_LGA1356 = 0x25,
Socket_LGA2011 = 0x26,
Socket_FS1 = 0x27,
Socket_FS2 = 0x28,
Socket_FM1 = 0x29,
Socket_FM2 = 0x2A,
Socket_LGA2011_3 = 0x2B,
Socket_LGA1356_3 = 0x2C,
Socket_LGA1150 = 0x2D,
Socket_BGA1168 = 0x2E,
Socket_BGA1234 = 0x2F,
Socket_BGA1364 = 0x30,
Socket_AM4 = 0x31,
Socket_LGA1151 = 0x32,
Socket_BGA1356 = 0x33,
Socket_BGA1440 = 0x34,
Socket_BGA1515 = 0x35,
Socket_LGA3647_1 = 0x36,
Socket_SP3 = 0x37,
Socket_SP3r2 = 0x38,
Socket_LGA2066 = 0x39,
Socket_BGA1392 = 0x3A,
Socket_BGA1510 = 0x3B,
Socket_BGA1528 = 0x3C
};
struct [[gnu::packed]] CacheInfo
{ // Type 7
TableHeader h;
u8 socket_designation_str_number;
u16 cache_config;
u16 max_cache_size;
u16 installed_size;
u16 supported_sram_type;
u16 current_sram_type;
u8 cache_speed;
u8 error_correction_type;
u8 system_cache_type;
u8 associativity;
u32 max_cache_size2;
u32 installed_size2;
};
struct [[gnu::packed]] PortConnectorInfo
{ // Type 8
TableHeader h;
u8 internal_reference_designator_str_number;
u8 internal_connector_type;
u8 external_reference_designator_str_number;
u8 external_connector_type;
u8 port_type;
};
enum class ConnectorType {
None = 0x0,
Centronics = 0x1,
Mini_Centronics = 0x2,
Proprietary = 0x3,
DB_25_pin_male = 0x4,
DB_25_pin_female = 0x5,
DB_15_pin_male = 0x6,
DB_15_pin_female = 0x7,
DB_9_pin_male = 0x8,
DB_9_pin_female = 0x9,
RJ_11 = 0xA,
RJ_45 = 0xB,
MiniSCSI_50_pin = 0xC,
MiniDIN = 0xD,
MicroDIN = 0xE,
PS2 = 0xF,
Infrared = 0x10,
HP_HIL = 0x11,
AccessBus_USB = 0x12,
SSA_SCSI = 0x13,
Circular_DIN8_male = 0x14,
Circular_DIN8_female = 0x15,
OnBoard_IDE = 0x16,
OnBoard_Floppy = 0x17,
Dual_Inline_9pin = 0x18,
Dual_Inline_25pin = 0x19,
Dual_Inline_50pin = 0x1A,
Dual_Inline_68pin = 0x1B,
OnBoard_SoundInput_CDROM = 0x1C,
Mini_Centronics_Type14 = 0x1D,
Mini_Centronics_Type26 = 0x1E,
Mini_Jack_Headphones = 0x1F,
BNC = 0x20,
Connector_1394 = 0x21,
SAS_SATA_Plug_Receptacle = 0x22,
USB_TypeC_Receptacle = 0x23,
PC98 = 0xA0,
PC98_Hireso = 0xA1,
PC_H98 = 0xA2,
PC98_Note = 0xA3,
PC98_Full = 0xA4,
Other = 0xFF
};
enum class PortType {
None = 0x0,
Parallel_Port_XT_AT_Compatible = 0x1,
Parallel_Port_PS2 = 0x2,
Parallel_Port_ECP = 0x3,
Parallel_Port_EPP = 0x4,
Parallel_Port_ECP_EPP = 0x5,
Serial_Port_XT_AT_Compatible = 0x6,
Serial_Port_16450_Compatible = 0x7,
Serial_Port_16550_Compatible = 0x8,
Serial_Port_16550A_Compatible = 0x9,
SCSI_Port = 0xA,
MIDI_Port = 0xB,
Joy_Stick_Port = 0xC,
Keyboard_Port = 0xD,
Mouse_Port = 0xE,
SSA_SCSI = 0xF,
USB = 0x10,
FireWire = 0x11,
PCMCIA_Type1 = 0x12,
PCMCIA_Type2 = 0x13,
PCMCIA_Type3 = 0x14,
Cardbus = 0x15,
AccessBus_Port = 0x16,
SCSI_2 = 0x17,
SCSI_Wide = 0x18,
PC98 = 0x19,
PC98_Hireso = 0x1A,
PC_H98 = 0x1B,
Video_Port = 0x1C,
Audio_Port = 0x1D,
Modem_Port = 0x1E,
Network_Port = 0x1F,
SATA = 0x20,
SAS = 0x21,
MFDP = 0x22,
Thunderbolt = 0x23,
Intel_8251_Compatible = 0xA0,
Intel_8251_FIFO_Compatible = 0xA1,
Other = 0xFF
};
struct [[gnu::packed]] SystemSlotPeerGroup
{
u16 segment_group_number;
u8 bus_number;
u8 device_function_number;
u8 data_bus_width;
};
struct [[gnu::packed]] SystemSlots
{ // Type 9
TableHeader h;
u8 slot_designation_str_number;
u8 slot_type;
u8 slot_data_bus_width;
u8 current_stage;
u8 slot_length;
u16 slot_id;
u8 slot_characteristics_1;
u8 slot_characteristics_2;
u16 segment_group_number;
u8 bus_number;
u8 device_function_number;
u8 data_bus_width;
u8 peer_grouping_count;
SystemSlotPeerGroup peer_groups[];
};
enum class SlotType {
Other = 0x1,
Unknown = 0x2,
ISA = 0x3,
MCA = 0x4,
EISA = 0x5,
PCI = 0x6,
PCMCIA = 0x7,
VL_VESA = 0x8,
Proprietary = 0x9,
Processor_Card_Slot = 0xA,
Proprietary_Memory_Card_Slot = 0xB,
IO_Riser_Card_Slot = 0xC,
NuBus = 0xD,
PCI_66MHZ_Capable = 0xE,
AGP = 0xF,
AGP_2X = 0x10,
AGP_4X = 0x11,
PCI_X = 0x12,
AGP_8X = 0x13,
M_Dot_2_Socket_1_DP = 0x14,
M_Dot_2_Socket_1_SD = 0x15,
M_Dot_2_Socket_2 = 0x16,
M_Dot_2_Socket_3 = 0x17,
MXM_Type1 = 0x18,
MXM_Type2 = 0x19,
MXM_Type3_Standard = 0x1A,
MXM_Type3_HE = 0x1B,
MXM_Type4 = 0x1C,
MXM_3_Type_A = 0x1D,
MXM_3_Type_B = 0x1E,
PCI_Express_Gen2 = 0x1F,
PCI_Express_Gen3 = 0x20,
PCI_Express_Mini_52pin_Type1 = 0x21,
PCI_Express_Mini_52pin_Type2 = 0x22,
PCI_Express_Mini_76pin = 0x23,
CXL_Flexbus_1_0 = 0x30,
PC98_C20 = 0xA0,
PC98_C24 = 0xA1,
PC98_E = 0xA2,
PC98_Local_Bus = 0xA3,
PC98_Card = 0xA4,
PCI_Express = 0xA5,
PCI_Express_x1 = 0xA6,
PCI_Express_x2 = 0xA7,
PCI_Express_x4 = 0xA8,
PCI_Express_x8 = 0xA9,
PCI_Express_x16 = 0xAA,
PCI_Express_Gen_2 = 0xAB,
PCI_Express_Gen_2_x1 = 0xAC,
PCI_Express_Gen_2_x2 = 0xAD,
PCI_Express_Gen_2_x4 = 0xAE,
PCI_Express_Gen_2_x8 = 0xAF,
PCI_Express_Gen_2_x16 = 0xB0,
PCI_Express_Gen_3 = 0xB1,
PCI_Express_Gen_3_x1 = 0xB2,
PCI_Express_Gen_3_x2 = 0xB3,
PCI_Express_Gen_3_x4 = 0xB4,
PCI_Express_Gen_3_x8 = 0xB5,
PCI_Express_Gen_3_x16 = 0xB6,
PCI_Express_Gen_4 = 0xB8,
PCI_Express_Gen_4_x1 = 0xB9,
PCI_Express_Gen_4_x2 = 0xBA,
PCI_Express_Gen_4_x4 = 0xBB,
PCI_Express_Gen_4_x8 = 0xBC,
PCI_Express_Gen_4_x16 = 0xBD
};
enum class SlotDataBusWidth {
Other = 0x1,
Unknown = 0x2,
_8_bit = 0x3,
_16_bit = 0x4,
_32_bit = 0x5,
_64_bit = 0x6,
_128_bit = 0x7,
_1x_x1 = 0x8,
_2x_x2 = 0x9,
_4x_x4 = 0xA,
_8x_x8 = 0xB,
_12x_x12 = 0xC,
_16x_x16 = 0xD,
_32x_x32 = 0xE
};
enum class SlotCurrentUsage {
Other = 0x1,
Unknown = 0x2,
Available = 0x3,
In_Use = 0x4,
Unavailable = 0x5
};
enum class SlotLength {
Other = 0x1,
Unknown = 0x2,
Short_Length = 0x3,
Long_Length = 0x4,
_2_5_Drive_Form_Factor = 0x5,
_3_5_Drive_Form_Factor = 0x6
};
enum class SlotCharacteristics1 {
Unknown = (1 << 0),
Provides_5volt = (1 << 1),
Provides_3_3volt = (1 << 2),
Shared_Slot = (1 << 3),
Support_PC_Card_16 = (1 << 4),
Support_CardBus = (1 << 5),
Support_Zoom_Video = (1 << 6),
Support_Modem_Ring_Resume = (1 << 7)
};
enum class SlotCharacteristics2 {
Support_PCI_PME = (1 << 0),
Support_Hot_Plug = (1 << 1),
Support_SMBus = (1 << 2),
Support_Bifurcation = (1 << 3),
};
struct [[gnu::packed]] OEMStrings
{ // Type 11
TableHeader h;
u8 strings_count;
};
struct [[gnu::packed]] SysConfigOptions
{ // Type 12
TableHeader h;
u8 strings_count;
};
struct [[gnu::packed]] BIOSLanguageInfo
{ // Type 13
TableHeader h;
u8 installable_langs_counts;
u8 flags;
u8 reserved[15];
u8 current_lang_str_number; // String number (one-based) of the currently installed language
};
struct [[gnu::packed]] GroupAssociations
{ // Type 14
TableHeader h;
u8 group_name_str_number;
u8 item_type;
u16 item_handle;
};
struct [[gnu::packed]] SysEventLog
{ // Type 15
TableHeader h;
u16 log_area_length;
u16 log_header_start_offset;
u16 log_data_start_offset;
u8 access_method;
u8 log_status;
u32 log_change_token;
u32 access_method_address;
u8 log_header_format;
u8 supported_log_type_descriptors_count;
u8 log_type_descriptor_length;
u8 supported_event_log_type_descriptor_list[];
};
struct [[gnu::packed]] PhysicalMemoryArray
{ // Type 16
TableHeader h;
u8 location;
u8 use;
u8 memory_error_correction;
u32 max_capacity;
u16 memory_error_info_handle;
u16 memory_devices_count;
u64 ext_max_capacity;
};
enum class MemoryArrayLocation {
Other = 0x1,
Unknown = 0x2,
Motherboard = 0x3,
ISA_addon_card = 0x4,
EISA_addon_card = 0x5,
PCI_addon_card = 0x6,
MCA_addon_card = 0x7,
PCMCIA_addon_card = 0x8,
Proprietary_addon_card = 0x9,
NuBus = 0xA,
PC98_C20_addon_card = 0xA0,
PC98_C24_addon_card = 0xA1,
PC98_E_addon_card = 0xA2,
PC98_Local_Bus_addon_card = 0xA3,
CXL_Flexbus_1_0_addon_card = 0xA4
};
enum class MemoryArrayUse {
Other = 0x1,
Unknown = 0x2,
System_Memory = 0x3,
Video_Memory = 0x4,
Flash_Memory = 0x5,
Non_Volatile_RAM = 0x6,
Cache_Memory = 0x7
};
enum class MemoryArrayErrorCorrectionType {
Other = 0x1,
Unknown = 0x2,
None = 0x3,
Parity = 0x4,
SingleBit_ECC = 0x5,
MultiBit_ECC = 0x6,
CRC = 0x7
};
struct [[gnu::packed]] MemoryDevice
{ // Type 17
TableHeader h;
u16 physical_memory_array_handle;
u16 memory_error_info_handle;
u16 total_width;
u16 data_width;
u16 size;
u8 form_factor;
u8 device_set;
u8 device_locator_str_number;
u8 bank_locator_str_number;
u8 memory_type;
u16 type_detail;
u16 speed;
u8 manufacturer_str_number;
u8 serial_number_str_number;
u8 asset_tag_str_number;
u8 part_number_str_number;
u8 attributes;
u32 ext_size;
u16 configured_memory_speed;
u16 min_voltage;
u16 max_voltage;
u16 configured_voltage;
u8 memory_technology;
u16 memory_operating_mode_capability;
u8 firmware_version_str_number;
u16 module_manufacturer_id;
u16 module_product_id;
u16 memory_subsystem_controller_manufacturer_id;
u16 memory_subsystem_controller_product_id;
u64 non_volatile_size;
u64 volatile_size;
u64 cache_size;
u64 logical_size;
u32 ext_speed;
u32 ext_configured_memory_speed;
};
enum class MemoryDeviceFormFactor {
Other = 0x1,
Unknown = 0x2,
SIMM = 0x3,
SIP = 0x4,
Chip = 0x5,
DIP = 0x6,
ZIP = 0x7,
ProprietaryCard = 0x8,
DIMM = 0x9,
TSOP = 0xA,
Chips_Row = 0xB,
RIMM = 0xC,
SODIMM = 0xD,
SRIMM = 0xE,
FB_DIMM = 0xF,
Die = 0x10
};
enum class MemoryDeviceType {
Other = 0x1,
Unknown = 0x2,
DRAM = 0x3,
EDRAM = 0x4,
VRAM = 0x5,
SRAM = 0x6,
RAM = 0x7,
ROM = 0x8,
FLASH = 0x9,
EEPROM = 0xA,
FEPROM = 0xB,
EPROM = 0xC,
CDRAM = 0xD,
_3DRAM = 0xE,
SDRAM = 0xF,
SGRAM = 0x10,
RDRAM = 0x11,
DDR = 0x12,
DDR2 = 0x13,
DDR2_FB_DIMM = 0x14,
DDR3 = 0x18,
FBD2 = 0x19,
DDR4 = 0x1A,
LPDDR = 0x1B,
LPDDR2 = 0x1C,
LPDDR3 = 0x1D,
LPDDR4 = 0x1E,
Logical_Non_Volatile_Device = 0x1F,
HBM = 0x20, // (High Bandwidth Memory)
HBM2 = 0x21, // (High Bandwidth Memory Generation 2)
};
enum class MemoryDeviceTypeDetail {
Other = (1 << 1),
Unknown = (1 << 2),
Fast_paged = (1 << 3),
Static_Column = (1 << 4),
Pseudo_Static = (1 << 5),
RAMBUS = (1 << 6),
Synchronous = (1 << 7),
CMOS = (1 << 8),
EDO = (1 << 9),
Window_DRAM = (1 << 10),
Cache_DRAM = (1 << 11),
Non_volatile = (1 << 12),
Registered_Buffered = (1 << 13),
Unbuffered_Unregistered = (1 << 14),
LRDIMM = (1 << 15)
};
enum class MemoryDeviceTechnology {
Other = 0x1,
Unknown = 0x2,
DRAM = 0x3,
NVDIMM_N = 0x4,
NVDIMM_F = 0x5,
NVDIMM_P = 0x6,
Intel_Optane_DC_Persistent_Memory = 0x7
};
enum class MemoryDeviceOperatingModeCapability {
Other = (1 << 1),
Unknown = (1 << 2),
Volatile_Memory = (1 << 3),
Byte_accessible_persistent_memory = (1 << 4),
Block_accessible_persistent_memory = (1 << 5),
};
struct MemoryErrorInfo32Bit { // Type 18
TableHeader h;
u8 error_type;
u8 error_granularity;
u8 error_operation;
u32 vendor_syndrome;
u32 memory_array_error_address;
u32 device_error_address;
u32 error_resolution;
};
enum class MemoryErrorType {
Other = 0x1,
Unknown = 0x2,
OK = 0x3,
Bad_read = 0x4,
Parity_error = 0x5,
SingleBit_error = 0x6,
DoubleBit_error = 0x7,
MultiBit_error = 0x8,
Nibble_error = 0x9,
Checksum_error = 0xA,
CRC_error = 0xB,
Corrected_SingleBit_error = 0xC,
Corrected_error = 0xD,
Uncorrectable_error = 0xE
};
enum class MemoryErrorGranularity {
Other = 0x1,
Unknown = 0x2,
Device_level = 0x3,
Memory_partition_level = 0x4
};
enum class MemoryErrorOperation {
Other = 0x1,
Unknown = 0x2,
Read = 0x3,
Write = 0x4,
Partial_Write = 0x5
};
struct [[gnu::packed]] MemoryArrayMappedAddress
{ // Type 19
TableHeader h;
u32 starting_address;
u32 ending_address;
u16 memory_array_handle;
u8 partition_width;
u64 ext_starting_address;
u64 ext_ending_address;
};
struct [[gnu::packed]] MemoryDeviceMappedAddress
{ // Type 20
TableHeader h;
u32 starting_address;
u32 ending_address;
u16 memory_device_handle;
u16 memory_array_mapped_handle;
u8 partition_row_position;
u8 interleave_position;
u8 interleaved_data_depth;
u64 ext_starting_address;
u64 ext_ending_address;
};
struct [[gnu::packed]] BuiltinPointingDevice
{ // Type 21
TableHeader h;
u8 type;
u8 interface;
u8 buttons_count;
};
enum class PointingDeviceType {
Other = 0x1,
Unknown = 0x2,
Mouse = 0x3,
Track_Ball = 0x4,
Track_Point = 0x5,
Glide_Point = 0x6,
Touch_Pad = 0x7,
Touch_Screen = 0x8,
Optical_Sensor = 0x9
};
enum class PointingDeviceInterface {
Other = 0x1,
Unknown = 0x2,
Serial = 0x3,
PS2 = 0x4,
Infrared = 0x5,
HP_HIL = 0x6,
Bus_mouse = 0x7,
AppleDesktopBus = 0x8,
Bus_mouse_DB9 = 0xA0,
Bus_mouse_microDIN = 0xA1,
USB = 0xA2
};
struct [[gnu::packed]] PortableBattery
{ // Type 22
TableHeader h;
u8 location_str_number;
u8 manufacturer_str_number;
u8 manufacture_date_str_number;
u8 serial_number_str_number;
u8 device_name_str_number;
u8 device_chemistry;
u16 design_capacity;
u16 design_voltage;
u8 sbds_version_number;
u8 max_error_battery_data;
u16 sbds_serial_number;
u16 sbds_manufacture_date;
u8 sbds_device_chemistry_str_number;
u8 design_capacity_multiplier;
u32 oem_specific;
};
enum class PortableBatteryChemistry {
Other = 0x1,
Unknown = 0x2,
Lead_Acid = 0x3,
Nickel_Cadmium = 0x4,
Nickel_metal_hydride = 0x5,
Lithium_ion = 0x6,
Zinc_air = 0x7,
Lithium_polymer = 0x8
};
struct [[gnu::packed]] SysReset
{ // Type 23
TableHeader h;
u8 capabilities;
u16 reset_count;
u16 reset_limit;
u16 timer_interval;
u16 timeout;
};
struct [[gnu::packed]] HardwareSecurity
{ // Type 24
TableHeader h;
u8 hardware_security_settings;
};
struct [[gnu::packed]] SysPowerControls
{ // Type 25
TableHeader h;
u8 next_scheduled_power_on_month;
u8 next_scheduled_power_on_day_of_month;
u8 next_scheduled_power_on_hour;
u8 next_scheduled_power_on_minute;
u8 next_scheduled_power_on_second;
};
struct [[gnu::packed]] VoltageProbe
{ // Type 26
TableHeader h;
u8 description_str_number;
u8 location_and_status;
u16 max_value;
u16 min_value;
u16 resolution;
u16 tolerance;
u16 accuracy;
u32 oem_defined;
u16 nominal_value;
};
struct [[gnu::packed]] CoolingDevice
{ // Type 27
TableHeader h;
u16 temperature_probe_handle;
u8 device_type_and_status;
u8 cooling_unit_group;
u32 oem_defined;
u16 nominal_speed;
u8 description_str_number;
};
struct [[gnu::packed]] TemperatureProbe
{ // Type 28
TableHeader h;
u8 description_str_number;
u8 location_and_status;
u16 max_value;
u16 min_value;
u16 resolution;
u16 tolerance;
u16 accuracy;
u32 oem_defined;
u16 nominal_value;
};
struct [[gnu::packed]] ElectricalCurrentProbe
{ // Type 29
TableHeader h;
u8 description_str_number;
u8 location_and_status;
u16 max_value;
u16 min_value;
u16 resolution;
u16 tolerance;
u16 accuracy;
u32 oem_defined;
u16 nominal_value;
};
struct [[gnu::packed]] OutOfBandRemoteAccess
{ // Type 30
TableHeader h;
u8 manufacturer_name_str_number;
u8 connections;
};
struct [[gnu::packed]] SystemBootInfo
{ // Type 32
TableHeader h;
u8 reserved[6];
u8 boot_status[10];
};
struct [[gnu::packed]] MemoryErrorInfo64Bit
{ // Type 33
TableHeader h;
u8 error_type;
u8 error_granularity;
u8 error_operation;
u32 vendor_syndrome;
u64 memory_array_error_address;
u64 device_error_address;
u32 error_resolution;
};
struct [[gnu::packed]] ManagementDevice
{ // Type 34
TableHeader h;
u8 description_str_number;
u8 type;
u32 address;
u8 address_type;
};
enum class ManagementDeviceType {
Other = 0x1,
Unknown = 0x2,
LM75 = 0x3,
LM78 = 0x4,
LM79 = 0x5,
LM80 = 0x6,
LM81 = 0x7,
ADM9240 = 0x8,
DS1780 = 0x9,
Maxim_1617 = 0xA,
GL518SM = 0xB, // Genesys GL518SM
W83781D = 0xC, // Winbond W83781D
HT82H791 = 0xD // Holtek HT82H791
};
enum class ManagementDeviceAddressType {
Other = 0x1,
Unknown = 0x2,
IO_Port = 0x3,
Memory = 0x4,
SMBus = 0x5
};
struct [[gnu::packed]] ManagementDeviceComponent
{ // Type 35
TableHeader h;
u8 description_str_number;
u16 management_device_handle;
u16 component_handle;
u16 threshold_handle;
};
struct [[gnu::packed]] ManagementDeviceThresholdData
{ // Type 36
TableHeader h;
u16 lower_threshold_non_critical;
u16 upper_threshold_non_critical;
u16 lower_threshold_critical;
u16 upper_threshold_critical;
u16 lower_threshold_non_recoverable;
u16 upper_threshold_non_recoverable;
};
struct [[gnu::packed]] MemoryDeviceDescriptor
{
u8 device_load;
u16 device_handle;
};
struct [[gnu::packed]] MemoryChannel
{ // Type 37
TableHeader h;
u8 channel_type;
u8 memory_device_count;
MemoryDeviceDescriptor memory_devices_descriptors[];
};
enum class MemroryChannelType {
Other = 0x1,
Unknown = 0x2,
RamBus = 0x3,
SyncLink = 0x4
};
struct [[gnu::packed]] IPMIDeviceInfo
{ // Type 38
TableHeader h;
u8 interface_type;
u8 ipmi_spec_revision;
u8 i2c_slave_address;
u8 nv_storage_device_address;
u64 base_address;
u8 base_address_modifier;
u8 interrupt_number;
};
enum class IPMIDeviceInfoBMCInterfaceType {
Unknown = 0x1,
KCS = 0x2, // KCS: Keyboard Controller Style
SMIC = 0x3, // SMIC: Server Management Interface Chip
BT = 0x4, // BT: Block Transfer
SSIF = 0x5 // SSIF: SMBus System Interface
};
struct [[gnu::packed]] SysPowerSupply
{ // Type 39
TableHeader h;
u8 power_unit_group;
u8 location_str_number;
u8 device_name_str_number;
u8 manufacturer_str_number;
u8 serial_number_str_number;
u8 asset_tag_number_str_number;
u8 model_part_number_str_number;
u8 revision_level_str_number;
u16 max_power_capacity;
u16 power_supply_characteristics;
u16 input_voltage_probe_handle;
u16 cooling_device_handle;
u16 input_current_probe_handle;
};
struct [[gnu::packed]] AdditionalInfoEntry
{
u8 entry_length;
u16 referenced_handle;
u8 referenced_offset;
u8 string_number;
u8 value[];
};
struct [[gnu::packed]] AdditionalInfo
{ // Type 40
TableHeader h;
u8 additional_info_entries_count;
AdditionalInfoEntry entries[];
};
struct [[gnu::packed]] OnboardDevicesExtendedInfo
{ // Type 41
TableHeader h;
u8 reference_designation_str_number;
u8 device_type;
u8 device_type_instance;
u16 segment_group_number;
u8 bus_number;
u8 device_function_number;
};
enum class OnboardDeviceType {
Other = 0x1,
Unknown = 0x2,
Video = 0x3,
SCSI_Controller = 0x4,
Ethernet = 0x5,
Token_Ring = 0x6,
Sound = 0x7,
PATA_Controller = 0x8,
SATA_Controller = 0x9,
SAS_Controller = 0xA
};
struct [[gnu::packed]] ManagementControllerHostInterface
{ // Type 42
TableHeader h;
u8 interface_type;
u8 interface_type_specific_data_length;
u8 interface_type_specific_data[];
};
struct [[gnu::packed]] ProtocolRecordData
{
u8 protocol_type;
u8 protocol_type_specific_data_length;
u8 protocol_type_specific_data[];
};
struct [[gnu::packed]] ExtManagementControllerHostInterface
{ // Type 42 Ext
u8 protocol_records_count;
ProtocolRecordData protocol_records[];
};
enum class ManagementControllerHostInterfaceProtocolType {
IPMI = 0x2,
MCTP = 0x3,
RedfishOverIP = 0x4
};
struct [[gnu::packed]] TPMDevice
{ // Type 43
TableHeader h;
char vendor_id[4];
u8 major_spec_version;
u8 minor_spec_version;
u32 firmware_version_1;
u32 firmware_version_2;
u8 description_str_number;
u64 characteristics;
u32 oem_defined;
};
enum class TPMDeviceCharacteristics {
Characteristics_not_supported = (1 << 2),
Family_Configurable_1 = (1 << 3), // Family configurable via firmware update; for example, switching between TPM 1.2 and TPM 2.0.
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.
Family_Configurable_3 = (1 << 5), // Family configurable via OEM proprietary mechanism; for example, switching between TPM 1.2 and TPM 2.0.
};
struct [[gnu::packed]] ProcessorSpecificBlock
{
u8 block_length;
u8 processor_type;
u8 processor_specific_data[];
};
struct [[gnu::packed]] ProcessorAdditionalInfo
{ // Type 44
TableHeader h;
u16 referenced_handle;
ProcessorSpecificBlock blocks[];
};
enum class ProcessorArchitectureType {
IA32 = 0x1,
x86_64 = 0x2,
Itanium = 0x3,
ARM32bit = 0x4,
ARM64bit = 0x5,
RISC_V_32bit = 0x6,
RISC_V_64bit = 0x7,
RISC_V_128bit = 0x8
};
struct [[gnu::packed]] Inactive
{ // Type 126
TableHeader h;
};
struct [[gnu::packed]] EndOfTable
{ // Type 127
TableHeader h;
};
}
class DMIDecoder {
public:
static DMIDecoder& the();
static void initialize();
static void initialize_untrusted();
Vector<SMBIOS::PhysicalMemoryArray*>& get_physical_memory_areas();
bool is_reliable();
u64 get_bios_characteristics();
private:
void enumerate_smbios_tables();
SMBIOS::TableHeader* get_next_physical_table(SMBIOS::TableHeader& p_table);
SMBIOS::TableHeader* get_smbios_physical_table_by_handle(u16 handle);
SMBIOS::TableHeader* get_smbios_physical_table_by_type(u8 table_type);
char* get_smbios_string(SMBIOS::TableHeader& p_table, u8 string_number);
size_t get_table_size(SMBIOS::TableHeader& table);
explicit DMIDecoder(bool trusted);
void initialize_parser();
void set_64_bit_entry_initialization_values(SMBIOS::EntryPoint64bit&);
void set_32_bit_entry_initialization_values(SMBIOS::EntryPoint32bit&);
SMBIOS::EntryPoint32bit* find_entry32bit_point();
SMBIOS::EntryPoint64bit* find_entry64bit_point();
SMBIOS::EntryPoint32bit* m_entry32bit_point;
SMBIOS::EntryPoint64bit* m_entry64bit_point;
SMBIOS::TableHeader* m_structure_table;
u32 m_structures_count;
u32 m_table_length;
bool m_use_64bit_entry;
bool m_operable;
bool m_untrusted;
SinglyLinkedList<SMBIOS::TableHeader*> m_smbios_tables;
};