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