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