RustForge

rust-kernel

Rustbelt: a hobby x86_64 kernel written in Rust

rust-kernel / src / arch / aarch64 / mmio.rs
1033 bytes ยท raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//! Device registers. Devices are reached at their physical address while
//! the MMU is off; once paging.rs has mapped them into the higher half too,
//! `use_high_half` makes every driver go through that mapping instead (the
//! identity mapping stays, so nothing breaks in between).

use core::sync::atomic::{AtomicU64, Ordering};

static OFFSET: AtomicU64 = AtomicU64::new(0);

/// From now on reach devices at `phys + offset` (paging::HIGH_BASE).
pub fn use_high_half(offset: u64) {
    OFFSET.store(offset, Ordering::SeqCst);
}

/// Where the CPU reaches physical address `phys` right now.
pub fn virt(phys: usize) -> usize {
    phys.wrapping_add(OFFSET.load(Ordering::Relaxed) as usize)
}

pub fn read32(phys: usize) -> u32 {
    unsafe { core::ptr::read_volatile(virt(phys) as *const u32) }
}

pub fn write32(phys: usize, value: u32) {
    unsafe { core::ptr::write_volatile(virt(phys) as *mut u32, value) }
}

pub fn write8(phys: usize, value: u8) {
    unsafe { core::ptr::write_volatile(virt(phys) as *mut u8, value) }
}