qemu_rv32_virt_chip/
uart.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! QEMU's memory mapped 16550 UART
6
7use core::cell::Cell;
8
9use kernel::hil;
10use kernel::utilities::cells::{OptionalCell, TakeCell};
11use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
12use kernel::utilities::registers::{
13    register_bitfields, Aliased, Field, InMemoryRegister, ReadOnly, ReadWrite,
14};
15use kernel::utilities::StaticRef;
16use kernel::ErrorCode;
17
18pub const UART0_BASE: StaticRef<Uart16550Registers> =
19    unsafe { StaticRef::new(0x1000_0000 as *const Uart16550Registers) };
20
21pub const UART_16550_BAUD_BASE: usize = 399193;
22
23type Uart16550RegshiftInt = u8;
24
25#[repr(C)]
26pub struct Uart16550Registers {
27    /// 0x00:
28    /// - DLAB = 0
29    ///   - Read: receiver buffer (RBR)
30    ///   - Write: transmitter holding (THR)
31    /// - DLAB = 1: divisor latch LSB (DLL)
32    rbr_thr: Aliased<Uart16550RegshiftInt, RBR::Register, THR::Register>,
33
34    /// 0x01:
35    /// - DLAB = 0: interrupt enable (IER)
36    /// - DLAB = 1: divisor latch MSB (DLM)
37    ier: ReadWrite<Uart16550RegshiftInt, IER::Register>,
38
39    /// 0x02:
40    /// - Read: interrupt identification (IIR)
41    /// - Write: FIFO control (FCR)
42    iir_fcr: Aliased<Uart16550RegshiftInt, IIR::Register, FCR::Register>,
43
44    /// 0x03: line control (LCR)
45    lcr: ReadWrite<Uart16550RegshiftInt, LCR::Register>,
46
47    /// 0x04: modem control (MCR)
48    mcr: ReadWrite<Uart16550RegshiftInt, MCR::Register>,
49
50    /// 0x05: line status (LSR)
51    lsr: ReadOnly<Uart16550RegshiftInt, LSR::Register>,
52
53    /// 0x06: modem status (MSR)
54    msr: ReadOnly<Uart16550RegshiftInt, MSR::Register>,
55}
56
57impl Uart16550Registers {
58    /// Access the DLL and DLM (divisor latch LSB and MSB) registers
59    ///
60    /// Setting the 7th bit of the line control register (LCR) changes
61    /// the RBR/THR and IER to be the DLL and DLM register
62    /// respectively.
63    ///
64    /// This function takes care of latching the registers and calling
65    /// a closure in which this virtual register can be
66    /// accessed. Prior to calling the closure, the register is
67    /// latched back and the closure is instead provided with an
68    /// in-memory copy of the register, which is then written back to
69    /// DLL and DLM.
70    ///
71    /// This provides a safe way to access the DLL and DLM
72    /// registers.
73    fn divisor_latch_reg<F, R>(&self, f: F) -> R
74    where
75        F: FnOnce(&InMemoryRegister<u16, DLR::Register>) -> R,
76    {
77        let dlab_field = Field::<Uart16550RegshiftInt, LCR::Register>::new(1, 7);
78
79        // Set DLAB = 1
80        self.lcr.modify(dlab_field.val(1));
81
82        // Read the old values of rbr_thr and ier and combine them
83        // into a u16
84        let old_val = u16::from_be_bytes([self.ier.get(), self.rbr_thr.get()]);
85
86        // Set DLAB = 0 prior to handing back to the caller
87        self.lcr.modify(dlab_field.val(0));
88
89        let dlr = InMemoryRegister::<u16, DLR::Register>::new(old_val);
90        let ret = f(&dlr);
91
92        // Get the bytes from the modified value
93        let [new_ier, new_rbr_thr] = u16::to_be_bytes(dlr.get());
94
95        // Set DLAB = 1
96        self.lcr.modify(dlab_field.val(1));
97
98        // Write the modified value back to the registers
99        self.ier.set(new_ier as Uart16550RegshiftInt);
100        self.rbr_thr.set(new_rbr_thr as Uart16550RegshiftInt);
101
102        // Set DLAB = 0
103        self.lcr.modify(dlab_field.val(0));
104
105        ret
106    }
107}
108
109register_bitfields![u8,
110    RBR [
111        Data OFFSET(0) NUMBITS(8) [],
112    ],
113    THR [
114        Data OFFSET(0) NUMBITS(8) [],
115    ],
116    IER [
117        ModemStatusRegisterChange OFFSET(3) NUMBITS(1) [],
118        ReceiverLineStatusRegisterChange OFFSET(2) NUMBITS(1) [],
119        TransmitterHoldingRegisterEmpty OFFSET(1) NUMBITS(1) [],
120        ReceivedDataAvailable OFFSET(0) NUMBITS(1) [],
121    ],
122    IIR [
123        FIFO OFFSET(6) NUMBITS(2) [
124            NoFIFO = 0,
125            UnusableFIFO = 2,
126            FIFOEnabled = 3,
127        ],
128        Identification OFFSET(1) NUMBITS(3) [
129            ModemStatusChange = 0,
130            TransmitterHoldingRegisterEmpty = 1,
131            ReceiveDataAvailable = 2,
132            LineStatusChange = 3,
133            CharacterTimeout = 6,
134        ],
135        Pending OFFSET(0) NUMBITS(1) [
136            Pending = 0,
137            NotPending = 1,
138        ],
139    ],
140    FCR [
141        ReceiveFIFOInterruptTriggerLevel OFFSET(6) NUMBITS(2) [
142            Bytes1 = 0,
143            Bytes4 = 1,
144            Bytes8 = 2,
145            Bytes14 = 3,
146        ],
147        DMAMode OFFSET(3) NUMBITS(1) [
148            Mode0 = 0,
149            Mode1 = 1,
150        ],
151        ClearTransmitFIFO OFFSET(2) NUMBITS(1) [],
152        ClearReceiveFIFO OFFSET(1) NUMBITS(1) [],
153        Enable OFFSET(0) NUMBITS(1) [],
154    ],
155    LCR [
156        BreakSignal OFFSET(6) NUMBITS(1) [],
157        ParityMode OFFSET(4) NUMBITS(2) [
158            Odd = 0,
159            Even = 1,
160            High = 2,
161            Low = 3,
162        ],
163        Parity OFFSET(3) NUMBITS(1) [],
164        StopBits OFFSET(2) NUMBITS(1) [
165            One = 0,
166            OneHalfTwo = 1,
167        ],
168        DataWordLength OFFSET(0) NUMBITS(2) [
169            Bits5 = 0,
170            Bits6 = 1,
171            Bits7 = 2,
172            Bits8 = 3,
173        ],
174    ],
175    MCR [
176        LoopbackMode OFFSET(4) NUMBITS(1) [],
177        AuxiliaryOutput2 OFFSET(3) NUMBITS(1) [],
178        AuxiliaryOutput1 OFFSET(2) NUMBITS(1) [],
179        RequestToSend OFFSET(1) NUMBITS(1) [],
180        DataTerminalReady OFFSET(0) NUMBITS(1) [],
181    ],
182    LSR [
183        ErronousDataInFIFO OFFSET(7) NUMBITS(1) [],
184        THREmptyLineIdle OFFSET(6) NUMBITS(1) [],
185        THREmpty OFFSET(5) NUMBITS(1) [],
186        BreakSignalReceived OFFSET(4) NUMBITS(1) [],
187        FramingError OFFSET(3) NUMBITS(1) [],
188        ParityError OFFSET(2) NUMBITS(1) [],
189        OverrunError OFFSET(1) NUMBITS(1) [],
190        DataAvailable OFFSET(0) NUMBITS(1) [],
191    ],
192    MSR [
193        CarrierDetect OFFSET(7) NUMBITS(1) [],
194        RingIndicator OFFSET(6) NUMBITS(1) [],
195        DataSetReady OFFSET(5) NUMBITS(1) [],
196        ClearToSend OFFSET(4) NUMBITS(1) [],
197        ChangeInCarrierDetect OFFSET(3) NUMBITS(1) [],
198        TrailingEdgeRingIndicator OFFSET(2) NUMBITS(1) [],
199        ChangeInDataSetReady OFFSET(1) NUMBITS(1) [],
200        ChangeInClearToSend OFFSET(0) NUMBITS(1) [],
201    ],
202];
203
204register_bitfields![u16,
205    DLR [
206        Divisor OFFSET(0) NUMBITS(16) [],
207    ],
208];
209
210pub struct Uart16550<'a> {
211    regs: StaticRef<Uart16550Registers>,
212    tx_client: OptionalCell<&'a dyn hil::uart::TransmitClient>,
213    rx_client: OptionalCell<&'a dyn hil::uart::ReceiveClient>,
214    tx_buffer: TakeCell<'static, [u8]>,
215    tx_len: Cell<usize>,
216    tx_index: Cell<usize>,
217    rx_buffer: TakeCell<'static, [u8]>,
218    rx_len: Cell<usize>,
219    rx_index: Cell<usize>,
220}
221
222impl<'a> Uart16550<'a> {
223    pub fn new(regs: StaticRef<Uart16550Registers>) -> Uart16550<'a> {
224        // Disable all interrupts when constructing the UART
225        regs.ier.set(0xF);
226
227        regs.iir_fcr.write(FCR::Enable::CLEAR);
228
229        Uart16550 {
230            regs,
231            tx_client: OptionalCell::empty(),
232            rx_client: OptionalCell::empty(),
233            tx_buffer: TakeCell::empty(),
234            tx_len: Cell::new(0),
235            tx_index: Cell::new(0),
236            rx_buffer: TakeCell::empty(),
237            rx_len: Cell::new(0),
238            rx_index: Cell::new(0),
239        }
240    }
241}
242
243impl Uart16550<'_> {
244    pub fn handle_interrupt(&self) {
245        // Currently we can only receive a tx interrupt, however we
246        // need to check the interrupt cause nonetheless as this will
247        // clear the TX interrupt bit
248        let iir = self.regs.iir_fcr.extract();
249
250        // Check if the register contained a valid interrupt at all
251        if !iir.matches_all(IIR::Pending::Pending) {
252            // There is no active interrupt. This happens on newer QEMU
253            // versions, where a transient interrupt occurs whose underlying
254            // interrupt condition clears on its own, but the PLIC still holds
255            // the interrupt in the asserted / pending state.
256            //
257            // In this case, we simply return and ignore the interrupt. It
258            // should already be cleared in the PLIC.
259            return;
260        }
261
262        // Check whether there is space for new data
263        if iir.matches_all(IIR::Identification::TransmitterHoldingRegisterEmpty) {
264            // The respective interrupt has already been cleared by
265            // the extraction of IIR
266
267            // We also check whether the tx_buffer is set, as we
268            // could've generated the interrupt by transmit_sync
269            if self.tx_buffer.is_some() {
270                self.transmit_continue();
271            }
272        }
273        // Check whether we've received some new data.
274        else if iir.matches_all(IIR::Identification::ReceiveDataAvailable) {
275            self.receive();
276        }
277        // We don't care about MSC interrupts, but have to ack the
278        // interrupt by reading MSR
279        else if iir.matches_all(IIR::Identification::ModemStatusChange) {
280            let _ = self.regs.msr.get();
281        }
282        // We don't care about LSC interrupts, but have to ack the
283        // interrupt by reading LSR
284        else if iir.matches_all(IIR::Identification::LineStatusChange) {
285            let _ = self.regs.lsr.get();
286        }
287        // We con't care about character timeout interrupts, but CAN'T
288        // SUPPRESS THEM and have to ack by reading RBR
289        else if iir.matches_all(IIR::Identification::CharacterTimeout) {
290            let _ = self.regs.rbr_thr.get();
291        }
292        // All other interrupt sources are unknown, panic if we see
293        // them
294        else {
295            panic!("UART 16550: unknown interrupt");
296        }
297    }
298
299    /// Blocking transmit
300    ///
301    /// This function will transmit the passed slice in a blocking
302    /// fashing, returning when finished.
303    ///
304    /// The current device configuration is used, and the device must
305    /// be enabled. Otherwise, this function may block indefinitely.
306    pub fn transmit_sync(&self, bytes: &[u8]) {
307        // We don't want to cause excessive interrupts here, so
308        // disable transmit interrupts temporarily
309        let prev_ier = self.regs.ier.extract();
310        if prev_ier.is_set(IER::TransmitterHoldingRegisterEmpty) {
311            self.regs
312                .ier
313                .modify_no_read(prev_ier, IER::TransmitterHoldingRegisterEmpty::CLEAR);
314        }
315
316        for byte in bytes.iter() {
317            while !self.regs.lsr.is_set(LSR::THREmpty) {}
318            self.regs.rbr_thr.write(THR::Data.val(*byte));
319        }
320
321        // Restore the IER register to its original state
322        self.regs.ier.set(prev_ier.get());
323    }
324
325    fn transmit_continue(&self) {
326        // This should only be called as a result of a transmit
327        // interrupt
328
329        // Get the current transmission information
330        let mut index = self.tx_index.get();
331        let tx_data = self.tx_buffer.take().expect("UART 16550: no tx buffer");
332
333        if index < self.tx_len.get() {
334            // Still data to send
335            while index < self.tx_len.get() && self.regs.lsr.is_set(LSR::THREmpty) {
336                self.regs.rbr_thr.write(THR::Data.val(tx_data[index]));
337                index += 1;
338            }
339
340            // Put the updated index and buffer back, wait for an
341            // interrupt
342            self.tx_index.set(index);
343            self.tx_buffer.replace(tx_data);
344        } else {
345            // We are finished, disable tx interrupts
346            self.regs
347                .ier
348                .modify(IER::TransmitterHoldingRegisterEmpty::CLEAR);
349
350            // Callback to the client
351            self.tx_client
352                .map(move |client| client.transmitted_buffer(tx_data, self.tx_len.get(), Ok(())));
353        }
354    }
355
356    fn receive(&self) {
357        // Receive interrupts must only be enabled when we're currently holding
358        // a buffer to receive data into:
359        let rx_buffer = self.rx_buffer.take().expect("UART 16550: no rx buffer");
360        let len = self.rx_len.get();
361        let mut index = self.rx_index.get();
362
363        // Read in a while loop, until no more data in the FIFO
364        while self.regs.lsr.is_set(LSR::DataAvailable) && index < len {
365            rx_buffer[index] = self.regs.rbr_thr.get();
366            index += 1;
367        }
368
369        // Check whether we've read sufficient data:
370        if index == len {
371            // We're done, disable interrupts and return to the client:
372            self.regs.ier.modify(IER::ReceivedDataAvailable::CLEAR);
373
374            self.rx_client.map(move |client| {
375                client.received_buffer(rx_buffer, len, Ok(()), hil::uart::Error::None)
376            });
377        } else {
378            // Store the new index and place the buffer back:
379            self.rx_index.set(index);
380            self.rx_buffer.replace(rx_buffer);
381        }
382    }
383}
384
385impl hil::uart::Configure for Uart16550<'_> {
386    fn configure(&self, params: hil::uart::Parameters) -> Result<(), ErrorCode> {
387        use hil::uart::{Parity, StopBits, Width};
388
389        // 16550 operates at a default frequency of 115200. Dividing
390        // this by the target frequency gives the divisor register
391        // contents.
392        let divisor: u16 = (115_200 / params.baud_rate) as u16;
393        self.regs.divisor_latch_reg(|dlr| {
394            dlr.set(divisor);
395        });
396
397        let mut lcr = self.regs.lcr.extract();
398
399        match params.width {
400            Width::Six => lcr.modify(LCR::DataWordLength::Bits6),
401            Width::Seven => lcr.modify(LCR::DataWordLength::Bits7),
402            Width::Eight => lcr.modify(LCR::DataWordLength::Bits8),
403        }
404
405        match params.stop_bits {
406            StopBits::One => LCR::StopBits::One,
407            // 1.5 stop bits for 5bit works, 2 stop bits for 6-8 bit
408            // words. We only support 6-8 bit words, so this
409            // configures 2 stop bits
410            StopBits::Two => LCR::StopBits::OneHalfTwo,
411        };
412
413        match params.parity {
414            Parity::None => lcr.modify(LCR::Parity.val(0b000)),
415            Parity::Odd => lcr.modify(LCR::Parity.val(0b001)),
416            Parity::Even => lcr.modify(LCR::Parity.val(0b011)),
417        }
418
419        match params.hw_flow_control {
420            true => lcr.modify(LCR::BreakSignal::SET),
421            false => lcr.modify(LCR::BreakSignal::CLEAR),
422        }
423
424        self.regs.lcr.set(lcr.get());
425
426        Ok(())
427    }
428}
429
430impl<'a> hil::uart::Transmit<'a> for Uart16550<'a> {
431    fn set_transmit_client(&self, client: &'a dyn hil::uart::TransmitClient) {
432        self.tx_client.set(client);
433    }
434
435    fn transmit_buffer(
436        &self,
437        tx_data: &'static mut [u8],
438        tx_len: usize,
439    ) -> Result<(), (ErrorCode, &'static mut [u8])> {
440        if tx_len > tx_data.len() {
441            return Err((ErrorCode::INVAL, tx_data));
442        }
443
444        if self.tx_buffer.is_some() {
445            return Err((ErrorCode::BUSY, tx_data));
446        }
447
448        // Enable interrupts for the transmitter holding register
449        // being empty such that we can callback to the client
450        self.regs
451            .ier
452            .modify(IER::TransmitterHoldingRegisterEmpty::SET);
453
454        // Start transmitting the first data word(s) already
455        let mut index = 0;
456        while index < tx_len && self.regs.lsr.is_set(LSR::THREmpty) {
457            self.regs.rbr_thr.write(THR::Data.val(tx_data[index]));
458            index += 1;
459        }
460
461        // Store the required buffer and information for the interrupt
462        // handler
463        self.tx_buffer.replace(tx_data);
464        self.tx_len.set(tx_len);
465        self.tx_index.set(index);
466
467        Ok(())
468    }
469
470    fn transmit_abort(&self) -> Result<(), ErrorCode> {
471        Err(ErrorCode::FAIL)
472    }
473
474    fn transmit_word(&self, _word: u32) -> Result<(), ErrorCode> {
475        Err(ErrorCode::FAIL)
476    }
477}
478
479impl<'a> hil::uart::Receive<'a> for Uart16550<'a> {
480    fn set_receive_client(&self, client: &'a dyn hil::uart::ReceiveClient) {
481        self.rx_client.set(client);
482    }
483
484    fn receive_buffer(
485        &self,
486        rx_buffer: &'static mut [u8],
487        rx_len: usize,
488    ) -> Result<(), (ErrorCode, &'static mut [u8])> {
489        // Ensure the provided buffer holds at least `rx_len` bytes, and
490        // `rx_len` is strictly positive (otherwise we'd need to use deferred
491        // calls):
492        if rx_buffer.len() < rx_len && rx_len > 0 {
493            return Err((ErrorCode::SIZE, rx_buffer));
494        }
495
496        // Store the receive buffer and byte count. We cannot call into the
497        // generic receive routine here, as the client callback needs to be
498        // called from another call stack. Hence simply enable interrupts here.
499        self.rx_buffer.replace(rx_buffer);
500        self.rx_len.set(rx_len);
501        self.rx_index.set(0);
502
503        // Enable receive interrupts:
504        self.regs.ier.modify(IER::ReceivedDataAvailable::SET);
505
506        Ok(())
507    }
508
509    fn receive_abort(&self) -> Result<(), ErrorCode> {
510        // Currently unsupported as we'd like to avoid using deferred
511        // calls. Needs to be migrated to the new UART HIL anyways.
512        Err(ErrorCode::FAIL)
513    }
514
515    fn receive_word(&self) -> Result<(), ErrorCode> {
516        // Currently unsupported.
517        Err(ErrorCode::FAIL)
518    }
519}