rust: sysbus: wrap SysBusDevice with Opaque<>

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Paolo Bonzini 2025-02-14 11:45:36 +01:00
parent 09fda8f5dc
commit f4751c7a42
2 changed files with 21 additions and 11 deletions

View file

@ -40,9 +40,6 @@ unsafe impl Sync for MemoryRegion {}
unsafe impl Send for ObjectClass {} unsafe impl Send for ObjectClass {}
unsafe impl Sync for ObjectClass {} unsafe impl Sync for ObjectClass {}
unsafe impl Send for SysBusDevice {}
unsafe impl Sync for SysBusDevice {}
// SAFETY: this is a pure data struct // SAFETY: this is a pure data struct
unsafe impl Send for CoalescedMemoryRange {} unsafe impl Send for CoalescedMemoryRange {}
unsafe impl Sync for CoalescedMemoryRange {} unsafe impl Sync for CoalescedMemoryRange {}

View file

@ -6,11 +6,11 @@
use std::{ffi::CStr, ptr::addr_of_mut}; use std::{ffi::CStr, ptr::addr_of_mut};
pub use bindings::{SysBusDevice, SysBusDeviceClass}; pub use bindings::SysBusDeviceClass;
use crate::{ use crate::{
bindings, bindings,
cell::bql_locked, cell::{bql_locked, Opaque},
irq::{IRQState, InterruptSource}, irq::{IRQState, InterruptSource},
memory::MemoryRegion, memory::MemoryRegion,
prelude::*, prelude::*,
@ -18,6 +18,14 @@ use crate::{
qom::Owned, qom::Owned,
}; };
/// A safe wrapper around [`bindings::SysBusDevice`].
#[repr(transparent)]
#[derive(Debug, qemu_api_macros::Wrapper)]
pub struct SysBusDevice(Opaque<bindings::SysBusDevice>);
unsafe impl Send for SysBusDevice {}
unsafe impl Sync for SysBusDevice {}
unsafe impl ObjectType for SysBusDevice { unsafe impl ObjectType for SysBusDevice {
type Class = SysBusDeviceClass; type Class = SysBusDeviceClass;
const TYPE_NAME: &'static CStr = const TYPE_NAME: &'static CStr =
@ -49,7 +57,7 @@ where
fn init_mmio(&self, iomem: &MemoryRegion) { fn init_mmio(&self, iomem: &MemoryRegion) {
assert!(bql_locked()); assert!(bql_locked());
unsafe { unsafe {
bindings::sysbus_init_mmio(self.as_mut_ptr(), iomem.as_mut_ptr()); bindings::sysbus_init_mmio(self.upcast().as_mut_ptr(), iomem.as_mut_ptr());
} }
} }
@ -60,14 +68,16 @@ where
fn init_irq(&self, irq: &InterruptSource) { fn init_irq(&self, irq: &InterruptSource) {
assert!(bql_locked()); assert!(bql_locked());
unsafe { unsafe {
bindings::sysbus_init_irq(self.as_mut_ptr(), irq.as_ptr()); bindings::sysbus_init_irq(self.upcast().as_mut_ptr(), irq.as_ptr());
} }
} }
// TODO: do we want a type like GuestAddress here? // TODO: do we want a type like GuestAddress here?
fn mmio_addr(&self, id: u32) -> Option<u64> { fn mmio_addr(&self, id: u32) -> Option<u64> {
assert!(bql_locked()); assert!(bql_locked());
let sbd = self.upcast(); // SAFETY: the BQL ensures that no one else writes to sbd.mmio[], and
// the SysBusDevice must be initialized to get an IsA<SysBusDevice>.
let sbd = unsafe { *self.upcast().as_ptr() };
let id: usize = id.try_into().unwrap(); let id: usize = id.try_into().unwrap();
if sbd.mmio[id].memory.is_null() { if sbd.mmio[id].memory.is_null() {
None None
@ -81,7 +91,7 @@ where
assert!(bql_locked()); assert!(bql_locked());
let id: i32 = id.try_into().unwrap(); let id: i32 = id.try_into().unwrap();
unsafe { unsafe {
bindings::sysbus_mmio_map(self.as_mut_ptr(), id, addr); bindings::sysbus_mmio_map(self.upcast().as_mut_ptr(), id, addr);
} }
} }
@ -93,7 +103,7 @@ where
let id: i32 = id.try_into().unwrap(); let id: i32 = id.try_into().unwrap();
let irq: &IRQState = irq; let irq: &IRQState = irq;
unsafe { unsafe {
bindings::sysbus_connect_irq(self.as_mut_ptr(), id, irq.as_mut_ptr()); bindings::sysbus_connect_irq(self.upcast().as_mut_ptr(), id, irq.as_mut_ptr());
} }
} }
@ -101,7 +111,10 @@ where
// TODO: return an Error // TODO: return an Error
assert!(bql_locked()); assert!(bql_locked());
unsafe { unsafe {
bindings::sysbus_realize(self.as_mut_ptr(), addr_of_mut!(bindings::error_fatal)); bindings::sysbus_realize(
self.upcast().as_mut_ptr(),
addr_of_mut!(bindings::error_fatal),
);
} }
} }
} }