1#![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#[derive(InspectMut)]
64pub struct SerialPl011 {
65 #[inspect(skip)]
67 debug_name: String,
68 #[inspect(skip)]
69 mmio_region: (&'static str, RangeInclusive<u64>),
70 wait_for_rts: bool,
75
76 interrupt: LineInterrupt,
78 #[inspect(mut)]
79 io: Box<dyn SerialIo>,
80
81 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
94struct DebuggerPollThrottle {
106 timer: PolledTimer,
107 empty_streak: u32,
110 pending: Option<PendingPollRead>,
112}
113
114struct PendingPollRead {
115 deferred: DeferredRead,
116 register: Register,
117 len: usize,
118 deadline: Instant,
119}
120
121const DEBUGGER_EMPTY_POLL_THRESHOLD: u32 = 8;
123const 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, ibrd: u16, fbrd: FractionalBaudRateRegister, lcr: LineControlRegister, cr: ControlRegister, ifls: InterruptFifoLevelSelectRegister, imsc: InterruptRegister, ris: InterruptRegister, dmacr: DmaControlRegister, new_ibrd: u16,
155 new_fbrd: FractionalBaudRateRegister,
156}
157
158const TX_BUFFER_MAX: usize = 256;
160const RX_BUFFER_MAX: usize = 256;
161
162#[derive(Debug, Error)]
164pub enum ConfigurationError {
165 #[error("unaligned base address: {0}")]
167 UnalignedBaseAddress(u64),
168 #[error("invalid register width: {0}")]
170 InvalidRegisterWidth(u8),
171}
172
173impl SerialPl011 {
174 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 fn sync(&mut self) {
212 if !self.state.tx_buffer.is_empty() {
214 if let Some(waker) = self.tx_waker.take() {
215 waker.wake();
216 }
217 }
218
219 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 self.state.ris.set_rt(!self.state.rx_buffer.is_empty());
236
237 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 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 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 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 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 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 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, 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 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 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 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 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 if len > size_of::<u64>() {
466 return None;
467 }
468 if !rx_empty {
469 dp.empty_streak = 0;
471 return None;
472 }
473 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 if let Some(waker) = self.poll_waker.take() {
492 waker.wake();
493 }
494 Some(token)
495 }
496
497 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 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 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 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 fn connect(&mut self) {
630 if !self.connected {
631 self.connected = true;
632 self.ris.set_cts(true);
634 self.ris.set_dcd(true);
635 self.ris.set_dsr(true);
636 }
637 }
638
639 fn disconnect(&mut self) {
641 if self.connected {
642 self.connected = false;
643 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, FifoLevelSelect::BYTES_8 => 8, FifoLevelSelect::BYTES_16 => 16, FifoLevelSelect::BYTES_24 => 24, FifoLevelSelect::BYTES_28 => 28, _ => 16, }
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, FifoLevelSelect::BYTES_8 => 8, FifoLevelSelect::BYTES_16 => 16, FifoLevelSelect::BYTES_24 => 24, FifoLevelSelect::BYTES_28 => 28, _ => 16, }
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 fn should_poll_rx(&self, wait_for_rts: bool) -> bool {
690 if self.cr.loopback() {
692 return false;
693 }
694
695 if !self.connected {
697 return false;
698 }
699
700 if wait_for_rts && (!self.cr.dtr() || !self.cr.rts()) {
706 return false;
707 }
708
709 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 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 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 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 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 .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 #[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 write(&mut serial, Register::UARTIMSC, 0);
1360 write(&mut serial, Register::UARTICR, 0x7ff);
1362 write(&mut serial, Register::UARTDMACR, 0x0);
1364
1365 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 write(&mut serial, Register::UARTFBRD, 0x0004);
1375 write(&mut serial, Register::UARTIBRD, 0x0027);
1376 write(
1380 &mut serial,
1381 Register::UARTLCR_H,
1382 UARTLCR_H_FIFO_ENABLE | UARTLCR_H_8BITS,
1383 );
1384
1385 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); 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 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); }
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); 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); 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 #[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 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 let burst: Vec<_> = (0..(20 * 1024)).map(|x| (x % 251) as u8).collect();
1724
1725 handle.inject_rx(&burst);
1726 handle.wait_until(|state| state.rx.is_empty()).await;
1728
1729 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 break;
1739 }
1740 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 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 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 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 #[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 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 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 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 #[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 for _ in 0..DEBUGGER_EMPTY_POLL_THRESHOLD {
1854 read(&mut serial, Register::UARTFR);
1855 }
1856
1857 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 #[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 handle.inject_rx(b"K");
1884
1885 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 poll_serial(&mut serial).await;
1891 assert_eq!(read(&mut serial, Register::UARTDR) as u8, b'K');
1892 }
1893
1894 #[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}