Skip to main content

serial_pl011/
lib.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Emulator for PL011 serial UART.
5//!
6//! This device does not fully implement the PL011 UART defined by ARM (e.g., it
7//! is missing DMA support), and Linux interprets it as an SBSA-compatible UART
8//! when it is enumerated by ACPI (even when we use ARM's PL011 ACPI CID). SBSA
9//! only defines a subset of the UART registers, leaving the rest as vendor
10//! specified.
11//!
12//! If you extend this emulator, do so only to make it closer to a real PL011;
13//! if you want to add other vendor-specific behavior, do it in a separate
14//! wrapping emulator.
15
16#![forbid(unsafe_code)]
17
18pub mod resolver;
19mod spec;
20
21use self::spec::ControlRegister;
22use self::spec::DmaControlRegister;
23use self::spec::FIFO_SIZE;
24use self::spec::FifoLevelSelect;
25use self::spec::FractionalBaudRateRegister;
26use self::spec::InterruptFifoLevelSelectRegister;
27use self::spec::InterruptRegister;
28use self::spec::LineControlRegister;
29use self::spec::REGISTERS_SIZE;
30use self::spec::Register;
31use self::spec::UARTPCELL_ID;
32use self::spec::UARTPERIPH_ID;
33use chipset_device::ChipsetDevice;
34use chipset_device::io::IoError;
35use chipset_device::io::IoResult;
36use chipset_device::io::deferred::DeferredRead;
37use chipset_device::io::deferred::DeferredToken;
38use chipset_device::io::deferred::defer_read;
39use chipset_device::mmio::MmioIntercept;
40use chipset_device::poll_device::PollDevice;
41use futures::AsyncRead;
42use futures::AsyncWrite;
43use inspect::Inspect;
44use inspect::InspectMut;
45use inspect_counters::Counter;
46use pal_async::timer::Instant;
47use pal_async::timer::PolledTimer;
48use serial_core::SerialIo;
49use std::collections::VecDeque;
50use std::io::ErrorKind;
51use std::ops::RangeInclusive;
52use std::pin::Pin;
53use std::task::Context;
54use std::task::Poll;
55use std::task::Waker;
56use std::task::ready;
57use std::time::Duration;
58use thiserror::Error;
59use vmcore::device_state::ChangeDeviceState;
60use vmcore::line_interrupt::LineInterrupt;
61
62/// A PL011 serial port emulator.
63#[derive(InspectMut)]
64pub struct SerialPl011 {
65    // Fixed configuration
66    #[inspect(skip)]
67    debug_name: String,
68    #[inspect(skip)]
69    mmio_region: (&'static str, RangeInclusive<u64>),
70    /// Don't transmit until the guest sets RTS. This exists here for symmetry
71    /// with the 16550 emulator, but it's not useful because this device is
72    /// enumerated as an SBSA UART, which does not support the RTS bit (a full
73    /// PL011 would).
74    wait_for_rts: bool,
75
76    // Runtime glue
77    interrupt: LineInterrupt,
78    #[inspect(mut)]
79    io: Box<dyn SerialIo>,
80
81    // Runtime book-keeping
82    state: State,
83    #[inspect(skip)]
84    rx_waker: Option<Waker>,
85    #[inspect(skip)]
86    tx_waker: Option<Waker>,
87    #[inspect(skip)]
88    poll_waker: Option<Waker>,
89    #[inspect(skip)]
90    debugger_poll: Option<DebuggerPollThrottle>,
91    stats: SerialStats,
92}
93
94/// State for the debugger-mode guest poll throttle.
95///
96/// When a COM port is in debugger mode, a kernel debugger (KD) typically busy-
97/// polls the port's flag register while waiting for data, generating a storm of
98/// register-read intercepts (and thus host CPU). Once the guest has read an
99/// empty RX FIFO [`DEBUGGER_EMPTY_POLL_THRESHOLD`] times in a row, subsequent
100/// such reads are deferred (via [`IoResult::Defer`]) for [`DEBUGGER_POLL_DELAY`]
101/// before completing, throttling the poll loop. The intercept always completes
102/// with the same value it would have returned; only its timing changes, and a
103/// deferred read completes early the instant real data arrives so debugger
104/// latency is unaffected. Only ever `Some` when the port is in debugger mode.
105struct DebuggerPollThrottle {
106    timer: PolledTimer,
107    /// Number of consecutive reads that observed an empty RX FIFO on a
108    /// poll register.
109    empty_streak: u32,
110    /// A read that has been deferred and is waiting to be completed.
111    pending: Option<PendingPollRead>,
112}
113
114struct PendingPollRead {
115    deferred: DeferredRead,
116    register: Register,
117    len: usize,
118    deadline: Instant,
119}
120
121/// Consecutive empty-FIFO poll reads before the throttle engages.
122const DEBUGGER_EMPTY_POLL_THRESHOLD: u32 = 8;
123/// How long each throttled poll read is deferred once the throttle engages.
124const DEBUGGER_POLL_DELAY: Duration = Duration::from_millis(4);
125
126#[derive(Inspect, Default)]
127struct SerialStats {
128    rx_bytes: Counter,
129    tx_bytes: Counter,
130    rx_dropped: Counter,
131    tx_dropped: Counter,
132}
133
134#[derive(Inspect)]
135struct State {
136    #[inspect(with = "VecDeque::len")]
137    tx_buffer: VecDeque<u8>,
138    #[inspect(with = "VecDeque::len")]
139    rx_buffer: VecDeque<u8>,
140    rx_overrun: bool,
141    connected: bool,
142    ilpr: u8,                               // UARTILPR
143    ibrd: u16,                              // UARTIBRD
144    fbrd: FractionalBaudRateRegister,       // UARTFBRD
145    lcr: LineControlRegister,               // UARTLCR_H: u8,
146    cr: ControlRegister,                    // UARTCR: u16,
147    ifls: InterruptFifoLevelSelectRegister, // UARTIFLS: u16
148    imsc: InterruptRegister,                // UARTIMSC
149    ris: InterruptRegister, // UARTRIS: 16 holds currently asserted interrupts, only to be updated by UpdateInterrupts and writes to UARTCIR
150    dmacr: DmaControlRegister, // UARTDMACR
151
152    // Updating UARTIBRD or UARTFBRD requires a write to UARTLCR_H.
153    // Thus, we need to store if we've seen a different value incase we ever see a UARTLCR_H write.
154    new_ibrd: u16,
155    new_fbrd: FractionalBaudRateRegister,
156}
157
158// A normal FIFO has only 16 bytes, but we get greater batching with these values.
159const TX_BUFFER_MAX: usize = 256;
160const RX_BUFFER_MAX: usize = 256;
161
162/// An error returned by [`SerialPl011::new`].
163#[derive(Debug, Error)]
164pub enum ConfigurationError {
165    /// The provided base address was not aligned to the register bank width.
166    #[error("unaligned base address: {0}")]
167    UnalignedBaseAddress(u64),
168    /// The specified register with was invalid.
169    #[error("invalid register width: {0}")]
170    InvalidRegisterWidth(u8),
171}
172
173impl SerialPl011 {
174    /// Returns a new emulator instance.
175    ///
176    /// `debug_name` is used to improve tracing statements. `base` is the base
177    /// IO port and will be used for an IO region spanning 8 bytes.
178    pub fn new(
179        debug_name: String,
180        base: u64,
181        interrupt: LineInterrupt,
182        io: Box<dyn SerialIo>,
183        debugger_poll_timer: Option<PolledTimer>,
184    ) -> Result<Self, ConfigurationError> {
185        if base & (REGISTERS_SIZE - 1) != 0 {
186            return Err(ConfigurationError::UnalignedBaseAddress(base));
187        }
188
189        let mut this = Self {
190            debug_name,
191            mmio_region: ("registers", base..=base + (REGISTERS_SIZE - 1)),
192            wait_for_rts: false,
193            state: State::new(io.is_connected()),
194            interrupt,
195            io,
196            rx_waker: None,
197            tx_waker: None,
198            poll_waker: None,
199            debugger_poll: debugger_poll_timer.map(|timer| DebuggerPollThrottle {
200                timer,
201                empty_streak: 0,
202                pending: None,
203            }),
204            stats: Default::default(),
205        };
206        this.sync();
207        Ok(this)
208    }
209
210    /// Synchronize interrupt and waker state with device state.
211    fn sync(&mut self) {
212        // Wake to poll if there are any bytes to write.
213        if !self.state.tx_buffer.is_empty() {
214            if let Some(waker) = self.tx_waker.take() {
215                waker.wake();
216            }
217        }
218
219        // Reduce wakeups by waking to poll if the rx buffer is at least half empty.
220        if self.state.should_poll_rx(self.wait_for_rts)
221            && self.state.rx_buffer.len() <= RX_BUFFER_MAX / 2
222        {
223            if let Some(waker) = self.rx_waker.take() {
224                waker.wake();
225            }
226        }
227
228        // Synchronize the receive timeout interrupt. In hardware, this would
229        // only raise after 32 bits worth of clock have expired and there is
230        // data in the RX FIFO. But that's too hard, so just treat the clock as
231        // expiring constantly.
232        //
233        // This means the guest can't really clear this interrupt as long as
234        // there is data in the FIFO.
235        self.state.ris.set_rt(!self.state.rx_buffer.is_empty());
236
237        // Synchronize the interrupt output.
238        self.interrupt.set_level(self.state.pending_interrupt());
239    }
240
241    fn poll_tx(&mut self, cx: &mut Context<'_>) -> Poll<()> {
242        while !self.state.tx_buffer.is_empty() {
243            if !self.state.connected {
244                // The backend is disconnected, so drop everything in the FIFO.
245                self.stats.tx_dropped.add(self.state.tx_buffer.len() as u64);
246                self.state.tx_buffer.clear();
247                self.state.ris.set_tx(true);
248                break;
249            }
250            let (buf, _) = self.state.tx_buffer.as_slices();
251            match ready!(Pin::new(&mut self.io).poll_write(cx, buf)) {
252                Ok(n) => {
253                    assert_ne!(n, 0);
254                    self.state.tx_buffer.drain(..n);
255                    self.stats.tx_bytes.add(n as u64);
256                }
257                Err(err) if err.kind() == ErrorKind::BrokenPipe => {
258                    tracing::info!(
259                        port = self.debug_name,
260                        "serial output broken pipe, disconnecting"
261                    );
262                    self.state.disconnect();
263                    continue;
264                }
265                Err(err) => {
266                    tracelimit::error_ratelimited!(
267                        port = self.debug_name,
268                        len = buf.len(),
269                        error = &err as &dyn std::error::Error,
270                        "serial write failed, dropping data"
271                    );
272                    self.stats.tx_dropped.add(buf.len() as u64);
273                    self.state.tx_buffer.drain(..buf.len());
274                }
275            }
276            let tx_fifo_trigger = self.state.tx_fifo_trigger();
277            if self.state.tx_buffer.len() <= tx_fifo_trigger {
278                self.state.ris.set_tx(true);
279            }
280        }
281        // Wait for more bytes to write.
282        self.tx_waker = Some(cx.waker().clone());
283        Poll::Pending
284    }
285
286    fn poll_rx(&mut self, cx: &mut Context<'_>) -> Poll<()> {
287        let mut buf = [0; RX_BUFFER_MAX];
288        loop {
289            if !self.state.connected {
290                // Wait for reconnect.
291                if let Err(err) = ready!(self.io.poll_connect(cx)) {
292                    tracing::info!(
293                        port = self.debug_name,
294                        error = &err as &dyn std::error::Error,
295                        "serial backend failure"
296                    );
297                    break Poll::Ready(());
298                }
299                tracing::trace!(port = self.debug_name, "serial connected");
300                self.state.connect();
301            }
302            if !self.state.should_poll_rx(self.wait_for_rts) {
303                // Wait for buffer space to read into, or to leave loopback mode.
304                self.rx_waker = Some(cx.waker().clone());
305                if let Err(err) = ready!(self.io.poll_disconnect(cx)) {
306                    tracing::info!(
307                        port = self.debug_name,
308                        error = &err as &dyn std::error::Error,
309                        "serial backend failure"
310                    );
311                    break Poll::Ready(());
312                }
313                tracing::trace!(port = self.debug_name, "serial disconnected");
314                self.state.disconnect();
315                continue;
316            }
317            let avail_space = RX_BUFFER_MAX - self.state.rx_buffer.len();
318            let buf = &mut buf[..avail_space];
319            match ready!(Pin::new(&mut self.io).poll_read(cx, buf)) {
320                Ok(0) => {
321                    tracing::trace!(port = self.debug_name, "serial disconnected");
322                    self.state.disconnect();
323                }
324                Ok(n) => {
325                    let rx_fifo_trigger = self.state.rx_fifo_trigger();
326                    if self.state.rx_buffer.len() < rx_fifo_trigger
327                        && self.state.rx_buffer.len() + n >= rx_fifo_trigger
328                    {
329                        self.state.ris.set_rx(true);
330                    }
331                    self.state.rx_buffer.extend(&buf[..n]);
332                    self.stats.rx_bytes.add(n as u64);
333                }
334                Err(err) => {
335                    tracing::error!(
336                        port = self.debug_name,
337                        error = &err as &dyn std::error::Error,
338                        "failed to read serial input, disconnecting"
339                    );
340                    self.state.disconnect();
341                    break Poll::Ready(());
342                }
343            }
344        }
345    }
346
347    fn register(&self, addr: u64) -> Result<Register, IoError> {
348        // All registers are 32 bits wide, and the SBSA spec requires aligned access.
349        if addr & 3 != 0 {
350            return Err(IoError::UnalignedAccess);
351        }
352        Ok(Register((addr & (REGISTERS_SIZE - 1)) as u16))
353    }
354
355    fn read(&mut self, addr: u64, data: &mut [u8]) -> IoResult {
356        let register = match self.register(addr) {
357            Err(e) => return IoResult::Err(e),
358            Ok(r) => r,
359        };
360
361        // In debugger mode, throttle a guest that is busy-polling an empty RX
362        // FIFO by deferring the read for a short while. See
363        // [`DebuggerPollThrottle`].
364        if let Some(token) = self.maybe_defer_debugger_poll(register, data.len()) {
365            return IoResult::Defer(token);
366        }
367
368        data.fill(0);
369        let val: u16 = match register {
370            Register::UARTDR => self.state.read_dr().into(),
371            Register::UARTRSR => 0, // Status flags we don't care about, return zeros.
372            Register::UARTFR => self.state.read_fr(),
373            Register::UARTILPR => self.state.ilpr as u16,
374            Register::UARTIBRD => self.state.ibrd,
375            Register::UARTFBRD => u8::from(self.state.fbrd) as u16,
376            Register::UARTLCR_H => u8::from(self.state.lcr) as u16,
377            Register::UARTCR => u16::from(self.state.cr),
378            Register::UARTIFLS => u16::from(self.state.ifls),
379            Register::UARTIMSC => u16::from(self.state.imsc),
380            Register::UARTRIS => u16::from(self.state.ris),
381            Register::UARTMIS => u16::from(self.state.ris) & u16::from(self.state.imsc),
382            Register::UARTDMACR => u16::from(self.state.dmacr),
383            Register::UARTPERIPHID0 => UARTPERIPH_ID[0],
384            Register::UARTPERIPHID1 => UARTPERIPH_ID[1],
385            Register::UARTPERIPHID2 => UARTPERIPH_ID[2],
386            Register::UARTPERIPHID3 => UARTPERIPH_ID[3],
387            Register::UARTPCELLID0 => UARTPCELL_ID[0],
388            Register::UARTPCELLID1 => UARTPCELL_ID[1],
389            Register::UARTPCELLID2 => UARTPCELL_ID[2],
390            Register::UARTPCELLID3 => UARTPCELL_ID[3],
391            _ => return IoResult::Err(IoError::InvalidRegister),
392        };
393
394        // The SBSA spec only requires the device to support 8-bit reads on some
395        // registers and leaves it implementation defined on others. Allow 8-bit
396        // reads on all registers for simplicity.
397        data[0] = val.to_le_bytes()[0];
398        if data.len() > 1 {
399            data[1] = val.to_le_bytes()[1];
400        }
401
402        self.sync();
403        IoResult::Ok
404    }
405
406    fn write(&mut self, addr: u64, data: &[u8]) -> IoResult {
407        let register = match self.register(addr) {
408            Err(e) => return IoResult::Err(e),
409            Ok(r) => r,
410        };
411
412        tracing::trace!(?register, ?data, "serial write");
413
414        // Registers that allow 8-bit access.
415        match register {
416            Register::UARTDR => self.state.write_dr(&mut self.stats, data[0]),
417            Register::UARTECR => {}
418            Register::UARTILPR => self.state.ilpr = data[0],
419            Register::UARTFBRD => self.state.write_fbrd(data[0]),
420            Register::UARTLCR_H => self.state.write_lcrh(&mut self.stats, data[0]),
421            _ => {
422                // 16-bit registers.
423                let Some(data) = data.get(..2) else {
424                    return IoResult::Err(IoError::InvalidAccessSize);
425                };
426                let data16 = u16::from_le_bytes(data.try_into().unwrap());
427                match register {
428                    Register::UARTIBRD => self.state.new_ibrd = data16,
429                    Register::UARTCR => self.state.write_cr(data16),
430                    Register::UARTIFLS => self.state.write_ifls(data16),
431                    Register::UARTIMSC => self.state.write_imsc(data16),
432                    Register::UARTICR => self.state.write_icr(data16),
433                    Register::UARTDMACR => self.state.write_dmacr(data16),
434                    _ => return IoResult::Err(IoError::InvalidRegister),
435                };
436            }
437        }
438        self.sync();
439        IoResult::Ok
440    }
441
442    /// If the port is in debugger mode and the guest is repeatedly polling an
443    /// empty RX FIFO, defers this read for a short while and returns the token
444    /// to defer the intercept. Returns `None` (read normally) otherwise.
445    ///
446    /// The registers a KD stub polls while waiting for data are the flag
447    /// register (to check the receive-FIFO-empty bit) and, for some stubs, the
448    /// data register directly.
449    fn maybe_defer_debugger_poll(
450        &mut self,
451        register: Register,
452        len: usize,
453    ) -> Option<DeferredToken> {
454        let is_poll_read = matches!(register, Register::UARTFR | Register::UARTDR);
455        let rx_empty = self.state.rx_buffer.is_empty();
456
457        let dp = self.debugger_poll.as_mut()?;
458        if !is_poll_read {
459            return None;
460        }
461        // The deferred-read mechanism packs its result into a `u64` (see
462        // `DeferredRead::complete`), so it only supports accesses up to 8 bytes.
463        // Let any wider (guest-controlled) access take the normal synchronous
464        // read path rather than deferring and panicking on completion.
465        if len > size_of::<u64>() {
466            return None;
467        }
468        if !rx_empty {
469            // The guest is making progress; reset the streak.
470            dp.empty_streak = 0;
471            return None;
472        }
473        // Only one deferred read may be outstanding (the guest vCPU is blocked
474        // on it and cannot issue another).
475        if dp.pending.is_some() {
476            return None;
477        }
478        dp.empty_streak = dp.empty_streak.saturating_add(1);
479        if dp.empty_streak <= DEBUGGER_EMPTY_POLL_THRESHOLD {
480            return None;
481        }
482
483        let (deferred, token) = defer_read();
484        dp.pending = Some(PendingPollRead {
485            deferred,
486            register,
487            len,
488            deadline: Instant::now() + DEBUGGER_POLL_DELAY,
489        });
490        // Ensure `poll_device` runs to arm the timer and later complete the read.
491        if let Some(waker) = self.poll_waker.take() {
492            waker.wake();
493        }
494        Some(token)
495    }
496
497    /// Completes a deferred debugger-mode poll read once its delay has elapsed,
498    /// or immediately if RX data has arrived in the meantime (so debugger
499    /// latency is unaffected).
500    fn complete_debugger_poll(&mut self, cx: &mut Context<'_>) {
501        let Some((register, len, deadline)) = self
502            .debugger_poll
503            .as_ref()
504            .and_then(|dp| dp.pending.as_ref())
505            .map(|p| (p.register, p.len, p.deadline))
506        else {
507            return;
508        };
509
510        let data_ready = !self.state.rx_buffer.is_empty();
511        let timer_expired = if data_ready {
512            false
513        } else {
514            self.debugger_poll
515                .as_mut()
516                .unwrap()
517                .timer
518                .poll_until(cx, deadline)
519                .is_ready()
520        };
521
522        if !data_ready && !timer_expired {
523            return;
524        }
525
526        // Compute the value now, so a read that completes because data arrived
527        // reflects that data.
528        let val: u16 = match register {
529            Register::UARTFR => self.state.read_fr(),
530            Register::UARTDR => self.state.read_dr().into(),
531            _ => 0,
532        };
533        let dp = self.debugger_poll.as_mut().unwrap();
534        let pending = dp.pending.take().unwrap();
535        if data_ready {
536            dp.empty_streak = 0;
537        }
538        // Match the synchronous read path, which zero-fills `data` and then
539        // writes the (little-endian) register value into the low bytes, so
540        // wider-than-register accesses are handled the same way.
541        let mut bytes = [0u8; 8];
542        bytes[..2].copy_from_slice(&val.to_le_bytes());
543        pending.deferred.complete(&bytes[..len]);
544    }
545}
546
547impl ChangeDeviceState for SerialPl011 {
548    fn start(&mut self) {}
549
550    async fn stop(&mut self) {}
551
552    async fn reset(&mut self) {
553        self.state = State::new(self.io.is_connected());
554        self.sync();
555    }
556}
557
558impl ChipsetDevice for SerialPl011 {
559    fn supports_mmio(&mut self) -> Option<&mut dyn MmioIntercept> {
560        Some(self)
561    }
562
563    fn supports_poll_device(&mut self) -> Option<&mut dyn PollDevice> {
564        Some(self)
565    }
566}
567
568impl PollDevice for SerialPl011 {
569    fn poll_device(&mut self, cx: &mut Context<'_>) {
570        self.poll_waker = Some(cx.waker().clone());
571        let _ = self.poll_tx(cx);
572        let _ = self.poll_rx(cx);
573        self.complete_debugger_poll(cx);
574        self.sync();
575    }
576}
577
578impl State {
579    fn new(is_connected: bool) -> Self {
580        // The initial state for this UART does not completely match the PL011
581        // specification. This is because Linux loads its SBSA-compatible UART
582        // driver instead of its PL011 driver, and the SBSA-compatible driver
583        // expects the firmware to initialize the UART.
584        //
585        // We could look at enumerating this as a true PL011 instead, but
586        // 1. It's unclear how to do this with ACPI (it's trivial with
587        //    DeviceTree).
588        // 2. There may be a compatibility concern with changing the
589        //    enumeration.
590        // 3. This is not really a full PL011 emulator anyway, since it does not
591        //    support DMA.
592        //
593        // Instead, initialize the state as defined in the SBSA. Normally
594        // firmware would do this, but we do it here.
595
596        let cr = ControlRegister::new()
597            .with_enabled(true)
598            .with_rxe(true)
599            .with_txe(true);
600
601        let lcr = LineControlRegister::new().with_enable_fifos(true);
602
603        let mut this = Self {
604            tx_buffer: VecDeque::new(),
605            rx_buffer: VecDeque::new(),
606            rx_overrun: false,
607            connected: false,
608            ilpr: 0,
609            ibrd: 0,
610            fbrd: FractionalBaudRateRegister::new(),
611            lcr,
612            cr,
613            ifls: InterruptFifoLevelSelectRegister::new()
614                .with_txiflsel(FifoLevelSelect::BYTES_16.0)
615                .with_rxiflsel(FifoLevelSelect::BYTES_16.0),
616            imsc: InterruptRegister::new(),
617            ris: InterruptRegister::new(),
618            dmacr: DmaControlRegister::new(),
619            new_ibrd: 0,
620            new_fbrd: FractionalBaudRateRegister::new(),
621        };
622        if is_connected {
623            this.connect();
624        }
625        this
626    }
627
628    /// Updates CR when the modem connects.
629    fn connect(&mut self) {
630        if !self.connected {
631            self.connected = true;
632            // CTS/DCD/DSR changed.
633            self.ris.set_cts(true);
634            self.ris.set_dcd(true);
635            self.ris.set_dsr(true);
636        }
637    }
638
639    /// Updates CR when the modem disconnects.
640    fn disconnect(&mut self) {
641        if self.connected {
642            self.connected = false;
643            // CTS/DCD/DSR changed.
644            self.ris.set_cts(true);
645            self.ris.set_dcd(true);
646            self.ris.set_dsr(true);
647        }
648    }
649
650    fn tx_fifo_trigger(&self) -> usize {
651        if self.lcr.enable_fifos() {
652            match FifoLevelSelect(self.ifls.txiflsel()) {
653                FifoLevelSelect::BYTES_4 => 4,   // <= 1/8 full
654                FifoLevelSelect::BYTES_8 => 8,   // <= 1/4 full
655                FifoLevelSelect::BYTES_16 => 16, // <= 1/2 full
656                FifoLevelSelect::BYTES_24 => 24, // <= 3/4 full
657                FifoLevelSelect::BYTES_28 => 28, // <= 7/8 full
658                _ => 16,                         // reserved
659            }
660        } else {
661            0
662        }
663    }
664
665    fn rx_fifo_trigger(&self) -> usize {
666        if self.lcr.enable_fifos() {
667            match FifoLevelSelect(self.ifls.rxiflsel()) {
668                FifoLevelSelect::BYTES_4 => 4,   // <= 1/8 full
669                FifoLevelSelect::BYTES_8 => 8,   // <= 1/4 full
670                FifoLevelSelect::BYTES_16 => 16, // <= 1/2 full
671                FifoLevelSelect::BYTES_24 => 24, // <= 3/4 full
672                FifoLevelSelect::BYTES_28 => 28, // <= 7/8 full
673                _ => 16,                         // reserved
674            }
675        } else {
676            1
677        }
678    }
679
680    fn fifo_size(&self) -> usize {
681        if self.lcr.enable_fifos() {
682            FIFO_SIZE
683        } else {
684            1
685        }
686    }
687
688    /// Returns whether it is time to poll the backend device for more data.
689    fn should_poll_rx(&self, wait_for_rts: bool) -> bool {
690        // Only poll if not in loopback mode, since data comes from THR in that case.
691        if self.cr.loopback() {
692            return false;
693        }
694
695        // Only poll if the backend is connected.
696        if !self.connected {
697            return false;
698        }
699
700        // If requested, only poll if the OS is requesting data. Essentially
701        // this means the backend device implements hardware flow control.
702        //
703        // Without this, any data buffered into the serial port will be lost
704        // during boot when the FIFO is cleared.
705        if wait_for_rts && (!self.cr.dtr() || !self.cr.rts()) {
706            return false;
707        }
708
709        // Only poll if there is space in the buffer.
710        self.rx_buffer.len() < RX_BUFFER_MAX
711    }
712
713    fn pending_interrupt(&mut self) -> bool {
714        u16::from(self.ris) & u16::from(self.imsc) != 0
715    }
716
717    fn read_dr(&mut self) -> u8 {
718        if self.rx_buffer.is_empty() {
719            return 0;
720        }
721
722        let rx = self.rx_buffer.pop_front().unwrap_or(0);
723        if self.rx_buffer.len() < self.rx_fifo_trigger() {
724            self.ris.set_rx(false);
725        }
726        rx
727    }
728
729    fn write_dr(&mut self, stats: &mut SerialStats, data: u8) {
730        if self.cr.loopback() {
731            // Loopback mode wires UARTTXD to UARTRXD, so just add a byte
732            // to the fifo along with updating tx state.
733            if self.cr.enabled() && self.cr.txe() {
734                if self.cr.rxe() {
735                    if self.rx_buffer.len() >= TX_BUFFER_MAX {
736                        stats
737                            .rx_dropped
738                            .add((self.rx_buffer.len() - TX_BUFFER_MAX) as u64);
739                        self.rx_buffer.truncate(TX_BUFFER_MAX);
740                        self.rx_overrun = true;
741                        self.ris.set_oe(true);
742                    }
743
744                    self.rx_buffer.push_back(data);
745                    if self.rx_buffer.len() == self.rx_fifo_trigger() {
746                        self.ris.set_rx(true);
747                    }
748                }
749            }
750        } else {
751            if self.tx_buffer.len() >= TX_BUFFER_MAX {
752                // The FIFO is full. Real hardware drops the newest byte in the
753                // FIFO, not the oldest one.
754                tracing::debug!("tx fifo overrun, dropping output data");
755                stats
756                    .tx_dropped
757                    .add((self.tx_buffer.len() - (TX_BUFFER_MAX - 1)) as u64);
758                self.tx_buffer.truncate(TX_BUFFER_MAX - 1);
759            }
760            self.tx_buffer.push_back(data);
761
762            if self.tx_buffer.len() > self.tx_fifo_trigger() {
763                self.ris.set_tx(false);
764            }
765        }
766    }
767
768    fn write_fbrd(&mut self, data: u8) {
769        self.new_fbrd = FractionalBaudRateRegister::from(data).clear_reserved();
770    }
771
772    fn write_lcrh(&mut self, stats: &mut SerialStats, data: u8) {
773        // This register should not be written to when the UART is enabled.
774        if self.cr.enabled() {
775            return;
776        }
777
778        if self.new_ibrd != self.ibrd || u8::from(self.new_fbrd) != u8::from(self.fbrd) {
779            self.ibrd = self.new_ibrd;
780            self.fbrd = self.new_fbrd;
781        }
782
783        let lcr = LineControlRegister::from(data);
784        if self.lcr.enable_fifos() && !lcr.enable_fifos() {
785            // Fifo went from enabled -> disabled, clear all fifos and update status regs.
786            // Additionally, since this can only happen when the UART is disabled, there's no need to update interrupts.
787            stats.rx_dropped.add(self.rx_buffer.len() as u64);
788            self.rx_buffer.clear();
789
790            stats.tx_dropped.add(self.tx_buffer.len() as u64);
791            self.tx_buffer.clear();
792        }
793
794        self.lcr = lcr;
795    }
796
797    fn write_cr(&mut self, data: u16) {
798        self.cr = ControlRegister::from(data).clear_reserved();
799    }
800
801    fn write_ifls(&mut self, data: u16) {
802        self.ifls = InterruptFifoLevelSelectRegister::from(data).clear_reserved();
803    }
804
805    fn write_imsc(&mut self, data: u16) {
806        self.imsc = InterruptRegister::from(data).clear_reserved();
807    }
808
809    fn write_icr(&mut self, data: u16) {
810        self.ris = InterruptRegister::from(u16::from(self.ris) & !data);
811    }
812
813    fn write_dmacr(&mut self, data: u16) {
814        self.dmacr = DmaControlRegister::from(data).clear_reserved()
815    }
816
817    fn read_fr(&self) -> u16 {
818        let fifo_size = self.fifo_size();
819        let fr = spec::FlagRegister::new()
820            .with_cts(self.connected)
821            .with_dcd(self.connected)
822            .with_dsr(self.connected)
823            // This virtual UART has no shift register latency. Reporting BUSY
824            // while bytes are queued can deadlock earlycon users that spin on
825            // BUSY before the asynchronous backend poller gets scheduled.
826            .with_busy(false)
827            .with_rxfe(self.rx_buffer.is_empty())
828            .with_txff(self.tx_buffer.len() >= fifo_size)
829            .with_rxff(self.rx_buffer.len() >= fifo_size)
830            .with_txfe(self.tx_buffer.is_empty());
831
832        fr.into()
833    }
834}
835
836impl MmioIntercept for SerialPl011 {
837    fn mmio_read(&mut self, addr: u64, data: &mut [u8]) -> IoResult {
838        self.read(addr, data)
839    }
840
841    fn mmio_write(&mut self, addr: u64, data: &[u8]) -> IoResult {
842        self.write(addr, data)
843    }
844
845    fn get_static_regions(&mut self) -> &[(&str, RangeInclusive<u64>)] {
846        std::slice::from_ref(&self.mmio_region)
847    }
848}
849
850mod save_restore {
851    use crate::SerialPl011;
852    use crate::State;
853    use vmcore::save_restore::RestoreError;
854    use vmcore::save_restore::SaveError;
855    use vmcore::save_restore::SaveRestore;
856
857    mod state {
858        use mesh::payload::Protobuf;
859        use vmcore::save_restore::SavedStateRoot;
860
861        #[derive(Protobuf, SavedStateRoot)]
862        #[mesh(package = "serial.PL011")]
863        pub struct SavedState {
864            #[mesh(1)]
865            pub(super) tx_buffer: Vec<u8>,
866            #[mesh(2)]
867            pub(super) rx_buffer: Vec<u8>,
868            #[mesh(3)]
869            pub(super) rx_overrun: bool,
870            #[mesh(4)]
871            pub(super) connected: bool,
872            #[mesh(5)]
873            pub(super) ilpr: u8,
874            #[mesh(6)]
875            pub(super) ibrd: u16,
876            #[mesh(7)]
877            pub(super) fbrd: u8,
878            #[mesh(8)]
879            pub(super) lcr: u8,
880            #[mesh(9)]
881            pub(super) cr: u16,
882            #[mesh(10)]
883            pub(super) ifls: u16,
884            #[mesh(11)]
885            pub(super) imsc: u16,
886            #[mesh(12)]
887            pub(super) ris: u16,
888            #[mesh(13)]
889            pub(super) dmacr: u16,
890            #[mesh(14)]
891            pub(super) new_ibrd: u16,
892            #[mesh(15)]
893            pub(super) new_fbrd: u8,
894        }
895    }
896
897    impl SaveRestore for SerialPl011 {
898        type SavedState = state::SavedState;
899
900        fn save(&mut self) -> Result<Self::SavedState, SaveError> {
901            let State {
902                ref tx_buffer,
903                ref rx_buffer,
904                rx_overrun,
905                connected,
906                ilpr,
907                ibrd,
908                fbrd,
909                lcr,
910                cr,
911                ifls,
912                imsc,
913                ris,
914                dmacr,
915                new_ibrd,
916                new_fbrd,
917            } = self.state;
918            Ok(state::SavedState {
919                tx_buffer: tx_buffer.clone().into(),
920                rx_buffer: rx_buffer.clone().into(),
921                rx_overrun,
922                connected,
923                ilpr,
924                ibrd,
925                fbrd: fbrd.into(),
926                lcr: lcr.into(),
927                cr: cr.into(),
928                ifls: ifls.into(),
929                imsc: imsc.into(),
930                ris: ris.into(),
931                dmacr: dmacr.into(),
932                new_ibrd,
933                new_fbrd: new_fbrd.into(),
934            })
935        }
936
937        fn restore(&mut self, state: Self::SavedState) -> Result<(), RestoreError> {
938            let state::SavedState {
939                tx_buffer,
940                rx_buffer,
941                rx_overrun,
942                connected,
943                ilpr,
944                ibrd,
945                fbrd,
946                lcr,
947                cr,
948                ifls,
949                imsc,
950                ris,
951                dmacr,
952                new_ibrd,
953                new_fbrd,
954            } = state;
955            self.state = State {
956                tx_buffer: tx_buffer.into(),
957                rx_buffer: rx_buffer.into(),
958                rx_overrun,
959                connected,
960                ilpr,
961                ibrd,
962                fbrd: fbrd.into(),
963                lcr: lcr.into(),
964                cr: cr.into(),
965                ifls: ifls.into(),
966                imsc: imsc.into(),
967                ris: ris.into(),
968                dmacr: dmacr.into(),
969                new_ibrd,
970                new_fbrd: new_fbrd.into(),
971            };
972            if self.io.is_connected() {
973                self.state.connect();
974            } else {
975                self.state.disconnect();
976            }
977            self.sync();
978            Ok(())
979        }
980    }
981}
982
983#[cfg(test)]
984mod tests {
985    use super::*;
986    use chipset_device::io::IoError;
987    use chipset_device::io::IoResult;
988    use chipset_device::mmio::MmioIntercept;
989    use futures::AsyncRead;
990    use futures::AsyncWrite;
991    use inspect::InspectMut;
992    use pal_async::DefaultDriver;
993    use pal_async::async_test;
994    use parking_lot::Mutex;
995    use serial_core::SerialIo;
996    use serial_core::debugger::DebuggerRelay;
997    use std::collections::VecDeque;
998    use std::future::poll_fn;
999    use std::io;
1000    use std::pin::Pin;
1001    use std::sync::Arc;
1002    use std::task::Context;
1003    use std::task::Poll;
1004    use std::task::Waker;
1005    use test_with_tracing::test;
1006    use vmcore::line_interrupt::LineInterrupt;
1007
1008    const PL011_SERIAL0_BASE: u64 = 0xEFFEC000;
1009
1010    const UARTCR_TXE: u16 = 0x0100;
1011    const UARTCR_RXE: u16 = 0x0200;
1012    const UARTCR_UARTEN: u16 = 0x0001;
1013
1014    const UARTLCR_H_FIFO_ENABLE: u16 = 0x0010;
1015    const UARTLCR_H_8BITS: u16 = 0x0060;
1016    const UARTINT_TX: u16 = 0x0020;
1017
1018    // This is a "loopback" kind of io, where a write to the serial port will appear in the read queue
1019    #[derive(InspectMut)]
1020    pub struct SerialIoMock {
1021        data: Vec<u8>,
1022        #[inspect(skip)]
1023        write_error: Option<ErrorKind>,
1024    }
1025
1026    impl SerialIo for SerialIoMock {
1027        fn is_connected(&self) -> bool {
1028            true
1029        }
1030
1031        fn poll_connect(&mut self, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
1032            Poll::Ready(Ok(()))
1033        }
1034
1035        fn poll_disconnect(&mut self, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
1036            Poll::Ready(Ok(()))
1037        }
1038    }
1039
1040    impl AsyncRead for SerialIoMock {
1041        fn poll_read(
1042            mut self: Pin<&mut Self>,
1043            _cx: &mut Context<'_>,
1044            buf: &mut [u8],
1045        ) -> Poll<io::Result<usize>> {
1046            if self.data.is_empty() {
1047                return Poll::Ready(Err(ErrorKind::ConnectionAborted.into()));
1048            }
1049            let n = buf.len().min(self.data.len());
1050            for (s, d) in self.data.drain(..n).zip(buf) {
1051                *d = s;
1052            }
1053            Poll::Ready(Ok(n))
1054        }
1055    }
1056
1057    impl AsyncWrite for SerialIoMock {
1058        fn poll_write(
1059            mut self: Pin<&mut Self>,
1060            _cx: &mut Context<'_>,
1061            buf: &[u8],
1062        ) -> Poll<io::Result<usize>> {
1063            if let Some(error) = self.write_error.take() {
1064                return Poll::Ready(Err(error.into()));
1065            }
1066            let buf = &buf[..buf.len().min(FIFO_SIZE)];
1067            self.data.extend_from_slice(buf);
1068            Poll::Ready(Ok(buf.len()))
1069        }
1070
1071        fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
1072            Poll::Ready(Ok(()))
1073        }
1074
1075        fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
1076            Poll::Ready(Ok(()))
1077        }
1078    }
1079
1080    impl SerialIoMock {
1081        pub fn new() -> Self {
1082            Self {
1083                data: Vec::new(),
1084                write_error: None,
1085            }
1086        }
1087
1088        fn with_write_error(error: ErrorKind) -> Self {
1089            Self {
1090                data: Vec::new(),
1091                write_error: Some(error),
1092            }
1093        }
1094    }
1095
1096    #[test]
1097    fn test_read() {
1098        let serial_io = SerialIoMock::new();
1099        let mut serial = SerialPl011::new(
1100            "com1".to_string(),
1101            PL011_SERIAL0_BASE,
1102            LineInterrupt::detached(),
1103            Box::new(serial_io),
1104            None,
1105        )
1106        .unwrap();
1107
1108        let mut data = vec![0; 1];
1109        serial.mmio_read(0, &mut data).unwrap();
1110
1111        let mut data = vec![0; 2];
1112        serial.mmio_read(0, &mut data).unwrap();
1113
1114        let mut data = vec![0; 4];
1115        serial.mmio_read(0, &mut data).unwrap();
1116
1117        assert!(matches!(
1118            serial.mmio_read(1, &mut data),
1119            IoResult::Err(IoError::UnalignedAccess)
1120        ));
1121        assert!(matches!(
1122            serial.mmio_read(2, &mut data),
1123            IoResult::Err(IoError::UnalignedAccess)
1124        ));
1125        assert!(matches!(
1126            serial.mmio_read(3, &mut data),
1127            IoResult::Err(IoError::UnalignedAccess)
1128        ));
1129
1130        serial
1131            .mmio_read(Register::UARTDR.0 as u64, &mut data)
1132            .unwrap();
1133        serial
1134            .mmio_read(Register::UARTRSR.0 as u64, &mut data)
1135            .unwrap();
1136        serial
1137            .mmio_read(Register::UARTECR.0 as u64, &mut data)
1138            .unwrap();
1139        serial
1140            .mmio_read(Register::UARTFR.0 as u64, &mut data)
1141            .unwrap();
1142        serial
1143            .mmio_read(Register::UARTILPR.0 as u64, &mut data)
1144            .unwrap();
1145        serial
1146            .mmio_read(Register::UARTIBRD.0 as u64, &mut data)
1147            .unwrap();
1148        serial
1149            .mmio_read(Register::UARTFBRD.0 as u64, &mut data)
1150            .unwrap();
1151        serial
1152            .mmio_read(Register::UARTLCR_H.0 as u64, &mut data)
1153            .unwrap();
1154        serial
1155            .mmio_read(Register::UARTCR.0 as u64, &mut data)
1156            .unwrap();
1157        serial
1158            .mmio_read(Register::UARTIFLS.0 as u64, &mut data)
1159            .unwrap();
1160        serial
1161            .mmio_read(Register::UARTIMSC.0 as u64, &mut data)
1162            .unwrap();
1163        serial
1164            .mmio_read(Register::UARTRIS.0 as u64, &mut data)
1165            .unwrap();
1166        serial
1167            .mmio_read(Register::UARTMIS.0 as u64, &mut data)
1168            .unwrap();
1169        assert!(matches!(
1170            serial.mmio_read(Register::UARTICR.0 as u64, &mut data),
1171            IoResult::Err(IoError::InvalidRegister)
1172        ));
1173        serial
1174            .mmio_read(Register::UARTDMACR.0 as u64, &mut data)
1175            .unwrap();
1176
1177        serial
1178            .mmio_read(Register::UARTPERIPHID0.0 as u64, &mut data)
1179            .unwrap();
1180        serial
1181            .mmio_read(Register::UARTPERIPHID1.0 as u64, &mut data)
1182            .unwrap();
1183        serial
1184            .mmio_read(Register::UARTPERIPHID2.0 as u64, &mut data)
1185            .unwrap();
1186        serial
1187            .mmio_read(Register::UARTPERIPHID3.0 as u64, &mut data)
1188            .unwrap();
1189        serial
1190            .mmio_read(Register::UARTPCELLID0.0 as u64, &mut data)
1191            .unwrap();
1192        serial
1193            .mmio_read(Register::UARTPCELLID1.0 as u64, &mut data)
1194            .unwrap();
1195        serial
1196            .mmio_read(Register::UARTPCELLID2.0 as u64, &mut data)
1197            .unwrap();
1198        serial
1199            .mmio_read(Register::UARTPCELLID3.0 as u64, &mut data)
1200            .unwrap();
1201    }
1202
1203    #[test]
1204    fn test_write() {
1205        let serial_io = SerialIoMock::new();
1206        let mut serial = SerialPl011::new(
1207            "com1".to_string(),
1208            PL011_SERIAL0_BASE,
1209            LineInterrupt::detached(),
1210            Box::new(serial_io),
1211            None,
1212        )
1213        .unwrap();
1214
1215        let data = vec![0; 1];
1216        assert!(matches!(
1217            serial.mmio_write(Register::UARTIBRD.0.into(), &data),
1218            IoResult::Err(IoError::InvalidAccessSize)
1219        ));
1220
1221        let data = vec![0; 2];
1222        serial.mmio_write(0, &data).unwrap();
1223
1224        let data = vec![0; 3];
1225        serial.mmio_write(0, &data).unwrap();
1226
1227        let data = vec![0; 4];
1228        serial.mmio_write(0, &data).unwrap();
1229
1230        let data = vec![0; 5];
1231        serial.mmio_write(0, &data).unwrap();
1232
1233        assert!(matches!(
1234            serial.mmio_write(1, &data),
1235            IoResult::Err(IoError::UnalignedAccess)
1236        ));
1237        assert!(matches!(
1238            serial.mmio_write(2, &data),
1239            IoResult::Err(IoError::UnalignedAccess)
1240        ));
1241        assert!(matches!(
1242            serial.mmio_write(3, &data),
1243            IoResult::Err(IoError::UnalignedAccess)
1244        ));
1245
1246        serial.mmio_write(Register::UARTDR.0 as u64, &data).unwrap();
1247        serial
1248            .mmio_write(Register::UARTRSR.0 as u64, &data)
1249            .unwrap();
1250        serial
1251            .mmio_write(Register::UARTECR.0 as u64, &data)
1252            .unwrap();
1253        assert!(matches!(
1254            serial.mmio_write(Register::UARTFR.0 as u64, &data),
1255            IoResult::Err(IoError::InvalidRegister)
1256        ));
1257        serial
1258            .mmio_write(Register::UARTILPR.0 as u64, &data)
1259            .unwrap();
1260        serial
1261            .mmio_write(Register::UARTIBRD.0 as u64, &data)
1262            .unwrap();
1263        serial
1264            .mmio_write(Register::UARTFBRD.0 as u64, &data)
1265            .unwrap();
1266        serial
1267            .mmio_write(Register::UARTLCR_H.0 as u64, &data)
1268            .unwrap();
1269        serial.mmio_write(Register::UARTCR.0 as u64, &data).unwrap();
1270        serial
1271            .mmio_write(Register::UARTIFLS.0 as u64, &data)
1272            .unwrap();
1273        serial
1274            .mmio_write(Register::UARTIMSC.0 as u64, &data)
1275            .unwrap();
1276        assert!(matches!(
1277            serial.mmio_write(Register::UARTRIS.0 as u64, &data),
1278            IoResult::Err(IoError::InvalidRegister)
1279        ));
1280        assert!(matches!(
1281            serial.mmio_write(Register::UARTMIS.0 as u64, &data),
1282            IoResult::Err(IoError::InvalidRegister)
1283        ));
1284        serial
1285            .mmio_write(Register::UARTICR.0 as u64, &data)
1286            .unwrap();
1287        serial
1288            .mmio_write(Register::UARTDMACR.0 as u64, &data)
1289            .unwrap();
1290
1291        assert!(matches!(
1292            serial.mmio_write(Register::UARTPERIPHID0.0 as u64, &data),
1293            IoResult::Err(IoError::InvalidRegister)
1294        ));
1295        assert!(matches!(
1296            serial.mmio_write(Register::UARTPERIPHID1.0 as u64, &data),
1297            IoResult::Err(IoError::InvalidRegister)
1298        ));
1299        assert!(matches!(
1300            serial.mmio_write(Register::UARTPERIPHID2.0 as u64, &data),
1301            IoResult::Err(IoError::InvalidRegister)
1302        ));
1303        assert!(matches!(
1304            serial.mmio_write(Register::UARTPERIPHID3.0 as u64, &data),
1305            IoResult::Err(IoError::InvalidRegister)
1306        ));
1307        assert!(matches!(
1308            serial.mmio_write(Register::UARTPCELLID0.0 as u64, &data),
1309            IoResult::Err(IoError::InvalidRegister)
1310        ));
1311        assert!(matches!(
1312            serial.mmio_write(Register::UARTPCELLID1.0 as u64, &data),
1313            IoResult::Err(IoError::InvalidRegister)
1314        ));
1315        assert!(matches!(
1316            serial.mmio_write(Register::UARTPCELLID2.0 as u64, &data),
1317            IoResult::Err(IoError::InvalidRegister)
1318        ));
1319        assert!(matches!(
1320            serial.mmio_write(Register::UARTPCELLID3.0 as u64, &data),
1321            IoResult::Err(IoError::InvalidRegister)
1322        ));
1323    }
1324
1325    fn read(serial: &mut SerialPl011, r: Register) -> u16 {
1326        let mut data = vec![0; 2];
1327        serial.mmio_read(r.0 as u64, &mut data).unwrap();
1328        u16::from_ne_bytes(data[..2].try_into().unwrap())
1329    }
1330
1331    fn write(serial: &mut SerialPl011, r: Register, val: u16) {
1332        let mut data = vec![0; 2];
1333        data[..2].copy_from_slice(&val.to_ne_bytes());
1334        serial.mmio_write(r.0 as u64, &data).unwrap();
1335    }
1336
1337    #[test]
1338    fn test_init() {
1339        let serial_io = SerialIoMock::new();
1340        let mut serial = SerialPl011::new(
1341            "com1".to_string(),
1342            PL011_SERIAL0_BASE,
1343            LineInterrupt::detached(),
1344            Box::new(serial_io),
1345            None,
1346        )
1347        .unwrap();
1348
1349        assert_eq!(read(&mut serial, Register::UARTPERIPHID0), UARTPERIPH_ID[0]);
1350        assert_eq!(read(&mut serial, Register::UARTPERIPHID1), UARTPERIPH_ID[1]);
1351        assert_eq!(read(&mut serial, Register::UARTPERIPHID2), UARTPERIPH_ID[2]);
1352        assert_eq!(read(&mut serial, Register::UARTPERIPHID3), UARTPERIPH_ID[3]);
1353        assert_eq!(read(&mut serial, Register::UARTPCELLID0), UARTPCELL_ID[0]);
1354        assert_eq!(read(&mut serial, Register::UARTPCELLID1), UARTPCELL_ID[1]);
1355        assert_eq!(read(&mut serial, Register::UARTPCELLID2), UARTPCELL_ID[2]);
1356        assert_eq!(read(&mut serial, Register::UARTPCELLID3), UARTPCELL_ID[3]);
1357
1358        // Mask interrupts
1359        write(&mut serial, Register::UARTIMSC, 0);
1360        // Disable interrupts (lower 11 bits)
1361        write(&mut serial, Register::UARTICR, 0x7ff);
1362        // Disable DMA on Rx and Tx
1363        write(&mut serial, Register::UARTDMACR, 0x0);
1364
1365        // Leave Rx and Tx enabled to drain FIFOs, wait a bit,
1366        // and then disable Rx, Tx, and UART.
1367        write(&mut serial, Register::UARTCR, UARTCR_RXE | UARTCR_TXE);
1368        read(&mut serial, Register::UARTCR);
1369        read(&mut serial, Register::UARTCR);
1370        write(&mut serial, Register::UARTCR, 0x0000);
1371
1372        // Set integer and fractinal parts of the baud rate,
1373        // hardcoded for now
1374        write(&mut serial, Register::UARTFBRD, 0x0004);
1375        write(&mut serial, Register::UARTIBRD, 0x0027);
1376        // The UARTLCR_H, UARTIBRD, and UARTFBRD registers form the single 30-bit
1377        // wide UARTLCR Register that is updated on a single write strobe generated by a
1378        // UARTLCR_H write
1379        write(
1380            &mut serial,
1381            Register::UARTLCR_H,
1382            UARTLCR_H_FIFO_ENABLE | UARTLCR_H_8BITS,
1383        );
1384
1385        // Enable Tx and Rx, wait a bit, and then enable UART
1386        write(&mut serial, Register::UARTCR, UARTCR_RXE | UARTCR_TXE);
1387        read(&mut serial, Register::UARTCR);
1388        read(&mut serial, Register::UARTCR);
1389        write(
1390            &mut serial,
1391            Register::UARTCR,
1392            UARTCR_RXE | UARTCR_TXE | UARTCR_UARTEN,
1393        );
1394    }
1395
1396    #[async_test]
1397    async fn test_writeread_data() {
1398        let serial_io = SerialIoMock::new();
1399        let mut serial = SerialPl011::new(
1400            "com1".to_string(),
1401            PL011_SERIAL0_BASE,
1402            LineInterrupt::detached(),
1403            Box::new(serial_io),
1404            None,
1405        )
1406        .unwrap();
1407
1408        write(&mut serial, Register::UARTCR, 0x400 | 0x800); // UARTCR_DTR | UARTCR_RTS
1409
1410        for n in 1..FIFO_SIZE as u16 {
1411            write(&mut serial, Register::UARTDR, n);
1412        }
1413
1414        poll_fn(|cx| {
1415            serial.poll_device(cx);
1416            std::task::Poll::Ready(())
1417        })
1418        .await;
1419
1420        for n in FIFO_SIZE as u16..1 {
1421            assert_eq!(read(&mut serial, Register::UARTDR), n);
1422        }
1423    }
1424
1425    #[test]
1426    fn tx_interrupt_asserts_after_short_fifo_drain() {
1427        let serial_io = SerialIoMock::new();
1428        let mut serial = SerialPl011::new(
1429            "com1".to_string(),
1430            PL011_SERIAL0_BASE,
1431            LineInterrupt::detached(),
1432            Box::new(serial_io),
1433            None,
1434        )
1435        .unwrap();
1436
1437        // FreeBSD enables the TX interrupt, clears stale status, writes a
1438        // short batch, and waits for TX-idle before submitting more. With a
1439        // fast backend, that batch can drain without ever exceeding the FIFO
1440        // trigger level.
1441        write(&mut serial, Register::UARTIMSC, UARTINT_TX);
1442        write(&mut serial, Register::UARTICR, 0x7ff);
1443        write(&mut serial, Register::UARTDR, b'x'.into());
1444
1445        serial.poll_device(&mut Context::from_waker(Waker::noop()));
1446
1447        assert!(serial.state.tx_buffer.is_empty());
1448        assert_ne!(read(&mut serial, Register::UARTMIS) & UARTINT_TX, 0);
1449    }
1450
1451    #[test]
1452    fn tx_interrupt_asserts_after_broken_pipe_drain() {
1453        let serial_io = SerialIoMock::with_write_error(ErrorKind::BrokenPipe);
1454        let mut serial = SerialPl011::new(
1455            "com1".to_string(),
1456            PL011_SERIAL0_BASE,
1457            LineInterrupt::detached(),
1458            Box::new(serial_io),
1459            None,
1460        )
1461        .unwrap();
1462
1463        write(&mut serial, Register::UARTIMSC, UARTINT_TX);
1464        write(&mut serial, Register::UARTICR, 0x7ff);
1465        write(&mut serial, Register::UARTDR, b'x'.into());
1466
1467        serial.poll_device(&mut Context::from_waker(Waker::noop()));
1468
1469        assert!(serial.state.tx_buffer.is_empty());
1470        assert_ne!(read(&mut serial, Register::UARTMIS) & UARTINT_TX, 0);
1471    }
1472
1473    #[test]
1474    fn test_write_ifls() {
1475        let serial_io = SerialIoMock::new();
1476        let mut serial = SerialPl011::new(
1477            "com1".to_string(),
1478            PL011_SERIAL0_BASE,
1479            LineInterrupt::detached(),
1480            Box::new(serial_io),
1481            None,
1482        )
1483        .unwrap();
1484
1485        write(&mut serial, Register::UARTIFLS, 0b000000);
1486        assert_eq!(u16::from(serial.state.ifls), 0b000000);
1487
1488        write(&mut serial, Register::UARTIFLS, 0b001001);
1489        assert_eq!(u16::from(serial.state.ifls), 0b001001);
1490
1491        write(&mut serial, Register::UARTIFLS, 0b100100);
1492        assert_eq!(u16::from(serial.state.ifls), 0b100100);
1493
1494        write(&mut serial, Register::UARTIFLS, 0b11001001);
1495        assert_eq!(u16::from(serial.state.ifls), 0b001001); // Drop extra bits
1496    }
1497
1498    #[test]
1499    fn test_write_icr() {
1500        let serial_io = SerialIoMock::new();
1501        let mut serial = SerialPl011::new(
1502            "com1".to_string(),
1503            PL011_SERIAL0_BASE,
1504            LineInterrupt::detached(),
1505            Box::new(serial_io),
1506            None,
1507        )
1508        .unwrap();
1509
1510        serial.state.ris = InterruptRegister::from(0b11111111111).clear_reserved();
1511        write(&mut serial, Register::UARTICR, 0b00000000000);
1512        assert_eq!(u16::from(serial.state.ris), 0b11110111111);
1513
1514        serial.state.ris = InterruptRegister::from(0b11111111111).clear_reserved();
1515        write(&mut serial, Register::UARTICR, 0b100000000000); // extra bit
1516        assert_eq!(u16::from(serial.state.ris), 0b11110111111);
1517
1518        serial.state.ris = InterruptRegister::from(0b11111111111).clear_reserved();
1519        write(&mut serial, Register::UARTICR, 0b11111111111);
1520        assert_eq!(u16::from(serial.state.ris), 0b00000000000);
1521
1522        serial.state.ris = InterruptRegister::from(0b11111111111).clear_reserved();
1523        write(&mut serial, Register::UARTICR, 0b111111111111); // extra bit
1524        assert_eq!(u16::from(serial.state.ris), 0b00000000000);
1525
1526        serial.state.ris = InterruptRegister::from(0b11111111111).clear_reserved();
1527        write(&mut serial, Register::UARTICR, 0b01111011110);
1528        assert_eq!(u16::from(serial.state.ris), 0b10000100001);
1529    }
1530
1531    struct DebuggerBackend {
1532        state: Arc<Mutex<DebuggerBackendState>>,
1533    }
1534
1535    #[derive(Clone)]
1536    struct DebuggerBackendHandle {
1537        state: Arc<Mutex<DebuggerBackendState>>,
1538    }
1539
1540    struct DebuggerBackendState {
1541        rx: VecDeque<u8>,
1542        written: Vec<u8>,
1543        write_stalled: bool,
1544        read_waker: Option<Waker>,
1545        write_waker: Option<Waker>,
1546        wait_waker: Option<Waker>,
1547    }
1548
1549    impl DebuggerBackend {
1550        fn new() -> (Self, DebuggerBackendHandle) {
1551            let state = Arc::new(Mutex::new(DebuggerBackendState {
1552                rx: VecDeque::new(),
1553                written: Vec::new(),
1554                write_stalled: false,
1555                read_waker: None,
1556                write_waker: None,
1557                wait_waker: None,
1558            }));
1559            (
1560                Self {
1561                    state: state.clone(),
1562                },
1563                DebuggerBackendHandle { state },
1564            )
1565        }
1566    }
1567
1568    impl InspectMut for DebuggerBackend {
1569        fn inspect_mut(&mut self, req: inspect::Request<'_>) {
1570            req.ignore();
1571        }
1572    }
1573
1574    impl SerialIo for DebuggerBackend {
1575        fn is_connected(&self) -> bool {
1576            true
1577        }
1578
1579        fn poll_connect(&mut self, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
1580            Poll::Ready(Ok(()))
1581        }
1582
1583        fn poll_disconnect(&mut self, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
1584            Poll::Pending
1585        }
1586    }
1587
1588    impl AsyncRead for DebuggerBackend {
1589        fn poll_read(
1590            self: Pin<&mut Self>,
1591            cx: &mut Context<'_>,
1592            buf: &mut [u8],
1593        ) -> Poll<io::Result<usize>> {
1594            let mut state = self.state.lock();
1595            if state.rx.is_empty() {
1596                state.read_waker = Some(cx.waker().clone());
1597                return Poll::Pending;
1598            }
1599
1600            let n = buf.len().min(state.rx.len());
1601            for (dst, src) in buf.iter_mut().zip(state.rx.drain(..n)) {
1602                *dst = src;
1603            }
1604            if let Some(waker) = state.wait_waker.take() {
1605                waker.wake();
1606            }
1607            Poll::Ready(Ok(n))
1608        }
1609    }
1610
1611    impl AsyncWrite for DebuggerBackend {
1612        fn poll_write(
1613            self: Pin<&mut Self>,
1614            cx: &mut Context<'_>,
1615            buf: &[u8],
1616        ) -> Poll<io::Result<usize>> {
1617            let mut state = self.state.lock();
1618            if state.write_stalled {
1619                state.write_waker = Some(cx.waker().clone());
1620                return Poll::Pending;
1621            }
1622
1623            state.written.extend_from_slice(buf);
1624            if let Some(waker) = state.wait_waker.take() {
1625                waker.wake();
1626            }
1627            Poll::Ready(Ok(buf.len()))
1628        }
1629
1630        fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
1631            Poll::Ready(Ok(()))
1632        }
1633
1634        fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
1635            Poll::Ready(Ok(()))
1636        }
1637    }
1638
1639    impl DebuggerBackendHandle {
1640        fn inject_rx(&self, data: &[u8]) {
1641            let mut state = self.state.lock();
1642            state.rx.extend(data);
1643            if let Some(waker) = state.read_waker.take() {
1644                waker.wake();
1645            }
1646            if let Some(waker) = state.wait_waker.take() {
1647                waker.wake();
1648            }
1649        }
1650
1651        fn set_write_stalled(&self, stalled: bool) {
1652            let mut state = self.state.lock();
1653            state.write_stalled = stalled;
1654            if let Some(waker) = state.write_waker.take() {
1655                waker.wake();
1656            }
1657        }
1658
1659        async fn wait_until(&self, mut predicate: impl FnMut(&DebuggerBackendState) -> bool) {
1660            poll_fn(|cx| {
1661                let mut state = self.state.lock();
1662                if predicate(&state) {
1663                    Poll::Ready(())
1664                } else {
1665                    state.wait_waker = Some(cx.waker().clone());
1666                    Poll::Pending
1667                }
1668            })
1669            .await
1670        }
1671    }
1672
1673    fn new_debugger_serial(driver: DefaultDriver, backend: DebuggerBackend) -> SerialPl011 {
1674        SerialPl011::new(
1675            "com1".to_string(),
1676            PL011_SERIAL0_BASE,
1677            LineInterrupt::detached(),
1678            Box::new(DebuggerRelay::new(driver, "com1", Box::new(backend))),
1679            None,
1680        )
1681        .unwrap()
1682    }
1683
1684    async fn poll_serial(serial: &mut SerialPl011) {
1685        poll_fn(|cx| {
1686            serial.poll_device(cx);
1687            Poll::Ready(())
1688        })
1689        .await
1690    }
1691
1692    /// Resetting the device must leave the modem lines matching the backend, so
1693    /// a port with no backend attached does not come back reporting carrier.
1694    #[async_test]
1695    async fn reset_does_not_connect_disconnected_backend() {
1696        let mut serial = SerialPl011::new(
1697            "com1".to_string(),
1698            PL011_SERIAL0_BASE,
1699            LineInterrupt::detached(),
1700            Box::new(serial_core::disconnected::Disconnected),
1701            None,
1702        )
1703        .unwrap();
1704
1705        serial.reset().await;
1706
1707        let fr = spec::FlagRegister::from(read(&mut serial, Register::UARTFR));
1708        assert!(!fr.cts() && !fr.dsr() && !fr.dcd(), "no carrier");
1709
1710        // And no modem-status change bits to raise an interrupt with.
1711        let ris = InterruptRegister::from(read(&mut serial, Register::UARTRIS));
1712        assert!(
1713            !ris.cts() && !ris.dsr() && !ris.dcd(),
1714            "no modem status change"
1715        );
1716    }
1717
1718    #[async_test]
1719    async fn debugger_relay_rx_does_not_report_overrun(driver: DefaultDriver) {
1720        let (backend, handle) = DebuggerBackend::new();
1721        let mut serial = new_debugger_serial(driver, backend);
1722        // Burst larger than the relay's RX ring so the relay must drop overflow.
1723        let burst: Vec<_> = (0..(20 * 1024)).map(|x| (x % 251) as u8).collect();
1724
1725        handle.inject_rx(&burst);
1726        // The relay's pump drains the whole burst independently of the guest.
1727        handle.wait_until(|state| state.rx.is_empty()).await;
1728
1729        // Drain everything the guest can see.
1730        let mut delivered = Vec::new();
1731        for _ in 0..1024 {
1732            poll_serial(&mut serial).await;
1733            let mut progressed = false;
1734            loop {
1735                let fr = read(&mut serial, Register::UARTFR);
1736                if fr & 0x0010 != 0 {
1737                    // RXFE set: receive FIFO empty.
1738                    break;
1739                }
1740                // Overrun must never be visible to the guest.
1741                let ris = read(&mut serial, Register::UARTRIS);
1742                assert_eq!(ris & 0x0400, 0, "debugger relay overflow must not set OE");
1743                delivered.push(read(&mut serial, Register::UARTDR) as u8);
1744                progressed = true;
1745            }
1746            if !progressed {
1747                break;
1748            }
1749        }
1750
1751        // The guest saw data, but strictly fewer bytes than were injected: the
1752        // relay dropped the overflow before it ever reached the emulator.
1753        assert!(!delivered.is_empty(), "guest should see data");
1754        assert!(
1755            delivered.len() < burst.len(),
1756            "relay must have dropped overflow bytes (got {} of {})",
1757            delivered.len(),
1758            burst.len()
1759        );
1760        // The delivered bytes are the earliest ones, in order (drop-newest).
1761        assert_eq!(delivered, burst[..delivered.len()]);
1762    }
1763
1764    #[async_test]
1765    async fn debugger_relay_tx_stalled_backend_reports_tx_empty(driver: DefaultDriver) {
1766        let (backend, handle) = DebuggerBackend::new();
1767        handle.set_write_stalled(true);
1768        let mut serial = new_debugger_serial(driver, backend);
1769
1770        for byte in b"windbg" {
1771            write(&mut serial, Register::UARTDR, (*byte).into());
1772        }
1773        poll_serial(&mut serial).await;
1774
1775        let fr = read(&mut serial, Register::UARTFR);
1776        assert_eq!(
1777            fr & 0x0008,
1778            0,
1779            "UART should not be busy with debugger relay"
1780        );
1781        assert_ne!(
1782            fr & 0x0080,
1783            0,
1784            "TX FIFO should be empty with debugger relay"
1785        );
1786    }
1787
1788    fn new_throttle_serial(driver: DefaultDriver, backend: DebuggerBackend) -> SerialPl011 {
1789        SerialPl011::new(
1790            "com1".to_string(),
1791            PL011_SERIAL0_BASE,
1792            LineInterrupt::detached(),
1793            Box::new(backend),
1794            Some(PolledTimer::new(&driver)),
1795        )
1796        .unwrap()
1797    }
1798
1799    /// Drives `poll_device` until the deferred read completes, returning the
1800    /// bytes delivered to the guest.
1801    async fn complete_deferred(
1802        serial: &mut SerialPl011,
1803        mut token: DeferredToken,
1804        len: usize,
1805    ) -> Vec<u8> {
1806        let mut buf = vec![0u8; len];
1807        poll_fn(|cx| {
1808            serial.poll_device(cx);
1809            token.poll_read(cx, &mut buf)
1810        })
1811        .await
1812        .unwrap();
1813        buf
1814    }
1815
1816    /// After the guest polls an empty RX FIFO enough times, a debugger-mode port
1817    /// defers the read (rather than completing it immediately), throttling the
1818    /// poll loop. The deferred intercept still completes with the correct value.
1819    #[async_test]
1820    async fn debugger_poll_throttle_defers_repeated_empty_polls(driver: DefaultDriver) {
1821        let (backend, _handle) = DebuggerBackend::new();
1822        let mut serial = new_throttle_serial(driver, backend);
1823
1824        // The first reads of the empty FIFO are answered immediately.
1825        for _ in 0..DEBUGGER_EMPTY_POLL_THRESHOLD {
1826            let fr = read(&mut serial, Register::UARTFR);
1827            assert_ne!(fr & 0x0010, 0, "RXFE should be set (FIFO empty)");
1828        }
1829
1830        // The next poll of the still-empty FIFO is throttled: the read is
1831        // deferred instead of answered synchronously.
1832        let mut data = vec![0u8; 2];
1833        let token = match serial.mmio_read(Register::UARTFR.0 as u64, &mut data) {
1834            IoResult::Defer(token) => token,
1835            other => panic!("expected deferred read, got {other:?}"),
1836        };
1837
1838        // But it still completes, with the (still empty) FR value.
1839        let out = complete_deferred(&mut serial, token, 2).await;
1840        let fr = u16::from_ne_bytes(out[..2].try_into().unwrap());
1841        assert_ne!(fr & 0x0010, 0, "RXFE should still be set");
1842    }
1843
1844    /// A guest-controlled read wider than the deferred-read mechanism supports
1845    /// (which packs its result into a `u64`) must not be deferred, even once the
1846    /// throttle threshold has been reached. Otherwise completing it would panic.
1847    #[async_test]
1848    async fn debugger_poll_throttle_ignores_oversized_reads(driver: DefaultDriver) {
1849        let (backend, _handle) = DebuggerBackend::new();
1850        let mut serial = new_throttle_serial(driver, backend);
1851
1852        // Reach the throttle threshold with normal 2-byte polls.
1853        for _ in 0..DEBUGGER_EMPTY_POLL_THRESHOLD {
1854            read(&mut serial, Register::UARTFR);
1855        }
1856
1857        // A wider-than-8-byte access is answered synchronously rather than
1858        // deferred, so it does not reach the u64-packed completion path.
1859        let mut data = vec![0u8; 16];
1860        match serial.mmio_read(Register::UARTFR.0 as u64, &mut data) {
1861            IoResult::Ok => {}
1862            other => panic!("expected synchronous read for oversized access, got {other:?}"),
1863        }
1864    }
1865
1866    /// A deferred debugger-mode poll completes early (without waiting out the
1867    /// full delay) as soon as real data arrives, so debugger latency is not hurt.
1868    #[async_test]
1869    async fn debugger_poll_throttle_completes_early_when_data_arrives(driver: DefaultDriver) {
1870        let (backend, handle) = DebuggerBackend::new();
1871        let mut serial = new_throttle_serial(driver, backend);
1872
1873        for _ in 0..DEBUGGER_EMPTY_POLL_THRESHOLD {
1874            read(&mut serial, Register::UARTFR);
1875        }
1876        let mut data = vec![0u8; 2];
1877        let token = match serial.mmio_read(Register::UARTFR.0 as u64, &mut data) {
1878            IoResult::Defer(token) => token,
1879            other => panic!("expected deferred read, got {other:?}"),
1880        };
1881
1882        // Data arrives while the poll is deferred.
1883        handle.inject_rx(b"K");
1884
1885        // The deferred FR read completes reporting data-ready (RXFE clear)...
1886        let out = complete_deferred(&mut serial, token, 2).await;
1887        let fr = u16::from_ne_bytes(out[..2].try_into().unwrap());
1888        assert_eq!(fr & 0x0010, 0, "RXFE should be clear: data ready");
1889        // ...and the byte is now readable by the guest.
1890        poll_serial(&mut serial).await;
1891        assert_eq!(read(&mut serial, Register::UARTDR) as u8, b'K');
1892    }
1893
1894    /// Without debugger mode (no throttle timer), reads are never deferred, no
1895    /// matter how many times the guest polls an empty FIFO.
1896    #[test]
1897    fn debugger_poll_throttle_disabled_without_debugger_mode() {
1898        let (backend, _handle) = DebuggerBackend::new();
1899        let mut serial = SerialPl011::new(
1900            "com1".to_string(),
1901            PL011_SERIAL0_BASE,
1902            LineInterrupt::detached(),
1903            Box::new(backend),
1904            None,
1905        )
1906        .unwrap();
1907
1908        for _ in 0..(DEBUGGER_EMPTY_POLL_THRESHOLD + 4) {
1909            let mut data = vec![0u8; 2];
1910            assert!(
1911                matches!(
1912                    serial.mmio_read(Register::UARTFR.0 as u64, &mut data),
1913                    IoResult::Ok
1914                ),
1915                "reads must never be deferred without debugger mode"
1916            );
1917        }
1918    }
1919}