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, zeroable::Zeroable}; 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 ..Zeroable::ZERO 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 default = true 34 ), 35 } 36 37 qemu_api::device_class_init! { 38 pl011_class_init, 39 props => PL011_PROPERTIES, 40 realize_fn => Some(pl011_realize), 41 legacy_reset_fn => Some(pl011_reset), 42 vmsd => VMSTATE_PL011, 43 } 44 45 /// # Safety 46 /// 47 /// We expect the FFI user of this function to pass a valid pointer, that has 48 /// the same size as [`PL011State`]. We also expect the device is 49 /// readable/writeable from one thread at any time. 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 pub unsafe extern "C" fn pl011_reset(dev: *mut DeviceState) { 64 unsafe { 65 assert!(!dev.is_null()); 66 let mut state = NonNull::new_unchecked(dev.cast::<PL011State>()); 67 state.as_mut().reset(); 68 } 69 } 70