-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add crate axhal_plat & axhal_plat_macros
- Loading branch information
1 parent
ff44ac0
commit 626455d
Showing
13 changed files
with
502 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
[package] | ||
name = "axhal_plat" | ||
version = "0.1.0" | ||
description = "This crate defines unified interfaces for various hardware platforms." | ||
documentation = "https://docs.rs/axhal_plat" | ||
keywords = ["arceos", "hal", "hardware-abstraction-layer"] | ||
categories = ["embedded", "no-std", "hardware-support", "os"] | ||
edition.workspace = true | ||
authors.workspace = true | ||
license.workspace = true | ||
homepage.workspace = true | ||
repository.workspace = true | ||
|
||
[dependencies] | ||
memory_addr = "0.3" | ||
bitflags = "2.6" | ||
crate_interface = "0.1" | ||
handler_table = "0.1" | ||
axhal_plat_macros = { path = "../axhal_plat_macros", version = "0.1.0" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# axhal-plat | ||
|
||
This crate defines unified interfaces for various hardware platforms. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
//! Console input and output. | ||
use core::fmt::{Arguments, Result, Write}; | ||
|
||
/// Console input and output interface. | ||
#[def_plat_interface] | ||
pub trait ConsoleIf { | ||
/// Writes bytes to the console from input u8 slice. | ||
fn write_bytes(bytes: &[u8]); | ||
|
||
/// Reads bytes from the console into the given mutable slice. | ||
/// Returns the number of bytes read. | ||
fn read_bytes(bytes: &mut [u8]) -> usize; | ||
} | ||
|
||
struct EarlyConsole; | ||
|
||
impl Write for EarlyConsole { | ||
fn write_str(&mut self, s: &str) -> Result { | ||
write_bytes(s.as_bytes()); | ||
Ok(()) | ||
} | ||
} | ||
|
||
/// Simple console print operation. | ||
#[macro_export] | ||
macro_rules! console_print { | ||
($($arg:tt)*) => { | ||
$crate::console::__simple_print(format_args!($($arg)*)); | ||
} | ||
} | ||
|
||
/// Simple console print operation, with a newline. | ||
#[macro_export] | ||
macro_rules! console_println { | ||
() => { $crate::ax_print!("\n") }; | ||
($($arg:tt)*) => { | ||
$crate::console::__simple_print(format_args!("{}\n", format_args!($($arg)*))); | ||
} | ||
} | ||
|
||
#[doc(hidden)] | ||
pub fn __simple_print(fmt: Arguments) { | ||
EarlyConsole.write_fmt(fmt).unwrap(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
//! Platform initialization. | ||
/// Platform initialization interface. | ||
#[def_plat_interface] | ||
pub trait InitIf { | ||
/// Initializes the platform devices for the primary CPU. | ||
fn platform_init(); | ||
|
||
/// Initializes the platform devices for secondary CPUs. | ||
fn platform_init_secondary(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
//! Interrupt request (IRQ) handling. | ||
pub use handler_table::HandlerTable; | ||
|
||
/// The type if an IRQ handler. | ||
pub type IrqHandler = handler_table::Handler; | ||
|
||
/// IRQ management interface. | ||
#[def_plat_interface] | ||
pub trait IrqIf { | ||
/// Enables or disables the given IRQ. | ||
fn set_enable(vector: usize, enabled: bool); | ||
|
||
/// Registers an IRQ handler for the given IRQ. | ||
/// | ||
/// Returns `true` if the handler is successfully registered. | ||
fn register(vector: usize, handler: IrqHandler) -> bool; | ||
|
||
/// Unregisters the IRQ handler for the given IRQ. | ||
/// | ||
/// Returns the existing handler if it is registered, `None` otherwise. | ||
fn unregister(vector: usize) -> Option<IrqHandler>; | ||
|
||
/// Handles the IRQ. | ||
/// | ||
/// This function is called by the common interrupt handler. It should look | ||
/// up in the IRQ handler table and calls the corresponding handler. If | ||
/// necessary, it also acknowledges the interrupt controller after handling. | ||
fn handle(vector: usize); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#![no_std] | ||
#![doc = include_str!("../README.md")] | ||
|
||
#[macro_use] | ||
extern crate axhal_plat_macros; | ||
|
||
pub mod console; | ||
pub mod init; | ||
pub mod irq; | ||
pub mod mem; | ||
pub mod power; | ||
pub mod time; | ||
|
||
pub use axhal_plat_macros::{main, secondary_main}; | ||
pub use crate_interface::impl_interface as impl_plat_interface; | ||
|
||
#[doc(hidden)] | ||
pub mod __priv { | ||
pub use crate_interface::{call_interface, def_interface}; | ||
} | ||
|
||
/// Call the function decorated by [`crate::main`] for the primary core. | ||
pub fn call_main(cpu_hw_id: usize, dtb: usize) -> ! { | ||
unsafe { __axhal_plat_main(cpu_hw_id, dtb) } | ||
} | ||
|
||
/// Call the function decorated by [`crate::secondary_main`] for secondary cores. | ||
pub fn call_secondary_main(cpu_hw_id: usize) -> ! { | ||
unsafe { __axhal_plat_secondary_main(cpu_hw_id) } | ||
} | ||
|
||
unsafe extern "Rust" { | ||
fn __axhal_plat_main(cpu_hw_id: usize, dtb: usize) -> !; | ||
fn __axhal_plat_secondary_main(cpu_hw_id: usize) -> !; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
//! Physical memory information. | ||
use core::fmt; | ||
|
||
use memory_addr::{PhysAddr, PhysAddrRange}; | ||
|
||
bitflags::bitflags! { | ||
/// The flags of a physical memory region. | ||
#[derive(Clone, Copy)] | ||
pub struct MemRegionFlags: usize { | ||
/// Readable. | ||
const READ = 1 << 0; | ||
/// Writable. | ||
const WRITE = 1 << 1; | ||
/// Executable. | ||
const EXECUTE = 1 << 2; | ||
/// Device memory. (e.g., MMIO regions) | ||
const DEVICE = 1 << 4; | ||
/// Uncachable memory. (e.g., framebuffer) | ||
const UNCACHED = 1 << 5; | ||
/// Reserved memory, do not use for allocation. | ||
const RESERVED = 1 << 6; | ||
/// Free memory for allocation. | ||
const FREE = 1 << 7; | ||
} | ||
} | ||
|
||
impl fmt::Debug for MemRegionFlags { | ||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
fmt::Debug::fmt(&self.0, f) | ||
} | ||
} | ||
|
||
/// A physical memory region. | ||
#[derive(Debug, Clone, Copy)] | ||
pub struct PhysMemRegion { | ||
/// The start physical address of the region. | ||
pub paddr: PhysAddr, | ||
/// The size in bytes of the region. | ||
pub size: usize, | ||
/// The region flags, see [`MemRegionFlags`]. | ||
pub flags: MemRegionFlags, | ||
/// The region name, used for identification. | ||
pub name: &'static str, | ||
} | ||
|
||
impl PhysMemRegion { | ||
/// Returns a [`PhysAddrRange`] that represents its physical address range. | ||
pub fn pa_range(&self) -> PhysAddrRange { | ||
PhysAddrRange::from_start_size(self.paddr, self.size) | ||
} | ||
} | ||
|
||
/// Fills the `.bss` section with zeros. | ||
/// | ||
/// It requires the symbols `_sbss` and `_ebss` to be defined in the linker script. | ||
/// | ||
/// # Safety | ||
/// | ||
/// This function is unsafe because it writes `.bss` section directly. | ||
pub unsafe fn clear_bss() { | ||
unsafe { | ||
core::slice::from_raw_parts_mut(_sbss as usize as *mut u8, _ebss as usize - _sbss as usize) | ||
.fill(0); | ||
} | ||
} | ||
|
||
unsafe extern "C" { | ||
fn _sbss(); | ||
fn _ebss(); | ||
} | ||
|
||
/// Physical memory interface. | ||
#[def_plat_interface] | ||
pub trait MemIf { | ||
/// Returns all normal memory (RAM) regions on the platform. | ||
fn ram_regions() -> &'static [PhysMemRegion]; | ||
|
||
/// Returns all device memory (MMIO) regions on the platform. | ||
fn mmio_regions() -> &'static [PhysMemRegion]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
//! Power management. | ||
/// Power management interface. | ||
#[def_plat_interface] | ||
pub trait PowerIf { | ||
/// Bootstraps the given CPU with the given initial stack (in physical address). | ||
/// | ||
/// Where `cpu_id` is the logical CPU ID (0, 1, ..., N-1, N is the number of | ||
/// CPU cores on the platform). | ||
fn cpu_boot(cpu_id: usize, stack_top_paddr: usize); | ||
|
||
/// Shutdown the whole system, including all CPUs. | ||
fn system_off() -> !; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
//! Time-related operations. | ||
pub use core::time::Duration; | ||
|
||
/// A measurement of the system clock. | ||
/// | ||
/// Currently, it reuses the [`core::time::Duration`] type. But it does not | ||
/// represent a duration, but a clock time. | ||
pub type TimeValue = Duration; | ||
|
||
/// Number of milliseconds in a second. | ||
pub const MILLIS_PER_SEC: u64 = 1_000; | ||
/// Number of microseconds in a second. | ||
pub const MICROS_PER_SEC: u64 = 1_000_000; | ||
/// Number of nanoseconds in a second. | ||
pub const NANOS_PER_SEC: u64 = 1_000_000_000; | ||
/// Number of nanoseconds in a millisecond. | ||
pub const NANOS_PER_MILLIS: u64 = 1_000_000; | ||
/// Number of nanoseconds in a microsecond. | ||
pub const NANOS_PER_MICROS: u64 = 1_000; | ||
|
||
/// Time-related interfaces. | ||
#[def_plat_interface] | ||
pub trait TimeIf { | ||
/// Returns the current clock time in hardware ticks. | ||
fn current_ticks() -> u64; | ||
|
||
/// Converts hardware ticks to nanoseconds. | ||
fn ticks_to_nanos(ticks: u64) -> u64; | ||
|
||
/// Converts nanoseconds to hardware ticks. | ||
fn nanos_to_ticks(nanos: u64) -> u64; | ||
|
||
/// Return epoch offset in nanoseconds (wall time offset to monotonic clock start). | ||
fn epochoffset_nanos() -> u64; | ||
|
||
/// Set a one-shot timer. | ||
/// | ||
/// A timer interrupt will be triggered at the specified monotonic time deadline (in nanoseconds). | ||
fn set_oneshot_timer(deadline_ns: u64); | ||
} | ||
|
||
/// Returns nanoseconds elapsed since system boot. | ||
pub fn monotonic_time_nanos() -> u64 { | ||
ticks_to_nanos(current_ticks()) | ||
} | ||
|
||
/// Returns the time elapsed since system boot in [`TimeValue`]. | ||
pub fn monotonic_time() -> TimeValue { | ||
TimeValue::from_nanos(monotonic_time_nanos()) | ||
} | ||
|
||
/// Returns nanoseconds elapsed since epoch (also known as realtime). | ||
pub fn wall_time_nanos() -> u64 { | ||
monotonic_time_nanos() + epochoffset_nanos() | ||
} | ||
|
||
/// Returns the time elapsed since epoch (also known as realtime) in [`TimeValue`]. | ||
pub fn wall_time() -> TimeValue { | ||
TimeValue::from_nanos(monotonic_time_nanos() + epochoffset_nanos()) | ||
} | ||
|
||
/// Busy waiting for the given duration. | ||
pub fn busy_wait(dur: Duration) { | ||
busy_wait_until(wall_time() + dur); | ||
} | ||
|
||
/// Busy waiting until reaching the given deadline. | ||
pub fn busy_wait_until(deadline: TimeValue) { | ||
while wall_time() < deadline { | ||
core::hint::spin_loop(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
[package] | ||
name = "axhal_plat_macros" | ||
version = "0.1.0" | ||
description = "Unified operations for various hardware platforms" | ||
documentation = "https://docs.rs/axhal_plat_macros" | ||
keywords = ["arceos", "hal", "hardware-abstraction-layer", "macros"] | ||
categories = ["development-tools::procedural-macro-helpers"] | ||
edition.workspace = true | ||
authors.workspace = true | ||
license.workspace = true | ||
homepage.workspace = true | ||
repository.workspace = true | ||
|
||
[dependencies] | ||
proc-macro2 = "1.0" | ||
quote = "1.0" | ||
syn = { version = "2.0", features = ["full"] } | ||
|
||
[dev-dependencies] | ||
crate_interface = "0.1" | ||
|
||
[lib] | ||
proc-macro = true |
Oops, something went wrong.