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