xref: /qemu/rust/hw/char/pl011/src/device_class.rs (revision c5f122fdcc280a82e7c5f31de890f985aa7ba773)
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::{
6e4fb0be1SPaolo 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     prelude::*,
13f7b87e46SZhao Liu     vmstate::VMStateDescription,
14f7b87e46SZhao Liu     vmstate_clock, vmstate_fields, vmstate_of, vmstate_struct, vmstate_subsections, vmstate_unused,
15f7b87e46SZhao Liu     zeroable::Zeroable,
1693243319SManos Pitsidianakis };
1737fdb2f5SManos Pitsidianakis 
1849bfe63fSPaolo Bonzini use crate::device::{PL011Registers, PL011State};
1937fdb2f5SManos Pitsidianakis 
pl011_clock_needed(opaque: *mut c_void) -> bool2093243319SManos Pitsidianakis extern "C" fn pl011_clock_needed(opaque: *mut c_void) -> bool {
217d052039SPaolo Bonzini     let state = NonNull::new(opaque).unwrap().cast::<PL011State>();
227d052039SPaolo Bonzini     unsafe { state.as_ref().migrate_clock }
2393243319SManos Pitsidianakis }
2493243319SManos Pitsidianakis 
2593243319SManos Pitsidianakis /// Migration subsection for [`PL011State`] clock.
26d1f27ae9SPaolo Bonzini static VMSTATE_PL011_CLOCK: VMStateDescription = VMStateDescription {
27*f117857bSPaolo Bonzini     name: c"pl011/clock".as_ptr(),
2893243319SManos Pitsidianakis     version_id: 1,
2993243319SManos Pitsidianakis     minimum_version_id: 1,
3093243319SManos Pitsidianakis     needed: Some(pl011_clock_needed),
3193243319SManos Pitsidianakis     fields: vmstate_fields! {
3224f0e8d8SPaolo Bonzini         vmstate_clock!(PL011State, clock),
3393243319SManos Pitsidianakis     },
3493243319SManos Pitsidianakis     ..Zeroable::ZERO
3593243319SManos Pitsidianakis };
3693243319SManos Pitsidianakis 
pl011_post_load(opaque: *mut c_void, version_id: c_int) -> c_int3793243319SManos Pitsidianakis extern "C" fn pl011_post_load(opaque: *mut c_void, version_id: c_int) -> c_int {
38a1ab4eedSPaolo Bonzini     let state = NonNull::new(opaque).unwrap().cast::<PL011State>();
39a1ab4eedSPaolo Bonzini     let result = unsafe { state.as_ref().post_load(version_id as u32) };
4093243319SManos Pitsidianakis     if result.is_err() {
4193243319SManos Pitsidianakis         -1
4293243319SManos Pitsidianakis     } else {
4393243319SManos Pitsidianakis         0
4493243319SManos Pitsidianakis     }
4593243319SManos Pitsidianakis }
4693243319SManos Pitsidianakis 
4749bfe63fSPaolo Bonzini static VMSTATE_PL011_REGS: VMStateDescription = VMStateDescription {
48*f117857bSPaolo Bonzini     name: c"pl011/regs".as_ptr(),
4949bfe63fSPaolo Bonzini     version_id: 2,
5049bfe63fSPaolo Bonzini     minimum_version_id: 2,
5149bfe63fSPaolo Bonzini     fields: vmstate_fields! {
5249bfe63fSPaolo Bonzini         vmstate_of!(PL011Registers, flags),
5349bfe63fSPaolo Bonzini         vmstate_of!(PL011Registers, line_control),
5449bfe63fSPaolo Bonzini         vmstate_of!(PL011Registers, receive_status_error_clear),
5549bfe63fSPaolo Bonzini         vmstate_of!(PL011Registers, control),
5649bfe63fSPaolo Bonzini         vmstate_of!(PL011Registers, dmacr),
5749bfe63fSPaolo Bonzini         vmstate_of!(PL011Registers, int_enabled),
5849bfe63fSPaolo Bonzini         vmstate_of!(PL011Registers, int_level),
5949bfe63fSPaolo Bonzini         vmstate_of!(PL011Registers, read_fifo),
6049bfe63fSPaolo Bonzini         vmstate_of!(PL011Registers, ilpr),
6149bfe63fSPaolo Bonzini         vmstate_of!(PL011Registers, ibrd),
6249bfe63fSPaolo Bonzini         vmstate_of!(PL011Registers, fbrd),
6349bfe63fSPaolo Bonzini         vmstate_of!(PL011Registers, ifl),
6449bfe63fSPaolo Bonzini         vmstate_of!(PL011Registers, read_pos),
6549bfe63fSPaolo Bonzini         vmstate_of!(PL011Registers, read_count),
6649bfe63fSPaolo Bonzini         vmstate_of!(PL011Registers, read_trigger),
6749bfe63fSPaolo Bonzini     },
6849bfe63fSPaolo Bonzini     ..Zeroable::ZERO
6949bfe63fSPaolo Bonzini };
7049bfe63fSPaolo Bonzini 
7137fdb2f5SManos Pitsidianakis pub static VMSTATE_PL011: VMStateDescription = VMStateDescription {
72*f117857bSPaolo Bonzini     name: c"pl011".as_ptr(),
7393243319SManos Pitsidianakis     version_id: 2,
7493243319SManos Pitsidianakis     minimum_version_id: 2,
7593243319SManos Pitsidianakis     post_load: Some(pl011_post_load),
7693243319SManos Pitsidianakis     fields: vmstate_fields! {
7793243319SManos Pitsidianakis         vmstate_unused!(core::mem::size_of::<u32>()),
78a1ab4eedSPaolo Bonzini         vmstate_struct!(PL011State, regs, &VMSTATE_PL011_REGS, BqlRefCell<PL011Registers>),
7993243319SManos Pitsidianakis     },
8093243319SManos Pitsidianakis     subsections: vmstate_subsections! {
8193243319SManos Pitsidianakis         VMSTATE_PL011_CLOCK
8293243319SManos Pitsidianakis     },
836e50bde1SPaolo Bonzini     ..Zeroable::ZERO
8437fdb2f5SManos Pitsidianakis };
8537fdb2f5SManos Pitsidianakis 
8637fdb2f5SManos Pitsidianakis qemu_api::declare_properties! {
8737fdb2f5SManos Pitsidianakis     PL011_PROPERTIES,
8837fdb2f5SManos Pitsidianakis     qemu_api::define_property!(
89*f117857bSPaolo Bonzini         c"chardev",
9037fdb2f5SManos Pitsidianakis         PL011State,
9137fdb2f5SManos Pitsidianakis         char_backend,
9237fdb2f5SManos Pitsidianakis         unsafe { &qdev_prop_chr },
9337fdb2f5SManos Pitsidianakis         CharBackend
9437fdb2f5SManos Pitsidianakis     ),
9537fdb2f5SManos Pitsidianakis     qemu_api::define_property!(
96*f117857bSPaolo Bonzini         c"migrate-clk",
9737fdb2f5SManos Pitsidianakis         PL011State,
9837fdb2f5SManos Pitsidianakis         migrate_clock,
9937fdb2f5SManos Pitsidianakis         unsafe { &qdev_prop_bool },
100113c6688SPaolo Bonzini         bool,
101113c6688SPaolo Bonzini         default = true
10237fdb2f5SManos Pitsidianakis     ),
10337fdb2f5SManos Pitsidianakis }
104