diff --git a/src/lib.rs b/src/lib.rs index f7b8dce..483bb0e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -80,3 +80,6 @@ pub use self::platform::set_tss_stack_top; #[cfg(feature = "smp")] pub use self::platform::platform_init_secondary; + +#[cfg(target_arch = "aarch64")] +pub use self::platform::aarch64_common::*; \ No newline at end of file diff --git a/src/platform/aarch64_common/mod.rs b/src/platform/aarch64_common/mod.rs index 116d1ff..9f430d2 100644 --- a/src/platform/aarch64_common/mod.rs +++ b/src/platform/aarch64_common/mod.rs @@ -38,8 +38,6 @@ pub fn platform_init() { #[cfg(feature = "irq")] crate::platform::irq::init_primary(); crate::platform::time::init_percpu(); - #[cfg(feature = "irq")] - crate::platform::console::init_irq(); } /// Initializes the platform devices for secondary CPUs. diff --git a/src/platform/aarch64_common/pl011.rs b/src/platform/aarch64_common/pl011.rs index bee465e..27d8565 100644 --- a/src/platform/aarch64_common/pl011.rs +++ b/src/platform/aarch64_common/pl011.rs @@ -8,12 +8,68 @@ use crate::mem::phys_to_virt; const UART_BASE: PhysAddr = PhysAddr::from(axconfig::UART_PADDR); -static UART: SpinNoIrq = - SpinNoIrq::new(Pl011Uart::new(phys_to_virt(UART_BASE).as_mut_ptr())); +#[cfg(feature = "irq")] +const BUFFER_SIZE: usize = 128; + +#[cfg(feature = "irq")] +pub struct RxRingBuffer { + buffer: [u8; BUFFER_SIZE], + head: usize, + tail: usize, + empty: bool, +} + +#[cfg(feature = "irq")] +impl RxRingBuffer { + const fn new() -> Self { + RxRingBuffer { + buffer: [0_u8; BUFFER_SIZE], + head: 0_usize, + tail: 0_usize, + empty: true, + } + } + + pub fn push(&mut self, n: u8) { + if self.tail != self.head || self.empty { + self.buffer[self.tail] = n; + self.tail = (self.tail + 1) % BUFFER_SIZE; + self.empty = false; + } + } + + pub fn pop(&mut self) -> Option { + if self.empty { + None + } else { + let ret = self.buffer[self.head]; + self.head = (self.head + 1) % BUFFER_SIZE; + if self.head == self.tail { + self.empty = true; + } + Some(ret) + } + } +} + +pub struct Uart { + pub inner: SpinNoIrq, + #[cfg(feature = "irq")] + pub buffer: SpinNoIrq, +} + +// static UART: SpinNoIrq = +// SpinNoIrq::new(Pl011Uart::new(phys_to_virt(UART_BASE).as_mut_ptr())); + +pub static UART: Uart = Uart { + inner: SpinNoIrq::new(Pl011Uart::new(phys_to_virt(UART_BASE).as_mut_ptr())), + #[cfg(feature = "irq")] + buffer: SpinNoIrq::new(RxRingBuffer::new()), +}; /// Writes a byte to the console. pub fn putchar(c: u8) { - let mut uart = UART.lock(); + let mut uart = UART.inner.lock(); match c { b'\n' => { uart.putchar(b'\r'); @@ -25,7 +81,13 @@ pub fn putchar(c: u8) { /// Reads a byte from the console, or returns [`None`] if no input is available. pub fn getchar() -> Option { - UART.lock().getchar() + cfg_if::cfg_if! { + if #[cfg(feature = "irq")] { + UART.buffer.lock().pop() + }else{ + UART.inner.lock().getchar() + } + } } /// Initialize the UART @@ -33,22 +95,6 @@ pub fn init_early() { unsafe { crate::platform::aarch64_common::mem::idmap_device(UART_BASE.as_usize()); } - UART.lock().init(); + UART.inner.lock().init(); } -/// Set UART IRQ Enable -#[cfg(feature = "irq")] -pub fn init_irq() { - crate::irq::set_enable(crate::platform::irq::UART_IRQ_NUM, true); -} - -/// UART IRQ Handler -pub fn handle() { - let is_receive_interrupt = UART.lock().is_receive_interrupt(); - UART.lock().ack_interrupts(); - if is_receive_interrupt { - while let Some(c) = getchar() { - putchar(c); - } - } -} diff --git a/src/platform/dummy/mod.rs b/src/platform/dummy/mod.rs index 9dd4866..d6a1407 100644 --- a/src/platform/dummy/mod.rs +++ b/src/platform/dummy/mod.rs @@ -66,6 +66,9 @@ pub mod irq { /// The timer IRQ number. pub const TIMER_IRQ_NUM: usize = 0; + /// The Uart IRQ numbe + pub const UART_IRQ_NUM: usize = usize::MAX; + /// Enables or disables the given IRQ. pub fn set_enable(irq_num: usize, enabled: bool) {} diff --git a/src/platform/mod.rs b/src/platform/mod.rs index 937dc48..9c84fcf 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -1,8 +1,9 @@ //! Platform-specific operations. cfg_if::cfg_if! { - if #[cfg(target_arch = "aarch64")]{ - mod aarch64_common; + if #[cfg(target_arch = "aarch64")] + { + pub mod aarch64_common; pub use self::aarch64_common::*; } }