diff options
Diffstat (limited to 'rust/hw/char')
-rw-r--r-- | rust/hw/char/pl011/Cargo.toml | 3 | ||||
-rw-r--r-- | rust/hw/char/pl011/src/device.rs | 103 | ||||
-rw-r--r-- | rust/hw/char/pl011/src/device_class.rs | 103 | ||||
-rw-r--r-- | rust/hw/char/pl011/src/lib.rs | 1 |
4 files changed, 96 insertions, 114 deletions
diff --git a/rust/hw/char/pl011/Cargo.toml b/rust/hw/char/pl011/Cargo.toml index 003ef96..88ef110 100644 --- a/rust/hw/char/pl011/Cargo.toml +++ b/rust/hw/char/pl011/Cargo.toml @@ -12,9 +12,6 @@ license.workspace = true repository.workspace = true rust-version.workspace = true -[lib] -crate-type = ["staticlib"] - [dependencies] bilge = { version = "0.2.0" } bilge-impl = { version = "0.2.0" } diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs index 5b53f26..ceb71dd 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -2,9 +2,14 @@ // Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org> // SPDX-License-Identifier: GPL-2.0-or-later -use std::{ffi::CStr, mem::size_of}; +use std::{ + ffi::{c_int, c_void, CStr}, + mem::size_of, + ptr::NonNull, +}; use qemu_api::{ + bindings::{qdev_prop_bool, qdev_prop_chr}, chardev::{CharBackend, Chardev, Event}, impl_vmstate_forward, irq::{IRQState, InterruptSource}, @@ -18,12 +23,11 @@ use qemu_api::{ sysbus::{SysBusDevice, SysBusDeviceImpl}, uninit_field_mut, vmstate::VMStateDescription, + vmstate_clock, vmstate_fields, vmstate_of, vmstate_struct, vmstate_subsections, vmstate_unused, + zeroable::Zeroable, }; -use crate::{ - device_class, - registers::{self, Interrupt, RegisterOffset}, -}; +use crate::registers::{self, Interrupt, RegisterOffset}; // TODO: You must disable the UART before any of the control registers are // reprogrammed. When the UART is disabled in the middle of transmission or @@ -173,10 +177,10 @@ impl ObjectImpl for PL011State { impl DeviceImpl for PL011State { fn properties() -> &'static [Property] { - &device_class::PL011_PROPERTIES + &PL011_PROPERTIES } fn vmsd() -> Option<&'static VMStateDescription> { - Some(&device_class::VMSTATE_PL011) + Some(&VMSTATE_PL011) } const REALIZE: Option<fn(&Self) -> qemu_api::Result<()>> = Some(Self::realize); } @@ -712,3 +716,88 @@ impl PL011Impl for PL011Luminary { impl DeviceImpl for PL011Luminary {} impl ResettablePhasesImpl for PL011Luminary {} impl SysBusDeviceImpl for PL011Luminary {} + +extern "C" fn pl011_clock_needed(opaque: *mut c_void) -> bool { + let state = NonNull::new(opaque).unwrap().cast::<PL011State>(); + unsafe { state.as_ref().migrate_clock } +} + +/// Migration subsection for [`PL011State`] clock. +static VMSTATE_PL011_CLOCK: VMStateDescription = VMStateDescription { + name: c"pl011/clock".as_ptr(), + version_id: 1, + minimum_version_id: 1, + needed: Some(pl011_clock_needed), + fields: vmstate_fields! { + vmstate_clock!(PL011State, clock), + }, + ..Zeroable::ZERO +}; + +extern "C" fn pl011_post_load(opaque: *mut c_void, version_id: c_int) -> c_int { + let state = NonNull::new(opaque).unwrap().cast::<PL011State>(); + let result = unsafe { state.as_ref().post_load(version_id as u32) }; + if result.is_err() { + -1 + } else { + 0 + } +} + +static VMSTATE_PL011_REGS: VMStateDescription = VMStateDescription { + name: c"pl011/regs".as_ptr(), + version_id: 2, + minimum_version_id: 2, + fields: vmstate_fields! { + vmstate_of!(PL011Registers, flags), + vmstate_of!(PL011Registers, line_control), + vmstate_of!(PL011Registers, receive_status_error_clear), + vmstate_of!(PL011Registers, control), + vmstate_of!(PL011Registers, dmacr), + vmstate_of!(PL011Registers, int_enabled), + vmstate_of!(PL011Registers, int_level), + vmstate_of!(PL011Registers, read_fifo), + vmstate_of!(PL011Registers, ilpr), + vmstate_of!(PL011Registers, ibrd), + vmstate_of!(PL011Registers, fbrd), + vmstate_of!(PL011Registers, ifl), + vmstate_of!(PL011Registers, read_pos), + vmstate_of!(PL011Registers, read_count), + vmstate_of!(PL011Registers, read_trigger), + }, + ..Zeroable::ZERO +}; + +pub static VMSTATE_PL011: VMStateDescription = VMStateDescription { + name: c"pl011".as_ptr(), + version_id: 2, + minimum_version_id: 2, + post_load: Some(pl011_post_load), + fields: vmstate_fields! { + vmstate_unused!(core::mem::size_of::<u32>()), + vmstate_struct!(PL011State, regs, &VMSTATE_PL011_REGS, BqlRefCell<PL011Registers>), + }, + subsections: vmstate_subsections! { + VMSTATE_PL011_CLOCK + }, + ..Zeroable::ZERO +}; + +qemu_api::declare_properties! { + PL011_PROPERTIES, + qemu_api::define_property!( + c"chardev", + PL011State, + char_backend, + unsafe { &qdev_prop_chr }, + CharBackend + ), + qemu_api::define_property!( + c"migrate-clk", + PL011State, + migrate_clock, + unsafe { &qdev_prop_bool }, + bool, + default = true + ), +} diff --git a/rust/hw/char/pl011/src/device_class.rs b/rust/hw/char/pl011/src/device_class.rs deleted file mode 100644 index d328d84..0000000 --- a/rust/hw/char/pl011/src/device_class.rs +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2024, Linaro Limited -// Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org> -// SPDX-License-Identifier: GPL-2.0-or-later - -use std::{ - ffi::{c_int, c_void}, - ptr::NonNull, -}; - -use qemu_api::{ - bindings::{qdev_prop_bool, qdev_prop_chr}, - prelude::*, - vmstate::VMStateDescription, - vmstate_clock, vmstate_fields, vmstate_of, vmstate_struct, vmstate_subsections, vmstate_unused, - zeroable::Zeroable, -}; - -use crate::device::{PL011Registers, PL011State}; - -extern "C" fn pl011_clock_needed(opaque: *mut c_void) -> bool { - let state = NonNull::new(opaque).unwrap().cast::<PL011State>(); - unsafe { state.as_ref().migrate_clock } -} - -/// Migration subsection for [`PL011State`] clock. -static VMSTATE_PL011_CLOCK: VMStateDescription = VMStateDescription { - name: c"pl011/clock".as_ptr(), - version_id: 1, - minimum_version_id: 1, - needed: Some(pl011_clock_needed), - fields: vmstate_fields! { - vmstate_clock!(PL011State, clock), - }, - ..Zeroable::ZERO -}; - -extern "C" fn pl011_post_load(opaque: *mut c_void, version_id: c_int) -> c_int { - let state = NonNull::new(opaque).unwrap().cast::<PL011State>(); - let result = unsafe { state.as_ref().post_load(version_id as u32) }; - if result.is_err() { - -1 - } else { - 0 - } -} - -static VMSTATE_PL011_REGS: VMStateDescription = VMStateDescription { - name: c"pl011/regs".as_ptr(), - version_id: 2, - minimum_version_id: 2, - fields: vmstate_fields! { - vmstate_of!(PL011Registers, flags), - vmstate_of!(PL011Registers, line_control), - vmstate_of!(PL011Registers, receive_status_error_clear), - vmstate_of!(PL011Registers, control), - vmstate_of!(PL011Registers, dmacr), - vmstate_of!(PL011Registers, int_enabled), - vmstate_of!(PL011Registers, int_level), - vmstate_of!(PL011Registers, read_fifo), - vmstate_of!(PL011Registers, ilpr), - vmstate_of!(PL011Registers, ibrd), - vmstate_of!(PL011Registers, fbrd), - vmstate_of!(PL011Registers, ifl), - vmstate_of!(PL011Registers, read_pos), - vmstate_of!(PL011Registers, read_count), - vmstate_of!(PL011Registers, read_trigger), - }, - ..Zeroable::ZERO -}; - -pub static VMSTATE_PL011: VMStateDescription = VMStateDescription { - name: c"pl011".as_ptr(), - version_id: 2, - minimum_version_id: 2, - post_load: Some(pl011_post_load), - fields: vmstate_fields! { - vmstate_unused!(core::mem::size_of::<u32>()), - vmstate_struct!(PL011State, regs, &VMSTATE_PL011_REGS, BqlRefCell<PL011Registers>), - }, - subsections: vmstate_subsections! { - VMSTATE_PL011_CLOCK - }, - ..Zeroable::ZERO -}; - -qemu_api::declare_properties! { - PL011_PROPERTIES, - qemu_api::define_property!( - c"chardev", - PL011State, - char_backend, - unsafe { &qdev_prop_chr }, - CharBackend - ), - qemu_api::define_property!( - c"migrate-clk", - PL011State, - migrate_clock, - unsafe { &qdev_prop_bool }, - bool, - default = true - ), -} diff --git a/rust/hw/char/pl011/src/lib.rs b/rust/hw/char/pl011/src/lib.rs index 5c4fbc9..2b70d2f 100644 --- a/rust/hw/char/pl011/src/lib.rs +++ b/rust/hw/char/pl011/src/lib.rs @@ -13,7 +13,6 @@ //! the [`registers`] module for register types. mod device; -mod device_class; mod registers; pub use device::pl011_create; |