some_serial/ns16550/
mmio.rs1use rdif_serial::{BSerial, SerialDyn};
6
7use crate::ns16550::{Ns16550IrqHandler, Ns16550Reciever, Ns16550Sender};
8
9use super::{Kind, Ns16550};
10use core::ptr::NonNull;
11
12#[derive(Clone)]
13pub struct Mmio {
14 base: usize,
15 width: usize,
16}
17
18impl Kind for Mmio {
19 fn read_reg(&self, reg: u8) -> u8 {
20 unsafe {
21 let addr = self.base + (reg as usize) * self.width;
22 (addr as *const u8).read_volatile()
23 }
24 }
25
26 fn write_reg(&self, reg: u8, val: u8) {
27 unsafe {
28 let addr = self.base + (reg as usize) * self.width;
29 (addr as *mut u8).write_volatile(val);
30 }
31 }
32
33 fn get_base(&self) -> usize {
34 self.base
35 }
36}
37
38impl Ns16550<Mmio> {
39 pub fn new_mmio(base: NonNull<u8>, clock_freq: u32, reg_width: usize) -> Ns16550<Mmio> {
40 let base = Mmio {
41 base: base.as_ptr() as usize,
42 width: reg_width,
43 };
44
45 Ns16550 {
46 base: base.clone(),
47 clock_freq,
48 irq: Some(Ns16550IrqHandler { base: base.clone() }),
49 tx: Some(crate::Sender::Ns16550MmioSender(Ns16550Sender {
50 base: base.clone(),
51 })),
52 rx: Some(crate::Reciever::Ns16550MmioReciever(Ns16550Reciever {
53 base,
54 })),
55 }
56 }
57
58 pub fn new_mmio_boxed(base: NonNull<u8>, clock_freq: u32, reg_width: usize) -> BSerial {
59 SerialDyn::new_boxed(Ns16550::new_mmio(base, clock_freq, reg_width))
60 }
61
62 pub fn take_tx(&mut self) -> Option<crate::Sender> {
63 self.tx.take()
64 }
65
66 pub fn take_rx(&mut self) -> Option<crate::Reciever> {
67 self.rx.take()
68 }
69}