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 use std::os::raw::{c_int, c_void}; 7 8 use qemu_api::{ 9 bindings::*, c_str, vmstate_clock, vmstate_fields, vmstate_of, vmstate_subsections, 10 vmstate_unused, zeroable::Zeroable, 11 }; 12 13 use crate::device::PL011State; 14 15 #[allow(clippy::missing_const_for_fn)] 16 extern "C" fn pl011_clock_needed(opaque: *mut c_void) -> bool { 17 let state = NonNull::new(opaque).unwrap().cast::<PL011State>(); 18 unsafe { state.as_ref().migrate_clock } 19 } 20 21 /// Migration subsection for [`PL011State`] clock. 22 pub static VMSTATE_PL011_CLOCK: VMStateDescription = VMStateDescription { 23 name: c_str!("pl011/clock").as_ptr(), 24 version_id: 1, 25 minimum_version_id: 1, 26 needed: Some(pl011_clock_needed), 27 fields: vmstate_fields! { 28 vmstate_clock!(PL011State, clock), 29 }, 30 ..Zeroable::ZERO 31 }; 32 33 extern "C" fn pl011_post_load(opaque: *mut c_void, version_id: c_int) -> c_int { 34 let mut state = NonNull::new(opaque).unwrap().cast::<PL011State>(); 35 let result = unsafe { state.as_mut().post_load(version_id as u32) }; 36 if result.is_err() { 37 -1 38 } else { 39 0 40 } 41 } 42 43 pub static VMSTATE_PL011: VMStateDescription = VMStateDescription { 44 name: c_str!("pl011").as_ptr(), 45 version_id: 2, 46 minimum_version_id: 2, 47 post_load: Some(pl011_post_load), 48 fields: vmstate_fields! { 49 vmstate_unused!(core::mem::size_of::<u32>()), 50 vmstate_of!(PL011State, flags), 51 vmstate_of!(PL011State, line_control), 52 vmstate_of!(PL011State, receive_status_error_clear), 53 vmstate_of!(PL011State, control), 54 vmstate_of!(PL011State, dmacr), 55 vmstate_of!(PL011State, int_enabled), 56 vmstate_of!(PL011State, int_level), 57 vmstate_of!(PL011State, read_fifo), 58 vmstate_of!(PL011State, ilpr), 59 vmstate_of!(PL011State, ibrd), 60 vmstate_of!(PL011State, fbrd), 61 vmstate_of!(PL011State, ifl), 62 vmstate_of!(PL011State, read_pos), 63 vmstate_of!(PL011State, read_count), 64 vmstate_of!(PL011State, read_trigger), 65 }, 66 subsections: vmstate_subsections! { 67 VMSTATE_PL011_CLOCK 68 }, 69 ..Zeroable::ZERO 70 }; 71 72 qemu_api::declare_properties! { 73 PL011_PROPERTIES, 74 qemu_api::define_property!( 75 c_str!("chardev"), 76 PL011State, 77 char_backend, 78 unsafe { &qdev_prop_chr }, 79 CharBackend 80 ), 81 qemu_api::define_property!( 82 c_str!("migrate-clk"), 83 PL011State, 84 migrate_clock, 85 unsafe { &qdev_prop_bool }, 86 bool, 87 default = true 88 ), 89 } 90