Skip to content

Commit 6b4f7b0

Browse files
committed
rust: pl011: fix migration stream
The Rust vmstate macros lack the type-safety of their C equivalents (so safe, much abstraction), and therefore they were predictably wrong. The registers have already been changed to 32-bits in the previous patch, but read_pos/read_count/read_trigger also have to be u32 instead of usize. The easiest way to do so is to let the FIFO use u32 indices instead of usize. My plan for making VMStateField typesafe is to have a trait to retrieve a basic VMStateField; for example something like vmstate_uint32 would become an implementation of the VMState trait on u32. Then you'd write something like "vmstate_of!(Type, field).with_version_id(2)". That is, vmstate_of retrieves the basic VMStateField and fills in the offset, and then more changes can be applied on top. Signed-off-by: Paolo Bonzini <[email protected]>
1 parent e2e0828 commit 6b4f7b0

File tree

3 files changed

+37
-33
lines changed

3 files changed

+37
-33
lines changed

rust/hw/char/pl011/src/device.rs

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const IBRD_MASK: u32 = 0xffff;
3131
const FBRD_MASK: u32 = 0x3f;
3232

3333
/// QEMU sourced constant.
34-
pub const PL011_FIFO_DEPTH: usize = 16_usize;
34+
pub const PL011_FIFO_DEPTH: u32 = 16;
3535

3636
#[derive(Clone, Copy, Debug)]
3737
enum DeviceId {
@@ -56,6 +56,32 @@ impl DeviceId {
5656
const PL011_ID_LUMINARY: [c_uchar; 8] = [0x11, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1];
5757
}
5858

59+
// FIFOs use 32-bit indices instead of usize, for compatibility with
60+
// the migration stream produced by the C version of this device.
61+
#[repr(transparent)]
62+
#[derive(Debug, Default)]
63+
pub struct Fifo([registers::Data; PL011_FIFO_DEPTH as usize]);
64+
65+
impl Fifo {
66+
const fn len(&self) -> u32 {
67+
self.0.len() as u32
68+
}
69+
}
70+
71+
impl std::ops::IndexMut<u32> for Fifo {
72+
fn index_mut(&mut self, idx: u32) -> &mut Self::Output {
73+
&mut self.0[idx as usize]
74+
}
75+
}
76+
77+
impl std::ops::Index<u32> for Fifo {
78+
type Output = registers::Data;
79+
80+
fn index(&self, idx: u32) -> &Self::Output {
81+
&self.0[idx as usize]
82+
}
83+
}
84+
5985
#[repr(C)]
6086
#[derive(Debug, qemu_api_macros::Object, qemu_api_macros::offsets)]
6187
/// PL011 Device Model in QEMU
@@ -73,14 +99,14 @@ pub struct PL011State {
7399
pub dmacr: u32,
74100
pub int_enabled: u32,
75101
pub int_level: u32,
76-
pub read_fifo: [registers::Data; PL011_FIFO_DEPTH],
102+
pub read_fifo: Fifo,
77103
pub ilpr: u32,
78104
pub ibrd: u32,
79105
pub fbrd: u32,
80106
pub ifl: u32,
81-
pub read_pos: usize,
82-
pub read_count: usize,
83-
pub read_trigger: usize,
107+
pub read_pos: u32,
108+
pub read_count: u32,
109+
pub read_trigger: u32,
84110
#[doc(alias = "chr")]
85111
pub char_backend: CharBackend,
86112
/// QEMU interrupts
@@ -480,7 +506,7 @@ impl PL011State {
480506
}
481507

482508
#[inline]
483-
pub fn fifo_depth(&self) -> usize {
509+
pub fn fifo_depth(&self) -> u32 {
484510
// Note: FIFO depth is expected to be power-of-2
485511
if self.fifo_enabled() {
486512
return PL011_FIFO_DEPTH;

rust/hw/char/pl011/src/device_class.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use core::ptr::NonNull;
66
use std::os::raw::{c_int, c_void};
77

88
use qemu_api::{
9-
bindings::*, c_str, vmstate_clock, vmstate_fields, vmstate_int32, vmstate_subsections,
10-
vmstate_uint32, vmstate_uint32_array, vmstate_unused, zeroable::Zeroable,
9+
bindings::*, c_str, vmstate_clock, vmstate_fields, vmstate_subsections, vmstate_uint32,
10+
vmstate_uint32_array, vmstate_unused, zeroable::Zeroable,
1111
};
1212

1313
use crate::device::{PL011State, PL011_FIFO_DEPTH};
@@ -64,9 +64,9 @@ pub static VMSTATE_PL011: VMStateDescription = VMStateDescription {
6464
vmstate_uint32!(ibrd, PL011State),
6565
vmstate_uint32!(fbrd, PL011State),
6666
vmstate_uint32!(ifl, PL011State),
67-
vmstate_int32!(read_pos, PL011State),
68-
vmstate_int32!(read_count, PL011State),
69-
vmstate_int32!(read_trigger, PL011State),
67+
vmstate_uint32!(read_pos, PL011State),
68+
vmstate_uint32!(read_count, PL011State),
69+
vmstate_uint32!(read_trigger, PL011State),
7070
},
7171
subsections: vmstate_subsections! {
7272
VMSTATE_PL011_CLOCK

rust/qemu-api/src/vmstate.rs

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -106,28 +106,6 @@ macro_rules! vmstate_uint32 {
106106
}};
107107
}
108108

109-
#[doc(alias = "VMSTATE_INT32_V")]
110-
#[macro_export]
111-
macro_rules! vmstate_int32_v {
112-
($field_name:ident, $struct_name:ty, $version_id:expr) => {{
113-
$crate::vmstate_single!(
114-
$field_name,
115-
$struct_name,
116-
$version_id,
117-
::core::ptr::addr_of!($crate::bindings::vmstate_info_int32),
118-
::core::mem::size_of::<i32>()
119-
)
120-
}};
121-
}
122-
123-
#[doc(alias = "VMSTATE_INT32")]
124-
#[macro_export]
125-
macro_rules! vmstate_int32 {
126-
($field_name:ident, $struct_name:ty) => {{
127-
$crate::vmstate_int32_v!($field_name, $struct_name, 0)
128-
}};
129-
}
130-
131109
#[doc(alias = "VMSTATE_ARRAY")]
132110
#[macro_export]
133111
macro_rules! vmstate_array {

0 commit comments

Comments
 (0)