博客 / 詳情

返回

sbi--底層原理以及調用規範(sbi_call)

image.png

用rust 實現規範的定義

// 定義 SbiRet 結構體,用於存儲 SBI 調用的返回值
struct SbiRet {
    error: i64,
    value: i64,
}

/// 實現一個封裝SBI調用的函數
#[inline(always)]
fn sbi_call(extension: usize, function: usize, arg0: usize, arg1: usize) -> SbiRet {
    let (error, value);
    unsafe {
        asm!(
            "ecall",                       // 執行ECALL指令
            in("a0") arg0,                 // 設置參數寄存器
            in("a1") arg1,
            in("a6") function,             // 設置功能ID
            in("a7") extension,            // 設置擴展ID
            lateout("a0") error,           // 獲取錯誤代碼
            lateout("a1") value,           // 獲取返回值
        );
    }
    SbiRet { error, value }
}

怎麼使用呢?

/// 啓動性能監控計數器的函數
#[inline]
fn pmu_start(counter_id: usize, event_id: usize) -> SbiRet {
    const EXTENSION_PMU: usize = 0x504D55; // 假設PMU擴展ID
    const FUNCTION_PMU_START: usize = 0;  // pmu_start 功能ID
    sbi_call(EXTENSION_PMU, FUNCTION_PMU_START, counter_id, event_id)
}

調用返回值:0是成功, 失敗都是負的,很多系統調用也是這樣玩的
截屏2024-07-10 21.27.29.png

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.