|
@@ -1,83 +0,0 @@
|
|
|
-//! 这个模块将会处理所有的 SBI 调用陷入,你应该在中断处理函数里调用 `handle_ecall`
|
|
|
-
|
|
|
-// §4
|
|
|
-mod base;
|
|
|
-// §6
|
|
|
-mod time;
|
|
|
-// §7
|
|
|
-mod spi;
|
|
|
-// §8
|
|
|
-mod rfnc;
|
|
|
-// §9
|
|
|
-mod hsm;
|
|
|
-// §10
|
|
|
-mod srst;
|
|
|
-// §11
|
|
|
-mod pmu;
|
|
|
-
|
|
|
-use sbi_spec::{self as spec, binary::SbiRet};
|
|
|
-
|
|
|
-/// Supervisor environment call handler function
|
|
|
-///
|
|
|
-/// This function is used by platform runtime to handle environment call `ecall` instruction.
|
|
|
-///
|
|
|
-/// You should call this function in your runtime's exception handler.
|
|
|
-/// If the incoming exception is caused by supervisor `ecall`,
|
|
|
-/// call this function with parameters extracted from trap frame.
|
|
|
-/// After this function returns, store the return value into `a0` and `a1` parameters.
|
|
|
-///
|
|
|
-/// # Example
|
|
|
-///
|
|
|
-/// A typical usage:
|
|
|
-///
|
|
|
-/// ```no_run
|
|
|
-/// # use riscv::register::{mepc, mcause::{self, Trap, Exception}};
|
|
|
-/// # struct TrapFrame { a0: usize, a1: usize, a2: usize, a3: usize,
|
|
|
-/// # a4: usize, a5: usize, a6: usize, a7: usize }
|
|
|
-/// extern "C" fn rust_handle_exception(ctx: &mut TrapFrame) {
|
|
|
-/// if mcause::read().cause() == Trap::Exception(Exception::SupervisorEnvCall) {
|
|
|
-/// let params = [ctx.a0, ctx.a1, ctx.a2, ctx.a3, ctx.a4, ctx.a5];
|
|
|
-/// let ans = rustsbi::ecall(ctx.a7, ctx.a6, params);
|
|
|
-/// ctx.a0 = ans.error;
|
|
|
-/// ctx.a1 = ans.value;
|
|
|
-/// mepc::write(mepc::read().wrapping_add(4));
|
|
|
-/// }
|
|
|
-/// // other conditions..
|
|
|
-/// }
|
|
|
-/// ```
|
|
|
-///
|
|
|
-/// Do not forget to advance `mepc` by 4 after an ecall is handled.
|
|
|
-/// This skips the `ecall` instruction itself which is 4-byte long in all conditions.
|
|
|
-#[inline]
|
|
|
-pub fn handle_ecall(extension: usize, function: usize, param: [usize; 6]) -> SbiRet {
|
|
|
- match extension {
|
|
|
- spec::rfnc::EID_RFNC => {
|
|
|
- rfnc::handle_ecall(function, param[0], param[1], param[2], param[3], param[4])
|
|
|
- }
|
|
|
- spec::time::EID_TIME => match () {
|
|
|
- #[cfg(target_pointer_width = "64")]
|
|
|
- () => time::handle_ecall(function, param[0]),
|
|
|
- #[cfg(target_pointer_width = "32")]
|
|
|
- () => time::handle_ecall(function, param[0], param[1]),
|
|
|
- },
|
|
|
- spec::spi::EID_SPI => spi::handle_ecall(function, param[0], param[1]),
|
|
|
- spec::base::EID_BASE => base::handle_ecall(function, param[0]),
|
|
|
- spec::hsm::EID_HSM => hsm::handle_ecall(function, param[0], param[1], param[2]),
|
|
|
- spec::srst::EID_SRST => srst::handle_ecall(function, param[0], param[1]),
|
|
|
- spec::pmu::EID_PMU => match () {
|
|
|
- #[cfg(target_pointer_width = "64")]
|
|
|
- () => pmu::handle_ecall(function, param[0], param[1], param[2], param[3], param[4]),
|
|
|
- #[cfg(target_pointer_width = "32")]
|
|
|
- () => pmu::handle_ecall(
|
|
|
- function, param[0], param[1], param[2], param[3], param[4], param[5],
|
|
|
- ),
|
|
|
- },
|
|
|
- _ => SbiRet::not_supported(),
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-#[cfg(target_pointer_width = "32")]
|
|
|
-#[inline]
|
|
|
-const fn concat_u32(h: usize, l: usize) -> u64 {
|
|
|
- ((h as u64) << 32) | (l as u64)
|
|
|
-}
|