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 //! Device registers exposed as typed structs which are backed by arbitrary 6 //! integer bitmaps. [`Data`], [`Control`], [`LineControl`], etc. 7 8 // For more detail see the PL011 Technical Reference Manual DDI0183: 9 // https://developer.arm.com/documentation/ddi0183/latest/ 10 11 use bilge::prelude::*; 12 use qemu_api::impl_vmstate_bitsized; 13 14 /// Offset of each register from the base memory address of the device. 15 #[doc(alias = "offset")] 16 #[allow(non_camel_case_types)] 17 #[repr(u64)] 18 #[derive(Debug, Eq, PartialEq, qemu_api_macros::TryInto)] 19 pub enum RegisterOffset { 20 /// Data Register 21 /// 22 /// A write to this register initiates the actual data transmission 23 #[doc(alias = "UARTDR")] 24 DR = 0x000, 25 /// Receive Status Register or Error Clear Register 26 #[doc(alias = "UARTRSR")] 27 #[doc(alias = "UARTECR")] 28 RSR = 0x004, 29 /// Flag Register 30 /// 31 /// A read of this register shows if transmission is complete 32 #[doc(alias = "UARTFR")] 33 FR = 0x018, 34 /// Fractional Baud Rate Register 35 /// 36 /// responsible for baud rate speed 37 #[doc(alias = "UARTFBRD")] 38 FBRD = 0x028, 39 /// `IrDA` Low-Power Counter Register 40 #[doc(alias = "UARTILPR")] 41 ILPR = 0x020, 42 /// Integer Baud Rate Register 43 /// 44 /// Responsible for baud rate speed 45 #[doc(alias = "UARTIBRD")] 46 IBRD = 0x024, 47 /// line control register (data frame format) 48 #[doc(alias = "UARTLCR_H")] 49 LCR_H = 0x02C, 50 /// Toggle UART, transmission or reception 51 #[doc(alias = "UARTCR")] 52 CR = 0x030, 53 /// Interrupt FIFO Level Select Register 54 #[doc(alias = "UARTIFLS")] 55 FLS = 0x034, 56 /// Interrupt Mask Set/Clear Register 57 #[doc(alias = "UARTIMSC")] 58 IMSC = 0x038, 59 /// Raw Interrupt Status Register 60 #[doc(alias = "UARTRIS")] 61 RIS = 0x03C, 62 /// Masked Interrupt Status Register 63 #[doc(alias = "UARTMIS")] 64 MIS = 0x040, 65 /// Interrupt Clear Register 66 #[doc(alias = "UARTICR")] 67 ICR = 0x044, 68 /// DMA control Register 69 #[doc(alias = "UARTDMACR")] 70 DMACR = 0x048, 71 ///// Reserved, offsets `0x04C` to `0x07C`. 72 //Reserved = 0x04C, 73 } 74 75 /// Receive Status Register / Data Register common error bits 76 /// 77 /// The `UARTRSR` register is updated only when a read occurs 78 /// from the `UARTDR` register with the same status information 79 /// that can also be obtained by reading the `UARTDR` register 80 #[bitsize(8)] 81 #[derive(Clone, Copy, Default, DebugBits, FromBits)] 82 pub struct Errors { 83 pub framing_error: bool, 84 pub parity_error: bool, 85 pub break_error: bool, 86 pub overrun_error: bool, 87 _reserved_unpredictable: u4, 88 } 89 90 /// Data Register, `UARTDR` 91 /// 92 /// The `UARTDR` register is the data register; write for TX and 93 /// read for RX. It is a 12-bit register, where bits 7..0 are the 94 /// character and bits 11..8 are error bits. 95 #[bitsize(32)] 96 #[derive(Clone, Copy, Default, DebugBits, FromBits)] 97 #[doc(alias = "UARTDR")] 98 pub struct Data { 99 pub data: u8, 100 pub errors: Errors, 101 _reserved: u16, 102 } 103 impl_vmstate_bitsized!(Data); 104 105 impl Data { 106 // bilge is not very const-friendly, unfortunately 107 pub const BREAK: Self = Self { value: 1 << 10 }; 108 } 109 110 /// Receive Status Register / Error Clear Register, `UARTRSR/UARTECR` 111 /// 112 /// This register provides a different way to read the four receive 113 /// status error bits that can be found in bits 11..8 of the UARTDR 114 /// on a read. It gets updated when the guest reads UARTDR, and the 115 /// status bits correspond to that character that was just read. 116 /// 117 /// The TRM confusingly describes this offset as UARTRSR for reads 118 /// and UARTECR for writes, but really it's a single error status 119 /// register where writing anything to the register clears the error 120 /// bits. 121 #[bitsize(32)] 122 #[derive(Clone, Copy, DebugBits, FromBits)] 123 pub struct ReceiveStatusErrorClear { 124 pub errors: Errors, 125 _reserved_unpredictable: u24, 126 } 127 impl_vmstate_bitsized!(ReceiveStatusErrorClear); 128 129 impl ReceiveStatusErrorClear { set_from_data(&mut self, data: Data)130 pub fn set_from_data(&mut self, data: Data) { 131 self.set_errors(data.errors()); 132 } 133 reset(&mut self)134 pub fn reset(&mut self) { 135 // All the bits are cleared to 0 on reset. 136 *self = Self::default(); 137 } 138 } 139 140 impl Default for ReceiveStatusErrorClear { default() -> Self141 fn default() -> Self { 142 0.into() 143 } 144 } 145 146 #[bitsize(32)] 147 #[derive(Clone, Copy, DebugBits, FromBits)] 148 /// Flag Register, `UARTFR` 149 /// 150 /// This has the usual inbound RS232 modem-control signals, plus flags 151 /// for RX and TX FIFO fill levels and a BUSY flag. 152 #[doc(alias = "UARTFR")] 153 pub struct Flags { 154 /// CTS: Clear to send 155 pub clear_to_send: bool, 156 /// DSR: Data set ready 157 pub data_set_ready: bool, 158 /// DCD: Data carrier detect 159 pub data_carrier_detect: bool, 160 /// BUSY: UART busy. In real hardware, set while the UART is 161 /// busy transmitting data. QEMU's implementation never sets BUSY. 162 pub busy: bool, 163 /// RXFE: Receive FIFO empty 164 pub receive_fifo_empty: bool, 165 /// TXFF: Transmit FIFO full 166 pub transmit_fifo_full: bool, 167 /// RXFF: Receive FIFO full 168 pub receive_fifo_full: bool, 169 /// TXFE: Transmit FIFO empty 170 pub transmit_fifo_empty: bool, 171 /// RI: Ring indicator 172 pub ring_indicator: bool, 173 _reserved_zero_no_modify: u23, 174 } 175 impl_vmstate_bitsized!(Flags); 176 177 impl Flags { reset(&mut self)178 pub fn reset(&mut self) { 179 *self = Self::default(); 180 } 181 } 182 183 impl Default for Flags { default() -> Self184 fn default() -> Self { 185 let mut ret: Self = 0.into(); 186 // After reset TXFF, RXFF, and BUSY are 0, and TXFE and RXFE are 1 187 ret.set_receive_fifo_empty(true); 188 ret.set_transmit_fifo_empty(true); 189 ret 190 } 191 } 192 193 #[bitsize(32)] 194 #[derive(Clone, Copy, DebugBits, FromBits)] 195 /// Line Control Register, `UARTLCR_H` 196 #[doc(alias = "UARTLCR_H")] 197 pub struct LineControl { 198 /// BRK: Send break 199 pub send_break: bool, 200 /// PEN: Parity enable 201 pub parity_enabled: bool, 202 /// EPS: Even parity select 203 pub parity: Parity, 204 /// STP2: Two stop bits select 205 pub two_stops_bits: bool, 206 /// FEN: Enable FIFOs 207 pub fifos_enabled: Mode, 208 /// WLEN: Word length in bits 209 /// b11 = 8 bits 210 /// b10 = 7 bits 211 /// b01 = 6 bits 212 /// b00 = 5 bits. 213 pub word_length: WordLength, 214 /// SPS Stick parity select 215 pub sticky_parity: bool, 216 /// 31:8 - Reserved, do not modify, read as zero. 217 _reserved_zero_no_modify: u24, 218 } 219 impl_vmstate_bitsized!(LineControl); 220 221 impl LineControl { reset(&mut self)222 pub fn reset(&mut self) { 223 // All the bits are cleared to 0 when reset. 224 *self = 0.into(); 225 } 226 } 227 228 impl Default for LineControl { default() -> Self229 fn default() -> Self { 230 0.into() 231 } 232 } 233 234 #[bitsize(1)] 235 #[derive(Clone, Copy, Debug, Eq, FromBits, PartialEq)] 236 /// `EPS` "Even parity select", field of [Line Control 237 /// register](LineControl). 238 pub enum Parity { 239 Odd = 0, 240 Even = 1, 241 } 242 243 #[bitsize(1)] 244 #[derive(Clone, Copy, Debug, Eq, FromBits, PartialEq)] 245 /// `FEN` "Enable FIFOs" or Device mode, field of [Line Control 246 /// register](LineControl). 247 pub enum Mode { 248 /// 0 = FIFOs are disabled (character mode) that is, the FIFOs become 249 /// 1-byte-deep holding registers 250 Character = 0, 251 /// 1 = transmit and receive FIFO buffers are enabled (FIFO mode). 252 FIFO = 1, 253 } 254 255 #[bitsize(2)] 256 #[derive(Clone, Copy, Debug, Eq, FromBits, PartialEq)] 257 /// `WLEN` Word length, field of [Line Control register](LineControl). 258 /// 259 /// These bits indicate the number of data bits transmitted or received in a 260 /// frame as follows: 261 pub enum WordLength { 262 /// b11 = 8 bits 263 _8Bits = 0b11, 264 /// b10 = 7 bits 265 _7Bits = 0b10, 266 /// b01 = 6 bits 267 _6Bits = 0b01, 268 /// b00 = 5 bits. 269 _5Bits = 0b00, 270 } 271 272 /// Control Register, `UARTCR` 273 /// 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. 277 #[bitsize(32)] 278 #[doc(alias = "UARTCR")] 279 #[derive(Clone, Copy, DebugBits, FromBits)] 280 pub struct Control { 281 /// `UARTEN` UART enable: 0 = UART is disabled. 282 pub enable_uart: bool, 283 /// `SIREN` `SIR` enable: disable or enable IrDA SIR ENDEC. 284 /// QEMU does not model this. 285 pub enable_sir: bool, 286 /// `SIRLP` SIR low-power IrDA mode. QEMU does not model this. 287 pub sir_lowpower_irda_mode: u1, 288 /// Reserved, do not modify, read as zero. 289 _reserved_zero_no_modify: u4, 290 /// `LBE` Loopback enable: feed UART output back to the input 291 pub enable_loopback: bool, 292 /// `TXE` Transmit enable 293 pub enable_transmit: bool, 294 /// `RXE` Receive enable 295 pub enable_receive: bool, 296 /// `DTR` Data transmit ready 297 pub data_transmit_ready: bool, 298 /// `RTS` Request to send 299 pub request_to_send: bool, 300 /// `Out1` UART Out1 signal; can be used as DCD 301 pub out_1: bool, 302 /// `Out2` UART Out2 signal; can be used as RI 303 pub out_2: bool, 304 /// `RTSEn` RTS hardware flow control enable 305 pub rts_hardware_flow_control_enable: bool, 306 /// `CTSEn` CTS hardware flow control enable 307 pub cts_hardware_flow_control_enable: bool, 308 /// 31:16 - Reserved, do not modify, read as zero. 309 _reserved_zero_no_modify2: u16, 310 } 311 impl_vmstate_bitsized!(Control); 312 313 impl Control { reset(&mut self)314 pub fn reset(&mut self) { 315 *self = 0.into(); 316 self.set_enable_receive(true); 317 self.set_enable_transmit(true); 318 } 319 } 320 321 impl Default for Control { default() -> Self322 fn default() -> Self { 323 let mut ret: Self = 0.into(); 324 ret.reset(); 325 ret 326 } 327 } 328 329 /// Interrupt status bits in UARTRIS, UARTMIS, UARTIMSC 330 pub struct Interrupt(pub u32); 331 332 impl Interrupt { 333 pub const OE: Self = Self(1 << 10); 334 pub const BE: Self = Self(1 << 9); 335 pub const PE: Self = Self(1 << 8); 336 pub const FE: Self = Self(1 << 7); 337 pub const RT: Self = Self(1 << 6); 338 pub const TX: Self = Self(1 << 5); 339 pub const RX: Self = Self(1 << 4); 340 pub const DSR: Self = Self(1 << 3); 341 pub const DCD: Self = Self(1 << 2); 342 pub const CTS: Self = Self(1 << 1); 343 pub const RI: Self = Self(1 << 0); 344 345 pub const E: Self = Self(Self::OE.0 | Self::BE.0 | Self::PE.0 | Self::FE.0); 346 pub const MS: Self = Self(Self::RI.0 | Self::DSR.0 | Self::DCD.0 | Self::CTS.0); 347 } 348