xref: /qemu/rust/hw/char/pl011/src/device_class.rs (revision 7d0520398f7f58214cf5242b34c1b46efa2fcf4f)
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