xref: /openbmc/qemu/rust/hw/char/pl011/src/device_class.rs (revision 6e50bde1)
137fdb2f5SManos Pitsidianakis // Copyright 2024, Linaro Limited
237fdb2f5SManos Pitsidianakis // Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
337fdb2f5SManos Pitsidianakis // SPDX-License-Identifier: GPL-2.0-or-later
437fdb2f5SManos Pitsidianakis 
537fdb2f5SManos Pitsidianakis use core::ptr::NonNull;
637fdb2f5SManos Pitsidianakis 
7*6e50bde1SPaolo Bonzini use qemu_api::{bindings::*, definitions::ObjectImpl, zeroable::Zeroable};
837fdb2f5SManos Pitsidianakis 
937fdb2f5SManos Pitsidianakis use crate::device::PL011State;
1037fdb2f5SManos Pitsidianakis 
1137fdb2f5SManos Pitsidianakis #[used]
1237fdb2f5SManos Pitsidianakis pub static VMSTATE_PL011: VMStateDescription = VMStateDescription {
1337fdb2f5SManos Pitsidianakis     name: PL011State::TYPE_INFO.name,
1437fdb2f5SManos Pitsidianakis     unmigratable: true,
15*6e50bde1SPaolo Bonzini     ..Zeroable::ZERO
1637fdb2f5SManos Pitsidianakis };
1737fdb2f5SManos Pitsidianakis 
1837fdb2f5SManos Pitsidianakis qemu_api::declare_properties! {
1937fdb2f5SManos Pitsidianakis     PL011_PROPERTIES,
2037fdb2f5SManos Pitsidianakis     qemu_api::define_property!(
2137fdb2f5SManos Pitsidianakis         c"chardev",
2237fdb2f5SManos Pitsidianakis         PL011State,
2337fdb2f5SManos Pitsidianakis         char_backend,
2437fdb2f5SManos Pitsidianakis         unsafe { &qdev_prop_chr },
2537fdb2f5SManos Pitsidianakis         CharBackend
2637fdb2f5SManos Pitsidianakis     ),
2737fdb2f5SManos Pitsidianakis     qemu_api::define_property!(
2837fdb2f5SManos Pitsidianakis         c"migrate-clk",
2937fdb2f5SManos Pitsidianakis         PL011State,
3037fdb2f5SManos Pitsidianakis         migrate_clock,
3137fdb2f5SManos Pitsidianakis         unsafe { &qdev_prop_bool },
3237fdb2f5SManos Pitsidianakis         bool
3337fdb2f5SManos Pitsidianakis     ),
3437fdb2f5SManos Pitsidianakis }
3537fdb2f5SManos Pitsidianakis 
3637fdb2f5SManos Pitsidianakis qemu_api::device_class_init! {
3737fdb2f5SManos Pitsidianakis     pl011_class_init,
3837fdb2f5SManos Pitsidianakis     props => PL011_PROPERTIES,
3937fdb2f5SManos Pitsidianakis     realize_fn => Some(pl011_realize),
4037fdb2f5SManos Pitsidianakis     legacy_reset_fn => Some(pl011_reset),
4137fdb2f5SManos Pitsidianakis     vmsd => VMSTATE_PL011,
4237fdb2f5SManos Pitsidianakis }
4337fdb2f5SManos Pitsidianakis 
4437fdb2f5SManos Pitsidianakis /// # Safety
4537fdb2f5SManos Pitsidianakis ///
4637fdb2f5SManos Pitsidianakis /// We expect the FFI user of this function to pass a valid pointer, that has
4737fdb2f5SManos Pitsidianakis /// the same size as [`PL011State`]. We also expect the device is
4837fdb2f5SManos Pitsidianakis /// readable/writeable from one thread at any time.
4937fdb2f5SManos Pitsidianakis pub unsafe extern "C" fn pl011_realize(dev: *mut DeviceState, _errp: *mut *mut Error) {
5037fdb2f5SManos Pitsidianakis     unsafe {
5137fdb2f5SManos Pitsidianakis         assert!(!dev.is_null());
5237fdb2f5SManos Pitsidianakis         let mut state = NonNull::new_unchecked(dev.cast::<PL011State>());
5337fdb2f5SManos Pitsidianakis         state.as_mut().realize();
5437fdb2f5SManos Pitsidianakis     }
5537fdb2f5SManos Pitsidianakis }
5637fdb2f5SManos Pitsidianakis 
5737fdb2f5SManos Pitsidianakis /// # Safety
5837fdb2f5SManos Pitsidianakis ///
5937fdb2f5SManos Pitsidianakis /// We expect the FFI user of this function to pass a valid pointer, that has
6037fdb2f5SManos Pitsidianakis /// the same size as [`PL011State`]. We also expect the device is
6137fdb2f5SManos Pitsidianakis /// readable/writeable from one thread at any time.
6237fdb2f5SManos Pitsidianakis pub unsafe extern "C" fn pl011_reset(dev: *mut DeviceState) {
6337fdb2f5SManos Pitsidianakis     unsafe {
6437fdb2f5SManos Pitsidianakis         assert!(!dev.is_null());
6537fdb2f5SManos Pitsidianakis         let mut state = NonNull::new_unchecked(dev.cast::<PL011State>());
6637fdb2f5SManos Pitsidianakis         state.as_mut().reset();
6737fdb2f5SManos Pitsidianakis     }
6837fdb2f5SManos Pitsidianakis }
69