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