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, 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;
24// MMIO 版本(通用)
25mod 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    /// Whether LSR.THRE grants a whole empty FIFO. Backends synthesizing THRE
35    /// from a not-full bit must instead recheck readiness after every byte.
36    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    /// Programs the divisor after validating all fallible parameters.
45    /// Implementations must not modify registers when returning `Err`.
46    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    // 类型安全的 bitflags 寄存器访问
105    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    /// Bytes accepted after THRE, established before the IRQ endpoint is live.
119    pub(crate) tx_load_size: usize,
120}
121
122/// IRQ endpoint for an NS16550-compatible UART.
123pub struct Ns16550Irq<T: Kind> {
124    base: T,
125    saved_lsr: LineStatusFlags,
126}
127
128/// Restricted non-blocking TX view used only for emergency output.
129pub 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        // Flush a posted MMIO write before the emergency path touches TX.
138        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            // Every current `Kind::set_baudrate` validates before its first
273            // register write, while the remaining typed settings are
274            // infallible. Restore the only register changed before config.
275            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        // 配置波特率
297        if let Some(baudrate) = config.baudrate {
298            self.set_baudrate_internal(baudrate)?;
299        }
300
301        // 配置数据位
302        if let Some(data_bits) = config.data_bits {
303            self.set_data_bits_internal(data_bits)?;
304        }
305
306        // 配置停止位
307        if let Some(stop_bits) = config.stop_bits {
308            self.set_stop_bits_internal(stop_bits)?;
309        }
310
311        // 配置奇偶校验
312        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        // Capture firmware FIFO mode before IIR reads belong to the IRQ owner.
407        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    // 类型安全的 bitflags 寄存器访问
435    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        // 16550 THRE means FIFO empty, not FIFO not-full. Once observed, the
460        // port owns one complete FIFO burst, as in Linux serial8250_tx_chars.
461        // Rechecking THRE after each byte would serialize output to one byte
462        // per interrupt even with 15 slots still available.
463        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    /// 检查是否为 16550+(支持 FIFO)
589    pub fn is_16550_plus(&self) -> bool {
590        // 通过读取 IIR 寄存器的 FIFO 位来判断
591        // IIR 的位7-6在 16550+ 中会显示 FIFO 启用状态
592        let fifo: InterruptIdentificationFlags = self.read_flags(UART_IIR);
593        fifo.contains(InterruptIdentificationFlags::FIFO_ENABLE_MASK)
594    }
595
596    /// 设置波特率
597    fn set_baudrate_internal(&mut self, baudrate: u32) -> Result<(), ConfigError> {
598        self.base.set_baudrate(self.clock_freq, baudrate)
599    }
600
601    /// 设置数据位
602    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        // 清除旧的数据位设置,然后设置新的
612        lcr.remove(LineControlFlags::WORD_LENGTH_MASK);
613        lcr.insert(wlen);
614        self.write_flags(UART_LCR, lcr);
615
616        Ok(())
617    }
618
619    /// 设置停止位
620    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    /// 设置奇偶校验
631    fn set_parity_internal(&mut self, parity: Parity) -> Result<(), ConfigError> {
632        let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
633
634        // 先清除所有校验相关位
635        lcr.remove(
636            LineControlFlags::PARITY_ENABLE
637                | LineControlFlags::EVEN_PARITY
638                | LineControlFlags::STICK_PARITY,
639        );
640
641        // 根据校验类型设置相应位
642        match parity {
643            Parity::None => {
644                // 已经清除,无需额外操作
645            }
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    /// 启用或禁用 FIFO
669    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            // Match Linux's 16550A default. A half-full threshold leaves FIFO
675            // headroom for deferred service while avoiding one IRQ wakeup per
676            // character on high-baudrate DesignWare UARTs.
677            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    /// 设置 FIFO 触发级别
689    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        // FCR is write-only and aliases IIR. Reading it would acknowledge an
702        // IRQ, then copy the interrupt ID into FIFO enable/reset bits. This
703        // driver uses FIFO mode without DMA; changing the RX trigger keeps
704        // FIFO enabled and does not issue either FIFO reset command.
705        self.write_flags(UART_FCR, FifoControlFlags::ENABLE_FIFO | trigger_value);
706    }
707
708    /// 初始化 UART
709    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    /// 检查 FIFO 是否启用
723    pub fn is_fifo_enabled(&self) -> bool {
724        if !self.is_16550_plus() {
725            return false;
726        }
727        // 通过检查 IIR 的 FIFO 位来判断
728        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                // THRE means empty, not not-full: it clears on the first byte
924                // even though an enabled 16550 FIFO still has 15 free slots.
925                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 &REGS {
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}