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 5c48700e8SZhao Liu use std::{ 6*e4fb0be1SPaolo Bonzini ffi::{c_int, c_void}, 7c48700e8SZhao Liu ptr::NonNull, 8c48700e8SZhao Liu }; 937fdb2f5SManos Pitsidianakis 1093243319SManos Pitsidianakis use qemu_api::{ 11f7b87e46SZhao Liu bindings::{qdev_prop_bool, qdev_prop_chr}, 12f7b87e46SZhao Liu c_str, 13f7b87e46SZhao Liu prelude::*, 14f7b87e46SZhao Liu vmstate::VMStateDescription, 15f7b87e46SZhao Liu vmstate_clock, vmstate_fields, vmstate_of, vmstate_struct, vmstate_subsections, vmstate_unused, 16f7b87e46SZhao Liu zeroable::Zeroable, 1793243319SManos Pitsidianakis }; 1837fdb2f5SManos Pitsidianakis 1949bfe63fSPaolo Bonzini use crate::device::{PL011Registers, PL011State}; 2037fdb2f5SManos Pitsidianakis 2193243319SManos Pitsidianakis extern "C" fn pl011_clock_needed(opaque: *mut c_void) -> bool { 227d052039SPaolo Bonzini let state = NonNull::new(opaque).unwrap().cast::<PL011State>(); 237d052039SPaolo Bonzini unsafe { state.as_ref().migrate_clock } 2493243319SManos Pitsidianakis } 2593243319SManos Pitsidianakis 2693243319SManos Pitsidianakis /// Migration subsection for [`PL011State`] clock. 27d1f27ae9SPaolo Bonzini static VMSTATE_PL011_CLOCK: VMStateDescription = VMStateDescription { 28718e255fSPaolo Bonzini name: c_str!("pl011/clock").as_ptr(), 2993243319SManos Pitsidianakis version_id: 1, 3093243319SManos Pitsidianakis minimum_version_id: 1, 3193243319SManos Pitsidianakis needed: Some(pl011_clock_needed), 3293243319SManos Pitsidianakis fields: vmstate_fields! { 3324f0e8d8SPaolo Bonzini vmstate_clock!(PL011State, clock), 3493243319SManos Pitsidianakis }, 3593243319SManos Pitsidianakis ..Zeroable::ZERO 3693243319SManos Pitsidianakis }; 3793243319SManos Pitsidianakis 3893243319SManos Pitsidianakis extern "C" fn pl011_post_load(opaque: *mut c_void, version_id: c_int) -> c_int { 39a1ab4eedSPaolo Bonzini let state = NonNull::new(opaque).unwrap().cast::<PL011State>(); 40a1ab4eedSPaolo Bonzini let result = unsafe { state.as_ref().post_load(version_id as u32) }; 4193243319SManos Pitsidianakis if result.is_err() { 4293243319SManos Pitsidianakis -1 4393243319SManos Pitsidianakis } else { 4493243319SManos Pitsidianakis 0 4593243319SManos Pitsidianakis } 4693243319SManos Pitsidianakis } 4793243319SManos Pitsidianakis 4849bfe63fSPaolo Bonzini static VMSTATE_PL011_REGS: VMStateDescription = VMStateDescription { 4949bfe63fSPaolo Bonzini name: c_str!("pl011/regs").as_ptr(), 5049bfe63fSPaolo Bonzini version_id: 2, 5149bfe63fSPaolo Bonzini minimum_version_id: 2, 5249bfe63fSPaolo Bonzini fields: vmstate_fields! { 5349bfe63fSPaolo Bonzini vmstate_of!(PL011Registers, flags), 5449bfe63fSPaolo Bonzini vmstate_of!(PL011Registers, line_control), 5549bfe63fSPaolo Bonzini vmstate_of!(PL011Registers, receive_status_error_clear), 5649bfe63fSPaolo Bonzini vmstate_of!(PL011Registers, control), 5749bfe63fSPaolo Bonzini vmstate_of!(PL011Registers, dmacr), 5849bfe63fSPaolo Bonzini vmstate_of!(PL011Registers, int_enabled), 5949bfe63fSPaolo Bonzini vmstate_of!(PL011Registers, int_level), 6049bfe63fSPaolo Bonzini vmstate_of!(PL011Registers, read_fifo), 6149bfe63fSPaolo Bonzini vmstate_of!(PL011Registers, ilpr), 6249bfe63fSPaolo Bonzini vmstate_of!(PL011Registers, ibrd), 6349bfe63fSPaolo Bonzini vmstate_of!(PL011Registers, fbrd), 6449bfe63fSPaolo Bonzini vmstate_of!(PL011Registers, ifl), 6549bfe63fSPaolo Bonzini vmstate_of!(PL011Registers, read_pos), 6649bfe63fSPaolo Bonzini vmstate_of!(PL011Registers, read_count), 6749bfe63fSPaolo Bonzini vmstate_of!(PL011Registers, read_trigger), 6849bfe63fSPaolo Bonzini }, 6949bfe63fSPaolo Bonzini ..Zeroable::ZERO 7049bfe63fSPaolo Bonzini }; 7149bfe63fSPaolo Bonzini 7237fdb2f5SManos Pitsidianakis pub static VMSTATE_PL011: VMStateDescription = VMStateDescription { 73718e255fSPaolo Bonzini name: c_str!("pl011").as_ptr(), 7493243319SManos Pitsidianakis version_id: 2, 7593243319SManos Pitsidianakis minimum_version_id: 2, 7693243319SManos Pitsidianakis post_load: Some(pl011_post_load), 7793243319SManos Pitsidianakis fields: vmstate_fields! { 7893243319SManos Pitsidianakis vmstate_unused!(core::mem::size_of::<u32>()), 79a1ab4eedSPaolo Bonzini vmstate_struct!(PL011State, regs, &VMSTATE_PL011_REGS, BqlRefCell<PL011Registers>), 8093243319SManos Pitsidianakis }, 8193243319SManos Pitsidianakis subsections: vmstate_subsections! { 8293243319SManos Pitsidianakis VMSTATE_PL011_CLOCK 8393243319SManos Pitsidianakis }, 846e50bde1SPaolo Bonzini ..Zeroable::ZERO 8537fdb2f5SManos Pitsidianakis }; 8637fdb2f5SManos Pitsidianakis 8737fdb2f5SManos Pitsidianakis qemu_api::declare_properties! { 8837fdb2f5SManos Pitsidianakis PL011_PROPERTIES, 8937fdb2f5SManos Pitsidianakis qemu_api::define_property!( 90718e255fSPaolo Bonzini c_str!("chardev"), 9137fdb2f5SManos Pitsidianakis PL011State, 9237fdb2f5SManos Pitsidianakis char_backend, 9337fdb2f5SManos Pitsidianakis unsafe { &qdev_prop_chr }, 9437fdb2f5SManos Pitsidianakis CharBackend 9537fdb2f5SManos Pitsidianakis ), 9637fdb2f5SManos Pitsidianakis qemu_api::define_property!( 97718e255fSPaolo Bonzini c_str!("migrate-clk"), 9837fdb2f5SManos Pitsidianakis PL011State, 9937fdb2f5SManos Pitsidianakis migrate_clock, 10037fdb2f5SManos Pitsidianakis unsafe { &qdev_prop_bool }, 101113c6688SPaolo Bonzini bool, 102113c6688SPaolo Bonzini default = true 10337fdb2f5SManos Pitsidianakis ), 10437fdb2f5SManos Pitsidianakis } 105