5
//! Device registers exposed as typed structs which are backed by arbitrary
6
//! integer bitmaps. [`Data`], [`Control`], [`LineControl`], etc.
7
8
+// rustc prefers "constant-like" enums to use upper case names, but that
9
+// is inconsistent in its own way.
10
+#![allow(non_upper_case_globals)]
11
+
12
// For more detail see the PL011 Technical Reference Manual DDI0183:
13
// https://developer.arm.com/documentation/ddi0183/latest/
14
11
-use bilge::prelude::*;
15
+use bitfield_struct::bitfield;
16
use bits::bits;
13
-use migration::{impl_vmstate_bitsized, impl_vmstate_forward};
17
+use migration::impl_vmstate_forward;
18
19
/// Offset of each register from the base memory address of the device.
20
#[doc(alias = "offset")]
82
/// The `UARTRSR` register is updated only when a read occurs
83
/// from the `UARTDR` register with the same status information
84
/// that can also be obtained by reading the `UARTDR` register
81
-#[bitsize(8)]
82
-#[derive(Clone, Copy, Default, DebugBits, FromBits)]
85
+#[bitfield(u8)]
86
pub struct Errors {
87
pub framing_error: bool,
88
pub parity_error: bool,
89
pub break_error: bool,
90
pub overrun_error: bool,
88
- _reserved_unpredictable: u4,
91
+ #[bits(4)]
92
+ _reserved_unpredictable: u8,
93
+}
94
+
95
+impl Errors {
96
+ pub const BREAK: Self = Errors::new().with_break_error(true);
97
}
98
99
/// Data Register, `UARTDR`
101
/// The `UARTDR` register is the data register; write for TX and
102
/// read for RX. It is a 12-bit register, where bits 7..0 are the
103
/// character and bits 11..8 are error bits.
96
-#[bitsize(32)]
97
-#[derive(Clone, Copy, Default, DebugBits, FromBits)]
104
+#[bitfield(u32)]
105
#[doc(alias = "UARTDR")]
106
pub struct Data {
107
pub data: u8,
108
+ #[bits(8)]
109
pub errors: Errors,
110
_reserved: u16,
111
}
104
-impl_vmstate_bitsized!(Data);
112
+impl_vmstate_forward!(Data);
113
114
impl Data {
107
- // bilge is not very const-friendly, unfortunately
108
- pub const BREAK: Self = Self { value: 1 << 10 };
115
+ pub const BREAK: Self = Self::new().with_errors(Errors::BREAK);
116
}
117
118
/// Receive Status Register / Error Clear Register, `UARTRSR/UARTECR`
126
/// and UARTECR for writes, but really it's a single error status
127
/// register where writing anything to the register clears the error
128
/// bits.
122
-#[bitsize(32)]
123
-#[derive(Clone, Copy, DebugBits, FromBits)]
129
+#[bitfield(u32)]
130
pub struct ReceiveStatusErrorClear {
131
+ #[bits(8)]
132
pub errors: Errors,
126
- _reserved_unpredictable: u24,
133
+ #[bits(24)]
134
+ _reserved_unpredictable: u32,
135
}
128
-impl_vmstate_bitsized!(ReceiveStatusErrorClear);
136
+impl_vmstate_forward!(ReceiveStatusErrorClear);
137
138
impl ReceiveStatusErrorClear {
139
pub fn set_from_data(&mut self, data: Data) {
146
}
147
}
148
141
-impl Default for ReceiveStatusErrorClear {
142
- fn default() -> Self {
143
- 0.into()
144
- }
145
-}
146
-
147
-#[bitsize(32)]
148
-#[derive(Clone, Copy, DebugBits, FromBits)]
149
+#[bitfield(u32, default = false)]
150
/// Flag Register, `UARTFR`
151
///
152
/// This has the usual inbound RS232 modem-control signals, plus flags
172
pub transmit_fifo_empty: bool,
173
/// RI: Ring indicator
174
pub ring_indicator: bool,
174
- _reserved_zero_no_modify: u23,
175
+ #[bits(23)]
176
+ _reserved_zero_no_modify: u32,
177
}
176
-impl_vmstate_bitsized!(Flags);
178
+impl_vmstate_forward!(Flags);
179
180
impl Flags {
181
pub fn reset(&mut self) {
185
186
impl Default for Flags {
187
fn default() -> Self {
186
- let mut ret: Self = 0.into();
188
// After reset TXFF, RXFF, and BUSY are 0, and TXFE and RXFE are 1
188
- ret.set_receive_fifo_empty(true);
189
- ret.set_transmit_fifo_empty(true);
190
- ret
189
+ Self::from(0)
190
+ .with_receive_fifo_empty(true)
191
+ .with_transmit_fifo_empty(true)
192
}
193
}
194
194
-#[bitsize(32)]
195
-#[derive(Clone, Copy, DebugBits, FromBits)]
195
+#[bitfield(u32)]
196
/// Line Control Register, `UARTLCR_H`
197
#[doc(alias = "UARTLCR_H")]
198
pub struct LineControl {
201
/// PEN: Parity enable
202
pub parity_enabled: bool,
203
/// EPS: Even parity select
204
+ #[bits(1)]
205
pub parity: Parity,
206
/// STP2: Two stop bits select
207
pub two_stops_bits: bool,
208
/// FEN: Enable FIFOs
209
+ #[bits(1)]
210
pub fifos_enabled: Mode,
211
/// WLEN: Word length in bits
212
/// b11 = 8 bits
213
/// b10 = 7 bits
214
/// b01 = 6 bits
215
/// b00 = 5 bits.
216
+ #[bits(2)]
217
pub word_length: WordLength,
218
/// SPS Stick parity select
219
pub sticky_parity: bool,
220
/// 31:8 - Reserved, do not modify, read as zero.
218
- _reserved_zero_no_modify: u24,
221
+ #[bits(24)]
222
+ _reserved_zero_no_modify: u32,
223
}
220
-impl_vmstate_bitsized!(LineControl);
224
+impl_vmstate_forward!(LineControl);
225
226
impl LineControl {
227
pub fn reset(&mut self) {
228
// All the bits are cleared to 0 when reset.
225
- *self = 0.into();
226
- }
227
-}
228
-
229
-impl Default for LineControl {
230
- fn default() -> Self {
231
- 0.into()
229
+ *self = Self::default();
230
}
231
}
232
235
-#[bitsize(1)]
236
-#[derive(Clone, Copy, Debug, Eq, FromBits, PartialEq)]
233
/// `EPS` "Even parity select", field of [Line Control
234
/// register](LineControl).
235
+#[repr(u8)]
236
+#[derive(Clone, Copy, Debug, Eq, PartialEq, common::TryInto)]
237
pub enum Parity {
238
Odd = 0,
239
Even = 1,
240
}
241
244
-#[bitsize(1)]
245
-#[derive(Clone, Copy, Debug, Eq, FromBits, PartialEq)]
242
+#[repr(u8)]
243
+#[derive(Clone, Copy, Debug, Eq, PartialEq, common::TryInto)]
244
/// `FEN` "Enable FIFOs" or Device mode, field of [Line Control
245
/// register](LineControl).
246
pub enum Mode {
251
FIFO = 1,
252
}
253
256
-#[bitsize(2)]
257
-#[derive(Clone, Copy, Debug, Eq, FromBits, PartialEq)]
254
+#[repr(u8)]
255
+#[derive(Clone, Copy, Debug, Eq, PartialEq, common::TryInto)]
256
#[allow(clippy::enum_variant_names)]
257
/// `WLEN` Word length, field of [Line Control register](LineControl).
258
///
274
/// The `UARTCR` register is the control register. It contains various
275
/// enable bits, and the bits to write to set the usual outbound RS232
276
/// modem control signals. All bits reset to 0 except TXE and RXE.
279
-#[bitsize(32)]
277
+#[bitfield(u32, default = false)]
278
#[doc(alias = "UARTCR")]
281
-#[derive(Clone, Copy, DebugBits, FromBits)]
279
pub struct Control {
280
/// `UARTEN` UART enable: 0 = UART is disabled.
281
pub enable_uart: bool,
283
/// QEMU does not model this.
284
pub enable_sir: bool,
285
/// `SIRLP` SIR low-power IrDA mode. QEMU does not model this.
289
- pub sir_lowpower_irda_mode: u1,
286
+ pub sir_lowpower_irda_mode: bool,
287
/// Reserved, do not modify, read as zero.
291
- _reserved_zero_no_modify: u4,
288
+ #[bits(4)]
289
+ _reserved_zero_no_modify: u8,
290
/// `LBE` Loopback enable: feed UART output back to the input
291
pub enable_loopback: bool,
292
/// `TXE` Transmit enable
308
/// 31:16 - Reserved, do not modify, read as zero.
309
_reserved_zero_no_modify2: u16,
310
}
313
-impl_vmstate_bitsized!(Control);
311
+impl_vmstate_forward!(Control);
312
313
impl Control {
314
pub fn reset(&mut self) {
317
- *self = 0.into();
318
- self.set_enable_receive(true);
319
- self.set_enable_transmit(true);
315
+ *self = Self::default();
316
}
317
}
318
319
impl Default for Control {
320
fn default() -> Self {
325
- let mut ret: Self = 0.into();
326
- ret.reset();
327
- ret
321
+ Self::from(0)
322
+ .with_enable_receive(true)
323
+ .with_enable_transmit(true)
324
}
325
}
326