mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-07 01:33:56 -06:00
rust: pl011: fix break errors and definition of Data struct
The Data struct is wrong, and does not show how bits 8-15 of DR are the receive status. Fix it, and use it to fix break errors ("c >> 8" in the C code does not translate to "c.to_be_bytes()[3]"). Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
f65314bdd0
commit
e1f9353334
2 changed files with 36 additions and 20 deletions
|
@ -30,8 +30,6 @@ const IBRD_MASK: u32 = 0xffff;
|
|||
/// Fractional Baud Rate Divider, `UARTFBRD`
|
||||
const FBRD_MASK: u32 = 0x3f;
|
||||
|
||||
const DATA_BREAK: u32 = 1 << 10;
|
||||
|
||||
/// QEMU sourced constant.
|
||||
pub const PL011_FIFO_DEPTH: usize = 16_usize;
|
||||
|
||||
|
@ -75,7 +73,7 @@ pub struct PL011State {
|
|||
pub dmacr: u32,
|
||||
pub int_enabled: u32,
|
||||
pub int_level: u32,
|
||||
pub read_fifo: [u32; PL011_FIFO_DEPTH],
|
||||
pub read_fifo: [registers::Data; PL011_FIFO_DEPTH],
|
||||
pub ilpr: u32,
|
||||
pub ibrd: u32,
|
||||
pub fbrd: u32,
|
||||
|
@ -210,10 +208,11 @@ impl PL011State {
|
|||
self.int_level &= !registers::INT_RX;
|
||||
}
|
||||
// Update error bits.
|
||||
self.receive_status_error_clear = c.to_be_bytes()[3].into();
|
||||
self.receive_status_error_clear.set_from_data(c);
|
||||
self.update();
|
||||
// Must call qemu_chr_fe_accept_input, so return Continue:
|
||||
return std::ops::ControlFlow::Continue(c.into());
|
||||
let c = u32::from(c);
|
||||
return std::ops::ControlFlow::Continue(u64::from(c));
|
||||
}
|
||||
Ok(RSR) => u8::from(self.receive_status_error_clear).into(),
|
||||
Ok(FR) => u16::from(self.flags).into(),
|
||||
|
@ -406,7 +405,7 @@ impl PL011State {
|
|||
|
||||
fn loopback_break(&mut self, enable: bool) {
|
||||
if enable {
|
||||
self.loopback_tx(DATA_BREAK);
|
||||
self.loopback_tx(registers::Data::BREAK.into());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -470,7 +469,7 @@ impl PL011State {
|
|||
|
||||
pub fn event(&mut self, event: QEMUChrEvent) {
|
||||
if event == bindings::QEMUChrEvent::CHR_EVENT_BREAK && !self.loopback_enabled() {
|
||||
self.put_fifo(DATA_BREAK);
|
||||
self.put_fifo(registers::Data::BREAK.into());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -497,7 +496,7 @@ impl PL011State {
|
|||
let depth = self.fifo_depth();
|
||||
assert!(depth > 0);
|
||||
let slot = (self.read_pos + self.read_count) & (depth - 1);
|
||||
self.read_fifo[slot] = value;
|
||||
self.read_fifo[slot] = registers::Data::from(value);
|
||||
self.read_count += 1;
|
||||
self.flags.set_receive_fifo_empty(false);
|
||||
if self.read_count == depth {
|
||||
|
|
|
@ -139,6 +139,21 @@ pub mod registers {
|
|||
//! unused thus treated as zero when read or written.
|
||||
use bilge::prelude::*;
|
||||
|
||||
/// Receive Status Register / Data Register common error bits
|
||||
///
|
||||
/// The `UARTRSR` register is updated only when a read occurs
|
||||
/// from the `UARTDR` register with the same status information
|
||||
/// that can also be obtained by reading the `UARTDR` register
|
||||
#[bitsize(8)]
|
||||
#[derive(Clone, Copy, Default, DebugBits, FromBits)]
|
||||
pub struct Errors {
|
||||
pub framing_error: bool,
|
||||
pub parity_error: bool,
|
||||
pub break_error: bool,
|
||||
pub overrun_error: bool,
|
||||
_reserved_unpredictable: u4,
|
||||
}
|
||||
|
||||
// TODO: FIFO Mode has different semantics
|
||||
/// Data Register, `UARTDR`
|
||||
///
|
||||
|
@ -181,16 +196,18 @@ pub mod registers {
|
|||
///
|
||||
/// # Source
|
||||
/// ARM DDI 0183G 3.3.1 Data Register, UARTDR
|
||||
#[bitsize(16)]
|
||||
#[derive(Clone, Copy, DebugBits, FromBits)]
|
||||
#[bitsize(32)]
|
||||
#[derive(Clone, Copy, Default, DebugBits, FromBits)]
|
||||
#[doc(alias = "UARTDR")]
|
||||
pub struct Data {
|
||||
_reserved: u4,
|
||||
pub data: u8,
|
||||
pub framing_error: bool,
|
||||
pub parity_error: bool,
|
||||
pub break_error: bool,
|
||||
pub overrun_error: bool,
|
||||
pub errors: Errors,
|
||||
_reserved: u16,
|
||||
}
|
||||
|
||||
impl Data {
|
||||
// bilge is not very const-friendly, unfortunately
|
||||
pub const BREAK: Self = Self { value: 1 << 10 };
|
||||
}
|
||||
|
||||
// TODO: FIFO Mode has different semantics
|
||||
|
@ -220,14 +237,14 @@ pub mod registers {
|
|||
#[bitsize(8)]
|
||||
#[derive(Clone, Copy, DebugBits, FromBits)]
|
||||
pub struct ReceiveStatusErrorClear {
|
||||
pub framing_error: bool,
|
||||
pub parity_error: bool,
|
||||
pub break_error: bool,
|
||||
pub overrun_error: bool,
|
||||
_reserved_unpredictable: u4,
|
||||
pub errors: Errors,
|
||||
}
|
||||
|
||||
impl ReceiveStatusErrorClear {
|
||||
pub fn set_from_data(&mut self, data: Data) {
|
||||
self.set_errors(data.errors());
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) {
|
||||
// All the bits are cleared to 0 on reset.
|
||||
*self = Self::default();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue