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
This commit is contained in:
parent
ea60891ef5
commit
464a61102e
7 changed files with 285 additions and 122 deletions
105
kernel/drivers/opensbi/extensions/legacy.cpp
Normal file
105
kernel/drivers/opensbi/extensions/legacy.cpp
Normal file
|
@ -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<sbiword_t>(ExtensionId::SET_TIMER),
|
||||
0,
|
||||
stime_value);
|
||||
#else
|
||||
return ecall(
|
||||
static_cast<sbiword_t>(ExtensionId::SET_TIMER),
|
||||
0,
|
||||
static_cast<uint32_t>(stime_value),
|
||||
static_cast<uint32_t>(stime_value >> 32));
|
||||
#endif
|
||||
}
|
||||
|
||||
SbiRet console_putchar(int ch) {
|
||||
return ecall(
|
||||
static_cast<sbiword_t>(ExtensionId::CONSOLE_PUTCHAR),
|
||||
0,
|
||||
ch);
|
||||
}
|
||||
|
||||
SbiRet console_getchar() {
|
||||
return ecall(
|
||||
static_cast<sbiword_t>(ExtensionId::CONSOLE_GETCHAR),
|
||||
0);
|
||||
}
|
||||
|
||||
SbiRet clear_ipmi() {
|
||||
return ecall(
|
||||
static_cast<sbiword_t>(ExtensionId::CLEAR_IPI),
|
||||
0);
|
||||
}
|
||||
|
||||
SbiRet send_ipmi(hart_mask_t hart_mask) {
|
||||
return ecall(
|
||||
static_cast<sbiword_t>(ExtensionId::SEND_IPI),
|
||||
0,
|
||||
reinterpret_cast<sbiword_t>(hart_mask));
|
||||
}
|
||||
|
||||
SbiRet remote_fence_i(hart_mask_t hart_mask) {
|
||||
return ecall(
|
||||
static_cast<sbiword_t>(ExtensionId::REMOTE_FENCE_I),
|
||||
0,
|
||||
reinterpret_cast<sbiword_t>(hart_mask));
|
||||
}
|
||||
|
||||
SbiRet remote_sfence_vma(
|
||||
hart_mask_t hart_mask,
|
||||
sbiword_t start,
|
||||
sbiword_t size) {
|
||||
return ecall(
|
||||
static_cast<sbiword_t>(ExtensionId::REMOTE_SFENCE_VMA),
|
||||
0,
|
||||
reinterpret_cast<sbiword_t>(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<sbiword_t>(ExtensionId::REMOTE_SFENCE_VMA_ASID),
|
||||
0,
|
||||
reinterpret_cast<sbiword_t>(hart_mask),
|
||||
start,
|
||||
size,
|
||||
asid);
|
||||
}
|
||||
|
||||
void shutdown() {
|
||||
ecall(
|
||||
static_cast<sbiword_t>(ExtensionId::SHUTDOWN),
|
||||
0);
|
||||
|
||||
// This should never be reached, explode if it is
|
||||
__builtin_trap();
|
||||
while(1);
|
||||
}
|
||||
|
||||
} // End namespace opensbi::legacy
|
||||
} // End namespace drivers
|
||||
|
|
@ -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
|
42
kernel/drivers/opensbi/include/opensbi/extensions/legacy.h
Normal file
42
kernel/drivers/opensbi/include/opensbi/extensions/legacy.h
Normal file
|
@ -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
|
65
kernel/drivers/opensbi/include/opensbi/opensbi.h
Normal file
65
kernel/drivers/opensbi/include/opensbi/opensbi.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
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
|
|
@ -1,6 +1,7 @@
|
|||
kernel_sources += [
|
||||
files(
|
||||
'opensbi.cpp'
|
||||
'opensbi.cpp',
|
||||
'extensions/legacy.cpp'
|
||||
),
|
||||
]
|
||||
|
||||
|
|
|
@ -1,26 +1,25 @@
|
|||
#include <cstdint>
|
||||
#include <opensbi.h>
|
||||
#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
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#include <stdarg.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <opensbi.h>
|
||||
#include <opensbi/opensbi.h>
|
||||
#include <opensbi/extensions/legacy.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue