从SBI到stdio
// libs/sbi.c
#include <sbi.h>
#include <defs.h>
//SBI编号和函数的对应
uint64_t SBI_SET_TIMER = 0;
uint64_t SBI_CONSOLE_PUTCHAR = 1;
uint64_t SBI_CONSOLE_GETCHAR = 2;
uint64_t SBI_CLEAR_IPI = 3;
uint64_t SBI_SEND_IPI = 4;
uint64_t SBI_REMOTE_FENCE_I = 5;
uint64_t SBI_REMOTE_SFENCE_VMA = 6;
uint64_t SBI_REMOTE_SFENCE_VMA_ASID = 7;
uint64_t SBI_SHUTDOWN = 8;
//sbi_call函数是我们关注的核心
uint64_t sbi_call(uint64_t sbi_type, uint64_t arg0, uint64_t arg1, uint64_t arg2) {
uint64_t ret_val;
__asm__ volatile (
"mv x17, %[sbi_type]\n"
"mv x10, %[arg0]\n"
"mv x11, %[arg1]\n"
"mv x12, %[arg2]\n" //mv操作把参数的数值放到寄存器里
"ecall\n" //参数放好之后,通过ecall, 交给OpenSBI来执行
"mv %[ret_val], x10"
//OpenSBI按照riscv的calling convention,把返回值放到x10寄存器里
//我们还需要自己通过内联汇编把返回值拿到我们的变量里
: [ret_val] "=r" (ret_val)
: [sbi_type] "r" (sbi_type), [arg0] "r" (arg0), [arg1] "r" (arg1), [arg2] "r" (arg2)
: "memory"
);
return ret_val;
}
void sbi_console_putchar(unsigned char ch) {
sbi_call(SBI_CONSOLE_PUTCHAR, ch, 0, 0); //注意这里ch隐式类型转换为int64_t
}
void sbi_set_timer(unsigned long long stime_value) {
sbi_call(SBI_SET_TIMER, stime_value, 0, 0);
}最后更新于