From 464a61102e3a7e91de1f4a9a32995f884a2155b5 Mon Sep 17 00:00:00 2001 From: Quantum Date: Sun, 23 Jan 2022 20:15:53 -0500 Subject: [PATCH] OpenSBI memes Added legacy extension Fixed typing memes by just define a sbiword_t typedef Renamed sbiret_t to SbiRet, I think i'll only use _t for typedefs Added ecall() variant that takes no additional arguments Moved opensbi includes to includes/opensbi/... kernel.cpp uses the legacy extensions instead of raw ecalls All legacy extension calls are marked as deprecated --- kernel/drivers/opensbi/extensions/legacy.cpp | 105 ++++++++++++++++++ kernel/drivers/opensbi/include/opensbi.h | 62 ----------- .../include/opensbi/extensions/legacy.h | 42 +++++++ .../drivers/opensbi/include/opensbi/opensbi.h | 65 +++++++++++ kernel/drivers/opensbi/meson.build | 3 +- kernel/drivers/opensbi/opensbi.cpp | 103 +++++++++-------- kernel/kernel.cpp | 27 +++-- 7 files changed, 285 insertions(+), 122 deletions(-) create mode 100644 kernel/drivers/opensbi/extensions/legacy.cpp delete mode 100644 kernel/drivers/opensbi/include/opensbi.h create mode 100644 kernel/drivers/opensbi/include/opensbi/extensions/legacy.h create mode 100644 kernel/drivers/opensbi/include/opensbi/opensbi.h diff --git a/kernel/drivers/opensbi/extensions/legacy.cpp b/kernel/drivers/opensbi/extensions/legacy.cpp new file mode 100644 index 0000000..c5f46ea --- /dev/null +++ b/kernel/drivers/opensbi/extensions/legacy.cpp @@ -0,0 +1,105 @@ +#include "opensbi/extensions/legacy.h" + +namespace drivers { +namespace opensbi::legacy { + namespace { + enum class ExtensionId { + SET_TIMER, + CONSOLE_PUTCHAR, + CONSOLE_GETCHAR, + CLEAR_IPI, + SEND_IPI, + REMOTE_FENCE_I, + REMOTE_SFENCE_VMA, + REMOTE_SFENCE_VMA_ASID, + SHUTDOWN + }; + } + + SbiRet set_timer(std::uint64_t stime_value) { +#if __riscv_xlen == 64 + return ecall( + static_cast(ExtensionId::SET_TIMER), + 0, + stime_value); +#else + return ecall( + static_cast(ExtensionId::SET_TIMER), + 0, + static_cast(stime_value), + static_cast(stime_value >> 32)); +#endif + } + + SbiRet console_putchar(int ch) { + return ecall( + static_cast(ExtensionId::CONSOLE_PUTCHAR), + 0, + ch); + } + + SbiRet console_getchar() { + return ecall( + static_cast(ExtensionId::CONSOLE_GETCHAR), + 0); + } + + SbiRet clear_ipmi() { + return ecall( + static_cast(ExtensionId::CLEAR_IPI), + 0); + } + + SbiRet send_ipmi(hart_mask_t hart_mask) { + return ecall( + static_cast(ExtensionId::SEND_IPI), + 0, + reinterpret_cast(hart_mask)); + } + + SbiRet remote_fence_i(hart_mask_t hart_mask) { + return ecall( + static_cast(ExtensionId::REMOTE_FENCE_I), + 0, + reinterpret_cast(hart_mask)); + } + + SbiRet remote_sfence_vma( + hart_mask_t hart_mask, + sbiword_t start, + sbiword_t size) { + return ecall( + static_cast(ExtensionId::REMOTE_SFENCE_VMA), + 0, + reinterpret_cast(hart_mask), + start, + size); + } + + SbiRet remote_sfence_vma_asid( + hart_mask_t hart_mask, + sbiword_t start, + sbiword_t size, + sbiword_t asid) { + return ecall( + static_cast(ExtensionId::REMOTE_SFENCE_VMA_ASID), + 0, + reinterpret_cast(hart_mask), + start, + size, + asid); + } + + void shutdown() { + ecall( + static_cast(ExtensionId::SHUTDOWN), + 0); + + // This should never be reached, explode if it is + __builtin_trap(); + while(1); + } + +} // End namespace opensbi::legacy +} // End namespace drivers + diff --git a/kernel/drivers/opensbi/include/opensbi.h b/kernel/drivers/opensbi/include/opensbi.h deleted file mode 100644 index d3083b5..0000000 --- a/kernel/drivers/opensbi/include/opensbi.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -typedef unsigned long uintmax_t; - -namespace drivers { -namespace opensbi { - - // We use uintmax_t to make sure this works on 32 and 64 bit - // At least thats how I hope this works.. - // TODO: Add assert() to make sure this is the case - struct sbiret_t { - uintmax_t error; - uintmax_t value; - }; - - sbiret_t call( - uintmax_t extension, - uintmax_t function, - uintmax_t a0, - uintmax_t a1, - uintmax_t a2, - uintmax_t a3, - uintmax_t a4, - uintmax_t a5); - - sbiret_t call( - uintmax_t extension, - uintmax_t function, - uintmax_t a0, - uintmax_t a1, - uintmax_t a2, - uintmax_t a3, - uintmax_t a4); - - sbiret_t call( - uintmax_t extension, - uintmax_t function, - uintmax_t a0, - uintmax_t a1, - uintmax_t a2, - uintmax_t a3); - - sbiret_t call( - uintmax_t extension, - uintmax_t function, - uintmax_t a0, - uintmax_t a1, - uintmax_t a2); - - sbiret_t call( - uintmax_t extension, - uintmax_t function, - uintmax_t a0, - uintmax_t a1); - - sbiret_t call( - uintmax_t extension, - uintmax_t function, - uintmax_t a0); - -} // End namespace opensbi -} // End namespace drivers diff --git a/kernel/drivers/opensbi/include/opensbi/extensions/legacy.h b/kernel/drivers/opensbi/include/opensbi/extensions/legacy.h new file mode 100644 index 0000000..f91c7e5 --- /dev/null +++ b/kernel/drivers/opensbi/include/opensbi/extensions/legacy.h @@ -0,0 +1,42 @@ +#pragma once + +#include "opensbi/opensbi.h" + +namespace drivers { +namespace opensbi::legacy { + [[deprecated("Use the time extension instead")]] + SbiRet set_timer(uint64_t stime_value); + + [[deprecated("No alternative, git gud git real driver")]] + SbiRet console_putchar(int ch); + + [[deprecated("No alternative, git gud git real driver")]] + SbiRet console_getchar(); + + [[deprecated("No alternative")]] + SbiRet clear_ipmi(); + + [[deprecated("Use the sPI extension instead")]] + SbiRet send_ipmi(hart_mask_t hart_mask); + + [[deprecated("Use the RFNC extension instead")]] + SbiRet remote_fence_i(hart_mask_t hart_mask); + + [[deprecated("Use the RFNC extension instead")]] + SbiRet remote_sfence_vma( + hart_mask_t hart_mask, + sbiword_t start, + sbiword_t size); + + [[deprecated("Use the RFNC extension instead")]] + SbiRet remote_sfence_vma_asid( + hart_mask_t hart_mask, + sbiword_t start, + sbiword_t size, + sbiword_t asid); + + [[deprecated("Use the SRST extension instead")]] + [[noreturn]] void shutdown(); + +} // End namespace opensbi::legacy +} // End namespace drivers diff --git a/kernel/drivers/opensbi/include/opensbi/opensbi.h b/kernel/drivers/opensbi/include/opensbi/opensbi.h new file mode 100644 index 0000000..a5c4aa4 --- /dev/null +++ b/kernel/drivers/opensbi/include/opensbi/opensbi.h @@ -0,0 +1,65 @@ +#pragma once + +#include + +namespace drivers { +namespace opensbi { + typedef unsigned long sbiword_t; + typedef const unsigned long * hart_mask_t; + + struct SbiRet { + sbiword_t error; + sbiword_t value; + }; + + SbiRet ecall( + sbiword_t extension, + sbiword_t function, + sbiword_t a0, + sbiword_t a1, + sbiword_t a2, + sbiword_t a3, + sbiword_t a4, + sbiword_t a5); + + SbiRet ecall( + sbiword_t extension, + sbiword_t function, + sbiword_t a0, + sbiword_t a1, + sbiword_t a2, + sbiword_t a3, + sbiword_t a4); + + SbiRet ecall( + sbiword_t extension, + sbiword_t function, + sbiword_t a0, + sbiword_t a1, + sbiword_t a2, + sbiword_t a3); + + SbiRet ecall( + sbiword_t extension, + sbiword_t function, + sbiword_t a0, + sbiword_t a1, + sbiword_t a2); + + SbiRet ecall( + sbiword_t extension, + sbiword_t function, + sbiword_t a0, + sbiword_t a1); + + SbiRet ecall( + sbiword_t extension, + sbiword_t function, + sbiword_t a0); + + SbiRet ecall( + sbiword_t extension, + sbiword_t function); + +} // End namespace opensbi +} // End namespace drivers diff --git a/kernel/drivers/opensbi/meson.build b/kernel/drivers/opensbi/meson.build index dfbc8de..33526ea 100644 --- a/kernel/drivers/opensbi/meson.build +++ b/kernel/drivers/opensbi/meson.build @@ -1,6 +1,7 @@ kernel_sources += [ files( - 'opensbi.cpp' + 'opensbi.cpp', + 'extensions/legacy.cpp' ), ] diff --git a/kernel/drivers/opensbi/opensbi.cpp b/kernel/drivers/opensbi/opensbi.cpp index b92d98e..fd591bc 100644 --- a/kernel/drivers/opensbi/opensbi.cpp +++ b/kernel/drivers/opensbi/opensbi.cpp @@ -1,26 +1,25 @@ -#include -#include +#include "opensbi/opensbi.h" namespace drivers { namespace opensbi { - sbiret_t ecall( - uintptr_t extension, - uintptr_t function, - uintptr_t a0, - uintptr_t a1, - uintptr_t a2, - uintptr_t a3, - uintptr_t a4, - uintptr_t a5) { - register uintptr_t r_a7 asm("a7") = extension; - register uintptr_t r_a6 asm("a6") = function; - register uintptr_t r_a0 asm("a0") = a0; - register uintptr_t r_a1 asm("a1") = a1; - register uintptr_t r_a2 asm("a2") = a2; - register uintptr_t r_a3 asm("a3") = a3; - register uintptr_t r_a4 asm("a4") = a4; - register uintptr_t r_a5 asm("a5") = a5; + SbiRet ecall( + sbiword_t extension, + sbiword_t function, + sbiword_t a0, + sbiword_t a1, + sbiword_t a2, + sbiword_t a3, + sbiword_t a4, + sbiword_t a5) { + register sbiword_t r_a7 asm("a7") = extension; + register sbiword_t r_a6 asm("a6") = function; + register sbiword_t r_a0 asm("a0") = a0; + register sbiword_t r_a1 asm("a1") = a1; + register sbiword_t r_a2 asm("a2") = a2; + register sbiword_t r_a3 asm("a3") = a3; + register sbiword_t r_a4 asm("a4") = a4; + register sbiword_t r_a5 asm("a5") = a5; asm volatile("ecall" : // Instruction "=r"(r_a0), "=r"(r_a1) : // Inputs "r"(r_a7), "r"(r_a6), // Outputs @@ -29,50 +28,56 @@ namespace opensbi { return {.error = a0, .value = a1}; } - sbiret_t ecall( - uintptr_t extension, - uintptr_t function, - uintptr_t a0, - uintptr_t a1, - uintptr_t a2, - uintptr_t a3, - uintptr_t a4) { + SbiRet ecall( + sbiword_t extension, + sbiword_t function, + sbiword_t a0, + sbiword_t a1, + sbiword_t a2, + sbiword_t a3, + sbiword_t a4) { return ecall(extension, function, a0, a1, a2, a3, a4, 0); } - sbiret_t ecall( - uintptr_t extension, - uintptr_t function, - uintptr_t a0, - uintptr_t a1, - uintptr_t a2, - uintptr_t a3) { + SbiRet ecall( + sbiword_t extension, + sbiword_t function, + sbiword_t a0, + sbiword_t a1, + sbiword_t a2, + sbiword_t a3) { return ecall(extension, function, a0, a1, a2, a3, 0, 0); } - sbiret_t ecall( - uintptr_t extension, - uintptr_t function, - uintptr_t a0, - uintptr_t a1, - uintptr_t a2) { + SbiRet ecall( + sbiword_t extension, + sbiword_t function, + sbiword_t a0, + sbiword_t a1, + sbiword_t a2) { return ecall(extension, function, a0, a1, a2, 0, 0, 0); } - sbiret_t ecall( - uintptr_t extension, - uintptr_t function, - uintptr_t a0, - uintptr_t a1) { + SbiRet ecall( + sbiword_t extension, + sbiword_t function, + sbiword_t a0, + sbiword_t a1) { return ecall(extension, function, a0, a1, 0, 0, 0, 0); } - sbiret_t ecall( - uintptr_t extension, - uintptr_t function, - uintptr_t a0) { + SbiRet ecall( + sbiword_t extension, + sbiword_t function, + sbiword_t a0) { return ecall(extension, function, a0, 0, 0, 0, 0, 0); } + SbiRet ecall( + sbiword_t extension, + sbiword_t function) { + return ecall(extension, function, 0, 0, 0, 0, 0, 0); + } + } // End namespace opensbi } // End namespace drivers diff --git a/kernel/kernel.cpp b/kernel/kernel.cpp index e2e9346..5c870ad 100644 --- a/kernel/kernel.cpp +++ b/kernel/kernel.cpp @@ -1,7 +1,8 @@ #include #include -#include +#include +#include #define read_csr(csr) \ ({ \ @@ -31,11 +32,13 @@ typedef unsigned long sbi_word; void fmt(const char *f, ...) { + using drivers::opensbi::legacy::console_putchar; + va_list va; va_start(va, f); while(*f) { if(*f != '{') { - drivers::opensbi::call(1, 0, *(f++)); + console_putchar(*(f++)); continue; } f++; @@ -51,7 +54,7 @@ void fmt(const char *f, ...) { for(int i = 0; i < 16; ++i) { const char *digits = "0123456789abcdef"; int d = (v >> (60 - i * 4)) & 0xF; - drivers::opensbi::call(1, 0, digits[d]); + console_putchar(digits[d]); } } va_end(va); @@ -189,6 +192,8 @@ void switch_task(void *ctx, continuation_t c) { extern "C" void isr(); extern "C" void handle_isr(isr_frame_t *frame) { + using drivers::opensbi::legacy::console_putchar; + unsigned long cause = read_csr("scause"); unsigned long code = cause & ~(1UL << 63); if(cause & (1UL << 63)) { @@ -198,20 +203,20 @@ extern "C" void handle_isr(isr_frame_t *frame) { }else if(code == 5) { // Timer interrupt. //clear_csr_bits("sie", sie_s_timer); unsigned long time = read_csr("time"); - drivers::opensbi::call(0x54494D45, 0, time + 100000); + drivers::opensbi::ecall(0x54494D45, 0, time + 100000); save_stack(switch_task, current_task); }else{ fmt("it's an unhandled interrupt, code: {}\n", code); } }else{ if(code == 8) { // Syscall. - drivers::opensbi::call(1, 0, frame->a[0]); + console_putchar(frame->a[0]); }else{ unsigned long sepc = read_csr("sepc"); fmt("it's an exception at {}\n", sepc); const char *s = exception_strings[cause]; while(*s) - drivers::opensbi::call(1, 0, *(s++)); + console_putchar(*(s++)); while(1) ; } @@ -261,6 +266,8 @@ extern "C" void kmain(unsigned long hart, void *dtb) { (void)hart; (void)dtb; + using drivers::opensbi::legacy::console_putchar; + fmt("test\n"); fmt("uintmax: {} bits\n", sizeof(uintmax_t) * 8); @@ -285,7 +292,7 @@ extern "C" void kmain(unsigned long hart, void *dtb) { set_csr_bits("sie", sie_s_software | sie_s_timer); // Self-IPI. - drivers::opensbi::call(0x735049, 0, 1 << hart, 0); + drivers::opensbi::ecall(0x735049, 0, 1 << hart, 0); sti(); cli(); @@ -318,17 +325,17 @@ extern "C" void kmain(unsigned long hart, void *dtb) { s = "paging works!\n"; s += 512UL * 1024 * 1024 * 1024; while(*s) - drivers::opensbi::call(1, 0, *(s++)); + console_putchar(*(s++)); create_task(&task1, task1_main); create_task(&task2, task2_main); time = read_csr("time"); - drivers::opensbi::call(0x54494D45, 0, time + 100000); + drivers::opensbi::ecall(0x54494D45, 0, time + 100000); save_stack(switch_task, 0); - drivers::opensbi::call(8, 0, 0); + drivers::opensbi::ecall(8, 0, 0); while(1); }