Try loading code at runtime
This commit is contained in:
101
src/riscv.rs
101
src/riscv.rs
@@ -1,101 +0,0 @@
|
||||
#![allow(unused)]
|
||||
|
||||
use core::arch::naked_asm;
|
||||
|
||||
use crate::clear_csr;
|
||||
use crate::read_csr;
|
||||
use crate::set_csr;
|
||||
|
||||
pub struct MStatus;
|
||||
pub struct SStatus;
|
||||
|
||||
impl MStatus {
|
||||
pub const MIE: usize = 1 << 3;
|
||||
pub const MPIE: usize = 1 << 7;
|
||||
}
|
||||
impl SStatus {
|
||||
pub const SIE: usize = 1 << 1;
|
||||
pub const SPIE: usize = 1 << 5;
|
||||
}
|
||||
|
||||
pub fn get_interrupt_state() -> bool {
|
||||
(read_csr!(mstatus) & MStatus::MIE as u64) != 0
|
||||
}
|
||||
pub fn get_supervisor_interrupt_state() -> bool {
|
||||
(read_csr!(sstatus) & SStatus::SIE as u64) != 0
|
||||
}
|
||||
pub fn enable_interrupt() {
|
||||
set_csr!(mstatus, MStatus::MIE);
|
||||
}
|
||||
pub fn enable_supervisor_interrupt() {
|
||||
set_csr!(sstatus, SStatus::SIE);
|
||||
}
|
||||
pub fn disable_interrupt() {
|
||||
clear_csr!(mstatus, MStatus::MIE);
|
||||
}
|
||||
pub fn disable_supervisor_interrupt() {
|
||||
clear_csr!(sstatus, SStatus::SIE);
|
||||
}
|
||||
pub fn restore_interrupt(previous_state: bool) {
|
||||
if previous_state {
|
||||
enable_interrupt();
|
||||
} else {
|
||||
disable_interrupt();
|
||||
}
|
||||
}
|
||||
pub fn restore_supervisor_interrupt(previous_state: bool) {
|
||||
if previous_state {
|
||||
enable_supervisor_interrupt();
|
||||
} else {
|
||||
disable_supervisor_interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! read_csr {
|
||||
($name:ident) => {{
|
||||
let res: u64;
|
||||
unsafe { core::arch::asm!(concat!("csrr {}, ", stringify!($name)), out(reg) res, options(nomem, nostack)) };
|
||||
res
|
||||
}};
|
||||
}
|
||||
#[macro_export]
|
||||
macro_rules! write_csr {
|
||||
($name:ident, $value:expr) => {
|
||||
let val = $value;
|
||||
unsafe { core::arch::asm!(concat!("csrw ", stringify!($name), ", {}"), in(reg) val, options(nomem, nostack)) };
|
||||
};
|
||||
}
|
||||
#[macro_export]
|
||||
macro_rules! set_csr {
|
||||
($name:ident, $value:expr) => {
|
||||
let val = $value;
|
||||
unsafe { core::arch::asm!(concat!("csrs ", stringify!($name), ", {}"), in(reg) val, options(nomem, nostack)) };
|
||||
};
|
||||
}
|
||||
#[macro_export]
|
||||
macro_rules! clear_csr {
|
||||
($name:ident, $value:expr) => {
|
||||
let val = $value;
|
||||
unsafe { core::arch::asm!(concat!("csrc ", stringify!($name), ", {}"), in(reg) val, options(nomem, nostack)) };
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! mret {
|
||||
() => {
|
||||
unsafe { core::arch::asm!("mret", options(noreturn)) }
|
||||
};
|
||||
}
|
||||
|
||||
#[unsafe(naked)]
|
||||
pub extern "C" fn exit_qemu() {
|
||||
naked_asm!(
|
||||
"
|
||||
li a0, 0x100000
|
||||
li a1, 0x5555
|
||||
sw a1, 0(a0)
|
||||
wfi
|
||||
"
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user