1mod registers;
9
10use bitflags::Flags;
11use rdif_serial::{
12 Config, ConfigError, DataBits, IRQ_RX_BATCH_CAPACITY, IrqRxBatch, Parity, RxErrorFlags, RxFlag,
13 RxSample, SerialEventSet, SerialIrqEvent, SerialIrqReport, SerialParts, SplitUart, StopBits,
14 UartEmergencyTx, UartInfo, UartIrq, UartPort,
15};
16use registers::*;
17
18use crate::{PollingUart, SerialDirection, SerialEvent, TransBytesError, TransferError};
19
20pub mod dw_apb;
21#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
22mod pio;
23pub mod rockchip_fiq;
24mod mmio;
26
27pub use dw_apb::*;
28pub use mmio::*;
29#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
30pub use pio::*;
31pub use rockchip_fiq::*;
32
33pub trait Kind: Clone + Send + Sync + 'static {
34 fn read_reg(&self, reg: u8) -> u8;
35 fn write_reg(&self, reg: u8, val: u8);
36 fn get_base(&self) -> usize;
37
38 fn ack_busy_detect(&self) {}
39
40 fn set_baudrate(&self, clock_freq: u32, baudrate: u32) -> Result<(), ConfigError> {
43 if baudrate == 0 || clock_freq == 0 {
44 return Err(ConfigError::InvalidBaudrate);
45 }
46
47 let divisor = clock_freq / (16 * baudrate);
48 if divisor == 0 || divisor > 0xFFFF {
49 return Err(ConfigError::InvalidBaudrate);
50 }
51
52 let lcr: LineControlFlags = self.read_flags(UART_LCR);
53 self.write_flags(UART_LCR, lcr | LineControlFlags::DIVISOR_LATCH_ACCESS);
54
55 self.write_reg(UART_DLL, (divisor & 0xFF) as u8);
56 self.write_reg(UART_DLH, ((divisor >> 8) & 0xFF) as u8);
57
58 self.write_flags(UART_LCR, lcr);
59
60 Ok(())
61 }
62
63 fn baudrate(&self, clock_freq: u32) -> u32 {
64 let lcr: LineControlFlags = self.read_flags(UART_LCR);
65 self.write_flags(UART_LCR, lcr | LineControlFlags::DIVISOR_LATCH_ACCESS);
66
67 let dll = self.read_reg(UART_DLL) as u16;
68 let dlh = self.read_reg(UART_DLH) as u16;
69
70 self.write_flags(UART_LCR, lcr);
71
72 let divisor = dll | (dlh << 8);
73
74 if divisor == 0 {
75 return 0;
76 }
77
78 clock_freq / (16 * divisor as u32)
79 }
80
81 fn init(&self) {
82 self.write_flags(UART_IER, InterruptEnableFlags::empty());
83 self.write_flags(
84 UART_FCR,
85 FifoControlFlags::ENABLE_FIFO
86 | FifoControlFlags::CLEAR_RECEIVER_FIFO
87 | FifoControlFlags::CLEAR_TRANSMITTER_FIFO
88 | FifoControlFlags::TRIGGER_1_BYTE,
89 );
90
91 let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
92 mcr.insert(
93 ModemControlFlags::DATA_TERMINAL_READY
94 | ModemControlFlags::REQUEST_TO_SEND
95 | ModemControlFlags::OUT_2,
96 );
97 self.write_flags(UART_MCR, mcr);
98 }
99
100 fn read_flags<F: Flags<Bits = u8>>(&self, reg: u8) -> F {
102 F::from_bits_retain(self.read_reg(reg))
103 }
104
105 fn write_flags<F: Flags<Bits = u8>>(&self, reg: u8, val: F) {
106 self.write_reg(reg, val.bits());
107 }
108}
109
110pub struct Ns16550<T: Kind> {
111 pub(crate) base: T,
112 pub(crate) clock_freq: u32,
113 pub(crate) saved_lsr: LineStatusFlags,
114}
115
116pub struct Ns16550Irq<T: Kind> {
118 base: T,
119 saved_lsr: LineStatusFlags,
120}
121
122pub struct Ns16550EmergencyTx<T: Kind> {
124 base: T,
125}
126
127impl<T: Kind> Ns16550EmergencyTx<T> {
128 fn mask_interrupts(&self) {
129 self.base
130 .write_flags(UART_IER, InterruptEnableFlags::empty());
131 let _: InterruptEnableFlags = self.base.read_flags(UART_IER);
133 }
134}
135
136impl<T: Kind> UartEmergencyTx for Ns16550EmergencyTx<T> {
137 unsafe fn mask_interrupts_unlocked(&self) {
138 self.mask_interrupts();
139 }
140
141 unsafe fn try_write_unlocked(&self, bytes: &[u8]) -> usize {
142 let mut written = 0;
143 for &byte in bytes.iter().take(UART_FIFO_SIZE as usize) {
144 let status: LineStatusFlags = self.base.read_flags(UART_LSR);
145 if !status.contains(LineStatusFlags::TRANSMITTER_HOLDING_EMPTY) {
146 break;
147 }
148 self.base.write_reg(UART_THR, byte);
149 written += 1;
150 }
151 written
152 }
153}
154
155impl<T: Kind> Ns16550Irq<T> {
156 fn next_event(&self) -> Option<SerialEventSet> {
157 let iir: InterruptIdentificationFlags = self.base.read_flags(UART_IIR);
158 if iir.bits() & (UART_IIR_ID | UART_IIR_NO_INT) == UART_IIR_BUSY {
159 return Some(SerialEventSet::BUSY_DETECT);
160 }
161 if iir.contains(InterruptIdentificationFlags::NO_INTERRUPT_PENDING) {
162 return None;
163 }
164
165 let interrupt_id = iir & InterruptIdentificationFlags::INTERRUPT_ID_MASK;
166 let event = if interrupt_id == InterruptIdentificationFlags::RECEIVER_LINE_STATUS {
167 SerialEventSet::RX_STATUS
168 } else if interrupt_id == InterruptIdentificationFlags::RECEIVED_DATA_AVAILABLE {
169 SerialEventSet::RX_DATA
170 } else if interrupt_id == InterruptIdentificationFlags::CHARACTER_TIMEOUT {
171 SerialEventSet::RX_TIMEOUT
172 } else if interrupt_id == InterruptIdentificationFlags::TRANSMITTER_HOLDING_EMPTY {
173 SerialEventSet::TX_SPACE
174 } else if interrupt_id == InterruptIdentificationFlags::MODEM_STATUS {
175 SerialEventSet::MODEM_STATUS
176 } else {
177 SerialEventSet::FAULT
178 };
179 Some(event)
180 }
181
182 fn ack_modem_status(&self) {
183 let _: ModemStatusFlags = self.base.read_flags(UART_MSR);
184 }
185
186 fn ack_busy_detect(&self) {
187 self.base.ack_busy_detect();
188 }
189
190 fn mask_sources(&self, events: SerialEventSet) {
191 let mut ier: InterruptEnableFlags = self.base.read_flags(UART_IER);
192 ier.remove(interrupt_enable_for_events(events));
193 self.base.write_flags(UART_IER, ier);
194 }
195}
196
197impl<T: Kind> UartIrq for Ns16550Irq<T> {
198 fn mask(&mut self, sources: SerialEventSet) {
199 self.mask_sources(sources);
200 }
201
202 fn handle(&mut self) -> Option<SerialIrqReport> {
203 const IRQ_PASS_BUDGET: usize = 32;
204
205 let mut event = SerialIrqEvent::default();
206 let mut rx = IrqRxBatch::new();
207 let mut rx_samples = 0;
208 let mut pass_budget_exhausted = false;
209 for pass in 0..IRQ_PASS_BUDGET {
210 let Some(current) = self.next_event() else {
211 break;
212 };
213 pass_budget_exhausted = pass + 1 == IRQ_PASS_BUDGET;
214 event.events |= current;
215 if current.intersects(SerialEventSet::RX) {
216 let before = rx_samples;
217 while rx_samples < IRQ_RX_BATCH_CAPACITY {
218 let Some(sample) = read_rx_sample(&self.base, &mut self.saved_lsr) else {
219 break;
220 };
221 event.rx_errors |= rx_errors_from_sample(sample);
222 rx.try_push(sample)
223 .expect("the fixed NS16550 IRQ loop cannot overflow its RX batch");
224 rx_samples += 1;
225 }
226 if rx_samples == IRQ_RX_BATCH_CAPACITY || rx_samples == before {
227 break;
228 }
229 }
230 if current.contains(SerialEventSet::MODEM_STATUS) {
231 self.ack_modem_status();
232 }
233 if current.contains(SerialEventSet::BUSY_DETECT) {
234 self.ack_busy_detect();
235 }
236 if current.contains(SerialEventSet::FAULT) {
237 self.base
238 .write_flags(UART_IER, InterruptEnableFlags::empty());
239 break;
240 }
241
242 let rearm = current & SerialEventSet::TX_SPACE;
243 if !rearm.is_empty() {
244 self.mask_sources(rearm);
245 event.rearm |= rearm;
246 }
247 }
248
249 let defer_rx = rx.len() == IRQ_RX_BATCH_CAPACITY
250 || event.rx_errors.contains(RxErrorFlags::OVERRUN)
251 || (pass_budget_exhausted && event.events.has_rx());
252 if defer_rx && !event.events.contains(SerialEventSet::FAULT) {
253 self.mask_sources(SerialEventSet::RX);
254 event.rearm |= SerialEventSet::RX;
255 }
256
257 (!event.events.is_empty()).then_some(SerialIrqReport::new(event, rx))
258 }
259}
260
261impl<T: Kind> UartPort for Ns16550<T> {
262 fn startup(&mut self, config: &Config) -> Result<(), ConfigError> {
263 let original_ier: InterruptEnableFlags = self.read_flags(UART_IER);
264 self.write_flags(UART_IER, InterruptEnableFlags::empty());
265 if let Err(error) = self.set_config(config) {
266 self.write_flags(UART_IER, original_ier);
270 return Err(error);
271 }
272 self.enable_fifo(true);
273
274 let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
275 mcr.insert(
276 ModemControlFlags::DATA_TERMINAL_READY
277 | ModemControlFlags::REQUEST_TO_SEND
278 | ModemControlFlags::OUT_2,
279 );
280 self.write_flags(UART_MCR, mcr);
281 self.saved_lsr = LineStatusFlags::empty();
282 Ok(())
283 }
284
285 fn shutdown(&mut self) {
286 self.close();
287 }
288
289 fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
290 if let Some(baudrate) = config.baudrate {
292 self.set_baudrate_internal(baudrate)?;
293 }
294
295 if let Some(data_bits) = config.data_bits {
297 self.set_data_bits_internal(data_bits)?;
298 }
299
300 if let Some(stop_bits) = config.stop_bits {
302 self.set_stop_bits_internal(stop_bits)?;
303 }
304
305 if let Some(parity) = config.parity {
307 self.set_parity_internal(parity)?;
308 }
309 Ok(())
310 }
311
312 fn read_rx(&mut self) -> Option<RxSample> {
313 Ns16550::read_rx(self)
314 }
315
316 fn discard_rx(&mut self) {
317 self.saved_lsr = LineStatusFlags::empty();
318 self.write_flags(
319 UART_FCR,
320 FifoControlFlags::ENABLE_FIFO
321 | FifoControlFlags::CLEAR_RECEIVER_FIFO
322 | FifoControlFlags::TRIGGER_8_BYTES,
323 );
324 }
325
326 fn write_tx(&mut self, bytes: &[u8]) -> usize {
327 self.try_write(bytes)
328 }
329
330 fn discard_tx(&mut self) -> bool {
331 self.write_flags(
332 UART_FCR,
333 FifoControlFlags::ENABLE_FIFO
334 | FifoControlFlags::CLEAR_TRANSMITTER_FIFO
335 | FifoControlFlags::TRIGGER_8_BYTES,
336 );
337 true
338 }
339
340 fn tx_idle(&mut self) -> bool {
341 let lsr: LineStatusFlags = self.read_flags(UART_LSR);
342 lsr.contains(
343 LineStatusFlags::TRANSMITTER_HOLDING_EMPTY | LineStatusFlags::TRANSMITTER_EMPTY,
344 )
345 }
346
347 fn mask(&mut self, sources: SerialEventSet) {
348 let mut ier: InterruptEnableFlags = self.read_flags(UART_IER);
349 ier.remove(interrupt_enable_for_events(sources));
350 self.write_flags(UART_IER, ier);
351 }
352
353 fn mask_all(&mut self) {
354 self.write_flags(UART_IER, InterruptEnableFlags::empty());
355 }
356
357 fn rearm(&mut self, sources: SerialEventSet) -> SerialEventSet {
358 let mut ier: InterruptEnableFlags = self.read_flags(UART_IER);
359 ier.insert(interrupt_enable_for_events(sources));
360 self.write_flags(UART_IER, ier);
361
362 let lsr = self.read_lsr_preserving();
363 let mut ready = SerialEventSet::empty();
364 if sources.intersects(SerialEventSet::RX)
365 && lsr.intersects(LineStatusFlags::DATA_READY | LineStatusFlags::ERROR_MASK)
366 {
367 ready |= if lsr.contains(LineStatusFlags::DATA_READY) {
368 SerialEventSet::RX_DATA
369 } else {
370 SerialEventSet::RX_STATUS
371 };
372 }
373 if sources.contains(SerialEventSet::TX_SPACE)
374 && lsr.contains(LineStatusFlags::TRANSMITTER_HOLDING_EMPTY)
375 {
376 ready |= SerialEventSet::TX_SPACE;
377 }
378 if !ready.is_empty() {
379 ier.remove(interrupt_enable_for_events(ready));
380 self.write_flags(UART_IER, ier);
381 }
382 ready
383 }
384}
385
386impl<T: Kind> SplitUart for Ns16550<T> {
387 type Control = Self;
388 type Irq = Ns16550Irq<T>;
389 type EmergencyTx = Ns16550EmergencyTx<T>;
390
391 fn runtime_info(&self) -> UartInfo {
392 UartInfo {
393 name: "NS16550 UART",
394 register_base: self.base.get_base(),
395 initial_baudrate: self.base.baudrate(self.clock_freq),
396 }
397 }
398
399 fn split(self) -> SerialParts<Self::Control, Self::Irq, Self::EmergencyTx> {
400 let irq = Ns16550Irq {
401 base: self.base.clone(),
402 saved_lsr: LineStatusFlags::empty(),
403 };
404 let emergency_tx = Ns16550EmergencyTx {
405 base: self.base.clone(),
406 };
407 SerialParts::new(self, irq, emergency_tx)
408 }
409}
410
411impl<T: Kind> PollingUart for Ns16550<T> {
412 fn poll_status(&mut self) -> SerialEvent {
413 Ns16550::poll_status(self)
414 }
415
416 fn write_byte(&mut self, byte: u8) {
417 Ns16550::write_byte(self, byte);
418 }
419
420 fn read_byte(&mut self, status: SerialEvent) -> Option<Result<u8, TransferError>> {
421 Ns16550::read_byte(self, status)
422 }
423}
424
425impl<T: Kind> Ns16550<T> {
426 fn read_flags<F: Flags<Bits = u8>>(&self, reg: u8) -> F {
428 F::from_bits_retain(self.base.read_reg(reg))
429 }
430
431 fn write_flags<F: Flags<Bits = u8>>(&mut self, reg: u8, val: F) {
432 self.base.write_reg(reg, val.bits());
433 }
434
435 pub fn pending(&mut self, direction: SerialDirection) -> bool {
436 let lsr = self.read_lsr_preserving();
437 match direction {
438 SerialDirection::Input => lsr.contains(LineStatusFlags::DATA_READY),
439 SerialDirection::Output => lsr.contains(LineStatusFlags::TRANSMITTER_HOLDING_EMPTY),
440 }
441 }
442
443 pub fn poll_status(&mut self) -> SerialEvent {
444 serial_event_from_lsr(self.read_lsr_preserving())
445 }
446
447 pub fn try_write(&mut self, bytes: &[u8]) -> usize {
448 let mut written = 0;
449 while written < bytes.len() {
450 let status = self.poll_status();
451 if !status.tx_ready() {
452 break;
453 }
454 self.write_byte(bytes[written]);
455 written += 1;
456 }
457 written
458 }
459
460 pub fn try_read(&mut self, bytes: &mut [u8]) -> Result<usize, TransBytesError> {
461 let mut read_count = 0;
462 let mut first_error = None;
463 for byte in bytes.iter_mut() {
464 let status = self.poll_status();
465 if !status.rx_ready() && !status.rx_error() {
466 break;
467 }
468 let result = self.read_byte(status);
469 match result {
470 Some(Ok(b)) => {
471 *byte = b;
472 read_count += 1;
473 }
474 Some(Err(TransferError::Overrun(b))) => {
475 *byte = b;
476 read_count += 1;
477 first_error.get_or_insert(TransferError::Overrun(b));
478 }
479 Some(Err(e)) => {
480 first_error.get_or_insert(e);
481 }
482 None => break,
483 }
484 }
485 if let Some(kind) = first_error {
486 Err(TransBytesError {
487 bytes_transferred: read_count,
488 kind,
489 })
490 } else {
491 Ok(read_count)
492 }
493 }
494
495 pub fn write_byte(&mut self, byte: u8) {
496 self.base.write_reg(UART_THR, byte);
497 }
498
499 pub fn read_rx(&mut self) -> Option<RxSample> {
500 read_rx_sample(&self.base, &mut self.saved_lsr)
501 }
502
503 fn read_lsr_preserving(&mut self) -> LineStatusFlags {
504 let lsr: LineStatusFlags = self.read_flags(UART_LSR);
505 self.saved_lsr
506 .insert(lsr & (LineStatusFlags::ERROR_MASK | LineStatusFlags::FIFO_ERROR));
507 lsr | self.saved_lsr
508 }
509
510 pub fn read_byte(&mut self, status: SerialEvent) -> Option<Result<u8, TransferError>> {
511 if !status.rx_ready() && !status.rx_error() {
512 return None;
513 }
514 if self.saved_lsr.contains(LineStatusFlags::OVERRUN_ERROR) {
515 let b = self.base.read_reg(UART_RBR);
516 self.saved_lsr.remove(LineStatusFlags::OVERRUN_ERROR);
517 return Some(Err(TransferError::Overrun(b)));
518 }
519 if self.saved_lsr.contains(LineStatusFlags::PARITY_ERROR) {
520 let _ = self.base.read_reg(UART_RBR);
521 self.saved_lsr.remove(LineStatusFlags::PARITY_ERROR);
522 return Some(Err(TransferError::Parity));
523 }
524 if self.saved_lsr.contains(LineStatusFlags::FRAMING_ERROR) {
525 let _ = self.base.read_reg(UART_RBR);
526 self.saved_lsr.remove(LineStatusFlags::FRAMING_ERROR);
527 return Some(Err(TransferError::Framing));
528 }
529 if self.saved_lsr.contains(LineStatusFlags::BREAK_INTERRUPT) {
530 let _ = self.base.read_reg(UART_RBR);
531 self.saved_lsr.remove(LineStatusFlags::BREAK_INTERRUPT);
532 return Some(Err(TransferError::Break));
533 }
534 if status.rx_ready() {
535 return Some(Ok(self.base.read_reg(UART_RBR)));
536 }
537 None
538 }
539
540 pub fn open(&mut self) {
541 self.init_core();
542 }
543
544 pub fn close(&mut self) {
545 self.write_flags(UART_IER, InterruptEnableFlags::empty());
546
547 let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
548 mcr.remove(ModemControlFlags::DATA_TERMINAL_READY | ModemControlFlags::REQUEST_TO_SEND);
549 self.write_flags(UART_MCR, mcr);
550 }
551
552 pub fn set_irq_mask(&mut self, events: SerialEventSet) {
553 self.write_flags(UART_IER, interrupt_enable_for_events(events));
554 }
555
556 pub fn get_irq_mask(&self) -> SerialEventSet {
557 let ier: InterruptEnableFlags = self.read_flags(UART_IER);
558 let mut events = SerialEventSet::empty();
559
560 if ier.contains(InterruptEnableFlags::RECEIVED_DATA_AVAILABLE) {
561 events |= SerialEventSet::RX_DATA;
562 }
563 if ier.contains(InterruptEnableFlags::RECEIVER_LINE_STATUS) {
564 events |= SerialEventSet::RX_STATUS;
565 }
566 if ier.contains(InterruptEnableFlags::TRANSMITTER_HOLDING_EMPTY) {
567 events |= SerialEventSet::TX_SPACE;
568 }
569
570 events
571 }
572
573 pub fn is_16550_plus(&self) -> bool {
575 let fifo: InterruptIdentificationFlags = self.read_flags(UART_IIR);
578 fifo.contains(InterruptIdentificationFlags::FIFO_ENABLE_MASK)
579 }
580
581 fn set_baudrate_internal(&mut self, baudrate: u32) -> Result<(), ConfigError> {
583 self.base.set_baudrate(self.clock_freq, baudrate)
584 }
585
586 fn set_data_bits_internal(&mut self, bits: DataBits) -> Result<(), ConfigError> {
588 let wlen = match bits {
589 DataBits::Five => LineControlFlags::WORD_LENGTH_5,
590 DataBits::Six => LineControlFlags::WORD_LENGTH_6,
591 DataBits::Seven => LineControlFlags::WORD_LENGTH_7,
592 DataBits::Eight => LineControlFlags::WORD_LENGTH_8,
593 };
594
595 let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
596 lcr.remove(LineControlFlags::WORD_LENGTH_MASK);
598 lcr.insert(wlen);
599 self.write_flags(UART_LCR, lcr);
600
601 Ok(())
602 }
603
604 fn set_stop_bits_internal(&mut self, bits: StopBits) -> Result<(), ConfigError> {
606 let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
607 match bits {
608 StopBits::One => lcr.remove(LineControlFlags::STOP_BITS),
609 StopBits::Two => lcr.insert(LineControlFlags::STOP_BITS),
610 }
611 self.write_flags(UART_LCR, lcr);
612 Ok(())
613 }
614
615 fn set_parity_internal(&mut self, parity: Parity) -> Result<(), ConfigError> {
617 let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
618
619 lcr.remove(
621 LineControlFlags::PARITY_ENABLE
622 | LineControlFlags::EVEN_PARITY
623 | LineControlFlags::STICK_PARITY,
624 );
625
626 match parity {
628 Parity::None => {
629 }
631 Parity::Odd => {
632 lcr.insert(LineControlFlags::PARITY_ENABLE);
633 }
634 Parity::Even => {
635 lcr.insert(LineControlFlags::PARITY_ENABLE | LineControlFlags::EVEN_PARITY);
636 }
637 Parity::Mark => {
638 lcr.insert(LineControlFlags::PARITY_ENABLE | LineControlFlags::STICK_PARITY);
639 }
640 Parity::Space => {
641 lcr.insert(
642 LineControlFlags::PARITY_ENABLE
643 | LineControlFlags::EVEN_PARITY
644 | LineControlFlags::STICK_PARITY,
645 );
646 }
647 }
648
649 self.write_flags(UART_LCR, lcr);
650 Ok(())
651 }
652
653 pub fn enable_fifo(&mut self, enable: bool) {
655 if enable {
656 let mut fcr = FifoControlFlags::ENABLE_FIFO;
657 fcr.insert(FifoControlFlags::CLEAR_RECEIVER_FIFO);
658 fcr.insert(FifoControlFlags::CLEAR_TRANSMITTER_FIFO);
659 fcr.insert(FifoControlFlags::TRIGGER_8_BYTES);
663 self.write_flags(UART_FCR, fcr);
664 if self.is_fifo_enabled() {
665 return;
666 }
667 }
668 self.write_flags(UART_FCR, FifoControlFlags::empty());
669 }
670
671 pub fn set_fifo_trigger_level(&mut self, level: u8) {
673 if !self.is_16550_plus() {
674 return;
675 }
676
677 let trigger_value = match level {
678 0..=3 => FifoControlFlags::TRIGGER_1_BYTE,
679 4..=7 => FifoControlFlags::TRIGGER_4_BYTES,
680 8..=11 => FifoControlFlags::TRIGGER_8_BYTES,
681 _ => FifoControlFlags::TRIGGER_14_BYTES,
682 };
683
684 let mut fcr: FifoControlFlags = self.read_flags(UART_FCR);
686 fcr.remove(FifoControlFlags::TRIGGER_LEVEL_MASK);
687 fcr.insert(trigger_value);
688 self.write_flags(UART_FCR, fcr);
689 }
690
691 fn init_core(&mut self) {
693 self.base.init();
694 }
695
696 pub fn is_fifo_enabled(&self) -> bool {
698 if !self.is_16550_plus() {
699 return false;
700 }
701 let iir: InterruptIdentificationFlags = self.read_flags(UART_IIR);
703 iir.contains(InterruptIdentificationFlags::FIFO_ENABLE_MASK)
704 }
705}
706
707fn read_rx_sample<T: Kind>(base: &T, saved_lsr: &mut LineStatusFlags) -> Option<RxSample> {
708 let current: LineStatusFlags = base.read_flags(UART_LSR);
709 saved_lsr.insert(current & (LineStatusFlags::ERROR_MASK | LineStatusFlags::FIFO_ERROR));
710 let lsr = current | *saved_lsr;
711 if !lsr.intersects(LineStatusFlags::DATA_READY | LineStatusFlags::ERROR_MASK) {
712 return None;
713 }
714
715 let byte = lsr
716 .contains(LineStatusFlags::DATA_READY)
717 .then(|| base.read_reg(UART_RBR));
718 let flag = if lsr.contains(LineStatusFlags::BREAK_INTERRUPT) {
719 RxFlag::Break
720 } else if lsr.contains(LineStatusFlags::PARITY_ERROR) {
721 RxFlag::Parity
722 } else if lsr.contains(LineStatusFlags::FRAMING_ERROR) {
723 RxFlag::Framing
724 } else {
725 RxFlag::Normal
726 };
727 let overrun = lsr.contains(LineStatusFlags::OVERRUN_ERROR);
728 saved_lsr.remove(LineStatusFlags::ERROR_MASK | LineStatusFlags::FIFO_ERROR);
729
730 Some(RxSample {
731 byte,
732 flag,
733 overrun,
734 })
735}
736
737fn rx_errors_from_sample(sample: RxSample) -> RxErrorFlags {
738 let mut errors = match sample.flag {
739 RxFlag::Normal => RxErrorFlags::empty(),
740 RxFlag::Break => RxErrorFlags::BREAK,
741 RxFlag::Parity => RxErrorFlags::PARITY,
742 RxFlag::Framing => RxErrorFlags::FRAMING,
743 };
744 if sample.overrun {
745 errors |= RxErrorFlags::OVERRUN;
746 }
747 errors
748}
749
750fn interrupt_enable_for_events(events: SerialEventSet) -> InterruptEnableFlags {
751 let mut ier = InterruptEnableFlags::empty();
752 if events.intersects(SerialEventSet::RX) {
753 ier.insert(
754 InterruptEnableFlags::RECEIVED_DATA_AVAILABLE
755 | InterruptEnableFlags::RECEIVER_LINE_STATUS,
756 );
757 }
758 if events.contains(SerialEventSet::TX_SPACE) {
759 ier.insert(InterruptEnableFlags::TRANSMITTER_HOLDING_EMPTY);
760 }
761 ier
762}
763
764fn serial_event_from_lsr(lsr: LineStatusFlags) -> SerialEvent {
765 let mut event = SerialEvent::empty();
766 if lsr.contains(LineStatusFlags::DATA_READY) {
767 event |= SerialEvent::RX_READY;
768 }
769 if lsr.intersects(
770 LineStatusFlags::PARITY_ERROR
771 | LineStatusFlags::FRAMING_ERROR
772 | LineStatusFlags::BREAK_INTERRUPT,
773 ) {
774 event |= SerialEvent::RX_ERROR;
775 }
776 if lsr.contains(LineStatusFlags::OVERRUN_ERROR) {
777 event |= SerialEvent::RX_ERROR | SerialEvent::OVERRUN;
778 }
779 if lsr.contains(LineStatusFlags::TRANSMITTER_HOLDING_EMPTY) {
780 event |= SerialEvent::TX_READY;
781 }
782 event
783}
784
785#[cfg(test)]
786mod tests {
787 use core::sync::atomic::{AtomicU8, AtomicUsize, Ordering};
788 use std::{
789 sync::{Arc, Mutex, MutexGuard},
790 vec::Vec,
791 };
792
793 use rdif_serial::UartRegisterGate;
794
795 use super::*;
796
797 static REGS: [AtomicU8; 8] = [const { AtomicU8::new(0) }; 8];
798 static DLL_REG: AtomicU8 = AtomicU8::new(0);
799 static DLH_REG: AtomicU8 = AtomicU8::new(0);
800 static THR_WRITES: AtomicUsize = AtomicUsize::new(0);
801 static THR_WRITE_IER: AtomicU8 = AtomicU8::new(u8::MAX);
802 static RBR_READS: AtomicUsize = AtomicUsize::new(0);
803 static LSR_READS: AtomicUsize = AtomicUsize::new(0);
804 static LAST_FCR_WRITE: AtomicU8 = AtomicU8::new(0);
805 static TEST_LOCK: Mutex<()> = Mutex::new(());
806
807 fn handle_irq(irq: &mut impl UartIrq) -> (Option<SerialIrqEvent>, Vec<RxSample>) {
808 let Some(report) = irq.handle() else {
809 return (None, Vec::new());
810 };
811 (Some(report.event), report.rx.as_slice().to_vec())
812 }
813
814 #[derive(Clone)]
815 struct MockKind;
816
817 impl Kind for MockKind {
818 fn read_reg(&self, reg: u8) -> u8 {
819 let dlab = REGS[UART_LCR as usize].load(Ordering::SeqCst)
820 & LineControlFlags::DIVISOR_LATCH_ACCESS.bits()
821 != 0;
822 if dlab {
823 return match reg {
824 UART_DLL => DLL_REG.load(Ordering::SeqCst),
825 UART_DLH => DLH_REG.load(Ordering::SeqCst),
826 _ => REGS[reg as usize].load(Ordering::SeqCst),
827 };
828 }
829
830 let value = REGS[reg as usize].load(Ordering::SeqCst);
831 if reg == UART_LSR {
832 LSR_READS.fetch_add(1, Ordering::SeqCst);
833 }
834 if reg == UART_RBR {
835 RBR_READS.fetch_add(1, Ordering::SeqCst);
836 REGS[UART_LSR as usize].fetch_and(
837 !(LineStatusFlags::ERROR_MASK | LineStatusFlags::DATA_READY).bits(),
838 Ordering::SeqCst,
839 );
840 } else if reg == UART_MSR {
841 REGS[UART_MSR as usize]
842 .fetch_and(!ModemStatusFlags::DELTA_MASK.bits(), Ordering::SeqCst);
843 }
844 value
845 }
846
847 fn write_reg(&self, reg: u8, val: u8) {
848 let dlab = REGS[UART_LCR as usize].load(Ordering::SeqCst)
849 & LineControlFlags::DIVISOR_LATCH_ACCESS.bits()
850 != 0;
851 if dlab {
852 match reg {
853 UART_DLL => {
854 DLL_REG.store(val, Ordering::SeqCst);
855 return;
856 }
857 UART_DLH => {
858 DLH_REG.store(val, Ordering::SeqCst);
859 return;
860 }
861 _ => {}
862 }
863 }
864
865 REGS[reg as usize].store(val, Ordering::SeqCst);
866 if reg == UART_FCR {
867 LAST_FCR_WRITE.store(val, Ordering::SeqCst);
868 if val & FifoControlFlags::CLEAR_RECEIVER_FIFO.bits() != 0 {
869 REGS[UART_LSR as usize].fetch_and(
870 !(LineStatusFlags::DATA_READY
871 | LineStatusFlags::ERROR_MASK
872 | LineStatusFlags::FIFO_ERROR)
873 .bits(),
874 Ordering::SeqCst,
875 );
876 }
877 if val & FifoControlFlags::ENABLE_FIFO.bits() != 0 {
878 REGS[UART_IIR as usize].fetch_or(
879 InterruptIdentificationFlags::FIFO_ENABLE_MASK.bits(),
880 Ordering::SeqCst,
881 );
882 } else {
883 REGS[UART_IIR as usize].fetch_and(
884 !InterruptIdentificationFlags::FIFO_ENABLE_MASK.bits(),
885 Ordering::SeqCst,
886 );
887 }
888 }
889 if reg == UART_THR {
890 THR_WRITE_IER.store(
891 REGS[UART_IER as usize].load(Ordering::SeqCst),
892 Ordering::SeqCst,
893 );
894 let iir = REGS[UART_IIR as usize].load(Ordering::SeqCst);
895 if iir & InterruptIdentificationFlags::FIFO_ENABLE_MASK.bits() == 0 {
896 REGS[UART_LSR as usize].fetch_and(
897 !LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
898 Ordering::SeqCst,
899 );
900 } else {
901 let writes = THR_WRITES.fetch_add(1, Ordering::SeqCst) + 1;
902 if writes >= UART_FIFO_SIZE as usize {
903 REGS[UART_LSR as usize].fetch_and(
904 !LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
905 Ordering::SeqCst,
906 );
907 }
908 }
909 }
910 }
911
912 fn get_base(&self) -> usize {
913 0x1000
914 }
915 }
916
917 #[derive(Clone)]
918 struct FloodKind {
919 rbr_reads: Arc<AtomicUsize>,
920 }
921
922 #[derive(Clone)]
923 struct AlwaysReadyTxKind {
924 writes: Arc<AtomicUsize>,
925 }
926
927 impl Kind for AlwaysReadyTxKind {
928 fn read_reg(&self, reg: u8) -> u8 {
929 if reg == UART_LSR {
930 LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits()
931 } else {
932 0
933 }
934 }
935
936 fn write_reg(&self, reg: u8, _val: u8) {
937 if reg == UART_THR {
938 self.writes.fetch_add(1, Ordering::SeqCst);
939 }
940 }
941
942 fn get_base(&self) -> usize {
943 0x3000
944 }
945 }
946
947 impl Kind for FloodKind {
948 fn read_reg(&self, reg: u8) -> u8 {
949 match reg {
950 UART_IIR => InterruptIdentificationFlags::RECEIVED_DATA_AVAILABLE.bits(),
951 UART_LSR => LineStatusFlags::DATA_READY.bits(),
952 UART_RBR => self.rbr_reads.fetch_add(1, Ordering::SeqCst) as u8,
953 _ => 0,
954 }
955 }
956
957 fn write_reg(&self, _reg: u8, _val: u8) {}
958
959 fn get_base(&self) -> usize {
960 0x2000
961 }
962 }
963
964 fn reset_regs() {
965 for reg in ®S {
966 reg.store(0, Ordering::SeqCst);
967 }
968 DLL_REG.store(0, Ordering::SeqCst);
969 DLH_REG.store(0, Ordering::SeqCst);
970 THR_WRITES.store(0, Ordering::SeqCst);
971 THR_WRITE_IER.store(u8::MAX, Ordering::SeqCst);
972 RBR_READS.store(0, Ordering::SeqCst);
973 LSR_READS.store(0, Ordering::SeqCst);
974 LAST_FCR_WRITE.store(0, Ordering::SeqCst);
975 }
976
977 fn serial() -> (MutexGuard<'static, ()>, Ns16550<MockKind>) {
978 let guard = TEST_LOCK.lock().unwrap_or_else(|error| error.into_inner());
979 reset_regs();
980 (
981 guard,
982 Ns16550 {
983 base: MockKind,
984 clock_freq: 1_843_200,
985 saved_lsr: LineStatusFlags::empty(),
986 },
987 )
988 }
989
990 fn started_parts(
991 uart: Ns16550<MockKind>,
992 ) -> SerialParts<Ns16550<MockKind>, Ns16550Irq<MockKind>, Ns16550EmergencyTx<MockKind>> {
993 let mut parts = uart.split();
994 parts.control.startup(&Config::new()).unwrap();
995 parts
996 }
997
998 #[test]
999 fn baudrate_reads_divisor_latch_without_consuming_rx_register() {
1000 let (_guard, uart) = serial();
1001 let original_lcr = LineControlFlags::WORD_LENGTH_8 | LineControlFlags::STOP_BITS;
1002 REGS[UART_LCR as usize].store(original_lcr.bits(), Ordering::SeqCst);
1003 REGS[UART_LSR as usize].store(LineStatusFlags::DATA_READY.bits(), Ordering::SeqCst);
1004 REGS[UART_RBR as usize].store(0, Ordering::SeqCst);
1005 REGS[UART_IER as usize].store(0, Ordering::SeqCst);
1006 DLL_REG.store(1, Ordering::SeqCst);
1007 DLH_REG.store(0, Ordering::SeqCst);
1008
1009 assert_eq!(uart.runtime_info().initial_baudrate, 115_200);
1010 assert_eq!(
1011 REGS[UART_LCR as usize].load(Ordering::SeqCst),
1012 original_lcr.bits()
1013 );
1014 assert!(
1015 LineStatusFlags::from_bits_retain(REGS[UART_LSR as usize].load(Ordering::SeqCst))
1016 .contains(LineStatusFlags::DATA_READY)
1017 );
1018 }
1019
1020 #[test]
1021 fn pending_output_preserves_rx_error_latch() {
1022 let (_guard, mut uart) = serial();
1023 REGS[UART_LSR as usize].store(
1024 (LineStatusFlags::TRANSMITTER_HOLDING_EMPTY | LineStatusFlags::PARITY_ERROR).bits(),
1025 Ordering::SeqCst,
1026 );
1027
1028 assert!(uart.pending(SerialDirection::Output));
1029
1030 REGS[UART_LSR as usize].store(LineStatusFlags::DATA_READY.bits(), Ordering::SeqCst);
1031 let mut buf = [0];
1032 let err = uart
1033 .try_read(&mut buf)
1034 .expect_err("saved parity error should be reported by next read");
1035 assert_eq!(err.bytes_transferred, 0);
1036 assert_eq!(err.kind, TransferError::Parity);
1037 }
1038
1039 #[test]
1040 fn try_write_stops_when_tx_fifo_becomes_full() {
1041 let (_guard, mut uart) = serial();
1042 REGS[UART_LSR as usize].store(
1043 LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
1044 Ordering::SeqCst,
1045 );
1046
1047 assert_eq!(uart.try_write(b"ab"), 1);
1048 assert_eq!(REGS[UART_THR as usize].load(Ordering::SeqCst), b'a');
1049 }
1050
1051 #[test]
1052 fn try_write_fills_enabled_tx_fifo_in_one_pass() {
1053 let (_guard, mut uart) = serial();
1054 REGS[UART_LSR as usize].store(
1055 LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
1056 Ordering::SeqCst,
1057 );
1058 REGS[UART_IIR as usize].store(
1059 InterruptIdentificationFlags::FIFO_ENABLE_MASK.bits(),
1060 Ordering::SeqCst,
1061 );
1062
1063 assert_eq!(uart.try_write(b"abcdefghijklmnopq"), 16);
1064 assert_eq!(REGS[UART_THR as usize].load(Ordering::SeqCst), b'p');
1065 }
1066
1067 #[test]
1068 fn open_enables_modem_interrupt_output_gate() {
1069 let (_guard, mut uart) = serial();
1070
1071 uart.open();
1072
1073 let fcr = FifoControlFlags::from_bits_retain(LAST_FCR_WRITE.load(Ordering::SeqCst));
1074 assert!(fcr.contains(FifoControlFlags::ENABLE_FIFO));
1075 assert!(fcr.contains(FifoControlFlags::CLEAR_RECEIVER_FIFO));
1076 assert!(fcr.contains(FifoControlFlags::CLEAR_TRANSMITTER_FIFO));
1077 let mcr =
1078 ModemControlFlags::from_bits_retain(REGS[UART_MCR as usize].load(Ordering::SeqCst));
1079 assert!(mcr.contains(ModemControlFlags::DATA_TERMINAL_READY));
1080 assert!(mcr.contains(ModemControlFlags::REQUEST_TO_SEND));
1081 assert!(mcr.contains(ModemControlFlags::OUT_2));
1082 }
1083
1084 #[test]
1085 fn startup_enables_fifo_before_checking_fifo_status() {
1086 let (_guard, mut uart) = serial();
1087
1088 uart.startup(&Config::new()).unwrap();
1089
1090 let iir = InterruptIdentificationFlags::from_bits_retain(
1091 REGS[UART_IIR as usize].load(Ordering::SeqCst),
1092 );
1093 assert!(iir.contains(InterruptIdentificationFlags::FIFO_ENABLE_MASK));
1094 assert_eq!(THR_WRITES.load(Ordering::SeqCst), 0);
1095 }
1096
1097 #[test]
1098 fn failed_startup_restores_the_early_interrupt_mask() {
1099 let (_guard, mut uart) = serial();
1100 let early_mask = UART_IER_RDI | UART_IER_RLSI;
1101 REGS[UART_IER as usize].store(early_mask, Ordering::SeqCst);
1102
1103 let result = uart.startup(&Config::new().baudrate(0));
1104
1105 assert_eq!(result, Err(ConfigError::InvalidBaudrate));
1106 assert_eq!(REGS[UART_IER as usize].load(Ordering::SeqCst), early_mask);
1107 }
1108
1109 #[test]
1110 fn startup_uses_half_full_rx_trigger_for_deferred_service() {
1111 let (_guard, mut uart) = serial();
1112
1113 uart.startup(&Config::new()).unwrap();
1114
1115 let fcr = FifoControlFlags::from_bits_retain(LAST_FCR_WRITE.load(Ordering::SeqCst));
1116 assert_eq!(
1117 fcr & FifoControlFlags::TRIGGER_LEVEL_MASK,
1118 FifoControlFlags::TRIGGER_8_BYTES,
1119 "deferred RX service must amortize IRQ wakeups at the Linux 16550A default trigger",
1120 );
1121 }
1122
1123 #[test]
1124 fn discard_tx_clears_only_the_transmitter_fifo() {
1125 let (_guard, mut uart) = serial();
1126
1127 assert!(UartPort::discard_tx(&mut uart));
1128
1129 let fcr = FifoControlFlags::from_bits_retain(LAST_FCR_WRITE.load(Ordering::SeqCst));
1130 assert!(fcr.contains(FifoControlFlags::ENABLE_FIFO));
1131 assert!(fcr.contains(FifoControlFlags::CLEAR_TRANSMITTER_FIFO));
1132 assert!(!fcr.contains(FifoControlFlags::CLEAR_RECEIVER_FIFO));
1133 assert_eq!(
1134 fcr & FifoControlFlags::TRIGGER_LEVEL_MASK,
1135 FifoControlFlags::TRIGGER_8_BYTES,
1136 );
1137 }
1138
1139 #[test]
1140 fn discard_rx_clears_only_the_receiver_fifo_and_saved_status() {
1141 let (_guard, mut uart) = serial();
1142 uart.saved_lsr = LineStatusFlags::PARITY_ERROR;
1143 REGS[UART_RBR as usize].store(b'x', Ordering::SeqCst);
1144 REGS[UART_LSR as usize].store(LineStatusFlags::DATA_READY.bits(), Ordering::SeqCst);
1145
1146 UartPort::discard_rx(&mut uart);
1147
1148 let fcr = FifoControlFlags::from_bits_retain(LAST_FCR_WRITE.load(Ordering::SeqCst));
1149 assert!(fcr.contains(FifoControlFlags::ENABLE_FIFO));
1150 assert!(fcr.contains(FifoControlFlags::CLEAR_RECEIVER_FIFO));
1151 assert!(!fcr.contains(FifoControlFlags::CLEAR_TRANSMITTER_FIFO));
1152 assert_eq!(
1153 fcr & FifoControlFlags::TRIGGER_LEVEL_MASK,
1154 FifoControlFlags::TRIGGER_8_BYTES,
1155 );
1156 assert!(uart.saved_lsr.is_empty());
1157 assert!(uart.read_rx().is_none());
1158 assert_eq!(RBR_READS.load(Ordering::SeqCst), 0);
1159 }
1160
1161 #[test]
1162 fn try_read_empty_returns_zero() {
1163 let (_guard, mut uart) = serial();
1164 let mut buf = [0];
1165
1166 assert_eq!(uart.try_read(&mut buf), Ok(0));
1167 }
1168
1169 #[test]
1170 fn irq_reports_rx_error_and_buffers_fifo_data() {
1171 let (_guard, uart) = serial();
1172 let mut parts = uart.split();
1173 REGS[UART_IIR as usize].store(
1174 InterruptIdentificationFlags::RECEIVER_LINE_STATUS.bits(),
1175 Ordering::SeqCst,
1176 );
1177 REGS[UART_LSR as usize].store(
1178 (LineStatusFlags::DATA_READY | LineStatusFlags::OVERRUN_ERROR).bits(),
1179 Ordering::SeqCst,
1180 );
1181 REGS[UART_RBR as usize].store(0xab, Ordering::SeqCst);
1182
1183 let (event, samples) = handle_irq(&mut parts.irq);
1184 let event = event.unwrap();
1185 assert!(event.events.contains(SerialEventSet::RX_STATUS));
1186 assert!(event.rx_errors.contains(RxErrorFlags::OVERRUN));
1187 assert_eq!(
1188 samples,
1189 [RxSample {
1190 byte: Some(0xab),
1191 flag: RxFlag::Normal,
1192 overrun: true,
1193 }]
1194 );
1195 assert_eq!(RBR_READS.load(Ordering::SeqCst), 1);
1196 }
1197
1198 #[test]
1199 fn split_endpoints_service_rx_and_tx_fifo() {
1200 let (_guard, uart) = serial();
1201 let mut parts = started_parts(uart);
1202
1203 REGS[UART_IIR as usize].store(
1204 InterruptIdentificationFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
1205 Ordering::SeqCst,
1206 );
1207 REGS[UART_LSR as usize].store(
1208 LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
1209 Ordering::SeqCst,
1210 );
1211 let event = handle_irq(&mut parts.irq).0.unwrap();
1212 assert!(event.events.contains(SerialEventSet::TX_SPACE));
1213 assert_eq!(parts.control.write_tx(b"ab"), 1);
1214 assert_eq!(REGS[UART_THR as usize].load(Ordering::SeqCst), b'a');
1215
1216 REGS[UART_IIR as usize].store(
1217 InterruptIdentificationFlags::RECEIVED_DATA_AVAILABLE.bits(),
1218 Ordering::SeqCst,
1219 );
1220 REGS[UART_LSR as usize].store(LineStatusFlags::DATA_READY.bits(), Ordering::SeqCst);
1221 REGS[UART_RBR as usize].store(b'z', Ordering::SeqCst);
1222 let (event, samples) = handle_irq(&mut parts.irq);
1223 let event = event.unwrap();
1224 assert!(event.events.contains(SerialEventSet::RX_DATA));
1225 assert_eq!(
1226 samples,
1227 [RxSample {
1228 byte: Some(b'z'),
1229 flag: RxFlag::Normal,
1230 overrun: false,
1231 }]
1232 );
1233 }
1234
1235 #[test]
1236 fn emergency_tx_writes_only_the_current_nonblocking_fifo_capacity() {
1237 let (_guard, uart) = serial();
1238 let parts = uart.split();
1239 let gate = UartRegisterGate::new(parts.emergency_tx);
1240 let access = gate.try_begin_emergency().unwrap();
1241 REGS[UART_LSR as usize].store(
1242 LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
1243 Ordering::SeqCst,
1244 );
1245
1246 assert_eq!(access.try_write(b"ab"), 1);
1247 assert_eq!(REGS[UART_THR as usize].load(Ordering::SeqCst), b'a');
1248 assert_eq!(access.try_write(b"b"), 0);
1249 }
1250
1251 #[test]
1252 fn emergency_takeover_leaves_device_interrupts_masked() {
1253 let (_guard, uart) = serial();
1254 let parts = uart.split();
1255 let gate = UartRegisterGate::new(parts.emergency_tx);
1256 let enabled = UART_IER_RDI | UART_IER_RLSI | UART_IER_THRI;
1257 REGS[UART_IER as usize].store(enabled, Ordering::SeqCst);
1258 REGS[UART_LSR as usize].store(
1259 LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
1260 Ordering::SeqCst,
1261 );
1262
1263 let access = gate.try_begin_emergency().unwrap();
1264 assert_eq!(access.try_write(b"x"), 1);
1265 assert_eq!(
1266 THR_WRITE_IER.load(Ordering::SeqCst),
1267 0,
1268 "a gate-busy IRQ must observe a device-masked emergency transaction"
1269 );
1270 assert_eq!(
1271 REGS[UART_IER as usize].load(Ordering::SeqCst),
1272 0,
1273 "terminal emergency ownership must not rearm the UART source"
1274 );
1275 }
1276
1277 #[test]
1278 fn emergency_tx_has_a_fixed_write_budget() {
1279 let writes = Arc::new(AtomicUsize::new(0));
1280 let tx = Ns16550EmergencyTx {
1281 base: AlwaysReadyTxKind {
1282 writes: writes.clone(),
1283 },
1284 };
1285 let bytes = [b'x'; 17];
1286 let gate = UartRegisterGate::new(tx);
1287 let access = gate.try_begin_emergency().unwrap();
1288
1289 assert_eq!(access.try_write(&bytes), 16);
1290 assert_eq!(writes.load(Ordering::SeqCst), 16);
1291 }
1292
1293 #[test]
1294 fn hard_irq_drains_rx_before_deferred_worker_can_overrun_fifo() {
1295 let (_guard, uart) = serial();
1296 let mut parts = started_parts(uart);
1297 REGS[UART_IIR as usize].store(
1298 InterruptIdentificationFlags::RECEIVER_LINE_STATUS.bits(),
1299 Ordering::SeqCst,
1300 );
1301 REGS[UART_LSR as usize].store(
1302 (LineStatusFlags::DATA_READY | LineStatusFlags::PARITY_ERROR).bits(),
1303 Ordering::SeqCst,
1304 );
1305 LSR_READS.store(0, Ordering::SeqCst);
1306
1307 let (event, samples) = handle_irq(&mut parts.irq);
1308 let event = event.unwrap();
1309
1310 assert!(event.events.contains(SerialEventSet::RX_STATUS));
1311 assert!(event.rx_errors.contains(RxErrorFlags::PARITY));
1312 assert!(LSR_READS.load(Ordering::SeqCst) > 0);
1313 assert_eq!(
1314 RBR_READS.load(Ordering::SeqCst),
1315 1,
1316 "the hard IRQ must free a bounded hardware FIFO slot before the worker runs",
1317 );
1318 assert_eq!(THR_WRITES.load(Ordering::SeqCst), 0);
1319 assert_eq!(REGS[UART_LSR as usize].load(Ordering::SeqCst), 0);
1320 assert_eq!(
1321 samples,
1322 [RxSample {
1323 byte: Some(0),
1324 flag: RxFlag::Parity,
1325 overrun: false,
1326 }]
1327 );
1328 }
1329
1330 #[test]
1331 fn hard_irq_rx_drain_is_bounded_to_the_report_capacity() {
1332 let reads = Arc::new(AtomicUsize::new(0));
1333 let mut irq = Ns16550Irq {
1334 base: FloodKind {
1335 rbr_reads: reads.clone(),
1336 },
1337 saved_lsr: LineStatusFlags::empty(),
1338 };
1339
1340 let (event, samples) = handle_irq(&mut irq);
1341
1342 assert!(event.unwrap().events.contains(SerialEventSet::RX_DATA));
1343 assert_eq!(samples.len(), IRQ_RX_BATCH_CAPACITY);
1344 assert_eq!(reads.load(Ordering::SeqCst), IRQ_RX_BATCH_CAPACITY);
1345 }
1346
1347 #[test]
1348 fn irq_endpoint_does_not_synthesize_tx_irq_from_plain_lsr_ready() {
1349 let (_guard, uart) = serial();
1350 let mut parts = started_parts(uart);
1351 REGS[UART_IIR as usize].store(
1352 InterruptIdentificationFlags::NO_INTERRUPT_PENDING.bits(),
1353 Ordering::SeqCst,
1354 );
1355 REGS[UART_LSR as usize].store(
1356 LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
1357 Ordering::SeqCst,
1358 );
1359
1360 assert!(handle_irq(&mut parts.irq).0.is_none());
1361 }
1362
1363 #[test]
1364 fn hard_irq_does_not_claim_tx_ready_without_iir_pending() {
1365 let (_guard, uart) = serial();
1366 let mut parts = uart.split();
1367 parts.control.set_irq_mask(SerialEventSet::TX_SPACE);
1368 REGS[UART_IIR as usize].store(
1369 InterruptIdentificationFlags::NO_INTERRUPT_PENDING.bits(),
1370 Ordering::SeqCst,
1371 );
1372 REGS[UART_LSR as usize].store(
1373 LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
1374 Ordering::SeqCst,
1375 );
1376
1377 assert!(handle_irq(&mut parts.irq).0.is_none());
1378 assert!(parts.control.poll_status().tx_ready());
1379 }
1380
1381 #[test]
1382 fn hard_irq_does_not_claim_rx_ready_without_iir_pending() {
1383 let (_guard, uart) = serial();
1384 let mut parts = uart.split();
1385 parts.control.set_irq_mask(SerialEventSet::RX);
1386 REGS[UART_IIR as usize].store(
1387 InterruptIdentificationFlags::NO_INTERRUPT_PENDING.bits(),
1388 Ordering::SeqCst,
1389 );
1390 REGS[UART_LSR as usize].store(LineStatusFlags::DATA_READY.bits(), Ordering::SeqCst);
1391
1392 assert!(handle_irq(&mut parts.irq).0.is_none());
1393 assert!(parts.control.poll_status().rx_ready());
1394 }
1395
1396 #[test]
1397 fn hard_irq_claims_and_clears_modem_status_interrupt() {
1398 let (_guard, uart) = serial();
1399 let mut parts = started_parts(uart);
1400
1401 REGS[UART_IIR as usize].store(
1402 InterruptIdentificationFlags::MODEM_STATUS.bits()
1403 | InterruptIdentificationFlags::FIFO_ENABLE_MASK.bits(),
1404 Ordering::SeqCst,
1405 );
1406 REGS[UART_MSR as usize].store(
1407 ModemStatusFlags::DELTA_CLEAR_TO_SEND.bits(),
1408 Ordering::SeqCst,
1409 );
1410
1411 let event = handle_irq(&mut parts.irq).0.unwrap();
1412 assert!(event.events.contains(SerialEventSet::MODEM_STATUS));
1413 assert!(
1414 ModemStatusFlags::from_bits_retain(REGS[UART_MSR as usize].load(Ordering::SeqCst))
1415 .intersection(ModemStatusFlags::DELTA_MASK)
1416 .is_empty()
1417 );
1418 }
1419
1420 #[test]
1421 fn irq_event_drains_rx_fifo_into_sink() {
1422 let (_guard, uart) = serial();
1423 let mut parts = started_parts(uart);
1424
1425 REGS[UART_IIR as usize].store(
1426 InterruptIdentificationFlags::RECEIVED_DATA_AVAILABLE.bits(),
1427 Ordering::SeqCst,
1428 );
1429 REGS[UART_LSR as usize].store(LineStatusFlags::DATA_READY.bits(), Ordering::SeqCst);
1430 REGS[UART_RBR as usize].store(b'r', Ordering::SeqCst);
1431
1432 let (event, samples) = handle_irq(&mut parts.irq);
1433 let event = event.unwrap();
1434 assert!(event.events.contains(SerialEventSet::RX_DATA));
1435 assert_eq!(
1436 samples,
1437 [RxSample {
1438 byte: Some(b'r'),
1439 flag: RxFlag::Normal,
1440 overrun: false,
1441 }]
1442 );
1443 }
1444
1445 #[test]
1446 fn tx_irq_exposes_space_without_owning_a_software_fifo() {
1447 let (_guard, uart) = serial();
1448 let mut parts = started_parts(uart);
1449
1450 REGS[UART_IIR as usize].store(
1451 InterruptIdentificationFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
1452 Ordering::SeqCst,
1453 );
1454 REGS[UART_LSR as usize].store(
1455 LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
1456 Ordering::SeqCst,
1457 );
1458
1459 let event = handle_irq(&mut parts.irq).0.unwrap();
1460 assert!(event.events.contains(SerialEventSet::TX_SPACE));
1461 assert_eq!(parts.control.write_tx(b"ab"), 1);
1462 assert_eq!(REGS[UART_THR as usize].load(Ordering::SeqCst), b'a');
1463 }
1464
1465 #[test]
1466 fn irq_lsr_error_is_preserved_in_buffered_sample() {
1467 let (_guard, uart) = serial();
1468 let mut parts = started_parts(uart);
1469
1470 REGS[UART_IIR as usize].store(
1471 InterruptIdentificationFlags::RECEIVER_LINE_STATUS.bits(),
1472 Ordering::SeqCst,
1473 );
1474 REGS[UART_LSR as usize].store(
1475 (LineStatusFlags::DATA_READY | LineStatusFlags::PARITY_ERROR).bits(),
1476 Ordering::SeqCst,
1477 );
1478 REGS[UART_RBR as usize].store(b'p', Ordering::SeqCst);
1479
1480 let (event, samples) = handle_irq(&mut parts.irq);
1481 let event = event.unwrap();
1482 assert!(event.rx_errors.contains(RxErrorFlags::PARITY));
1483 assert_eq!(
1484 samples,
1485 [RxSample {
1486 byte: Some(b'p'),
1487 flag: RxFlag::Parity,
1488 overrun: false,
1489 }]
1490 );
1491 }
1492
1493 #[test]
1494 fn port_rx_returns_current_byte_and_overrun_marker() {
1495 let (_guard, uart) = serial();
1496 let mut parts = started_parts(uart);
1497
1498 REGS[UART_IIR as usize].store(
1499 InterruptIdentificationFlags::RECEIVER_LINE_STATUS.bits(),
1500 Ordering::SeqCst,
1501 );
1502 REGS[UART_LSR as usize].store(
1503 (LineStatusFlags::DATA_READY | LineStatusFlags::OVERRUN_ERROR).bits(),
1504 Ordering::SeqCst,
1505 );
1506 REGS[UART_RBR as usize].store(b'S', Ordering::SeqCst);
1507
1508 assert_eq!(
1509 parts.control.read_rx(),
1510 Some(RxSample {
1511 byte: Some(b'S'),
1512 flag: RxFlag::Normal,
1513 overrun: true,
1514 })
1515 );
1516 }
1517
1518 #[test]
1519 fn irq_keeps_rx_source_enabled_after_draining_fifo() {
1520 let (_guard, uart) = serial();
1521 let mut parts = started_parts(uart);
1522 REGS[UART_IER as usize].store(UART_IER_RDI | UART_IER_RLSI, Ordering::SeqCst);
1523 REGS[UART_IIR as usize].store(UART_IIR_RDI, Ordering::SeqCst);
1524 REGS[UART_LSR as usize].store(LineStatusFlags::DATA_READY.bits(), Ordering::SeqCst);
1525 REGS[UART_RBR as usize].store(b'q', Ordering::SeqCst);
1526
1527 let (event, samples) = handle_irq(&mut parts.irq);
1528 let event = event.unwrap();
1529
1530 assert!(event.events.contains(SerialEventSet::RX_DATA));
1531 assert!(!event.rearm.intersects(SerialEventSet::RX));
1532 assert_eq!(
1533 REGS[UART_IER as usize].load(Ordering::SeqCst),
1534 UART_IER_RDI | UART_IER_RLSI
1535 );
1536 assert_eq!(RBR_READS.load(Ordering::SeqCst), 1);
1537 assert_eq!(samples[0].byte, Some(b'q'));
1538 }
1539
1540 #[test]
1541 fn irq_overrun_masks_rx_source_until_worker_rearm() {
1542 let (_guard, uart) = serial();
1543 let mut parts = started_parts(uart);
1544 REGS[UART_IER as usize].store(UART_IER_RDI | UART_IER_RLSI, Ordering::SeqCst);
1545 REGS[UART_IIR as usize].store(UART_IIR_RLSI, Ordering::SeqCst);
1546 REGS[UART_LSR as usize].store(
1547 (LineStatusFlags::DATA_READY | LineStatusFlags::OVERRUN_ERROR).bits(),
1548 Ordering::SeqCst,
1549 );
1550 REGS[UART_RBR as usize].store(b'o', Ordering::SeqCst);
1551
1552 let event = handle_irq(&mut parts.irq).0.unwrap();
1553
1554 assert!(event.rx_errors.contains(RxErrorFlags::OVERRUN));
1555 assert!(event.rearm.contains(SerialEventSet::RX));
1556 assert_eq!(REGS[UART_IER as usize].load(Ordering::SeqCst), 0);
1557 }
1558
1559 #[test]
1560 fn rearm_remasks_a_source_that_is_already_ready() {
1561 let (_guard, mut uart) = serial();
1562 uart.startup(&Config::new()).unwrap();
1563 REGS[UART_LSR as usize].store(LineStatusFlags::DATA_READY.bits(), Ordering::SeqCst);
1564
1565 let ready = uart.rearm(SerialEventSet::RX);
1566
1567 assert_eq!(ready, SerialEventSet::RX_DATA);
1568 assert_eq!(REGS[UART_IER as usize].load(Ordering::SeqCst), 0);
1569 }
1570
1571 #[test]
1572 fn unknown_irq_source_masks_all_and_reports_fault() {
1573 let (_guard, uart) = serial();
1574 let mut parts = started_parts(uart);
1575 REGS[UART_IER as usize].store(0xff, Ordering::SeqCst);
1576 REGS[UART_IIR as usize].store(0x08, Ordering::SeqCst);
1577
1578 let event = handle_irq(&mut parts.irq).0.unwrap();
1579
1580 assert!(event.events.contains(SerialEventSet::FAULT));
1581 assert_eq!(REGS[UART_IER as usize].load(Ordering::SeqCst), 0);
1582 assert_eq!(RBR_READS.load(Ordering::SeqCst), 0);
1583 assert_eq!(THR_WRITES.load(Ordering::SeqCst), 0);
1584 }
1585}