diff options
| author | Stefan Hajnoczi <stefanha@redhat.com> | 2025-01-17 10:12:52 -0500 |
|---|---|---|
| committer | Stefan Hajnoczi <stefanha@redhat.com> | 2025-01-17 10:12:52 -0500 |
| commit | 09360a048bd7a133e47cb8dea617d44540bdebbd (patch) | |
| tree | 2b4868526830031398f0f8077c8bfc86854cf5c5 /rust/hw/char/pl011/src | |
| parent | 4d5d933bbc7cc52f6cc6b9021f91fa06266222d5 (diff) | |
| parent | 99a637a86f55c8486b06c698656befdf012eec4d (diff) | |
| download | focaccia-qemu-09360a048bd7a133e47cb8dea617d44540bdebbd.tar.gz focaccia-qemu-09360a048bd7a133e47cb8dea617d44540bdebbd.zip | |
Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging
* rust: miscellaneous changes * target/i386: small code generation improvements * target/i386: various cleanups and fixes * cpu: remove env->nr_cores # -----BEGIN PGP SIGNATURE----- # # iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmeBoIgUHHBib256aW5p # QHJlZGhhdC5jb20ACgkQv/vSX3jHroOD2gf+NK7U1EhNIrsbBsbtu2i7+tnbRKIB # MTu+Mxb2wz4C7//pxq+vva4bgT3iOuL9RF19PRe/63CMD65xMiwyyNrEWX2HbRIJ # 5dytLLLdef3yMhHh2x1uZfm54g12Ppvn9kulMCbPawrlqWgg1sZbkUBrRtFzS45c # NeYjGWWSpBDe7LtsrgSRYLPnz6wWEiy3tDpu2VoDtjrE86UVDXwyzpbtBk9Y8jPi # CKdvLyQeO9xDE5OoXMjJMlJeQq3D9iwYEprXUqy+RUZtpW7YmqMCf2JQ4dAjVCad # 07v/kITF4brGCVnzDcDA6W7LqHpBu1w+Hn23yLw3HEDDBt11o9JjQCl9qA== # =xIQ4 # -----END PGP SIGNATURE----- # gpg: Signature made Fri 10 Jan 2025 17:34:48 EST # gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83 # gpg: issuer "pbonzini@redhat.com" # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full] # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * tag 'for-upstream' of https://gitlab.com/bonzini/qemu: (38 commits) i386/cpu: Set and track CPUID_EXT3_CMP_LEG in env->features[FEAT_8000_0001_ECX] i386/cpu: Set up CPUID_HT in x86_cpu_expand_features() instead of cpu_x86_cpuid() cpu: Remove nr_cores from struct CPUState i386/cpu: Hoist check of CPUID_EXT3_TOPOEXT against threads_per_core i386/cpu: Track a X86CPUTopoInfo directly in CPUX86State i386/topology: Introduce helpers for various topology info of different level i386/topology: Update the comment of x86_apicid_from_topo_ids() i386/cpu: Drop cores_per_pkg in cpu_x86_cpuid() i386/cpu: Drop the variable smp_cores and smp_threads in x86_cpu_pre_plug() i386/cpu: Extract a common fucntion to setup value of MSR_CORE_THREAD_COUNT target/i386/kvm: Replace ARRAY_SIZE(msr_handlers) with KVM_MSR_FILTER_MAX_RANGES target/i386/kvm: Clean up error handling in kvm_arch_init() target/i386/kvm: Return -1 when kvm_msr_energy_thread_init() fails target/i386/kvm: Clean up return values of MSR filter related functions target/i386/confidential-guest: Fix comment of x86_confidential_guest_kvm_type() target/i386/kvm: Drop workaround for KVM_X86_DISABLE_EXITS_HTL typo target/i386/kvm: Only save/load kvmclock MSRs when kvmclock enabled target/i386/kvm: Remove local MSR_KVM_WALL_CLOCK and MSR_KVM_SYSTEM_TIME definitions target/i386/kvm: Add feature bit definitions for KVM CPUID i386/cpu: Mark avx10_version filtered when prefix is NULL ... Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'rust/hw/char/pl011/src')
| -rw-r--r-- | rust/hw/char/pl011/src/device.rs | 79 | ||||
| -rw-r--r-- | rust/hw/char/pl011/src/lib.rs | 28 |
2 files changed, 39 insertions, 68 deletions
diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs index 18cc122951..994c2fc059 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -5,7 +5,7 @@ use core::ptr::{addr_of_mut, NonNull}; use std::{ ffi::CStr, - os::raw::{c_int, c_uchar, c_uint, c_void}, + os::raw::{c_int, c_uint, c_void}, }; use qemu_api::{ @@ -14,7 +14,7 @@ use qemu_api::{ irq::InterruptSource, prelude::*, qdev::DeviceImpl, - qom::ObjectImpl, + qom::{ClassInitImpl, ObjectImpl, ParentField}, }; use crate::{ @@ -33,27 +33,20 @@ const FBRD_MASK: u32 = 0x3f; /// QEMU sourced constant. pub const PL011_FIFO_DEPTH: u32 = 16; -#[derive(Clone, Copy, Debug)] -enum DeviceId { - #[allow(dead_code)] - Arm = 0, - Luminary, -} +#[derive(Clone, Copy)] +struct DeviceId(&'static [u8; 8]); impl std::ops::Index<hwaddr> for DeviceId { - type Output = c_uchar; + type Output = u8; fn index(&self, idx: hwaddr) -> &Self::Output { - match self { - Self::Arm => &Self::PL011_ID_ARM[idx as usize], - Self::Luminary => &Self::PL011_ID_LUMINARY[idx as usize], - } + &self.0[idx as usize] } } impl DeviceId { - const PL011_ID_ARM: [c_uchar; 8] = [0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1]; - const PL011_ID_LUMINARY: [c_uchar; 8] = [0x11, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1]; + const ARM: Self = Self(&[0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1]); + const LUMINARY: Self = Self(&[0x11, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1]); } // FIFOs use 32-bit indices instead of usize, for compatibility with @@ -86,7 +79,7 @@ impl std::ops::Index<u32> for Fifo { #[derive(Debug, qemu_api_macros::Object, qemu_api_macros::offsets)] /// PL011 Device Model in QEMU pub struct PL011State { - pub parent_obj: SysBusDevice, + pub parent_obj: ParentField<SysBusDevice>, pub iomem: MemoryRegion, #[doc(alias = "fr")] pub flags: registers::Flags, @@ -126,21 +119,33 @@ pub struct PL011State { pub clock: NonNull<Clock>, #[doc(alias = "migrate_clk")] pub migrate_clock: bool, - /// The byte string that identifies the device. - device_id: DeviceId, } qom_isa!(PL011State : SysBusDevice, DeviceState, Object); +pub struct PL011Class { + parent_class: <SysBusDevice as ObjectType>::Class, + /// The byte string that identifies the device. + device_id: DeviceId, +} + unsafe impl ObjectType for PL011State { - type Class = <SysBusDevice as ObjectType>::Class; + type Class = PL011Class; const TYPE_NAME: &'static CStr = crate::TYPE_PL011; } +impl ClassInitImpl<PL011Class> for PL011State { + fn class_init(klass: &mut PL011Class) { + klass.device_id = DeviceId::ARM; + <Self as ClassInitImpl<SysBusDeviceClass>>::class_init(&mut klass.parent_class); + } +} + impl ObjectImpl for PL011State { type ParentType = SysBusDevice; const INSTANCE_INIT: Option<unsafe fn(&mut Self)> = Some(Self::init); + const INSTANCE_POST_INIT: Option<fn(&Self)> = Some(Self::post_init); } impl DeviceImpl for PL011State { @@ -179,14 +184,6 @@ impl PL011State { Self::TYPE_NAME.as_ptr(), 0x1000, ); - - let sbd: &mut SysBusDevice = self.upcast_mut(); - sysbus_init_mmio(sbd, addr_of_mut!(self.iomem)); - } - - for irq in self.interrupts.iter() { - let sbd: &SysBusDevice = self.upcast(); - sbd.init_irq(irq); } // SAFETY: @@ -209,12 +206,20 @@ impl PL011State { } } + fn post_init(&self) { + self.init_mmio(&self.iomem); + for irq in self.interrupts.iter() { + self.init_irq(irq); + } + } + pub fn read(&mut self, offset: hwaddr, _size: c_uint) -> std::ops::ControlFlow<u64, u64> { use RegisterOffset::*; let value = match RegisterOffset::try_from(offset) { Err(v) if (0x3f8..0x400).contains(&(v >> 2)) => { - u32::from(self.device_id[(offset - 0xfe0) >> 2]) + let device_id = self.get_class().device_id; + u32::from(device_id[(offset - 0xfe0) >> 2]) } Err(_) => { // qemu_log_mask(LOG_GUEST_ERROR, "pl011_read: Bad offset 0x%x\n", (int)offset); @@ -645,19 +650,13 @@ pub unsafe extern "C" fn pl011_create( #[derive(Debug, qemu_api_macros::Object)] /// PL011 Luminary device model. pub struct PL011Luminary { - parent_obj: PL011State, + parent_obj: ParentField<PL011State>, } -impl PL011Luminary { - /// Initializes a pre-allocated, unitialized instance of `PL011Luminary`. - /// - /// # Safety - /// - /// We expect the FFI user of this function to pass a valid pointer, that - /// has the same size as [`PL011Luminary`]. We also expect the device is - /// readable/writeable from one thread at any time. - unsafe fn init(&mut self) { - self.parent_obj.device_id = DeviceId::Luminary; +impl ClassInitImpl<PL011Class> for PL011Luminary { + fn class_init(klass: &mut PL011Class) { + klass.device_id = DeviceId::LUMINARY; + <Self as ClassInitImpl<SysBusDeviceClass>>::class_init(&mut klass.parent_class); } } @@ -670,8 +669,6 @@ unsafe impl ObjectType for PL011Luminary { impl ObjectImpl for PL011Luminary { type ParentType = PL011State; - - const INSTANCE_INIT: Option<unsafe fn(&mut Self)> = Some(Self::init); } impl DeviceImpl for PL011Luminary {} diff --git a/rust/hw/char/pl011/src/lib.rs b/rust/hw/char/pl011/src/lib.rs index 69064d6929..0a89d393e0 100644 --- a/rust/hw/char/pl011/src/lib.rs +++ b/rust/hw/char/pl011/src/lib.rs @@ -45,7 +45,7 @@ pub const TYPE_PL011_LUMINARY: &::std::ffi::CStr = c_str!("pl011_luminary"); #[doc(alias = "offset")] #[allow(non_camel_case_types)] #[repr(u64)] -#[derive(Debug)] +#[derive(Debug, qemu_api_macros::TryInto)] pub enum RegisterOffset { /// Data Register /// @@ -102,32 +102,6 @@ pub enum RegisterOffset { //Reserved = 0x04C, } -impl core::convert::TryFrom<u64> for RegisterOffset { - type Error = u64; - - fn try_from(value: u64) -> Result<Self, Self::Error> { - macro_rules! case { - ($($discriminant:ident),*$(,)*) => { - /* check that matching on all macro arguments compiles, which means we are not - * missing any enum value; if the type definition ever changes this will stop - * compiling. - */ - const fn _assert_exhaustive(val: RegisterOffset) { - match val { - $(RegisterOffset::$discriminant => (),)* - } - } - - match value { - $(x if x == Self::$discriminant as u64 => Ok(Self::$discriminant),)* - _ => Err(value), - } - } - } - case! { DR, RSR, FR, FBRD, ILPR, IBRD, LCR_H, CR, FLS, IMSC, RIS, MIS, ICR, DMACR } - } -} - pub mod registers { //! Device registers exposed as typed structs which are backed by arbitrary //! integer bitmaps. [`Data`], [`Control`], [`LineControl`], etc. |