From 6c5854458f594e9d99515bd145f5b227827f4d01 Mon Sep 17 00:00:00 2001 From: Luiz Aoqui Date: Thu, 2 Jul 2026 21:15:44 +0000 Subject: [PATCH 1/3] acpi: add DSDT device type Allow `DsdtGenerator` to specify the type of device it is generating code for. The DSDT can then organize devices types in a stable order, regardless of the component name and position in the device map. --- lib/propolis/src/firmware/acpi/dsdt.rs | 108 ++++++++++++++++++---- lib/propolis/src/firmware/acpi/mod.rs | 2 +- lib/propolis/src/hw/ps2/ctrl.rs | 4 + lib/propolis/src/hw/uart/lpc.rs | 4 + phd-tests/tests/testdata/acpi/v0/dsdt.dat | Bin 3362 -> 3362 bytes 5 files changed, 100 insertions(+), 18 deletions(-) diff --git a/lib/propolis/src/firmware/acpi/dsdt.rs b/lib/propolis/src/firmware/acpi/dsdt.rs index acb40a5b1..29b2b136e 100644 --- a/lib/propolis/src/firmware/acpi/dsdt.rs +++ b/lib/propolis/src/firmware/acpi/dsdt.rs @@ -50,6 +50,13 @@ pub enum DsdtScope { Lpc, // \_SB.PCI0.LPC scope. } +/// The types of devices represented in specific parts of the DSDT. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum DsdtDeviceType { + PS2Ctrl, + Uart, +} + /// An implementer of DsdtGenerator is able to generate AML code to be loaded /// into the DSDT ACPI table. pub trait DsdtGenerator { @@ -57,6 +64,16 @@ pub trait DsdtGenerator { /// should be placed. fn dsdt_scope(&self) -> DsdtScope; + /// Returns the device type this generator represents. + /// + /// This value can be used to place the generated code into specific + /// positions in the DSDT. + /// + /// If `None`, the generated code is not guaranteed have a stable position. + fn device_type(&self) -> Option { + None + } + fn to_aml_bytes( &self, acpi_variant: AcpiVariant, @@ -69,6 +86,7 @@ pub trait DsdtGenerator { /// where a `&dyn Aml` is needed. struct DsdtGeneratorAml<'a> { scope: DsdtScope, + device_type: Option, config: &'a DsdtConfig<'a>, } impl<'a> Aml for DsdtGeneratorAml<'a> { @@ -76,7 +94,10 @@ impl<'a> Aml for DsdtGeneratorAml<'a> { self.config .generators .iter() - .filter(|&&g| g.dsdt_scope() == self.scope) + .filter(|&&g| { + g.dsdt_scope() == self.scope + && g.device_type() == self.device_type + }) .for_each(|&g| { g.to_aml_bytes( self.config.acpi_variant, @@ -155,6 +176,7 @@ impl<'a> Aml for Dsdt<'a> { &PciRootBridge { config: &self.config }, &DsdtGeneratorAml { scope: DsdtScope::SystemBus, + device_type: None, config: &self.config, }, ], @@ -187,6 +209,7 @@ impl<'a> Aml for PciRootBridge<'a> { &PciRootBridgeLpc { config: self.config }, &DsdtGeneratorAml { scope: DsdtScope::PciRoot, + device_type: None, config: self.config, }, ], @@ -805,6 +828,12 @@ impl<'a> Aml for PciRootBridgeLpc<'a> { ), &DsdtGeneratorAml { scope: DsdtScope::Lpc, + device_type: Some(DsdtDeviceType::PS2Ctrl), + config: self.config, + }, + &DsdtGeneratorAml { + scope: DsdtScope::Lpc, + device_type: Some(DsdtDeviceType::Uart), config: self.config, }, // QEMU panic device. @@ -859,6 +888,11 @@ impl<'a> Aml for PciRootBridgeLpc<'a> { ), ], ), + &DsdtGeneratorAml { + scope: DsdtScope::Lpc, + device_type: None, + config: self.config, + }, ], ) .to_aml_bytes(sink); @@ -1043,12 +1077,17 @@ mod test { struct MockDsdtGenerator { scope: DsdtScope, + device_type: Option, } impl DsdtGenerator for MockDsdtGenerator { fn dsdt_scope(&self) -> DsdtScope { self.scope } + fn device_type(&self) -> Option { + self.device_type + } + fn to_aml_bytes( &self, acpi_variant: AcpiVariant, @@ -1089,11 +1128,20 @@ mod test { #[test] fn dsdt_generator_aml() { - let sb = Arc::new(MockDsdtGenerator { scope: DsdtScope::SystemBus }); - let pci = Arc::new(MockDsdtGenerator { scope: DsdtScope::PciRoot }); - let lpc = Arc::new(MockDsdtGenerator { scope: DsdtScope::Lpc }); - - let generators: Vec<&dyn DsdtGenerator> = vec![&*sb, &*pci, &*lpc]; + let sb = Arc::new(MockDsdtGenerator { + scope: DsdtScope::SystemBus, + device_type: None, + }); + let pci = Arc::new(MockDsdtGenerator { + scope: DsdtScope::PciRoot, + device_type: None, + }); + let lpc_ps2 = Arc::new(MockDsdtGenerator { + scope: DsdtScope::Lpc, + device_type: Some(DsdtDeviceType::PS2Ctrl), + }); + + let generators: Vec<&dyn DsdtGenerator> = vec![&*sb, &*pci, &*lpc_ps2]; let mut got = Vec::new(); let mut expected = Vec::new(); @@ -1104,7 +1152,7 @@ mod test { device_metadata .insert(&pci, Box::new(MockDsdtGeneratorMetadata { data: 2 })); device_metadata - .insert(&lpc, Box::new(MockDsdtGeneratorMetadata { data: 3 })); + .insert(&lpc_ps2, Box::new(MockDsdtGeneratorMetadata { data: 3 })); let config = DsdtConfig { acpi_variant: AcpiVariant::V0, @@ -1113,8 +1161,12 @@ mod test { }; // Filter by SystemBus. - DsdtGeneratorAml { scope: DsdtScope::SystemBus, config: &config } - .to_aml_bytes(&mut got); + DsdtGeneratorAml { + scope: DsdtScope::SystemBus, + device_type: None, + config: &config, + } + .to_aml_bytes(&mut got); aml::ResourceTemplate::new(vec![ &aml::Name::new("SCOP".into(), &"SystemBus"), @@ -1129,8 +1181,12 @@ mod test { got.clear(); expected.clear(); - DsdtGeneratorAml { scope: DsdtScope::PciRoot, config: &config } - .to_aml_bytes(&mut got); + DsdtGeneratorAml { + scope: DsdtScope::PciRoot, + device_type: None, + config: &config, + } + .to_aml_bytes(&mut got); aml::ResourceTemplate::new(vec![ &aml::Name::new("SCOP".into(), &"PciRoot"), @@ -1141,12 +1197,24 @@ mod test { assert_eq!(expected, got); - // Filter by Lpc. + // Filter by Lpc scope and device type. got.clear(); expected.clear(); - DsdtGeneratorAml { scope: DsdtScope::Lpc, config: &config } - .to_aml_bytes(&mut got); + DsdtGeneratorAml { + scope: DsdtScope::Lpc, + device_type: Some(DsdtDeviceType::PS2Ctrl), + config: &config, + } + .to_aml_bytes(&mut got); + + // Filter on device type without generators. + DsdtGeneratorAml { + scope: DsdtScope::Lpc, + device_type: Some(DsdtDeviceType::Uart), + config: &config, + } + .to_aml_bytes(&mut got); aml::ResourceTemplate::new(vec![ &aml::Name::new("SCOP".into(), &"Lpc"), @@ -1163,9 +1231,15 @@ mod test { let config = DsdtConfig { acpi_variant: AcpiVariant::V0, generators: &[ - &MockDsdtGenerator { scope: DsdtScope::SystemBus }, - &MockDsdtGenerator { scope: DsdtScope::PciRoot }, - &MockDsdtGenerator { scope: DsdtScope::Lpc }, + &MockDsdtGenerator { + scope: DsdtScope::SystemBus, + device_type: None, + }, + &MockDsdtGenerator { + scope: DsdtScope::PciRoot, + device_type: None, + }, + &MockDsdtGenerator { scope: DsdtScope::Lpc, device_type: None }, ], device_metadata: &DeviceMetadataMap::new(), }; diff --git a/lib/propolis/src/firmware/acpi/mod.rs b/lib/propolis/src/firmware/acpi/mod.rs index 84340bd76..f5f5330fd 100644 --- a/lib/propolis/src/firmware/acpi/mod.rs +++ b/lib/propolis/src/firmware/acpi/mod.rs @@ -32,7 +32,7 @@ pub mod rsdp; pub mod ssdt_edk2; pub mod xsdt; -pub use dsdt::{Dsdt, DsdtConfig, DsdtGenerator, DsdtScope}; +pub use dsdt::{Dsdt, DsdtConfig, DsdtDeviceType, DsdtGenerator, DsdtScope}; pub use facs::{Facs, FacsConfig}; pub use fadt::{ Fadt, FadtConfig, FADT_DSDT_LEN, FADT_DSDT_OFFSET, FADT_FACS_LEN, diff --git a/lib/propolis/src/hw/ps2/ctrl.rs b/lib/propolis/src/hw/ps2/ctrl.rs index 43d4937fc..a1c10f777 100644 --- a/lib/propolis/src/hw/ps2/ctrl.rs +++ b/lib/propolis/src/hw/ps2/ctrl.rs @@ -714,6 +714,10 @@ impl acpi::DsdtGenerator for PS2Ctrl { acpi::DsdtScope::Lpc } + fn device_type(&self) -> Option { + Some(acpi::DsdtDeviceType::PS2Ctrl) + } + fn to_aml_bytes( &self, _: acpi::AcpiVariant, diff --git a/lib/propolis/src/hw/uart/lpc.rs b/lib/propolis/src/hw/uart/lpc.rs index 8e9a6c37b..4e3da8063 100644 --- a/lib/propolis/src/hw/uart/lpc.rs +++ b/lib/propolis/src/hw/uart/lpc.rs @@ -208,6 +208,10 @@ impl acpi::DsdtGenerator for LpcUart { acpi::DsdtScope::Lpc } + fn device_type(&self) -> Option { + Some(acpi::DsdtDeviceType::Uart) + } + // This AML code is inherited from the original EDK2 static tables. fn to_aml_bytes( &self, diff --git a/phd-tests/tests/testdata/acpi/v0/dsdt.dat b/phd-tests/tests/testdata/acpi/v0/dsdt.dat index fa6c52316acdc6d29a7bec84429f43ddd4f6343c..a25050b9a58ebc22bfde4edae81dbc2dbdb018a9 100644 GIT binary patch delta 19 bcmZ1^wMc4%2+!np9*fDsJjIju^CSZRLL3H- delta 19 bcmZ1^wMc4%2+w3+o}$UZJeHI9^CSZRK!yfW From 8d38895e3e9f4a115662178c56add059f424646d Mon Sep 17 00:00:00 2001 From: Luiz Aoqui Date: Fri, 3 Jul 2026 00:26:41 +0000 Subject: [PATCH 2/3] acpi: ensure all `DsdtGenerator` are called --- lib/propolis/src/firmware/acpi/dsdt.rs | 102 +++++++++++++++++++++---- lib/propolis/src/hw/qemu/fwcfg.rs | 10 +-- 2 files changed, 92 insertions(+), 20 deletions(-) diff --git a/lib/propolis/src/firmware/acpi/dsdt.rs b/lib/propolis/src/firmware/acpi/dsdt.rs index 29b2b136e..93192070b 100644 --- a/lib/propolis/src/firmware/acpi/dsdt.rs +++ b/lib/propolis/src/firmware/acpi/dsdt.rs @@ -13,6 +13,14 @@ //! //! Structs that implement the [`DsdtGenerator`] trait can be passed to //! [`DsdtConfig`] and their AML code will be added to the scope they selected. +//! [`DsdtGenerator`] implementations can also use [`DsdtDeviceType`] to +//! indicate that the code being generated represents a specific type of +//! device that should be placed in specific parts of the table. +//! +//! # Panics +//! +//! Table generation panics if a [`DsdtGenerator`] is defined in [`DsdtConfig`] +//! but it is not used during table generation. // The DSDT and SSDT tables generated here are kept consistent with the // original EDK2 static tables. @@ -26,6 +34,8 @@ // // This pattern is already used for some devices when possible. +use std::cell::RefCell; + use super::aml::{devids, methods, names, paths, *}; use super::{ AcpiVariant, GPE0_BLK_ADDR, GPE0_BLK_LEN, IO_APIC_ADDR, IO_APIC_LEN, @@ -94,11 +104,13 @@ impl<'a> Aml for DsdtGeneratorAml<'a> { self.config .generators .iter() - .filter(|&&g| { + .enumerate() + .filter(|&(_, &g)| { g.dsdt_scope() == self.scope && g.device_type() == self.device_type }) - .for_each(|&g| { + .for_each(|(i, &g)| { + self.config.generator_used(i); g.to_aml_bytes( self.config.acpi_variant, self.config.device_metadata, @@ -122,13 +134,53 @@ const PM1A_CNT_SLP_TYP_S5: u8 = 0; /// Configuration for generating a DSDT table. pub struct DsdtConfig<'a> { /// The ACPI table variant to use. - pub acpi_variant: AcpiVariant, + acpi_variant: AcpiVariant, /// Devices that generate their own ACPI code. - pub generators: &'a [&'a dyn DsdtGenerator], + generators: &'a [&'a dyn DsdtGenerator], + + /// Track which generators have been used during table generation to ensure + /// all of them are called at least once. + /// + /// Table generation is a sequential single-threaded process that writes + /// to a common sink, so generators are guaranteed to be called (and + /// `borrow_mut()` this `RefCell`) one at a time. + generators_used: RefCell>, /// Storage for device metadata. - pub device_metadata: &'a DeviceMetadataMap, + device_metadata: &'a DeviceMetadataMap, +} +impl<'a> DsdtConfig<'a> { + pub fn new( + acpi_variant: AcpiVariant, + generators: &'a [&'a dyn DsdtGenerator], + device_metadata: &'a DeviceMetadataMap, + ) -> Self { + Self { + acpi_variant, + generators, + device_metadata, + generators_used: RefCell::new(vec![false; generators.len()]), + } + } + + fn generator_used(&self, i: usize) { + self.generators_used.borrow_mut()[i] = true + } +} +impl<'a> Drop for DsdtConfig<'a> { + fn drop(&mut self) { + let leftovers: Vec<_> = self + .generators_used + .borrow() + .iter() + .enumerate() + .filter_map(|(i, &used)| if used { None } else { Some(i) }) + .collect(); + if leftovers.len() > 0 { + panic!("DSDT generators not called: {:?}", leftovers); + } + } } /// The DSDT table is part of the fixed ACPI tables and is used to describe @@ -1154,11 +1206,8 @@ mod test { device_metadata .insert(&lpc_ps2, Box::new(MockDsdtGeneratorMetadata { data: 3 })); - let config = DsdtConfig { - acpi_variant: AcpiVariant::V0, - generators: &generators, - device_metadata: &device_metadata, - }; + let config = + DsdtConfig::new(AcpiVariant::V0, &generators, &device_metadata); // Filter by SystemBus. DsdtGeneratorAml { @@ -1226,11 +1275,34 @@ mod test { assert_eq!(expected, got); } + #[test] + #[should_panic(expected = "DSDT generators not called")] + fn panic_if_generator_not_called() { + let lpc_uart = Arc::new(MockDsdtGenerator { + scope: DsdtScope::Lpc, + device_type: Some(DsdtDeviceType::Uart), + }); + let generators: Vec<&dyn DsdtGenerator> = vec![&*lpc_uart]; + let device_metadata = DeviceMetadataMap::new(); + let config = + DsdtConfig::new(AcpiVariant::V0, &generators, &device_metadata); + + // Generate AML code without calling the lpc_uart generator. + let mut sink = Vec::new(); + DsdtGeneratorAml { + scope: DsdtScope::SystemBus, + device_type: None, + config: &config, + } + .to_aml_bytes(&mut sink); + } + #[test] fn dsdt_valid_aml() { - let config = DsdtConfig { - acpi_variant: AcpiVariant::V0, - generators: &[ + let device_metadata = DeviceMetadataMap::new(); + let config = DsdtConfig::new( + AcpiVariant::V0, + &[ &MockDsdtGenerator { scope: DsdtScope::SystemBus, device_type: None, @@ -1241,8 +1313,8 @@ mod test { }, &MockDsdtGenerator { scope: DsdtScope::Lpc, device_type: None }, ], - device_metadata: &DeviceMetadataMap::new(), - }; + &device_metadata, + ); let dsdt = Dsdt::new(config); let mut aml = Vec::new(); dsdt.to_aml_bytes(&mut aml); diff --git a/lib/propolis/src/hw/qemu/fwcfg.rs b/lib/propolis/src/hw/qemu/fwcfg.rs index 3b47d7c09..c5fb5441a 100644 --- a/lib/propolis/src/hw/qemu/fwcfg.rs +++ b/lib/propolis/src/hw/qemu/fwcfg.rs @@ -1491,11 +1491,11 @@ pub mod formats { } fn add_dsdt(&mut self) -> usize { - let dsdt_config = acpi::DsdtConfig { - acpi_variant: self.config.acpi_variant, - generators: self.config.dsdt_generators, - device_metadata: self.config.device_metadata, - }; + let dsdt_config = acpi::DsdtConfig::new( + self.config.acpi_variant, + self.config.dsdt_generators, + self.config.device_metadata, + ); let dsdt = acpi::Dsdt::new(dsdt_config); let dsdt_offset = self.tables.len(); dsdt.to_aml_bytes(&mut self.tables); From 42acb24dc244f116dc310d854e8721737aea077e Mon Sep 17 00:00:00 2001 From: Luiz Aoqui Date: Fri, 3 Jul 2026 18:06:38 +0000 Subject: [PATCH 3/3] acpi: move state from DsdtConfig to Dsdt --- lib/propolis/src/firmware/acpi/dsdt.rs | 121 ++++++++++++------------- lib/propolis/src/hw/qemu/fwcfg.rs | 10 +- 2 files changed, 63 insertions(+), 68 deletions(-) diff --git a/lib/propolis/src/firmware/acpi/dsdt.rs b/lib/propolis/src/firmware/acpi/dsdt.rs index 93192070b..fc329edc3 100644 --- a/lib/propolis/src/firmware/acpi/dsdt.rs +++ b/lib/propolis/src/firmware/acpi/dsdt.rs @@ -95,13 +95,14 @@ pub trait DsdtGenerator { /// Wraps a list of DsdtGenerators to help generate their AML code in places /// where a `&dyn Aml` is needed. struct DsdtGeneratorAml<'a> { + dsdt: &'a Dsdt<'a>, scope: DsdtScope, device_type: Option, - config: &'a DsdtConfig<'a>, } impl<'a> Aml for DsdtGeneratorAml<'a> { fn to_aml_bytes(&self, sink: &mut dyn AmlSink) { - self.config + self.dsdt + .config .generators .iter() .enumerate() @@ -110,10 +111,10 @@ impl<'a> Aml for DsdtGeneratorAml<'a> { && g.device_type() == self.device_type }) .for_each(|(i, &g)| { - self.config.generator_used(i); + self.dsdt.generator_used(i); g.to_aml_bytes( - self.config.acpi_variant, - self.config.device_metadata, + self.dsdt.config.acpi_variant, + self.dsdt.config.device_metadata, sink, ) }); @@ -134,10 +135,21 @@ const PM1A_CNT_SLP_TYP_S5: u8 = 0; /// Configuration for generating a DSDT table. pub struct DsdtConfig<'a> { /// The ACPI table variant to use. - acpi_variant: AcpiVariant, + pub acpi_variant: AcpiVariant, /// Devices that generate their own ACPI code. - generators: &'a [&'a dyn DsdtGenerator], + pub generators: &'a [&'a dyn DsdtGenerator], + + /// Storage for device metadata. + pub device_metadata: &'a DeviceMetadataMap, +} + +/// The DSDT table is part of the fixed ACPI tables and is used to describe +/// system resources. +/// +/// ACPI rev. 6.6 section 5.2.11.1 "Differentiated System Description Table (DSDT)" +pub struct Dsdt<'a> { + config: DsdtConfig<'a>, /// Track which generators have been used during table generation to ensure /// all of them are called at least once. @@ -146,29 +158,21 @@ pub struct DsdtConfig<'a> { /// to a common sink, so generators are guaranteed to be called (and /// `borrow_mut()` this `RefCell`) one at a time. generators_used: RefCell>, - - /// Storage for device metadata. - device_metadata: &'a DeviceMetadataMap, } -impl<'a> DsdtConfig<'a> { - pub fn new( - acpi_variant: AcpiVariant, - generators: &'a [&'a dyn DsdtGenerator], - device_metadata: &'a DeviceMetadataMap, - ) -> Self { - Self { - acpi_variant, - generators, - device_metadata, - generators_used: RefCell::new(vec![false; generators.len()]), - } + +impl<'a> Dsdt<'a> { + pub fn new(config: DsdtConfig<'a>) -> Self { + let generators_used = + RefCell::new(vec![false; config.generators.len()]); + Self { config, generators_used } } fn generator_used(&self, i: usize) { self.generators_used.borrow_mut()[i] = true } } -impl<'a> Drop for DsdtConfig<'a> { + +impl<'a> Drop for Dsdt<'a> { fn drop(&mut self) { let leftovers: Vec<_> = self .generators_used @@ -183,20 +187,6 @@ impl<'a> Drop for DsdtConfig<'a> { } } -/// The DSDT table is part of the fixed ACPI tables and is used to describe -/// system resources. -/// -/// ACPI rev. 6.6 section 5.2.11.1 "Differentiated System Description Table (DSDT)" -pub struct Dsdt<'a> { - config: DsdtConfig<'a>, -} - -impl<'a> Dsdt<'a> { - pub fn new(config: DsdtConfig<'a>) -> Self { - Self { config } - } -} - impl<'a> Aml for Dsdt<'a> { fn to_aml_bytes(&self, sink: &mut dyn AmlSink) { let mut dsdt = Vec::new(); @@ -225,11 +215,11 @@ impl<'a> Aml for Dsdt<'a> { aml::Scope::new( "_SB_".into(), vec![ - &PciRootBridge { config: &self.config }, + &PciRootBridge { dsdt: &self }, &DsdtGeneratorAml { + dsdt: &self, scope: DsdtScope::SystemBus, device_type: None, - config: &self.config, }, ], ) @@ -244,7 +234,7 @@ impl<'a> Aml for Dsdt<'a> { /// PCI root bridge namespace (\_SB.PCI0). struct PciRootBridge<'a> { - config: &'a DsdtConfig<'a>, + dsdt: &'a Dsdt<'a>, } impl<'a> Aml for PciRootBridge<'a> { @@ -258,11 +248,11 @@ impl<'a> Aml for PciRootBridge<'a> { &names::uid(&aml::ZERO), &PciRootBridgeCrs {}, &PciRootBridgePrt {}, - &PciRootBridgeLpc { config: self.config }, + &PciRootBridgeLpc { dsdt: self.dsdt }, &DsdtGeneratorAml { + dsdt: self.dsdt, scope: DsdtScope::PciRoot, device_type: None, - config: self.config, }, ], ) @@ -613,7 +603,7 @@ const NMISC_PORT: u16 = 0x61; /// /// struct PciRootBridgeLpc<'a> { - config: &'a DsdtConfig<'a>, + dsdt: &'a Dsdt<'a>, } // This table is currently kept the same as the original EDK2 static table, but @@ -738,7 +728,7 @@ impl<'a> Aml for PciRootBridgeLpc<'a> { // table. Its IO ports are not actually handled anywhere. // It can be removed in the future . &AcpiVariantFilter::new( - self.config.acpi_variant, + self.dsdt.config.acpi_variant, vec![AcpiVariant::V0], &aml::Device::new( "DMAC".into(), @@ -805,7 +795,7 @@ impl<'a> Aml for PciRootBridgeLpc<'a> { // table. Its IO ports are not actually handled anywhere. // It can be removed in the future . &AcpiVariantFilter::new( - self.config.acpi_variant, + self.dsdt.config.acpi_variant, vec![AcpiVariant::V0], &aml::Device::new( "FPU_".into(), @@ -879,14 +869,14 @@ impl<'a> Aml for PciRootBridgeLpc<'a> { ], ), &DsdtGeneratorAml { + dsdt: self.dsdt, scope: DsdtScope::Lpc, device_type: Some(DsdtDeviceType::PS2Ctrl), - config: self.config, }, &DsdtGeneratorAml { + dsdt: self.dsdt, scope: DsdtScope::Lpc, device_type: Some(DsdtDeviceType::Uart), - config: self.config, }, // QEMU panic device. // @@ -941,9 +931,9 @@ impl<'a> Aml for PciRootBridgeLpc<'a> { ], ), &DsdtGeneratorAml { + dsdt: self.dsdt, scope: DsdtScope::Lpc, device_type: None, - config: self.config, }, ], ) @@ -1206,14 +1196,17 @@ mod test { device_metadata .insert(&lpc_ps2, Box::new(MockDsdtGeneratorMetadata { data: 3 })); - let config = - DsdtConfig::new(AcpiVariant::V0, &generators, &device_metadata); + let dsdt = Dsdt::new(DsdtConfig { + acpi_variant: AcpiVariant::V0, + generators: &generators, + device_metadata: &device_metadata, + }); // Filter by SystemBus. DsdtGeneratorAml { + dsdt: &dsdt, scope: DsdtScope::SystemBus, device_type: None, - config: &config, } .to_aml_bytes(&mut got); @@ -1231,9 +1224,9 @@ mod test { expected.clear(); DsdtGeneratorAml { + dsdt: &dsdt, scope: DsdtScope::PciRoot, device_type: None, - config: &config, } .to_aml_bytes(&mut got); @@ -1251,17 +1244,17 @@ mod test { expected.clear(); DsdtGeneratorAml { + dsdt: &dsdt, scope: DsdtScope::Lpc, device_type: Some(DsdtDeviceType::PS2Ctrl), - config: &config, } .to_aml_bytes(&mut got); // Filter on device type without generators. DsdtGeneratorAml { + dsdt: &dsdt, scope: DsdtScope::Lpc, device_type: Some(DsdtDeviceType::Uart), - config: &config, } .to_aml_bytes(&mut got); @@ -1284,15 +1277,18 @@ mod test { }); let generators: Vec<&dyn DsdtGenerator> = vec![&*lpc_uart]; let device_metadata = DeviceMetadataMap::new(); - let config = - DsdtConfig::new(AcpiVariant::V0, &generators, &device_metadata); + let dsdt = Dsdt::new(DsdtConfig { + acpi_variant: AcpiVariant::V0, + generators: &generators, + device_metadata: &device_metadata, + }); // Generate AML code without calling the lpc_uart generator. let mut sink = Vec::new(); DsdtGeneratorAml { + dsdt: &dsdt, scope: DsdtScope::SystemBus, device_type: None, - config: &config, } .to_aml_bytes(&mut sink); } @@ -1300,9 +1296,9 @@ mod test { #[test] fn dsdt_valid_aml() { let device_metadata = DeviceMetadataMap::new(); - let config = DsdtConfig::new( - AcpiVariant::V0, - &[ + let dsdt = Dsdt::new(DsdtConfig { + acpi_variant: AcpiVariant::V0, + generators: &[ &MockDsdtGenerator { scope: DsdtScope::SystemBus, device_type: None, @@ -1313,9 +1309,8 @@ mod test { }, &MockDsdtGenerator { scope: DsdtScope::Lpc, device_type: None }, ], - &device_metadata, - ); - let dsdt = Dsdt::new(config); + device_metadata: &device_metadata, + }); let mut aml = Vec::new(); dsdt.to_aml_bytes(&mut aml); diff --git a/lib/propolis/src/hw/qemu/fwcfg.rs b/lib/propolis/src/hw/qemu/fwcfg.rs index c5fb5441a..3b47d7c09 100644 --- a/lib/propolis/src/hw/qemu/fwcfg.rs +++ b/lib/propolis/src/hw/qemu/fwcfg.rs @@ -1491,11 +1491,11 @@ pub mod formats { } fn add_dsdt(&mut self) -> usize { - let dsdt_config = acpi::DsdtConfig::new( - self.config.acpi_variant, - self.config.dsdt_generators, - self.config.device_metadata, - ); + let dsdt_config = acpi::DsdtConfig { + acpi_variant: self.config.acpi_variant, + generators: self.config.dsdt_generators, + device_metadata: self.config.device_metadata, + }; let dsdt = acpi::Dsdt::new(dsdt_config); let dsdt_offset = self.tables.len(); dsdt.to_aml_bytes(&mut self.tables);