summary refs log tree commit diff stats
path: root/rust/hw/char/pl011/src/device_class.rs
diff options
context:
space:
mode:
authorManos Pitsidianakis <manos.pitsidianakis@linaro.org>2024-10-24 17:03:00 +0300
committerPaolo Bonzini <pbonzini@redhat.com>2024-11-05 14:18:15 +0100
commit37fdb2f56a90c7d5ea7093b920a7bf72c03aff17 (patch)
treebc992b6a83b62d964819addea7fdc5fd0d6c9f48 /rust/hw/char/pl011/src/device_class.rs
parentca5aa28e244ee3dfe0dd6c76c7c33ce78f25beed (diff)
downloadfocaccia-qemu-37fdb2f56a90c7d5ea7093b920a7bf72c03aff17.tar.gz
focaccia-qemu-37fdb2f56a90c7d5ea7093b920a7bf72c03aff17.zip
rust: add PL011 device model
This commit adds a re-implementation of hw/char/pl011.c in Rust.

How to build:

1. Configure a QEMU build with:
   --enable-system --target-list=aarch64-softmmu --enable-rust
2. Launching a VM with qemu-system-aarch64 should use the Rust version
   of the pl011 device

Co-authored-by: Junjie Mao <junjie.mao@intel.com>
Co-authored-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Junjie Mao <junjie.mao@intel.com>
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Link: https://lore.kernel.org/r/20241024-rust-round-2-v1-2-051e7a25b978@linaro.org
Diffstat (limited to 'rust/hw/char/pl011/src/device_class.rs')
-rw-r--r--rust/hw/char/pl011/src/device_class.rs70
1 files changed, 70 insertions, 0 deletions
diff --git a/rust/hw/char/pl011/src/device_class.rs b/rust/hw/char/pl011/src/device_class.rs
new file mode 100644
index 0000000000..b7ab31af02
--- /dev/null
+++ b/rust/hw/char/pl011/src/device_class.rs
@@ -0,0 +1,70 @@
+// Copyright 2024, Linaro Limited
+// Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+use core::ptr::NonNull;
+
+use qemu_api::{bindings::*, definitions::ObjectImpl};
+
+use crate::device::PL011State;
+
+#[used]
+pub static VMSTATE_PL011: VMStateDescription = VMStateDescription {
+    name: PL011State::TYPE_INFO.name,
+    unmigratable: true,
+    ..unsafe { ::core::mem::MaybeUninit::<VMStateDescription>::zeroed().assume_init() }
+};
+
+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
+    ),
+}
+
+qemu_api::device_class_init! {
+    pl011_class_init,
+    props => PL011_PROPERTIES,
+    realize_fn => Some(pl011_realize),
+    legacy_reset_fn => Some(pl011_reset),
+    vmsd => VMSTATE_PL011,
+}
+
+/// # Safety
+///
+/// We expect the FFI user of this function to pass a valid pointer, that has
+/// the same size as [`PL011State`]. We also expect the device is
+/// readable/writeable from one thread at any time.
+#[no_mangle]
+pub unsafe extern "C" fn pl011_realize(dev: *mut DeviceState, _errp: *mut *mut Error) {
+    unsafe {
+        assert!(!dev.is_null());
+        let mut state = NonNull::new_unchecked(dev.cast::<PL011State>());
+        state.as_mut().realize();
+    }
+}
+
+/// # Safety
+///
+/// We expect the FFI user of this function to pass a valid pointer, that has
+/// the same size as [`PL011State`]. We also expect the device is
+/// readable/writeable from one thread at any time.
+#[no_mangle]
+pub unsafe extern "C" fn pl011_reset(dev: *mut DeviceState) {
+    unsafe {
+        assert!(!dev.is_null());
+        let mut state = NonNull::new_unchecked(dev.cast::<PL011State>());
+        state.as_mut().reset();
+    }
+}