Skip to content
This repository was archived by the owner on Sep 2, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
2 changes: 0 additions & 2 deletions src/platform/aarch64_common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
88 changes: 67 additions & 21 deletions src/platform/aarch64_common/pl011.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,68 @@ use crate::mem::phys_to_virt;

const UART_BASE: PhysAddr = PhysAddr::from(axconfig::UART_PADDR);

static UART: SpinNoIrq<Pl011Uart> =
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<u8> {
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<Pl011Uart>,
#[cfg(feature = "irq")]
pub buffer: SpinNoIrq<RxRingBuffer>,
}

// static UART: SpinNoIrq<Pl011Uart> =
// 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');
Expand All @@ -25,30 +81,20 @@ pub fn putchar(c: u8) {

/// Reads a byte from the console, or returns [`None`] if no input is available.
pub fn getchar() -> Option<u8> {
UART.lock().getchar()
cfg_if::cfg_if! {
if #[cfg(feature = "irq")] {
UART.buffer.lock().pop()
}else{
UART.inner.lock().getchar()
}
}
}

/// Initialize the UART
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);
}
}
}
3 changes: 3 additions & 0 deletions src/platform/dummy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {}

Expand Down
5 changes: 3 additions & 2 deletions src/platform/mod.rs
Original file line number Diff line number Diff line change
@@ -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::*;
}
}
Expand Down