xref: /openbmc/qemu/rust/hw/char/pl011/src/device_class.rs (revision feb58e3b)
1 // Copyright 2024, Linaro Limited
2 // Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
3 // SPDX-License-Identifier: GPL-2.0-or-later
4 
5 use core::ptr::NonNull;
6 
7 use qemu_api::{bindings::*, definitions::ObjectImpl};
8 
9 use crate::device::PL011State;
10 
11 #[used]
12 pub static VMSTATE_PL011: VMStateDescription = VMStateDescription {
13     name: PL011State::TYPE_INFO.name,
14     unmigratable: true,
15     ..unsafe { ::core::mem::MaybeUninit::<VMStateDescription>::zeroed().assume_init() }
16 };
17 
18 qemu_api::declare_properties! {
19     PL011_PROPERTIES,
20     qemu_api::define_property!(
21         c"chardev",
22         PL011State,
23         char_backend,
24         unsafe { &qdev_prop_chr },
25         CharBackend
26     ),
27     qemu_api::define_property!(
28         c"migrate-clk",
29         PL011State,
30         migrate_clock,
31         unsafe { &qdev_prop_bool },
32         bool
33     ),
34 }
35 
36 qemu_api::device_class_init! {
37     pl011_class_init,
38     props => PL011_PROPERTIES,
39     realize_fn => Some(pl011_realize),
40     legacy_reset_fn => Some(pl011_reset),
41     vmsd => VMSTATE_PL011,
42 }
43 
44 /// # Safety
45 ///
46 /// We expect the FFI user of this function to pass a valid pointer, that has
47 /// the same size as [`PL011State`]. We also expect the device is
48 /// readable/writeable from one thread at any time.
49 #[no_mangle]
50 pub unsafe extern "C" fn pl011_realize(dev: *mut DeviceState, _errp: *mut *mut Error) {
51     unsafe {
52         assert!(!dev.is_null());
53         let mut state = NonNull::new_unchecked(dev.cast::<PL011State>());
54         state.as_mut().realize();
55     }
56 }
57 
58 /// # Safety
59 ///
60 /// We expect the FFI user of this function to pass a valid pointer, that has
61 /// the same size as [`PL011State`]. We also expect the device is
62 /// readable/writeable from one thread at any time.
63 #[no_mangle]
64 pub unsafe extern "C" fn pl011_reset(dev: *mut DeviceState) {
65     unsafe {
66         assert!(!dev.is_null());
67         let mut state = NonNull::new_unchecked(dev.cast::<PL011State>());
68         state.as_mut().reset();
69     }
70 }
71