1959fd759SPaolo Bonzini // Copyright 2024, Linaro Limited 2959fd759SPaolo Bonzini // Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org> 3959fd759SPaolo Bonzini // SPDX-License-Identifier: GPL-2.0-or-later 4959fd759SPaolo Bonzini 5959fd759SPaolo Bonzini //! Device registers exposed as typed structs which are backed by arbitrary 6959fd759SPaolo Bonzini //! integer bitmaps. [`Data`], [`Control`], [`LineControl`], etc. 7959fd759SPaolo Bonzini 86414b770SPeter Maydell // For more detail see the PL011 Technical Reference Manual DDI0183: 96414b770SPeter Maydell // https://developer.arm.com/documentation/ddi0183/latest/ 106414b770SPeter Maydell 11959fd759SPaolo Bonzini use bilge::prelude::*; 12*9c8ff2a1SPaolo Bonzini use bits::bits; 13*9c8ff2a1SPaolo Bonzini use qemu_api::{impl_vmstate_bitsized, impl_vmstate_forward}; 14959fd759SPaolo Bonzini 15959fd759SPaolo Bonzini /// Offset of each register from the base memory address of the device. 16959fd759SPaolo Bonzini #[doc(alias = "offset")] 17959fd759SPaolo Bonzini #[allow(non_camel_case_types)] 18959fd759SPaolo Bonzini #[repr(u64)] 19959fd759SPaolo Bonzini #[derive(Debug, Eq, PartialEq, qemu_api_macros::TryInto)] 20959fd759SPaolo Bonzini pub enum RegisterOffset { 21959fd759SPaolo Bonzini /// Data Register 22959fd759SPaolo Bonzini /// 23959fd759SPaolo Bonzini /// A write to this register initiates the actual data transmission 24959fd759SPaolo Bonzini #[doc(alias = "UARTDR")] 25959fd759SPaolo Bonzini DR = 0x000, 26959fd759SPaolo Bonzini /// Receive Status Register or Error Clear Register 27959fd759SPaolo Bonzini #[doc(alias = "UARTRSR")] 28959fd759SPaolo Bonzini #[doc(alias = "UARTECR")] 29959fd759SPaolo Bonzini RSR = 0x004, 30959fd759SPaolo Bonzini /// Flag Register 31959fd759SPaolo Bonzini /// 32959fd759SPaolo Bonzini /// A read of this register shows if transmission is complete 33959fd759SPaolo Bonzini #[doc(alias = "UARTFR")] 34959fd759SPaolo Bonzini FR = 0x018, 35959fd759SPaolo Bonzini /// Fractional Baud Rate Register 36959fd759SPaolo Bonzini /// 37959fd759SPaolo Bonzini /// responsible for baud rate speed 38959fd759SPaolo Bonzini #[doc(alias = "UARTFBRD")] 39959fd759SPaolo Bonzini FBRD = 0x028, 40959fd759SPaolo Bonzini /// `IrDA` Low-Power Counter Register 41959fd759SPaolo Bonzini #[doc(alias = "UARTILPR")] 42959fd759SPaolo Bonzini ILPR = 0x020, 43959fd759SPaolo Bonzini /// Integer Baud Rate Register 44959fd759SPaolo Bonzini /// 45959fd759SPaolo Bonzini /// Responsible for baud rate speed 46959fd759SPaolo Bonzini #[doc(alias = "UARTIBRD")] 47959fd759SPaolo Bonzini IBRD = 0x024, 48959fd759SPaolo Bonzini /// line control register (data frame format) 49959fd759SPaolo Bonzini #[doc(alias = "UARTLCR_H")] 50959fd759SPaolo Bonzini LCR_H = 0x02C, 51959fd759SPaolo Bonzini /// Toggle UART, transmission or reception 52959fd759SPaolo Bonzini #[doc(alias = "UARTCR")] 53959fd759SPaolo Bonzini CR = 0x030, 54959fd759SPaolo Bonzini /// Interrupt FIFO Level Select Register 55959fd759SPaolo Bonzini #[doc(alias = "UARTIFLS")] 56959fd759SPaolo Bonzini FLS = 0x034, 57959fd759SPaolo Bonzini /// Interrupt Mask Set/Clear Register 58959fd759SPaolo Bonzini #[doc(alias = "UARTIMSC")] 59959fd759SPaolo Bonzini IMSC = 0x038, 60959fd759SPaolo Bonzini /// Raw Interrupt Status Register 61959fd759SPaolo Bonzini #[doc(alias = "UARTRIS")] 62959fd759SPaolo Bonzini RIS = 0x03C, 63959fd759SPaolo Bonzini /// Masked Interrupt Status Register 64959fd759SPaolo Bonzini #[doc(alias = "UARTMIS")] 65959fd759SPaolo Bonzini MIS = 0x040, 66959fd759SPaolo Bonzini /// Interrupt Clear Register 67959fd759SPaolo Bonzini #[doc(alias = "UARTICR")] 68959fd759SPaolo Bonzini ICR = 0x044, 69959fd759SPaolo Bonzini /// DMA control Register 70959fd759SPaolo Bonzini #[doc(alias = "UARTDMACR")] 71959fd759SPaolo Bonzini DMACR = 0x048, 72959fd759SPaolo Bonzini ///// Reserved, offsets `0x04C` to `0x07C`. 73959fd759SPaolo Bonzini //Reserved = 0x04C, 74959fd759SPaolo Bonzini } 75959fd759SPaolo Bonzini 76959fd759SPaolo Bonzini /// Receive Status Register / Data Register common error bits 77959fd759SPaolo Bonzini /// 78959fd759SPaolo Bonzini /// The `UARTRSR` register is updated only when a read occurs 79959fd759SPaolo Bonzini /// from the `UARTDR` register with the same status information 80959fd759SPaolo Bonzini /// that can also be obtained by reading the `UARTDR` register 81959fd759SPaolo Bonzini #[bitsize(8)] 82959fd759SPaolo Bonzini #[derive(Clone, Copy, Default, DebugBits, FromBits)] 83959fd759SPaolo Bonzini pub struct Errors { 84959fd759SPaolo Bonzini pub framing_error: bool, 85959fd759SPaolo Bonzini pub parity_error: bool, 86959fd759SPaolo Bonzini pub break_error: bool, 87959fd759SPaolo Bonzini pub overrun_error: bool, 88959fd759SPaolo Bonzini _reserved_unpredictable: u4, 89959fd759SPaolo Bonzini } 90959fd759SPaolo Bonzini 91959fd759SPaolo Bonzini /// Data Register, `UARTDR` 92959fd759SPaolo Bonzini /// 936414b770SPeter Maydell /// The `UARTDR` register is the data register; write for TX and 946414b770SPeter Maydell /// read for RX. It is a 12-bit register, where bits 7..0 are the 956414b770SPeter Maydell /// character and bits 11..8 are error bits. 96959fd759SPaolo Bonzini #[bitsize(32)] 97959fd759SPaolo Bonzini #[derive(Clone, Copy, Default, DebugBits, FromBits)] 98959fd759SPaolo Bonzini #[doc(alias = "UARTDR")] 99959fd759SPaolo Bonzini pub struct Data { 100959fd759SPaolo Bonzini pub data: u8, 101959fd759SPaolo Bonzini pub errors: Errors, 102959fd759SPaolo Bonzini _reserved: u16, 103959fd759SPaolo Bonzini } 104959fd759SPaolo Bonzini impl_vmstate_bitsized!(Data); 105959fd759SPaolo Bonzini 106959fd759SPaolo Bonzini impl Data { 107959fd759SPaolo Bonzini // bilge is not very const-friendly, unfortunately 108959fd759SPaolo Bonzini pub const BREAK: Self = Self { value: 1 << 10 }; 109959fd759SPaolo Bonzini } 110959fd759SPaolo Bonzini 111959fd759SPaolo Bonzini /// Receive Status Register / Error Clear Register, `UARTRSR/UARTECR` 112959fd759SPaolo Bonzini /// 1136414b770SPeter Maydell /// This register provides a different way to read the four receive 1146414b770SPeter Maydell /// status error bits that can be found in bits 11..8 of the UARTDR 1156414b770SPeter Maydell /// on a read. It gets updated when the guest reads UARTDR, and the 1166414b770SPeter Maydell /// status bits correspond to that character that was just read. 117959fd759SPaolo Bonzini /// 1186414b770SPeter Maydell /// The TRM confusingly describes this offset as UARTRSR for reads 1196414b770SPeter Maydell /// and UARTECR for writes, but really it's a single error status 1206414b770SPeter Maydell /// register where writing anything to the register clears the error 1216414b770SPeter Maydell /// bits. 122959fd759SPaolo Bonzini #[bitsize(32)] 123959fd759SPaolo Bonzini #[derive(Clone, Copy, DebugBits, FromBits)] 124959fd759SPaolo Bonzini pub struct ReceiveStatusErrorClear { 125959fd759SPaolo Bonzini pub errors: Errors, 126959fd759SPaolo Bonzini _reserved_unpredictable: u24, 127959fd759SPaolo Bonzini } 128959fd759SPaolo Bonzini impl_vmstate_bitsized!(ReceiveStatusErrorClear); 129959fd759SPaolo Bonzini 130959fd759SPaolo Bonzini impl ReceiveStatusErrorClear { set_from_data(&mut self, data: Data)131959fd759SPaolo Bonzini pub fn set_from_data(&mut self, data: Data) { 132959fd759SPaolo Bonzini self.set_errors(data.errors()); 133959fd759SPaolo Bonzini } 134959fd759SPaolo Bonzini reset(&mut self)135959fd759SPaolo Bonzini pub fn reset(&mut self) { 136959fd759SPaolo Bonzini // All the bits are cleared to 0 on reset. 137959fd759SPaolo Bonzini *self = Self::default(); 138959fd759SPaolo Bonzini } 139959fd759SPaolo Bonzini } 140959fd759SPaolo Bonzini 141959fd759SPaolo Bonzini impl Default for ReceiveStatusErrorClear { default() -> Self142959fd759SPaolo Bonzini fn default() -> Self { 143959fd759SPaolo Bonzini 0.into() 144959fd759SPaolo Bonzini } 145959fd759SPaolo Bonzini } 146959fd759SPaolo Bonzini 147959fd759SPaolo Bonzini #[bitsize(32)] 148959fd759SPaolo Bonzini #[derive(Clone, Copy, DebugBits, FromBits)] 149959fd759SPaolo Bonzini /// Flag Register, `UARTFR` 1506414b770SPeter Maydell /// 1516414b770SPeter Maydell /// This has the usual inbound RS232 modem-control signals, plus flags 1526414b770SPeter Maydell /// for RX and TX FIFO fill levels and a BUSY flag. 153959fd759SPaolo Bonzini #[doc(alias = "UARTFR")] 154959fd759SPaolo Bonzini pub struct Flags { 1556414b770SPeter Maydell /// CTS: Clear to send 156959fd759SPaolo Bonzini pub clear_to_send: bool, 1576414b770SPeter Maydell /// DSR: Data set ready 158959fd759SPaolo Bonzini pub data_set_ready: bool, 1596414b770SPeter Maydell /// DCD: Data carrier detect 160959fd759SPaolo Bonzini pub data_carrier_detect: bool, 1616414b770SPeter Maydell /// BUSY: UART busy. In real hardware, set while the UART is 1626414b770SPeter Maydell /// busy transmitting data. QEMU's implementation never sets BUSY. 163959fd759SPaolo Bonzini pub busy: bool, 1646414b770SPeter Maydell /// RXFE: Receive FIFO empty 165959fd759SPaolo Bonzini pub receive_fifo_empty: bool, 1666414b770SPeter Maydell /// TXFF: Transmit FIFO full 167959fd759SPaolo Bonzini pub transmit_fifo_full: bool, 1686414b770SPeter Maydell /// RXFF: Receive FIFO full 169959fd759SPaolo Bonzini pub receive_fifo_full: bool, 1706414b770SPeter Maydell /// TXFE: Transmit FIFO empty 171959fd759SPaolo Bonzini pub transmit_fifo_empty: bool, 1726414b770SPeter Maydell /// RI: Ring indicator 173959fd759SPaolo Bonzini pub ring_indicator: bool, 174959fd759SPaolo Bonzini _reserved_zero_no_modify: u23, 175959fd759SPaolo Bonzini } 176959fd759SPaolo Bonzini impl_vmstate_bitsized!(Flags); 177959fd759SPaolo Bonzini 178959fd759SPaolo Bonzini impl Flags { reset(&mut self)179959fd759SPaolo Bonzini pub fn reset(&mut self) { 180959fd759SPaolo Bonzini *self = Self::default(); 181959fd759SPaolo Bonzini } 182959fd759SPaolo Bonzini } 183959fd759SPaolo Bonzini 184959fd759SPaolo Bonzini impl Default for Flags { default() -> Self185959fd759SPaolo Bonzini fn default() -> Self { 186959fd759SPaolo Bonzini let mut ret: Self = 0.into(); 187959fd759SPaolo Bonzini // After reset TXFF, RXFF, and BUSY are 0, and TXFE and RXFE are 1 188959fd759SPaolo Bonzini ret.set_receive_fifo_empty(true); 189959fd759SPaolo Bonzini ret.set_transmit_fifo_empty(true); 190959fd759SPaolo Bonzini ret 191959fd759SPaolo Bonzini } 192959fd759SPaolo Bonzini } 193959fd759SPaolo Bonzini 194959fd759SPaolo Bonzini #[bitsize(32)] 195959fd759SPaolo Bonzini #[derive(Clone, Copy, DebugBits, FromBits)] 196959fd759SPaolo Bonzini /// Line Control Register, `UARTLCR_H` 197959fd759SPaolo Bonzini #[doc(alias = "UARTLCR_H")] 198959fd759SPaolo Bonzini pub struct LineControl { 1996414b770SPeter Maydell /// BRK: Send break 200959fd759SPaolo Bonzini pub send_break: bool, 2016414b770SPeter Maydell /// PEN: Parity enable 202959fd759SPaolo Bonzini pub parity_enabled: bool, 2036414b770SPeter Maydell /// EPS: Even parity select 204959fd759SPaolo Bonzini pub parity: Parity, 2056414b770SPeter Maydell /// STP2: Two stop bits select 206959fd759SPaolo Bonzini pub two_stops_bits: bool, 2076414b770SPeter Maydell /// FEN: Enable FIFOs 208959fd759SPaolo Bonzini pub fifos_enabled: Mode, 2096414b770SPeter Maydell /// WLEN: Word length in bits 2106414b770SPeter Maydell /// b11 = 8 bits 211959fd759SPaolo Bonzini /// b10 = 7 bits 212959fd759SPaolo Bonzini /// b01 = 6 bits 213959fd759SPaolo Bonzini /// b00 = 5 bits. 214959fd759SPaolo Bonzini pub word_length: WordLength, 2156414b770SPeter Maydell /// SPS Stick parity select 216959fd759SPaolo Bonzini pub sticky_parity: bool, 217959fd759SPaolo Bonzini /// 31:8 - Reserved, do not modify, read as zero. 218959fd759SPaolo Bonzini _reserved_zero_no_modify: u24, 219959fd759SPaolo Bonzini } 220959fd759SPaolo Bonzini impl_vmstate_bitsized!(LineControl); 221959fd759SPaolo Bonzini 222959fd759SPaolo Bonzini impl LineControl { reset(&mut self)223959fd759SPaolo Bonzini pub fn reset(&mut self) { 224959fd759SPaolo Bonzini // All the bits are cleared to 0 when reset. 225959fd759SPaolo Bonzini *self = 0.into(); 226959fd759SPaolo Bonzini } 227959fd759SPaolo Bonzini } 228959fd759SPaolo Bonzini 229959fd759SPaolo Bonzini impl Default for LineControl { default() -> Self230959fd759SPaolo Bonzini fn default() -> Self { 231959fd759SPaolo Bonzini 0.into() 232959fd759SPaolo Bonzini } 233959fd759SPaolo Bonzini } 234959fd759SPaolo Bonzini 235959fd759SPaolo Bonzini #[bitsize(1)] 236959fd759SPaolo Bonzini #[derive(Clone, Copy, Debug, Eq, FromBits, PartialEq)] 237959fd759SPaolo Bonzini /// `EPS` "Even parity select", field of [Line Control 238959fd759SPaolo Bonzini /// register](LineControl). 239959fd759SPaolo Bonzini pub enum Parity { 240959fd759SPaolo Bonzini Odd = 0, 241959fd759SPaolo Bonzini Even = 1, 242959fd759SPaolo Bonzini } 243959fd759SPaolo Bonzini 244959fd759SPaolo Bonzini #[bitsize(1)] 245959fd759SPaolo Bonzini #[derive(Clone, Copy, Debug, Eq, FromBits, PartialEq)] 246959fd759SPaolo Bonzini /// `FEN` "Enable FIFOs" or Device mode, field of [Line Control 247959fd759SPaolo Bonzini /// register](LineControl). 248959fd759SPaolo Bonzini pub enum Mode { 249959fd759SPaolo Bonzini /// 0 = FIFOs are disabled (character mode) that is, the FIFOs become 250959fd759SPaolo Bonzini /// 1-byte-deep holding registers 251959fd759SPaolo Bonzini Character = 0, 252959fd759SPaolo Bonzini /// 1 = transmit and receive FIFO buffers are enabled (FIFO mode). 253959fd759SPaolo Bonzini FIFO = 1, 254959fd759SPaolo Bonzini } 255959fd759SPaolo Bonzini 256959fd759SPaolo Bonzini #[bitsize(2)] 257959fd759SPaolo Bonzini #[derive(Clone, Copy, Debug, Eq, FromBits, PartialEq)] 258959fd759SPaolo Bonzini /// `WLEN` Word length, field of [Line Control register](LineControl). 259959fd759SPaolo Bonzini /// 260959fd759SPaolo Bonzini /// These bits indicate the number of data bits transmitted or received in a 261959fd759SPaolo Bonzini /// frame as follows: 262959fd759SPaolo Bonzini pub enum WordLength { 263959fd759SPaolo Bonzini /// b11 = 8 bits 264959fd759SPaolo Bonzini _8Bits = 0b11, 265959fd759SPaolo Bonzini /// b10 = 7 bits 266959fd759SPaolo Bonzini _7Bits = 0b10, 267959fd759SPaolo Bonzini /// b01 = 6 bits 268959fd759SPaolo Bonzini _6Bits = 0b01, 269959fd759SPaolo Bonzini /// b00 = 5 bits. 270959fd759SPaolo Bonzini _5Bits = 0b00, 271959fd759SPaolo Bonzini } 272959fd759SPaolo Bonzini 273959fd759SPaolo Bonzini /// Control Register, `UARTCR` 274959fd759SPaolo Bonzini /// 2756414b770SPeter Maydell /// The `UARTCR` register is the control register. It contains various 2766414b770SPeter Maydell /// enable bits, and the bits to write to set the usual outbound RS232 2776414b770SPeter Maydell /// modem control signals. All bits reset to 0 except TXE and RXE. 278959fd759SPaolo Bonzini #[bitsize(32)] 279959fd759SPaolo Bonzini #[doc(alias = "UARTCR")] 280959fd759SPaolo Bonzini #[derive(Clone, Copy, DebugBits, FromBits)] 281959fd759SPaolo Bonzini pub struct Control { 2826414b770SPeter Maydell /// `UARTEN` UART enable: 0 = UART is disabled. 283959fd759SPaolo Bonzini pub enable_uart: bool, 2846414b770SPeter Maydell /// `SIREN` `SIR` enable: disable or enable IrDA SIR ENDEC. 2856414b770SPeter Maydell /// QEMU does not model this. 286959fd759SPaolo Bonzini pub enable_sir: bool, 2876414b770SPeter Maydell /// `SIRLP` SIR low-power IrDA mode. QEMU does not model this. 288959fd759SPaolo Bonzini pub sir_lowpower_irda_mode: u1, 289959fd759SPaolo Bonzini /// Reserved, do not modify, read as zero. 290959fd759SPaolo Bonzini _reserved_zero_no_modify: u4, 2916414b770SPeter Maydell /// `LBE` Loopback enable: feed UART output back to the input 292959fd759SPaolo Bonzini pub enable_loopback: bool, 2936414b770SPeter Maydell /// `TXE` Transmit enable 294959fd759SPaolo Bonzini pub enable_transmit: bool, 2956414b770SPeter Maydell /// `RXE` Receive enable 296959fd759SPaolo Bonzini pub enable_receive: bool, 2976414b770SPeter Maydell /// `DTR` Data transmit ready 298959fd759SPaolo Bonzini pub data_transmit_ready: bool, 2996414b770SPeter Maydell /// `RTS` Request to send 300959fd759SPaolo Bonzini pub request_to_send: bool, 3016414b770SPeter Maydell /// `Out1` UART Out1 signal; can be used as DCD 302959fd759SPaolo Bonzini pub out_1: bool, 3036414b770SPeter Maydell /// `Out2` UART Out2 signal; can be used as RI 304959fd759SPaolo Bonzini pub out_2: bool, 3056414b770SPeter Maydell /// `RTSEn` RTS hardware flow control enable 306959fd759SPaolo Bonzini pub rts_hardware_flow_control_enable: bool, 3076414b770SPeter Maydell /// `CTSEn` CTS hardware flow control enable 308959fd759SPaolo Bonzini pub cts_hardware_flow_control_enable: bool, 309959fd759SPaolo Bonzini /// 31:16 - Reserved, do not modify, read as zero. 310959fd759SPaolo Bonzini _reserved_zero_no_modify2: u16, 311959fd759SPaolo Bonzini } 312959fd759SPaolo Bonzini impl_vmstate_bitsized!(Control); 313959fd759SPaolo Bonzini 314959fd759SPaolo Bonzini impl Control { reset(&mut self)315959fd759SPaolo Bonzini pub fn reset(&mut self) { 316959fd759SPaolo Bonzini *self = 0.into(); 317959fd759SPaolo Bonzini self.set_enable_receive(true); 318959fd759SPaolo Bonzini self.set_enable_transmit(true); 319959fd759SPaolo Bonzini } 320959fd759SPaolo Bonzini } 321959fd759SPaolo Bonzini 322959fd759SPaolo Bonzini impl Default for Control { default() -> Self323959fd759SPaolo Bonzini fn default() -> Self { 324959fd759SPaolo Bonzini let mut ret: Self = 0.into(); 325959fd759SPaolo Bonzini ret.reset(); 326959fd759SPaolo Bonzini ret 327959fd759SPaolo Bonzini } 328959fd759SPaolo Bonzini } 329959fd759SPaolo Bonzini 330*9c8ff2a1SPaolo Bonzini bits! { 331959fd759SPaolo Bonzini /// Interrupt status bits in UARTRIS, UARTMIS, UARTIMSC 332*9c8ff2a1SPaolo Bonzini #[derive(Default)] 333*9c8ff2a1SPaolo Bonzini pub struct Interrupt(u32) { 334*9c8ff2a1SPaolo Bonzini OE = 1 << 10, 335*9c8ff2a1SPaolo Bonzini BE = 1 << 9, 336*9c8ff2a1SPaolo Bonzini PE = 1 << 8, 337*9c8ff2a1SPaolo Bonzini FE = 1 << 7, 338*9c8ff2a1SPaolo Bonzini RT = 1 << 6, 339*9c8ff2a1SPaolo Bonzini TX = 1 << 5, 340*9c8ff2a1SPaolo Bonzini RX = 1 << 4, 341*9c8ff2a1SPaolo Bonzini DSR = 1 << 3, 342*9c8ff2a1SPaolo Bonzini DCD = 1 << 2, 343*9c8ff2a1SPaolo Bonzini CTS = 1 << 1, 344*9c8ff2a1SPaolo Bonzini RI = 1 << 0, 345959fd759SPaolo Bonzini 346*9c8ff2a1SPaolo Bonzini E = bits!(Self as u32: OE | BE | PE | FE), 347*9c8ff2a1SPaolo Bonzini MS = bits!(Self as u32: RI | DSR | DCD | CTS), 348959fd759SPaolo Bonzini } 349*9c8ff2a1SPaolo Bonzini } 350*9c8ff2a1SPaolo Bonzini impl_vmstate_forward!(Interrupt); 351