Skip to content

Commit

Permalink
port HAL for riscv64
Browse files Browse the repository at this point in the history
  • Loading branch information
n1tram1 committed Oct 2, 2024
1 parent 6c9fd3b commit ae0acf6
Show file tree
Hide file tree
Showing 17 changed files with 201 additions and 215 deletions.
15 changes: 15 additions & 0 deletions hal_aarch64/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,18 @@ unsafe extern "C" fn _start() -> ! {
options(noreturn)
);
}

pub struct Aarch64CoreInfo;

impl hal_core::CoreInfo for Aarch64CoreInfo {
fn init(_core_id: usize) {
// We just read MPIDR_EL1 on aarch64.
}

fn core_id() -> usize {
let mpidr = MPIDR_EL1.get() as usize;
assert!(mpidr < usize::MAX);

mpidr
}
}
46 changes: 0 additions & 46 deletions hal_aarch64/src/mm/mod.rs
Original file line number Diff line number Diff line change
@@ -1,47 +1 @@
use hal_core::{
mm::{self, PageAlloc, PageMap},
AddressRange, Error,
};

pub mod pgt48;

use pgt48::PageTable;

pub type EntryType = usize;

pub const PAGE_SIZE: usize = PageTable::PAGE_SIZE;

use core::cell::OnceCell;

static mut GPT: OnceCell<&'static mut PageTable> = OnceCell::new();

pub fn is_pagetable_installed() -> bool {
unsafe { GPT.get_mut().is_some() }
}

pub fn prefill_pagetable(
r: impl Iterator<Item = AddressRange>,
rw: impl Iterator<Item = AddressRange>,
rwx: impl Iterator<Item = AddressRange>,
pre_allocated: impl Iterator<Item = AddressRange>,
allocator: &impl PageAlloc,
) -> Result<(), Error> {
let pt = hal_core::mm::prefill_pagetable::<PageTable>(r, rw, rwx, pre_allocated, allocator)?;

// TODO: put into into the hal_core::Error
unsafe {
if GPT.set(pt).is_err() {
panic!("GPT is already set ?");
}
};

Ok(())
}

pub fn align_up(addr: usize) -> usize {
mm::align_up(addr, PAGE_SIZE)
}

pub fn align_down(addr: usize) -> usize {
mm::align_down(addr, PAGE_SIZE)
}
15 changes: 10 additions & 5 deletions hal_core/src/hal.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
use super::mm::{self, Mmu, PageAlloc, PageMap};
use super::once_lock::OnceLock;
use super::AddressRange;
use super::CoreInfo;
use super::Error;
use super::ReentrantSpinlock;
use super::{IrqOps, TimerCallbackFn};

pub struct Hal<P: PageMap + 'static, I: IrqOps> {
kpt: OnceLock<ReentrantSpinlock<&'static mut P>>,
pub struct Hal<P: PageMap + 'static, I: IrqOps, G: CoreInfo> {
kpt: OnceLock<ReentrantSpinlock<G, &'static mut P>>,
irq_ops: I,
}

impl<P: PageMap + Mmu + 'static, I: IrqOps> Hal<P, I> {
pub const fn new(irq_ops: I) -> Hal<P, I> {
impl<P: PageMap + Mmu + 'static, I: IrqOps, G: CoreInfo> Hal<P, I, G> {
pub const fn new(irq_ops: I) -> Hal<P, I, G> {
Self {
kpt: OnceLock::new(),
irq_ops,
}
}

pub fn init_core_info(&self, core_id: usize) {
G::init(core_id)
}

pub fn init_irqs(&'static self) {
self.irq_ops.init();
}
Expand Down Expand Up @@ -91,7 +96,7 @@ impl<P: PageMap + Mmu + 'static, I: IrqOps> Hal<P, I> {
mm::align_down(val, self.page_size())
}

pub fn kpt(&'static self) -> &ReentrantSpinlock<&'static mut P> {
pub fn kpt(&'static self) -> &ReentrantSpinlock<G, &'static mut P> {
self.kpt.get().unwrap()
}
}
5 changes: 5 additions & 0 deletions hal_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ pub mod once_lock;
mod reentrant_spinlock;
pub use reentrant_spinlock::ReentrantSpinlock;

pub trait CoreInfo {
fn init(core_id: usize);
fn core_id() -> usize;
}

pub trait IrqOps {
fn init(&'static self);
fn init_irq_chip(&self, allocator: &impl mm::PageAlloc) -> Result<(), Error>;
Expand Down
25 changes: 11 additions & 14 deletions hal_core/src/reentrant_spinlock.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,25 @@
use core::marker::PhantomData;
use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use lock_api::{GuardSend, RawMutex};

pub struct RawReentrantSpinlock {
use crate::CoreInfo;

pub struct RawReentrantSpinlock<G> {
user: AtomicUsize,
lock: AtomicBool,
_marker: PhantomData<G>,
}

fn core_id() -> usize {
let mut id: u64;

unsafe { core::arch::asm!("mrs {:x}, mpidr_el1", out(reg) id) };

id as usize
}

unsafe impl RawMutex for RawReentrantSpinlock {
unsafe impl<G: CoreInfo> RawMutex for RawReentrantSpinlock<G> {
// The underlying const with interior mutability is fine because it is only used for
// construction.
// Clippy recommends using a const fn for constructors but I don't have that freedom of choice
// since we depend on lock_api.
#[allow(clippy::declare_interior_mutable_const)]
const INIT: RawReentrantSpinlock = RawReentrantSpinlock {
const INIT: RawReentrantSpinlock<G> = RawReentrantSpinlock::<G> {
user: AtomicUsize::new(usize::MAX),
lock: AtomicBool::new(false),
_marker: PhantomData,
};

// A spinlock guard can be sent to another thread and unlocked there
Expand All @@ -35,7 +32,7 @@ unsafe impl RawMutex for RawReentrantSpinlock {
}

fn try_lock(&self) -> bool {
let my_id = core_id();
let my_id = G::core_id();

if self.user.load(Ordering::Acquire) == my_id {
assert!(self.lock.load(Ordering::Relaxed));
Expand All @@ -54,7 +51,7 @@ unsafe impl RawMutex for RawReentrantSpinlock {
.is_ok()
&& self
.user
.compare_exchange(usize::MAX, core_id(), Ordering::Acquire, Ordering::Relaxed)
.compare_exchange(usize::MAX, my_id, Ordering::Acquire, Ordering::Relaxed)
.is_ok()
}

Expand All @@ -64,4 +61,4 @@ unsafe impl RawMutex for RawReentrantSpinlock {
}
}

pub type ReentrantSpinlock<T> = lock_api::Mutex<RawReentrantSpinlock, T>;
pub type ReentrantSpinlock<G, T> = lock_api::Mutex<RawReentrantSpinlock<G>, T>;
1 change: 1 addition & 0 deletions hal_riscv64/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ hal_core = { path = "../hal_core" }
modular-bitfield = "0.11"
sbi = "0.2.0"
riscv = "0.10"
log = "0.4"
12 changes: 0 additions & 12 deletions hal_riscv64/src/cpu.rs

This file was deleted.

Loading

0 comments on commit ae0acf6

Please sign in to comment.