Skip to main content

some_serial/ns16550/
mod.rs

1//! NS16550/16450 UART 驱动模块
2//!
3//! 提供两种访问方式:
4//! - IO Port 版本(x86_64 架构)
5//! - MMIO 版本(通用嵌入式平台)
6
7// 公共寄存器定义
8mod registers;
9
10use bitflags::Flags;
11use rdif_serial::{
12    Config, ConfigError, DataBits, IrqRxSink, Parity, RxErrorFlags, RxFlag, RxSample,
13    SerialEventSet, SerialIrqEvent, SplitUart, StopBits, UartInfo, UartIrq, UartParts, UartPort,
14};
15use registers::*;
16
17use crate::{PollingUart, SerialDirection, SerialEvent, TransBytesError, TransferError};
18
19pub mod dw_apb;
20#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
21mod pio;
22pub mod rockchip_fiq;
23// MMIO 版本(通用)
24mod mmio;
25
26pub use dw_apb::*;
27pub use mmio::*;
28#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
29pub use pio::*;
30pub use rockchip_fiq::*;
31
32pub trait Kind: Clone + Send + Sync + 'static {
33    fn read_reg(&self, reg: u8) -> u8;
34    fn write_reg(&self, reg: u8, val: u8);
35    fn get_base(&self) -> usize;
36
37    fn ack_busy_detect(&self) {}
38
39    fn set_baudrate(&self, clock_freq: u32, baudrate: u32) -> Result<(), ConfigError> {
40        if baudrate == 0 || clock_freq == 0 {
41            return Err(ConfigError::InvalidBaudrate);
42        }
43
44        let divisor = clock_freq / (16 * baudrate);
45        if divisor == 0 || divisor > 0xFFFF {
46            return Err(ConfigError::InvalidBaudrate);
47        }
48
49        let lcr: LineControlFlags = self.read_flags(UART_LCR);
50        self.write_flags(UART_LCR, lcr | LineControlFlags::DIVISOR_LATCH_ACCESS);
51
52        self.write_reg(UART_DLL, (divisor & 0xFF) as u8);
53        self.write_reg(UART_DLH, ((divisor >> 8) & 0xFF) as u8);
54
55        self.write_flags(UART_LCR, lcr);
56
57        Ok(())
58    }
59
60    fn baudrate(&self, clock_freq: u32) -> u32 {
61        let lcr: LineControlFlags = self.read_flags(UART_LCR);
62        self.write_flags(UART_LCR, lcr | LineControlFlags::DIVISOR_LATCH_ACCESS);
63
64        let dll = self.read_reg(UART_DLL) as u16;
65        let dlh = self.read_reg(UART_DLH) as u16;
66
67        self.write_flags(UART_LCR, lcr);
68
69        let divisor = dll | (dlh << 8);
70
71        if divisor == 0 {
72            return 0;
73        }
74
75        clock_freq / (16 * divisor as u32)
76    }
77
78    fn init(&self) {
79        self.write_flags(UART_IER, InterruptEnableFlags::empty());
80        self.write_flags(
81            UART_FCR,
82            FifoControlFlags::ENABLE_FIFO
83                | FifoControlFlags::CLEAR_RECEIVER_FIFO
84                | FifoControlFlags::CLEAR_TRANSMITTER_FIFO
85                | FifoControlFlags::TRIGGER_1_BYTE,
86        );
87
88        let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
89        mcr.insert(
90            ModemControlFlags::DATA_TERMINAL_READY
91                | ModemControlFlags::REQUEST_TO_SEND
92                | ModemControlFlags::OUT_2,
93        );
94        self.write_flags(UART_MCR, mcr);
95    }
96
97    // 类型安全的 bitflags 寄存器访问
98    fn read_flags<F: Flags<Bits = u8>>(&self, reg: u8) -> F {
99        F::from_bits_retain(self.read_reg(reg))
100    }
101
102    fn write_flags<F: Flags<Bits = u8>>(&self, reg: u8, val: F) {
103        self.write_reg(reg, val.bits());
104    }
105}
106
107pub struct Ns16550<T: Kind> {
108    pub(crate) base: T,
109    pub(crate) clock_freq: u32,
110    pub(crate) saved_lsr: LineStatusFlags,
111}
112
113/// IRQ endpoint for an NS16550-compatible UART.
114pub struct Ns16550Irq<T: Kind> {
115    base: T,
116    saved_lsr: LineStatusFlags,
117}
118
119impl<T: Kind> Ns16550Irq<T> {
120    fn next_event(&self) -> Option<SerialEventSet> {
121        let iir: InterruptIdentificationFlags = self.base.read_flags(UART_IIR);
122        if iir.bits() & (UART_IIR_ID | UART_IIR_NO_INT) == UART_IIR_BUSY {
123            return Some(SerialEventSet::BUSY_DETECT);
124        }
125        if iir.contains(InterruptIdentificationFlags::NO_INTERRUPT_PENDING) {
126            return None;
127        }
128
129        let interrupt_id = iir & InterruptIdentificationFlags::INTERRUPT_ID_MASK;
130        let event = if interrupt_id == InterruptIdentificationFlags::RECEIVER_LINE_STATUS {
131            SerialEventSet::RX_STATUS
132        } else if interrupt_id == InterruptIdentificationFlags::RECEIVED_DATA_AVAILABLE {
133            SerialEventSet::RX_DATA
134        } else if interrupt_id == InterruptIdentificationFlags::CHARACTER_TIMEOUT {
135            SerialEventSet::RX_TIMEOUT
136        } else if interrupt_id == InterruptIdentificationFlags::TRANSMITTER_HOLDING_EMPTY {
137            SerialEventSet::TX_SPACE
138        } else if interrupt_id == InterruptIdentificationFlags::MODEM_STATUS {
139            SerialEventSet::MODEM_STATUS
140        } else {
141            SerialEventSet::FAULT
142        };
143        Some(event)
144    }
145
146    fn ack_modem_status(&self) {
147        let _: ModemStatusFlags = self.base.read_flags(UART_MSR);
148    }
149
150    fn ack_busy_detect(&self) {
151        self.base.ack_busy_detect();
152    }
153
154    fn mask(&self, events: SerialEventSet) {
155        let mut ier: InterruptEnableFlags = self.base.read_flags(UART_IER);
156        ier.remove(interrupt_enable_for_events(events));
157        self.base.write_flags(UART_IER, ier);
158    }
159}
160
161impl<T: Kind> UartIrq for Ns16550Irq<T> {
162    fn handle(&mut self, rx: &mut dyn IrqRxSink) -> Option<SerialIrqEvent> {
163        const IRQ_PASS_BUDGET: usize = 32;
164        const RX_SAMPLE_BUDGET: usize = 256;
165
166        let mut event = SerialIrqEvent::default();
167        let mut rx_samples = 0;
168        for _ in 0..IRQ_PASS_BUDGET {
169            let Some(current) = self.next_event() else {
170                break;
171            };
172            event.events |= current;
173            if current.intersects(SerialEventSet::RX) {
174                let before = rx_samples;
175                while rx_samples < RX_SAMPLE_BUDGET {
176                    let Some(sample) = read_rx_sample(&self.base, &mut self.saved_lsr) else {
177                        break;
178                    };
179                    event.rx_errors |= rx_errors_from_sample(sample);
180                    rx.push(sample);
181                    rx_samples += 1;
182                }
183                if rx_samples == RX_SAMPLE_BUDGET || rx_samples == before {
184                    break;
185                }
186            }
187            if current.contains(SerialEventSet::MODEM_STATUS) {
188                self.ack_modem_status();
189            }
190            if current.contains(SerialEventSet::BUSY_DETECT) {
191                self.ack_busy_detect();
192            }
193            if current.contains(SerialEventSet::FAULT) {
194                self.base
195                    .write_flags(UART_IER, InterruptEnableFlags::empty());
196                break;
197            }
198
199            let rearm = current & SerialEventSet::TX_SPACE;
200            if !rearm.is_empty() {
201                self.mask(rearm);
202                event.rearm |= rearm;
203            }
204        }
205
206        (!event.events.is_empty()).then_some(event)
207    }
208}
209
210impl<T: Kind> UartPort for Ns16550<T> {
211    fn startup(&mut self, config: &Config) -> Result<(), ConfigError> {
212        self.write_flags(UART_IER, InterruptEnableFlags::empty());
213        self.set_config(config)?;
214        self.enable_fifo(true);
215
216        let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
217        mcr.insert(
218            ModemControlFlags::DATA_TERMINAL_READY
219                | ModemControlFlags::REQUEST_TO_SEND
220                | ModemControlFlags::OUT_2,
221        );
222        self.write_flags(UART_MCR, mcr);
223        self.saved_lsr = LineStatusFlags::empty();
224        Ok(())
225    }
226
227    fn shutdown(&mut self) {
228        self.close();
229    }
230
231    fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
232        // 配置波特率
233        if let Some(baudrate) = config.baudrate {
234            self.set_baudrate_internal(baudrate)?;
235        }
236
237        // 配置数据位
238        if let Some(data_bits) = config.data_bits {
239            self.set_data_bits_internal(data_bits)?;
240        }
241
242        // 配置停止位
243        if let Some(stop_bits) = config.stop_bits {
244            self.set_stop_bits_internal(stop_bits)?;
245        }
246
247        // 配置奇偶校验
248        if let Some(parity) = config.parity {
249            self.set_parity_internal(parity)?;
250        }
251        Ok(())
252    }
253
254    fn read_rx(&mut self) -> Option<RxSample> {
255        Ns16550::read_rx(self)
256    }
257
258    fn write_tx(&mut self, bytes: &[u8]) -> usize {
259        self.try_write(bytes)
260    }
261
262    fn tx_idle(&mut self) -> bool {
263        let lsr: LineStatusFlags = self.read_flags(UART_LSR);
264        lsr.contains(
265            LineStatusFlags::TRANSMITTER_HOLDING_EMPTY | LineStatusFlags::TRANSMITTER_EMPTY,
266        )
267    }
268
269    fn mask_all(&mut self) {
270        self.write_flags(UART_IER, InterruptEnableFlags::empty());
271    }
272
273    fn rearm(&mut self, sources: SerialEventSet) -> SerialEventSet {
274        let mut ier: InterruptEnableFlags = self.read_flags(UART_IER);
275        ier.insert(interrupt_enable_for_events(sources));
276        self.write_flags(UART_IER, ier);
277
278        let lsr = self.read_lsr_preserving();
279        let mut ready = SerialEventSet::empty();
280        if sources.intersects(SerialEventSet::RX)
281            && lsr.intersects(LineStatusFlags::DATA_READY | LineStatusFlags::ERROR_MASK)
282        {
283            ready |= if lsr.contains(LineStatusFlags::DATA_READY) {
284                SerialEventSet::RX_DATA
285            } else {
286                SerialEventSet::RX_STATUS
287            };
288        }
289        if sources.contains(SerialEventSet::TX_SPACE)
290            && lsr.contains(LineStatusFlags::TRANSMITTER_HOLDING_EMPTY)
291        {
292            ready |= SerialEventSet::TX_SPACE;
293        }
294        if !ready.is_empty() {
295            ier.remove(interrupt_enable_for_events(ready));
296            self.write_flags(UART_IER, ier);
297        }
298        ready
299    }
300}
301
302impl<T: Kind> SplitUart for Ns16550<T> {
303    type Port = Self;
304    type Irq = Ns16550Irq<T>;
305
306    fn runtime_info(&self) -> UartInfo {
307        UartInfo {
308            name: "NS16550 UART",
309            register_base: self.base.get_base(),
310            initial_baudrate: self.base.baudrate(self.clock_freq),
311        }
312    }
313
314    fn split(self) -> UartParts<Self::Port, Self::Irq> {
315        let irq = Ns16550Irq {
316            base: self.base.clone(),
317            saved_lsr: LineStatusFlags::empty(),
318        };
319        UartParts::new(self, irq)
320    }
321}
322
323impl<T: Kind> PollingUart for Ns16550<T> {
324    fn poll_status(&mut self) -> SerialEvent {
325        Ns16550::poll_status(self)
326    }
327
328    fn write_byte(&mut self, byte: u8) {
329        Ns16550::write_byte(self, byte);
330    }
331
332    fn read_byte(&mut self, status: SerialEvent) -> Option<Result<u8, TransferError>> {
333        Ns16550::read_byte(self, status)
334    }
335}
336
337impl<T: Kind> Ns16550<T> {
338    // 类型安全的 bitflags 寄存器访问
339    fn read_flags<F: Flags<Bits = u8>>(&self, reg: u8) -> F {
340        F::from_bits_retain(self.base.read_reg(reg))
341    }
342
343    fn write_flags<F: Flags<Bits = u8>>(&mut self, reg: u8, val: F) {
344        self.base.write_reg(reg, val.bits());
345    }
346
347    pub fn pending(&mut self, direction: SerialDirection) -> bool {
348        let lsr = self.read_lsr_preserving();
349        match direction {
350            SerialDirection::Input => lsr.contains(LineStatusFlags::DATA_READY),
351            SerialDirection::Output => lsr.contains(LineStatusFlags::TRANSMITTER_HOLDING_EMPTY),
352        }
353    }
354
355    pub fn poll_status(&mut self) -> SerialEvent {
356        serial_event_from_lsr(self.read_lsr_preserving())
357    }
358
359    pub fn try_write(&mut self, bytes: &[u8]) -> usize {
360        let mut written = 0;
361        while written < bytes.len() {
362            let status = self.poll_status();
363            if !status.tx_ready() {
364                break;
365            }
366            self.write_byte(bytes[written]);
367            written += 1;
368        }
369        written
370    }
371
372    pub fn try_read(&mut self, bytes: &mut [u8]) -> Result<usize, TransBytesError> {
373        let mut read_count = 0;
374        let mut first_error = None;
375        for byte in bytes.iter_mut() {
376            let status = self.poll_status();
377            if !status.rx_ready() && !status.rx_error() {
378                break;
379            }
380            let result = self.read_byte(status);
381            match result {
382                Some(Ok(b)) => {
383                    *byte = b;
384                    read_count += 1;
385                }
386                Some(Err(TransferError::Overrun(b))) => {
387                    *byte = b;
388                    read_count += 1;
389                    first_error.get_or_insert(TransferError::Overrun(b));
390                }
391                Some(Err(e)) => {
392                    first_error.get_or_insert(e);
393                }
394                None => break,
395            }
396        }
397        if let Some(kind) = first_error {
398            Err(TransBytesError {
399                bytes_transferred: read_count,
400                kind,
401            })
402        } else {
403            Ok(read_count)
404        }
405    }
406
407    pub fn write_byte(&mut self, byte: u8) {
408        self.base.write_reg(UART_THR, byte);
409    }
410
411    pub fn read_rx(&mut self) -> Option<RxSample> {
412        read_rx_sample(&self.base, &mut self.saved_lsr)
413    }
414
415    fn read_lsr_preserving(&mut self) -> LineStatusFlags {
416        let lsr: LineStatusFlags = self.read_flags(UART_LSR);
417        self.saved_lsr
418            .insert(lsr & (LineStatusFlags::ERROR_MASK | LineStatusFlags::FIFO_ERROR));
419        lsr | self.saved_lsr
420    }
421
422    pub fn read_byte(&mut self, status: SerialEvent) -> Option<Result<u8, TransferError>> {
423        if !status.rx_ready() && !status.rx_error() {
424            return None;
425        }
426        if self.saved_lsr.contains(LineStatusFlags::OVERRUN_ERROR) {
427            let b = self.base.read_reg(UART_RBR);
428            self.saved_lsr.remove(LineStatusFlags::OVERRUN_ERROR);
429            return Some(Err(TransferError::Overrun(b)));
430        }
431        if self.saved_lsr.contains(LineStatusFlags::PARITY_ERROR) {
432            let _ = self.base.read_reg(UART_RBR);
433            self.saved_lsr.remove(LineStatusFlags::PARITY_ERROR);
434            return Some(Err(TransferError::Parity));
435        }
436        if self.saved_lsr.contains(LineStatusFlags::FRAMING_ERROR) {
437            let _ = self.base.read_reg(UART_RBR);
438            self.saved_lsr.remove(LineStatusFlags::FRAMING_ERROR);
439            return Some(Err(TransferError::Framing));
440        }
441        if self.saved_lsr.contains(LineStatusFlags::BREAK_INTERRUPT) {
442            let _ = self.base.read_reg(UART_RBR);
443            self.saved_lsr.remove(LineStatusFlags::BREAK_INTERRUPT);
444            return Some(Err(TransferError::Break));
445        }
446        if status.rx_ready() {
447            return Some(Ok(self.base.read_reg(UART_RBR)));
448        }
449        None
450    }
451
452    pub fn open(&mut self) {
453        self.init_core();
454    }
455
456    pub fn close(&mut self) {
457        self.write_flags(UART_IER, InterruptEnableFlags::empty());
458
459        let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
460        mcr.remove(ModemControlFlags::DATA_TERMINAL_READY | ModemControlFlags::REQUEST_TO_SEND);
461        self.write_flags(UART_MCR, mcr);
462    }
463
464    pub fn set_irq_mask(&mut self, events: SerialEventSet) {
465        self.write_flags(UART_IER, interrupt_enable_for_events(events));
466    }
467
468    pub fn get_irq_mask(&self) -> SerialEventSet {
469        let ier: InterruptEnableFlags = self.read_flags(UART_IER);
470        let mut events = SerialEventSet::empty();
471
472        if ier.contains(InterruptEnableFlags::RECEIVED_DATA_AVAILABLE) {
473            events |= SerialEventSet::RX_DATA;
474        }
475        if ier.contains(InterruptEnableFlags::RECEIVER_LINE_STATUS) {
476            events |= SerialEventSet::RX_STATUS;
477        }
478        if ier.contains(InterruptEnableFlags::TRANSMITTER_HOLDING_EMPTY) {
479            events |= SerialEventSet::TX_SPACE;
480        }
481
482        events
483    }
484
485    /// 检查是否为 16550+(支持 FIFO)
486    pub fn is_16550_plus(&self) -> bool {
487        // 通过读取 IIR 寄存器的 FIFO 位来判断
488        // IIR 的位7-6在 16550+ 中会显示 FIFO 启用状态
489        let fifo: InterruptIdentificationFlags = self.read_flags(UART_IIR);
490        fifo.contains(InterruptIdentificationFlags::FIFO_ENABLE_MASK)
491    }
492
493    /// 设置波特率
494    fn set_baudrate_internal(&mut self, baudrate: u32) -> Result<(), ConfigError> {
495        self.base.set_baudrate(self.clock_freq, baudrate)
496    }
497
498    /// 设置数据位
499    fn set_data_bits_internal(&mut self, bits: DataBits) -> Result<(), ConfigError> {
500        let wlen = match bits {
501            DataBits::Five => LineControlFlags::WORD_LENGTH_5,
502            DataBits::Six => LineControlFlags::WORD_LENGTH_6,
503            DataBits::Seven => LineControlFlags::WORD_LENGTH_7,
504            DataBits::Eight => LineControlFlags::WORD_LENGTH_8,
505        };
506
507        let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
508        // 清除旧的数据位设置,然后设置新的
509        lcr.remove(LineControlFlags::WORD_LENGTH_MASK);
510        lcr.insert(wlen);
511        self.write_flags(UART_LCR, lcr);
512
513        Ok(())
514    }
515
516    /// 设置停止位
517    fn set_stop_bits_internal(&mut self, bits: StopBits) -> Result<(), ConfigError> {
518        let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
519        match bits {
520            StopBits::One => lcr.remove(LineControlFlags::STOP_BITS),
521            StopBits::Two => lcr.insert(LineControlFlags::STOP_BITS),
522        }
523        self.write_flags(UART_LCR, lcr);
524        Ok(())
525    }
526
527    /// 设置奇偶校验
528    fn set_parity_internal(&mut self, parity: Parity) -> Result<(), ConfigError> {
529        let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
530
531        // 先清除所有校验相关位
532        lcr.remove(
533            LineControlFlags::PARITY_ENABLE
534                | LineControlFlags::EVEN_PARITY
535                | LineControlFlags::STICK_PARITY,
536        );
537
538        // 根据校验类型设置相应位
539        match parity {
540            Parity::None => {
541                // 已经清除,无需额外操作
542            }
543            Parity::Odd => {
544                lcr.insert(LineControlFlags::PARITY_ENABLE);
545            }
546            Parity::Even => {
547                lcr.insert(LineControlFlags::PARITY_ENABLE | LineControlFlags::EVEN_PARITY);
548            }
549            Parity::Mark => {
550                lcr.insert(LineControlFlags::PARITY_ENABLE | LineControlFlags::STICK_PARITY);
551            }
552            Parity::Space => {
553                lcr.insert(
554                    LineControlFlags::PARITY_ENABLE
555                        | LineControlFlags::EVEN_PARITY
556                        | LineControlFlags::STICK_PARITY,
557                );
558            }
559        }
560
561        self.write_flags(UART_LCR, lcr);
562        Ok(())
563    }
564
565    /// 启用或禁用 FIFO
566    pub fn enable_fifo(&mut self, enable: bool) {
567        if enable {
568            let mut fcr = FifoControlFlags::ENABLE_FIFO;
569            fcr.insert(FifoControlFlags::CLEAR_RECEIVER_FIFO);
570            fcr.insert(FifoControlFlags::CLEAR_TRANSMITTER_FIFO);
571            // Match Linux's 16550A default. A half-full threshold leaves FIFO
572            // headroom for deferred service while avoiding one IRQ wakeup per
573            // character on high-baudrate DesignWare UARTs.
574            fcr.insert(FifoControlFlags::TRIGGER_8_BYTES);
575            self.write_flags(UART_FCR, fcr);
576            if self.is_fifo_enabled() {
577                return;
578            }
579        }
580        self.write_flags(UART_FCR, FifoControlFlags::empty());
581    }
582
583    /// 设置 FIFO 触发级别
584    pub fn set_fifo_trigger_level(&mut self, level: u8) {
585        if !self.is_16550_plus() {
586            return;
587        }
588
589        let trigger_value = match level {
590            0..=3 => FifoControlFlags::TRIGGER_1_BYTE,
591            4..=7 => FifoControlFlags::TRIGGER_4_BYTES,
592            8..=11 => FifoControlFlags::TRIGGER_8_BYTES,
593            _ => FifoControlFlags::TRIGGER_14_BYTES,
594        };
595
596        // 读取当前 FCR 设置,清除触发级别位,然后设置新的触发级别
597        let mut fcr: FifoControlFlags = self.read_flags(UART_FCR);
598        fcr.remove(FifoControlFlags::TRIGGER_LEVEL_MASK);
599        fcr.insert(trigger_value);
600        self.write_flags(UART_FCR, fcr);
601    }
602
603    /// 初始化 UART
604    fn init_core(&mut self) {
605        self.base.init();
606    }
607
608    /// 检查 FIFO 是否启用
609    pub fn is_fifo_enabled(&self) -> bool {
610        if !self.is_16550_plus() {
611            return false;
612        }
613        // 通过检查 IIR 的 FIFO 位来判断
614        let iir: InterruptIdentificationFlags = self.read_flags(UART_IIR);
615        iir.contains(InterruptIdentificationFlags::FIFO_ENABLE_MASK)
616    }
617}
618
619fn read_rx_sample<T: Kind>(base: &T, saved_lsr: &mut LineStatusFlags) -> Option<RxSample> {
620    let current: LineStatusFlags = base.read_flags(UART_LSR);
621    saved_lsr.insert(current & (LineStatusFlags::ERROR_MASK | LineStatusFlags::FIFO_ERROR));
622    let lsr = current | *saved_lsr;
623    if !lsr.intersects(LineStatusFlags::DATA_READY | LineStatusFlags::ERROR_MASK) {
624        return None;
625    }
626
627    let byte = lsr
628        .contains(LineStatusFlags::DATA_READY)
629        .then(|| base.read_reg(UART_RBR));
630    let flag = if lsr.contains(LineStatusFlags::BREAK_INTERRUPT) {
631        RxFlag::Break
632    } else if lsr.contains(LineStatusFlags::PARITY_ERROR) {
633        RxFlag::Parity
634    } else if lsr.contains(LineStatusFlags::FRAMING_ERROR) {
635        RxFlag::Framing
636    } else {
637        RxFlag::Normal
638    };
639    let overrun = lsr.contains(LineStatusFlags::OVERRUN_ERROR);
640    saved_lsr.remove(LineStatusFlags::ERROR_MASK | LineStatusFlags::FIFO_ERROR);
641
642    Some(RxSample {
643        byte,
644        flag,
645        overrun,
646    })
647}
648
649fn rx_errors_from_sample(sample: RxSample) -> RxErrorFlags {
650    let mut errors = match sample.flag {
651        RxFlag::Normal => RxErrorFlags::empty(),
652        RxFlag::Break => RxErrorFlags::BREAK,
653        RxFlag::Parity => RxErrorFlags::PARITY,
654        RxFlag::Framing => RxErrorFlags::FRAMING,
655    };
656    if sample.overrun {
657        errors |= RxErrorFlags::OVERRUN;
658    }
659    errors
660}
661
662fn interrupt_enable_for_events(events: SerialEventSet) -> InterruptEnableFlags {
663    let mut ier = InterruptEnableFlags::empty();
664    if events.intersects(SerialEventSet::RX) {
665        ier.insert(
666            InterruptEnableFlags::RECEIVED_DATA_AVAILABLE
667                | InterruptEnableFlags::RECEIVER_LINE_STATUS,
668        );
669    }
670    if events.contains(SerialEventSet::TX_SPACE) {
671        ier.insert(InterruptEnableFlags::TRANSMITTER_HOLDING_EMPTY);
672    }
673    ier
674}
675
676fn serial_event_from_lsr(lsr: LineStatusFlags) -> SerialEvent {
677    let mut event = SerialEvent::empty();
678    if lsr.contains(LineStatusFlags::DATA_READY) {
679        event |= SerialEvent::RX_READY;
680    }
681    if lsr.intersects(
682        LineStatusFlags::PARITY_ERROR
683            | LineStatusFlags::FRAMING_ERROR
684            | LineStatusFlags::BREAK_INTERRUPT,
685    ) {
686        event |= SerialEvent::RX_ERROR;
687    }
688    if lsr.contains(LineStatusFlags::OVERRUN_ERROR) {
689        event |= SerialEvent::RX_ERROR | SerialEvent::OVERRUN;
690    }
691    if lsr.contains(LineStatusFlags::TRANSMITTER_HOLDING_EMPTY) {
692        event |= SerialEvent::TX_READY;
693    }
694    event
695}
696
697#[cfg(test)]
698mod tests {
699    use core::sync::atomic::{AtomicU8, AtomicUsize, Ordering};
700    use std::{
701        sync::{Arc, Mutex, MutexGuard},
702        vec::Vec,
703    };
704
705    use super::*;
706
707    static REGS: [AtomicU8; 8] = [const { AtomicU8::new(0) }; 8];
708    static DLL_REG: AtomicU8 = AtomicU8::new(0);
709    static DLH_REG: AtomicU8 = AtomicU8::new(0);
710    static THR_WRITES: AtomicUsize = AtomicUsize::new(0);
711    static RBR_READS: AtomicUsize = AtomicUsize::new(0);
712    static LSR_READS: AtomicUsize = AtomicUsize::new(0);
713    static LAST_FCR_WRITE: AtomicU8 = AtomicU8::new(0);
714    static TEST_LOCK: Mutex<()> = Mutex::new(());
715
716    #[derive(Default)]
717    struct CollectRx(Vec<RxSample>);
718
719    impl IrqRxSink for CollectRx {
720        fn push(&mut self, sample: RxSample) {
721            self.0.push(sample);
722        }
723    }
724
725    fn handle_irq(irq: &mut impl UartIrq) -> (Option<SerialIrqEvent>, Vec<RxSample>) {
726        let mut rx = CollectRx::default();
727        let event = irq.handle(&mut rx);
728        (event, rx.0)
729    }
730
731    #[derive(Clone)]
732    struct MockKind;
733
734    impl Kind for MockKind {
735        fn read_reg(&self, reg: u8) -> u8 {
736            let dlab = REGS[UART_LCR as usize].load(Ordering::SeqCst)
737                & LineControlFlags::DIVISOR_LATCH_ACCESS.bits()
738                != 0;
739            if dlab {
740                return match reg {
741                    UART_DLL => DLL_REG.load(Ordering::SeqCst),
742                    UART_DLH => DLH_REG.load(Ordering::SeqCst),
743                    _ => REGS[reg as usize].load(Ordering::SeqCst),
744                };
745            }
746
747            let value = REGS[reg as usize].load(Ordering::SeqCst);
748            if reg == UART_LSR {
749                LSR_READS.fetch_add(1, Ordering::SeqCst);
750            }
751            if reg == UART_RBR {
752                RBR_READS.fetch_add(1, Ordering::SeqCst);
753                REGS[UART_LSR as usize].fetch_and(
754                    !(LineStatusFlags::ERROR_MASK | LineStatusFlags::DATA_READY).bits(),
755                    Ordering::SeqCst,
756                );
757            } else if reg == UART_MSR {
758                REGS[UART_MSR as usize]
759                    .fetch_and(!ModemStatusFlags::DELTA_MASK.bits(), Ordering::SeqCst);
760            }
761            value
762        }
763
764        fn write_reg(&self, reg: u8, val: u8) {
765            let dlab = REGS[UART_LCR as usize].load(Ordering::SeqCst)
766                & LineControlFlags::DIVISOR_LATCH_ACCESS.bits()
767                != 0;
768            if dlab {
769                match reg {
770                    UART_DLL => {
771                        DLL_REG.store(val, Ordering::SeqCst);
772                        return;
773                    }
774                    UART_DLH => {
775                        DLH_REG.store(val, Ordering::SeqCst);
776                        return;
777                    }
778                    _ => {}
779                }
780            }
781
782            REGS[reg as usize].store(val, Ordering::SeqCst);
783            if reg == UART_FCR {
784                LAST_FCR_WRITE.store(val, Ordering::SeqCst);
785                if val & FifoControlFlags::ENABLE_FIFO.bits() != 0 {
786                    REGS[UART_IIR as usize].fetch_or(
787                        InterruptIdentificationFlags::FIFO_ENABLE_MASK.bits(),
788                        Ordering::SeqCst,
789                    );
790                } else {
791                    REGS[UART_IIR as usize].fetch_and(
792                        !InterruptIdentificationFlags::FIFO_ENABLE_MASK.bits(),
793                        Ordering::SeqCst,
794                    );
795                }
796            }
797            if reg == UART_THR {
798                let iir = REGS[UART_IIR as usize].load(Ordering::SeqCst);
799                if iir & InterruptIdentificationFlags::FIFO_ENABLE_MASK.bits() == 0 {
800                    REGS[UART_LSR as usize].fetch_and(
801                        !LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
802                        Ordering::SeqCst,
803                    );
804                } else {
805                    let writes = THR_WRITES.fetch_add(1, Ordering::SeqCst) + 1;
806                    if writes >= UART_FIFO_SIZE as usize {
807                        REGS[UART_LSR as usize].fetch_and(
808                            !LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
809                            Ordering::SeqCst,
810                        );
811                    }
812                }
813            }
814        }
815
816        fn get_base(&self) -> usize {
817            0x1000
818        }
819    }
820
821    #[derive(Clone)]
822    struct FloodKind {
823        rbr_reads: Arc<AtomicUsize>,
824    }
825
826    impl Kind for FloodKind {
827        fn read_reg(&self, reg: u8) -> u8 {
828            match reg {
829                UART_IIR => InterruptIdentificationFlags::RECEIVED_DATA_AVAILABLE.bits(),
830                UART_LSR => LineStatusFlags::DATA_READY.bits(),
831                UART_RBR => self.rbr_reads.fetch_add(1, Ordering::SeqCst) as u8,
832                _ => 0,
833            }
834        }
835
836        fn write_reg(&self, _reg: u8, _val: u8) {}
837
838        fn get_base(&self) -> usize {
839            0x2000
840        }
841    }
842
843    fn reset_regs() {
844        for reg in &REGS {
845            reg.store(0, Ordering::SeqCst);
846        }
847        DLL_REG.store(0, Ordering::SeqCst);
848        DLH_REG.store(0, Ordering::SeqCst);
849        THR_WRITES.store(0, Ordering::SeqCst);
850        RBR_READS.store(0, Ordering::SeqCst);
851        LSR_READS.store(0, Ordering::SeqCst);
852        LAST_FCR_WRITE.store(0, Ordering::SeqCst);
853    }
854
855    fn serial() -> (MutexGuard<'static, ()>, Ns16550<MockKind>) {
856        let guard = TEST_LOCK.lock().unwrap_or_else(|error| error.into_inner());
857        reset_regs();
858        (
859            guard,
860            Ns16550 {
861                base: MockKind,
862                clock_freq: 1_843_200,
863                saved_lsr: LineStatusFlags::empty(),
864            },
865        )
866    }
867
868    fn started_parts(
869        uart: Ns16550<MockKind>,
870    ) -> UartParts<Ns16550<MockKind>, Ns16550Irq<MockKind>> {
871        let mut parts = uart.split();
872        parts.port.startup(&Config::new()).unwrap();
873        parts
874    }
875
876    #[test]
877    fn baudrate_reads_divisor_latch_without_consuming_rx_register() {
878        let (_guard, uart) = serial();
879        let original_lcr = LineControlFlags::WORD_LENGTH_8 | LineControlFlags::STOP_BITS;
880        REGS[UART_LCR as usize].store(original_lcr.bits(), Ordering::SeqCst);
881        REGS[UART_LSR as usize].store(LineStatusFlags::DATA_READY.bits(), Ordering::SeqCst);
882        REGS[UART_RBR as usize].store(0, Ordering::SeqCst);
883        REGS[UART_IER as usize].store(0, Ordering::SeqCst);
884        DLL_REG.store(1, Ordering::SeqCst);
885        DLH_REG.store(0, Ordering::SeqCst);
886
887        assert_eq!(uart.runtime_info().initial_baudrate, 115_200);
888        assert_eq!(
889            REGS[UART_LCR as usize].load(Ordering::SeqCst),
890            original_lcr.bits()
891        );
892        assert!(
893            LineStatusFlags::from_bits_retain(REGS[UART_LSR as usize].load(Ordering::SeqCst))
894                .contains(LineStatusFlags::DATA_READY)
895        );
896    }
897
898    #[test]
899    fn pending_output_preserves_rx_error_latch() {
900        let (_guard, mut uart) = serial();
901        REGS[UART_LSR as usize].store(
902            (LineStatusFlags::TRANSMITTER_HOLDING_EMPTY | LineStatusFlags::PARITY_ERROR).bits(),
903            Ordering::SeqCst,
904        );
905
906        assert!(uart.pending(SerialDirection::Output));
907
908        REGS[UART_LSR as usize].store(LineStatusFlags::DATA_READY.bits(), Ordering::SeqCst);
909        let mut buf = [0];
910        let err = uart
911            .try_read(&mut buf)
912            .expect_err("saved parity error should be reported by next read");
913        assert_eq!(err.bytes_transferred, 0);
914        assert_eq!(err.kind, TransferError::Parity);
915    }
916
917    #[test]
918    fn try_write_stops_when_tx_fifo_becomes_full() {
919        let (_guard, mut uart) = serial();
920        REGS[UART_LSR as usize].store(
921            LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
922            Ordering::SeqCst,
923        );
924
925        assert_eq!(uart.try_write(b"ab"), 1);
926        assert_eq!(REGS[UART_THR as usize].load(Ordering::SeqCst), b'a');
927    }
928
929    #[test]
930    fn try_write_fills_enabled_tx_fifo_in_one_pass() {
931        let (_guard, mut uart) = serial();
932        REGS[UART_LSR as usize].store(
933            LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
934            Ordering::SeqCst,
935        );
936        REGS[UART_IIR as usize].store(
937            InterruptIdentificationFlags::FIFO_ENABLE_MASK.bits(),
938            Ordering::SeqCst,
939        );
940
941        assert_eq!(uart.try_write(b"abcdefghijklmnopq"), 16);
942        assert_eq!(REGS[UART_THR as usize].load(Ordering::SeqCst), b'p');
943    }
944
945    #[test]
946    fn open_enables_modem_interrupt_output_gate() {
947        let (_guard, mut uart) = serial();
948
949        uart.open();
950
951        let fcr = FifoControlFlags::from_bits_retain(LAST_FCR_WRITE.load(Ordering::SeqCst));
952        assert!(fcr.contains(FifoControlFlags::ENABLE_FIFO));
953        assert!(fcr.contains(FifoControlFlags::CLEAR_RECEIVER_FIFO));
954        assert!(fcr.contains(FifoControlFlags::CLEAR_TRANSMITTER_FIFO));
955        let mcr =
956            ModemControlFlags::from_bits_retain(REGS[UART_MCR as usize].load(Ordering::SeqCst));
957        assert!(mcr.contains(ModemControlFlags::DATA_TERMINAL_READY));
958        assert!(mcr.contains(ModemControlFlags::REQUEST_TO_SEND));
959        assert!(mcr.contains(ModemControlFlags::OUT_2));
960    }
961
962    #[test]
963    fn startup_enables_fifo_before_checking_fifo_status() {
964        let (_guard, mut uart) = serial();
965
966        uart.startup(&Config::new()).unwrap();
967
968        let iir = InterruptIdentificationFlags::from_bits_retain(
969            REGS[UART_IIR as usize].load(Ordering::SeqCst),
970        );
971        assert!(iir.contains(InterruptIdentificationFlags::FIFO_ENABLE_MASK));
972        assert_eq!(THR_WRITES.load(Ordering::SeqCst), 0);
973    }
974
975    #[test]
976    fn startup_uses_half_full_rx_trigger_for_deferred_service() {
977        let (_guard, mut uart) = serial();
978
979        uart.startup(&Config::new()).unwrap();
980
981        let fcr = FifoControlFlags::from_bits_retain(LAST_FCR_WRITE.load(Ordering::SeqCst));
982        assert_eq!(
983            fcr & FifoControlFlags::TRIGGER_LEVEL_MASK,
984            FifoControlFlags::TRIGGER_8_BYTES,
985            "deferred RX service must amortize IRQ wakeups at the Linux 16550A default trigger",
986        );
987    }
988
989    #[test]
990    fn try_read_empty_returns_zero() {
991        let (_guard, mut uart) = serial();
992        let mut buf = [0];
993
994        assert_eq!(uart.try_read(&mut buf), Ok(0));
995    }
996
997    #[test]
998    fn irq_reports_rx_error_and_buffers_fifo_data() {
999        let (_guard, uart) = serial();
1000        let mut parts = uart.split();
1001        REGS[UART_IIR as usize].store(
1002            InterruptIdentificationFlags::RECEIVER_LINE_STATUS.bits(),
1003            Ordering::SeqCst,
1004        );
1005        REGS[UART_LSR as usize].store(
1006            (LineStatusFlags::DATA_READY | LineStatusFlags::OVERRUN_ERROR).bits(),
1007            Ordering::SeqCst,
1008        );
1009        REGS[UART_RBR as usize].store(0xab, Ordering::SeqCst);
1010
1011        let (event, samples) = handle_irq(&mut parts.irq);
1012        let event = event.unwrap();
1013        assert!(event.events.contains(SerialEventSet::RX_STATUS));
1014        assert!(event.rx_errors.contains(RxErrorFlags::OVERRUN));
1015        assert_eq!(
1016            samples,
1017            [RxSample {
1018                byte: Some(0xab),
1019                flag: RxFlag::Normal,
1020                overrun: true,
1021            }]
1022        );
1023        assert_eq!(RBR_READS.load(Ordering::SeqCst), 1);
1024    }
1025
1026    #[test]
1027    fn split_endpoints_service_rx_and_tx_fifo() {
1028        let (_guard, uart) = serial();
1029        let mut parts = started_parts(uart);
1030
1031        REGS[UART_IIR as usize].store(
1032            InterruptIdentificationFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
1033            Ordering::SeqCst,
1034        );
1035        REGS[UART_LSR as usize].store(
1036            LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
1037            Ordering::SeqCst,
1038        );
1039        let event = handle_irq(&mut parts.irq).0.unwrap();
1040        assert!(event.events.contains(SerialEventSet::TX_SPACE));
1041        assert_eq!(parts.port.write_tx(b"ab"), 1);
1042        assert_eq!(REGS[UART_THR as usize].load(Ordering::SeqCst), b'a');
1043
1044        REGS[UART_IIR as usize].store(
1045            InterruptIdentificationFlags::RECEIVED_DATA_AVAILABLE.bits(),
1046            Ordering::SeqCst,
1047        );
1048        REGS[UART_LSR as usize].store(LineStatusFlags::DATA_READY.bits(), Ordering::SeqCst);
1049        REGS[UART_RBR as usize].store(b'z', Ordering::SeqCst);
1050        let (event, samples) = handle_irq(&mut parts.irq);
1051        let event = event.unwrap();
1052        assert!(event.events.contains(SerialEventSet::RX_DATA));
1053        assert_eq!(
1054            samples,
1055            [RxSample {
1056                byte: Some(b'z'),
1057                flag: RxFlag::Normal,
1058                overrun: false,
1059            }]
1060        );
1061    }
1062
1063    #[test]
1064    fn hard_irq_drains_rx_before_deferred_worker_can_overrun_fifo() {
1065        let (_guard, uart) = serial();
1066        let mut parts = started_parts(uart);
1067        REGS[UART_IIR as usize].store(
1068            InterruptIdentificationFlags::RECEIVER_LINE_STATUS.bits(),
1069            Ordering::SeqCst,
1070        );
1071        REGS[UART_LSR as usize].store(
1072            (LineStatusFlags::DATA_READY | LineStatusFlags::PARITY_ERROR).bits(),
1073            Ordering::SeqCst,
1074        );
1075        LSR_READS.store(0, Ordering::SeqCst);
1076
1077        let (event, samples) = handle_irq(&mut parts.irq);
1078        let event = event.unwrap();
1079
1080        assert!(event.events.contains(SerialEventSet::RX_STATUS));
1081        assert!(event.rx_errors.contains(RxErrorFlags::PARITY));
1082        assert!(LSR_READS.load(Ordering::SeqCst) > 0);
1083        assert_eq!(
1084            RBR_READS.load(Ordering::SeqCst),
1085            1,
1086            "the hard IRQ must free a bounded hardware FIFO slot before the worker runs",
1087        );
1088        assert_eq!(THR_WRITES.load(Ordering::SeqCst), 0);
1089        assert_eq!(REGS[UART_LSR as usize].load(Ordering::SeqCst), 0);
1090        assert_eq!(
1091            samples,
1092            [RxSample {
1093                byte: Some(0),
1094                flag: RxFlag::Parity,
1095                overrun: false,
1096            }]
1097        );
1098    }
1099
1100    #[test]
1101    fn hard_irq_rx_drain_is_bounded_to_256_samples() {
1102        let reads = Arc::new(AtomicUsize::new(0));
1103        let mut irq = Ns16550Irq {
1104            base: FloodKind {
1105                rbr_reads: reads.clone(),
1106            },
1107            saved_lsr: LineStatusFlags::empty(),
1108        };
1109
1110        let (event, samples) = handle_irq(&mut irq);
1111
1112        assert!(event.unwrap().events.contains(SerialEventSet::RX_DATA));
1113        assert_eq!(samples.len(), 256);
1114        assert_eq!(reads.load(Ordering::SeqCst), 256);
1115    }
1116
1117    #[test]
1118    fn irq_endpoint_does_not_synthesize_tx_irq_from_plain_lsr_ready() {
1119        let (_guard, uart) = serial();
1120        let mut parts = started_parts(uart);
1121        REGS[UART_IIR as usize].store(
1122            InterruptIdentificationFlags::NO_INTERRUPT_PENDING.bits(),
1123            Ordering::SeqCst,
1124        );
1125        REGS[UART_LSR as usize].store(
1126            LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
1127            Ordering::SeqCst,
1128        );
1129
1130        assert!(handle_irq(&mut parts.irq).0.is_none());
1131    }
1132
1133    #[test]
1134    fn hard_irq_does_not_claim_tx_ready_without_iir_pending() {
1135        let (_guard, uart) = serial();
1136        let mut parts = uart.split();
1137        parts.port.set_irq_mask(SerialEventSet::TX_SPACE);
1138        REGS[UART_IIR as usize].store(
1139            InterruptIdentificationFlags::NO_INTERRUPT_PENDING.bits(),
1140            Ordering::SeqCst,
1141        );
1142        REGS[UART_LSR as usize].store(
1143            LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
1144            Ordering::SeqCst,
1145        );
1146
1147        assert!(handle_irq(&mut parts.irq).0.is_none());
1148        assert!(parts.port.poll_status().tx_ready());
1149    }
1150
1151    #[test]
1152    fn hard_irq_does_not_claim_rx_ready_without_iir_pending() {
1153        let (_guard, uart) = serial();
1154        let mut parts = uart.split();
1155        parts.port.set_irq_mask(SerialEventSet::RX);
1156        REGS[UART_IIR as usize].store(
1157            InterruptIdentificationFlags::NO_INTERRUPT_PENDING.bits(),
1158            Ordering::SeqCst,
1159        );
1160        REGS[UART_LSR as usize].store(LineStatusFlags::DATA_READY.bits(), Ordering::SeqCst);
1161
1162        assert!(handle_irq(&mut parts.irq).0.is_none());
1163        assert!(parts.port.poll_status().rx_ready());
1164    }
1165
1166    #[test]
1167    fn hard_irq_claims_and_clears_modem_status_interrupt() {
1168        let (_guard, uart) = serial();
1169        let mut parts = started_parts(uart);
1170
1171        REGS[UART_IIR as usize].store(
1172            InterruptIdentificationFlags::MODEM_STATUS.bits()
1173                | InterruptIdentificationFlags::FIFO_ENABLE_MASK.bits(),
1174            Ordering::SeqCst,
1175        );
1176        REGS[UART_MSR as usize].store(
1177            ModemStatusFlags::DELTA_CLEAR_TO_SEND.bits(),
1178            Ordering::SeqCst,
1179        );
1180
1181        let event = handle_irq(&mut parts.irq).0.unwrap();
1182        assert!(event.events.contains(SerialEventSet::MODEM_STATUS));
1183        assert!(
1184            ModemStatusFlags::from_bits_retain(REGS[UART_MSR as usize].load(Ordering::SeqCst))
1185                .intersection(ModemStatusFlags::DELTA_MASK)
1186                .is_empty()
1187        );
1188    }
1189
1190    #[test]
1191    fn irq_event_drains_rx_fifo_into_sink() {
1192        let (_guard, uart) = serial();
1193        let mut parts = started_parts(uart);
1194
1195        REGS[UART_IIR as usize].store(
1196            InterruptIdentificationFlags::RECEIVED_DATA_AVAILABLE.bits(),
1197            Ordering::SeqCst,
1198        );
1199        REGS[UART_LSR as usize].store(LineStatusFlags::DATA_READY.bits(), Ordering::SeqCst);
1200        REGS[UART_RBR as usize].store(b'r', Ordering::SeqCst);
1201
1202        let (event, samples) = handle_irq(&mut parts.irq);
1203        let event = event.unwrap();
1204        assert!(event.events.contains(SerialEventSet::RX_DATA));
1205        assert_eq!(
1206            samples,
1207            [RxSample {
1208                byte: Some(b'r'),
1209                flag: RxFlag::Normal,
1210                overrun: false,
1211            }]
1212        );
1213    }
1214
1215    #[test]
1216    fn tx_irq_exposes_space_without_owning_a_software_fifo() {
1217        let (_guard, uart) = serial();
1218        let mut parts = started_parts(uart);
1219
1220        REGS[UART_IIR as usize].store(
1221            InterruptIdentificationFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
1222            Ordering::SeqCst,
1223        );
1224        REGS[UART_LSR as usize].store(
1225            LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
1226            Ordering::SeqCst,
1227        );
1228
1229        let event = handle_irq(&mut parts.irq).0.unwrap();
1230        assert!(event.events.contains(SerialEventSet::TX_SPACE));
1231        assert_eq!(parts.port.write_tx(b"ab"), 1);
1232        assert_eq!(REGS[UART_THR as usize].load(Ordering::SeqCst), b'a');
1233    }
1234
1235    #[test]
1236    fn irq_lsr_error_is_preserved_in_buffered_sample() {
1237        let (_guard, uart) = serial();
1238        let mut parts = started_parts(uart);
1239
1240        REGS[UART_IIR as usize].store(
1241            InterruptIdentificationFlags::RECEIVER_LINE_STATUS.bits(),
1242            Ordering::SeqCst,
1243        );
1244        REGS[UART_LSR as usize].store(
1245            (LineStatusFlags::DATA_READY | LineStatusFlags::PARITY_ERROR).bits(),
1246            Ordering::SeqCst,
1247        );
1248        REGS[UART_RBR as usize].store(b'p', Ordering::SeqCst);
1249
1250        let (event, samples) = handle_irq(&mut parts.irq);
1251        let event = event.unwrap();
1252        assert!(event.rx_errors.contains(RxErrorFlags::PARITY));
1253        assert_eq!(
1254            samples,
1255            [RxSample {
1256                byte: Some(b'p'),
1257                flag: RxFlag::Parity,
1258                overrun: false,
1259            }]
1260        );
1261    }
1262
1263    #[test]
1264    fn port_rx_returns_current_byte_and_overrun_marker() {
1265        let (_guard, uart) = serial();
1266        let mut parts = started_parts(uart);
1267
1268        REGS[UART_IIR as usize].store(
1269            InterruptIdentificationFlags::RECEIVER_LINE_STATUS.bits(),
1270            Ordering::SeqCst,
1271        );
1272        REGS[UART_LSR as usize].store(
1273            (LineStatusFlags::DATA_READY | LineStatusFlags::OVERRUN_ERROR).bits(),
1274            Ordering::SeqCst,
1275        );
1276        REGS[UART_RBR as usize].store(b'S', Ordering::SeqCst);
1277
1278        assert_eq!(
1279            parts.port.read_rx(),
1280            Some(RxSample {
1281                byte: Some(b'S'),
1282                flag: RxFlag::Normal,
1283                overrun: true,
1284            })
1285        );
1286    }
1287
1288    #[test]
1289    fn irq_keeps_rx_source_enabled_after_draining_fifo() {
1290        let (_guard, uart) = serial();
1291        let mut parts = started_parts(uart);
1292        REGS[UART_IER as usize].store(UART_IER_RDI | UART_IER_RLSI, Ordering::SeqCst);
1293        REGS[UART_IIR as usize].store(UART_IIR_RDI, Ordering::SeqCst);
1294        REGS[UART_LSR as usize].store(LineStatusFlags::DATA_READY.bits(), Ordering::SeqCst);
1295        REGS[UART_RBR as usize].store(b'q', Ordering::SeqCst);
1296
1297        let (event, samples) = handle_irq(&mut parts.irq);
1298        let event = event.unwrap();
1299
1300        assert!(event.events.contains(SerialEventSet::RX_DATA));
1301        assert!(!event.rearm.intersects(SerialEventSet::RX));
1302        assert_eq!(
1303            REGS[UART_IER as usize].load(Ordering::SeqCst),
1304            UART_IER_RDI | UART_IER_RLSI
1305        );
1306        assert_eq!(RBR_READS.load(Ordering::SeqCst), 1);
1307        assert_eq!(samples[0].byte, Some(b'q'));
1308    }
1309
1310    #[test]
1311    fn rearm_remasks_a_source_that_is_already_ready() {
1312        let (_guard, mut uart) = serial();
1313        uart.startup(&Config::new()).unwrap();
1314        REGS[UART_LSR as usize].store(LineStatusFlags::DATA_READY.bits(), Ordering::SeqCst);
1315
1316        let ready = uart.rearm(SerialEventSet::RX);
1317
1318        assert_eq!(ready, SerialEventSet::RX_DATA);
1319        assert_eq!(REGS[UART_IER as usize].load(Ordering::SeqCst), 0);
1320    }
1321
1322    #[test]
1323    fn unknown_irq_source_masks_all_and_reports_fault() {
1324        let (_guard, uart) = serial();
1325        let mut parts = started_parts(uart);
1326        REGS[UART_IER as usize].store(0xff, Ordering::SeqCst);
1327        REGS[UART_IIR as usize].store(0x08, Ordering::SeqCst);
1328
1329        let event = handle_irq(&mut parts.irq).0.unwrap();
1330
1331        assert!(event.events.contains(SerialEventSet::FAULT));
1332        assert_eq!(REGS[UART_IER as usize].load(Ordering::SeqCst), 0);
1333        assert_eq!(RBR_READS.load(Ordering::SeqCst), 0);
1334        assert_eq!(THR_WRITES.load(Ordering::SeqCst), 0);
1335    }
1336}