Message ID | 20250606171033.3882079-1-igor.korotin.linux@gmail.com |
---|---|
State | New |
Headers | show |
Series | rust: Add ACPI match table support for Rust drivers | expand |
On Fri Jun 6, 2025 at 7:10 PM CEST, Igor Korotin wrote: > Extend the Rust sample platform driver to probe using device/driver name > matching, OF ID table matching, or ACPI ID table matching. > > Signed-off-by: Igor Korotin <igor.korotin.linux@gmail.com> > --- > samples/rust/rust_driver_platform.rs | 96 +++++++++++++++++++++++++++- > 1 file changed, 95 insertions(+), 1 deletion(-) > > diff --git a/samples/rust/rust_driver_platform.rs b/samples/rust/rust_driver_platform.rs > index e3992e7a71e9..be7c311dca07 100644 > --- a/samples/rust/rust_driver_platform.rs > +++ b/samples/rust/rust_driver_platform.rs > @@ -17,10 +17,104 @@ struct SampleDriver { > [(of::DeviceId::new(c_str!("test,rust-device")), Info(42))] > ); > > +// ACPI match table test This looks great, let's move it to the crate-level documentation. That way it gets rendered :) --- Cheers, Benno > +// > +// This demonstrates how to test an ACPI-based Rust platform driver using QEMU > +// with a custom SSDT. > +// > +// Steps:
On Sun, Jun 08, 2025 at 09:58:46AM +0200, Benno Lossin wrote: > On Fri Jun 6, 2025 at 7:10 PM CEST, Igor Korotin wrote: > > Extend the Rust sample platform driver to probe using device/driver name > > matching, OF ID table matching, or ACPI ID table matching. > > > > Signed-off-by: Igor Korotin <igor.korotin.linux@gmail.com> > > --- > > samples/rust/rust_driver_platform.rs | 96 +++++++++++++++++++++++++++- > > 1 file changed, 95 insertions(+), 1 deletion(-) > > > > diff --git a/samples/rust/rust_driver_platform.rs b/samples/rust/rust_driver_platform.rs > > index e3992e7a71e9..be7c311dca07 100644 > > --- a/samples/rust/rust_driver_platform.rs > > +++ b/samples/rust/rust_driver_platform.rs > > @@ -17,10 +17,104 @@ struct SampleDriver { > > [(of::DeviceId::new(c_str!("test,rust-device")), Info(42))] > > ); > > > > +// ACPI match table test > > This looks great, let's move it to the crate-level documentation. +1 > That way it gets rendered :) Just to be precise, I think the build system does not yet render driver documentation, but it should be in the future.
On Fri, Jun 06, 2025 at 06:10:33PM +0100, Igor Korotin wrote: > Extend the Rust sample platform driver to probe using device/driver name > +/// OF/ACPI match tables for Platform Driver implementation > +/// > +/// The platform::Driver requires declaration of both OF_ID_TABLE and > +/// ACPI_ID_TABLE, but if driver is not going to use either of them > +/// it can implement one of them or both as None. > +/// > +/// # Example: > +/// > +/// ```ignore > +/// impl platform::Driver for SampleDriver { > +/// type IdInfo = (); > +/// const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None; > +/// const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = None; > +/// > +/// fn probe( > +/// pdev: &platform::Device<Core>, > +/// _info: Option<&Self::IdInfo>, > +/// ) -> Result<Pin<KBox<Self>>> { > +/// dev_dbg!(pdev.as_ref(), "Probe Rust Platform driver sample.\n"); > +/// > +/// let drvdata = KBox::new(Self { pdev: pdev.into() }, GFP_KERNEL)?; > +/// > +/// Ok(drvdata.into()) > +/// } > +/// } > +/// ``` What I meant with [1] was that I think we should make this code compile and remove everything that's not needed, i.e.: ///``` /// # use kernel::{acpi, device::Core, of, platform}; /// /// struct MyDriver; /// /// impl platform::Driver for MyDriver { /// type IdInfo = (); /// const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None; /// const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = None; /// /// fn probe( /// _pdev: &platform::Device<Core>, /// _id_info: Option<&Self::IdInfo>, /// ) -> Result<Pin<KBox<Self>>> { /// Err(ENODEV) /// } /// } ///``` However, given that we can't run doctests from drivers yet, we should just remove this doctest I think. It much more belongs into rust/kernel/platform.rs anyways (where we already have a similar one). [1] https://lore.kernel.org/lkml/aEL0AGBZqDp1lMFe@pollux/
diff --git a/samples/rust/rust_driver_platform.rs b/samples/rust/rust_driver_platform.rs index e3992e7a71e9..be7c311dca07 100644 --- a/samples/rust/rust_driver_platform.rs +++ b/samples/rust/rust_driver_platform.rs @@ -17,10 +17,104 @@ struct SampleDriver { [(of::DeviceId::new(c_str!("test,rust-device")), Info(42))] ); +// ACPI match table test +// +// This demonstrates how to test an ACPI-based Rust platform driver using QEMU +// with a custom SSDT. +// +// Steps: +// +// 1. **Create an SSDT source file** (`ssdt.dsl`) with the following content: +// +// ```asl +// DefinitionBlock ("", "SSDT", 2, "TEST", "VIRTACPI", 0x00000001) +// { +// Scope (\_SB) +// { +// Device (T432) +// { +// Name (_HID, "TEST4321") // ACPI hardware ID to match +// Name (_UID, 1) +// Name (_STA, 0x0F) // Device present, enabled +// Name (_CRS, ResourceTemplate () +// { +// Memory32Fixed (ReadWrite, 0xFED00000, 0x1000) +// }) +// } +// } +// } +// ``` +// +// 2. **Compile the table**: +// +// ```sh +// iasl -tc ssdt.dsl +// ``` +// +// This generates `ssdt.aml` +// +// 3. **Run QEMU** with the compiled AML file: +// +// ```sh +// qemu-system-x86_64 -m 512M \ +// -enable-kvm \ +// -kernel path/to/bzImage \ +// -append "root=/dev/sda console=ttyS0" \ +// -hda rootfs.img \ +// -serial stdio \ +// -acpitable file=ssdt.aml +// ``` +// +// Requirements: +// - The `rust_driver_platform` must be present either: +// - built directly into the kernel (`bzImage`), or +// - available as a `.ko` file and loadable from `rootfs.img` +// +// 4. **Verify it worked** by checking `dmesg`: +// +// ``` +// rust_driver_platform TEST4321:00: Probed with info: '0'. +// ``` +// +// This demonstrates ACPI table matching using a custom ID in QEMU with a minimal SSDT + +kernel::acpi_device_table!( + ACPI_TABLE, + MODULE_ACPI_TABLE, + <SampleDriver as platform::Driver>::IdInfo, + [(acpi::DeviceId::new(c_str!("TEST4321")), Info(0))] +); + +/// OF/ACPI match tables for Platform Driver implementation +/// +/// The platform::Driver requires declaration of both OF_ID_TABLE and +/// ACPI_ID_TABLE, but if driver is not going to use either of them +/// it can implement one of them or both as None. +/// +/// # Example: +/// +/// ```ignore +/// impl platform::Driver for SampleDriver { +/// type IdInfo = (); +/// const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None; +/// const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = None; +/// +/// fn probe( +/// pdev: &platform::Device<Core>, +/// _info: Option<&Self::IdInfo>, +/// ) -> Result<Pin<KBox<Self>>> { +/// dev_dbg!(pdev.as_ref(), "Probe Rust Platform driver sample.\n"); +/// +/// let drvdata = KBox::new(Self { pdev: pdev.into() }, GFP_KERNEL)?; +/// +/// Ok(drvdata.into()) +/// } +/// } +/// ``` impl platform::Driver for SampleDriver { type IdInfo = Info; const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE); - const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = None; + const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE); fn probe( pdev: &platform::Device<Core>,
Extend the Rust sample platform driver to probe using device/driver name matching, OF ID table matching, or ACPI ID table matching. Signed-off-by: Igor Korotin <igor.korotin.linux@gmail.com> --- samples/rust/rust_driver_platform.rs | 96 +++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-)