Skip to content

Commit 0d8efa1

Browse files
authored
smbios: add enums/bitflags types for some SMBIOS fields (#694)
Currently, most of the SMBIOS fields that we populate are magic numbers, with comments describing what that magic number indicates. For SMBIOS enum fields, this isn't too bad, but for bitfields like the various "characteristics" fields, it's a bit of a shame, since the hex constant doesn't always make it obvious which bit corresponds to which characteristic. To make this a bit nicer, this commit adds enums for most of the SMBIOS enum fields we currently populate, and bitflags for most of the bitflags fields. This way, we can refer to them by name rather than as magic numbers. Also, I've made the `Default` implementation for the various enum fields return the "unknown" (0x2) variant. Eventually, we may want to default-initialize more SMBIOS tables --- but, we should probably hold off on that until *all* the enum fields in the tables we populate are Rust types with `Default` impls, so that we don't have to manually initialize some of them to 0x2. Furthermore, I've added `serde::{Serialize, Deserialize}` implementations for these SMBIOS field types, in order to support (eventually) overriding them from the config file. Using structured types here also lets us perform some nicer validation of said hypothetical future config file. Current `dmidecode` output in an Alpine guest on this branch matches what's on `master`.
1 parent 27af670 commit 0d8efa1

File tree

3 files changed

+637
-54
lines changed

3 files changed

+637
-54
lines changed

bin/propolis-server/src/lib/initializer.rs

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,7 @@ impl<'a> MachineInitializer<'a> {
853853

854854
fn generate_smbios(&self) -> smbios::TableBytes {
855855
use propolis::cpuid;
856+
use smbios::table::{type0, type1, type16, type4};
856857

857858
let rom_size =
858859
self.state.rom_size_bytes.expect("ROM is already populated");
@@ -863,10 +864,10 @@ impl<'a> MachineInitializer<'a> {
863864
.try_into()
864865
.unwrap(),
865866
bios_rom_size: ((rom_size / (64 * 1024)) - 1) as u8,
866-
// Characteristics-not-supported
867-
bios_characteristics: 0x8,
868-
// ACPI + UEFI + IsVM
869-
bios_ext_characteristics: 0x1801,
867+
bios_characteristics: type0::BiosCharacteristics::UNSUPPORTED,
868+
bios_ext_characteristics: type0::BiosExtCharacteristics::ACPI
869+
| type0::BiosExtCharacteristics::UEFI
870+
| type0::BiosExtCharacteristics::IS_VM,
870871
..Default::default()
871872
};
872873

@@ -882,8 +883,7 @@ impl<'a> MachineInitializer<'a> {
882883
.unwrap_or_default(),
883884
uuid: self.properties.id.to_bytes_le(),
884885

885-
// power switch
886-
wake_up_type: 0x06,
886+
wake_up_type: type1::WakeUpType::PowerSwitch,
887887
..Default::default()
888888
};
889889

@@ -928,33 +928,28 @@ impl<'a> MachineInitializer<'a> {
928928
cpuid::parse_brand_string(cpuid_procname).unwrap_or("".to_string());
929929

930930
let smb_type4 = smbios::table::Type4 {
931-
// central processor
932-
proc_type: 0x03,
931+
proc_type: type4::ProcType::Central,
933932
proc_family,
934933
proc_manufacturer,
935934
proc_id,
936935
proc_version: proc_version.try_into().unwrap_or_default(),
937-
// cpu enabled, socket populated
938-
status: 0x41,
936+
status: type4::ProcStatus::Enabled,
939937
// unknown
940938
proc_upgrade: 0x2,
941939
// make core and thread counts equal for now
942940
core_count: self.properties.vcpus,
943941
core_enabled: self.properties.vcpus,
944942
thread_count: self.properties.vcpus,
945-
// 64-bit capable, multicore
946-
proc_characteristics: 0xc,
943+
proc_characteristics: type4::Characteristics::IS_64_BIT
944+
| type4::Characteristics::MULTI_CORE,
947945
..Default::default()
948946
};
949947

950948
let memsize_bytes = (self.properties.memory as usize) * MB;
951949
let mut smb_type16 = smbios::table::Type16 {
952-
// system board
953-
location: 0x3,
954-
// system memory
955-
array_use: 0x3,
956-
// unknown
957-
error_correction: 0x2,
950+
location: type16::Location::SystemBoard,
951+
array_use: type16::ArrayUse::System,
952+
error_correction: type16::ErrorCorrection::Unknown,
958953
num_mem_devices: 1,
959954
..Default::default()
960955
};

bin/propolis-standalone/src/main.rs

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -812,23 +812,24 @@ struct SmbiosParams {
812812
cpuid_procname: Option<[cpuid::Entry; 3]>,
813813
}
814814
fn generate_smbios(params: SmbiosParams) -> anyhow::Result<smbios::TableBytes> {
815+
use smbios::table::{type0, type1, type16, type4};
816+
815817
let smb_type0 = smbios::table::Type0 {
816818
vendor: "Oxide".try_into().unwrap(),
817819
bios_version: "v0.0.1 alpha1".try_into().unwrap(),
818820
bios_release_date: "Bureaucracy 41, 3186 YOLD".try_into().unwrap(),
819821
bios_rom_size: ((params.rom_size / (64 * 1024)) - 1) as u8,
820-
// Characteristics-not-supported
821-
bios_characteristics: 0x8,
822-
// ACPI + UEFI + IsVM
823-
bios_ext_characteristics: 0x1801,
822+
bios_characteristics: type0::BiosCharacteristics::UNSUPPORTED,
823+
bios_ext_characteristics: type0::BiosExtCharacteristics::ACPI
824+
| type0::BiosExtCharacteristics::UEFI
825+
| type0::BiosExtCharacteristics::IS_VM,
824826
..Default::default()
825827
};
826828

827829
let smb_type1 = smbios::table::Type1 {
828830
manufacturer: "Oxide".try_into().unwrap(),
829831
product_name: "OxVM".try_into().unwrap(),
830-
// power switch
831-
wake_up_type: 0x06,
832+
wake_up_type: type1::WakeUpType::PowerSwitch,
832833
..Default::default()
833834
};
834835

@@ -875,32 +876,27 @@ fn generate_smbios(params: SmbiosParams) -> anyhow::Result<smbios::TableBytes> {
875876
.unwrap_or("".to_string());
876877

877878
let smb_type4 = smbios::table::Type4 {
878-
// central processor
879-
proc_type: 0x03,
879+
proc_type: type4::ProcType::Central,
880880
proc_family,
881881
proc_manufacturer,
882882
proc_id,
883883
proc_version: proc_version.as_str().try_into().unwrap_or_default(),
884-
// cpu enabled, socket populated
885-
status: 0x41,
884+
status: type4::ProcStatus::Enabled,
886885
// unknown
887886
proc_upgrade: 0x2,
888887
// make core and thread counts equal for now
889888
core_count: params.num_cpus,
890889
core_enabled: params.num_cpus,
891890
thread_count: params.num_cpus,
892-
// 64-bit capable, multicore
893-
proc_characteristics: 0xc,
891+
proc_characteristics: type4::Characteristics::IS_64_BIT
892+
| type4::Characteristics::MULTI_CORE,
894893
..Default::default()
895894
};
896895

897896
let mut smb_type16 = smbios::table::Type16 {
898-
// system board
899-
location: 0x3,
900-
// system memory
901-
array_use: 0x3,
902-
// unknown
903-
error_correction: 0x2,
897+
location: type16::Location::SystemBoard,
898+
array_use: type16::ArrayUse::System,
899+
error_correction: type16::ErrorCorrection::Unknown,
904900
num_mem_devices: 1,
905901
..Default::default()
906902
};

0 commit comments

Comments
 (0)