refactor(adapter-riscv): restructure into hw/, mmu/, trap/ modules with board constants
Add Priority::DEFAULT and TimeSlice::DEFAULT to types crate. All QEMU virt addresses consolidated in board.rs. Structure mirrors future adapter-arm/ layout.
This commit is contained in:
3
crates/adapter-riscv/src/hw/mod.rs
Normal file
3
crates/adapter-riscv/src/hw/mod.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
pub mod plic;
|
||||
pub mod timer;
|
||||
pub mod uart;
|
||||
44
crates/adapter-riscv/src/hw/plic.rs
Normal file
44
crates/adapter-riscv/src/hw/plic.rs
Normal file
@@ -0,0 +1,44 @@
|
||||
use crate::board;
|
||||
|
||||
const PLIC_PRIORITY: usize = board::PLIC_BASE;
|
||||
const PLIC_S_ENABLE: usize = board::PLIC_BASE + 0x2080;
|
||||
const PLIC_S_THRESHOLD: usize = board::PLIC_BASE + 0x201000;
|
||||
const PLIC_S_CLAIM: usize = board::PLIC_BASE + 0x201004;
|
||||
|
||||
pub struct Plic;
|
||||
|
||||
impl Plic {
|
||||
pub fn init() {
|
||||
unsafe { core::ptr::write_volatile(PLIC_S_THRESHOLD as *mut u32, 0) };
|
||||
}
|
||||
|
||||
pub fn enable(irq: u32) {
|
||||
let word = (irq / 32) as usize;
|
||||
let bit = irq % 32;
|
||||
let addr = PLIC_S_ENABLE + word * 4;
|
||||
unsafe {
|
||||
let current = core::ptr::read_volatile(addr as *const u32);
|
||||
core::ptr::write_volatile(addr as *mut u32, current | (1 << bit));
|
||||
}
|
||||
let prio_addr = PLIC_PRIORITY + (irq as usize) * 4;
|
||||
unsafe { core::ptr::write_volatile(prio_addr as *mut u32, 1) };
|
||||
}
|
||||
|
||||
pub fn disable(irq: u32) {
|
||||
let word = (irq / 32) as usize;
|
||||
let bit = irq % 32;
|
||||
let addr = PLIC_S_ENABLE + word * 4;
|
||||
unsafe {
|
||||
let current = core::ptr::read_volatile(addr as *const u32);
|
||||
core::ptr::write_volatile(addr as *mut u32, current & !(1 << bit));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn claim() -> u32 {
|
||||
unsafe { core::ptr::read_volatile(PLIC_S_CLAIM as *const u32) }
|
||||
}
|
||||
|
||||
pub fn complete(irq: u32) {
|
||||
unsafe { core::ptr::write_volatile(PLIC_S_CLAIM as *mut u32, irq) };
|
||||
}
|
||||
}
|
||||
32
crates/adapter-riscv/src/hw/timer.rs
Normal file
32
crates/adapter-riscv/src/hw/timer.rs
Normal file
@@ -0,0 +1,32 @@
|
||||
use crate::board;
|
||||
|
||||
pub fn read_time() -> u64 {
|
||||
let time: u64;
|
||||
unsafe { core::arch::asm!("rdtime {0}", out(reg) time) };
|
||||
time
|
||||
}
|
||||
|
||||
fn sbi_set_timer(stime: u64) {
|
||||
unsafe {
|
||||
core::arch::asm!(
|
||||
"ecall",
|
||||
in("a0") stime,
|
||||
in("a6") 0usize,
|
||||
in("a7") 0x54494D45usize,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init() {
|
||||
let now = read_time();
|
||||
sbi_set_timer(now + board::TICK_INTERVAL);
|
||||
}
|
||||
|
||||
pub fn set_next(deadline: u64) {
|
||||
sbi_set_timer(deadline);
|
||||
}
|
||||
|
||||
pub fn handle_interrupt() {
|
||||
let now = read_time();
|
||||
sbi_set_timer(now + board::TICK_INTERVAL);
|
||||
}
|
||||
60
crates/adapter-riscv/src/hw/uart.rs
Normal file
60
crates/adapter-riscv/src/hw/uart.rs
Normal file
@@ -0,0 +1,60 @@
|
||||
use crate::board;
|
||||
|
||||
pub struct Uart {
|
||||
base: usize,
|
||||
}
|
||||
|
||||
impl Uart {
|
||||
pub fn new() -> Self {
|
||||
Self { base: board::UART_BASE }
|
||||
}
|
||||
|
||||
pub fn put_char(&self, byte: u8) {
|
||||
let ptr = self.base as *mut u8;
|
||||
unsafe { core::ptr::write_volatile(ptr, byte) };
|
||||
}
|
||||
|
||||
pub fn write_str(&self, s: &str) {
|
||||
for byte in s.bytes() {
|
||||
self.put_char(byte);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_hex(&self, mut value: usize) {
|
||||
self.write_str("0x");
|
||||
if value == 0 {
|
||||
self.put_char(b'0');
|
||||
return;
|
||||
}
|
||||
let mut buf = [0u8; 16];
|
||||
let mut i = 0;
|
||||
while value > 0 {
|
||||
let digit = (value & 0xF) as u8;
|
||||
buf[i] = if digit < 10 { b'0' + digit } else { b'a' + digit - 10 };
|
||||
value >>= 4;
|
||||
i += 1;
|
||||
}
|
||||
while i > 0 {
|
||||
i -= 1;
|
||||
self.put_char(buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_dec(&self, mut value: usize) {
|
||||
if value == 0 {
|
||||
self.put_char(b'0');
|
||||
return;
|
||||
}
|
||||
let mut buf = [0u8; 20];
|
||||
let mut i = 0;
|
||||
while value > 0 {
|
||||
buf[i] = b'0' + (value % 10) as u8;
|
||||
value /= 10;
|
||||
i += 1;
|
||||
}
|
||||
while i > 0 {
|
||||
i -= 1;
|
||||
self.put_char(buf[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user