diff --git a/.cache/clangd/index/atomic_helpers.h.32E35DD60967E074.idx b/.cache/clangd/index/atomic_helpers.h.32E35DD60967E074.idx deleted file mode 100644 index c3559f3..0000000 Binary files a/.cache/clangd/index/atomic_helpers.h.32E35DD60967E074.idx and /dev/null differ diff --git a/.cache/clangd/index/atomic_helpers.h.5A95DDE70BB8C83F.idx b/.cache/clangd/index/atomic_helpers.h.5A95DDE70BB8C83F.idx deleted file mode 100644 index bbd4f85..0000000 Binary files a/.cache/clangd/index/atomic_helpers.h.5A95DDE70BB8C83F.idx and /dev/null differ diff --git a/.cache/clangd/index/kernel.c.888550018A9D5949.idx b/.cache/clangd/index/kernel.c.888550018A9D5949.idx deleted file mode 100644 index 5dc4088..0000000 Binary files a/.cache/clangd/index/kernel.c.888550018A9D5949.idx and /dev/null differ diff --git a/.cache/clangd/index/kernel.c.D9A3E99583D1279A.idx b/.cache/clangd/index/kernel.c.D9A3E99583D1279A.idx deleted file mode 100644 index c750935..0000000 Binary files a/.cache/clangd/index/kernel.c.D9A3E99583D1279A.idx and /dev/null differ diff --git a/.gitignore b/.gitignore index a78cba5..5bec384 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ compile_commands.json kernel.elf +.cache/ *.o diff --git a/Makefile b/Makefile index 94a06e1..e49cc7c 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ TOOLCHAIN = riscv64-linux-gnu- QEMU=qemu-system-riscv64 KERNEL = kernel.elf -CFLAGS=-march=rv64i_zicsr_d -mabi=lp64d -Wall -Wextra -Werror -O2 -g -Iinclude +CFLAGS=-march=rv64i_zicsr_d -mabi=lp64d -Wall -Wextra -Werror -O2 -Iinclude -g LDFLAGS=-T linker.ld --no-dynamic-linker -m elf64lriscv -static -nostdlib QEMUFLAGS=-nographic -serial mon:stdio --no-reboot diff --git a/include/atomic_helpers.h b/include/atomic_helpers.h index 8d1bf7d..d0f8f79 100644 --- a/include/atomic_helpers.h +++ b/include/atomic_helpers.h @@ -3,14 +3,14 @@ #define csrr(reg) \ ({ \ - uintptr_t temp; \ + long temp; \ __asm__ volatile("csrr %0, " #reg : "=r"(temp)); \ temp; \ }) #define csrw(reg, val) \ ({ \ - uintptr_t temp = (uintptr_t)val; \ + long temp = (long)val; \ __asm__ volatile("csrw " #reg ", %0" ::"r"(temp)); \ }) diff --git a/include/sbi.h b/include/sbi.h new file mode 100644 index 0000000..12eeee2 --- /dev/null +++ b/include/sbi.h @@ -0,0 +1,31 @@ +#ifndef SBI_H +#define SBI_H + +#include +#include + +#define EID_DEBUG_CONSOLE 0x4442434E +#define EID_TIMER 0x54494D45 + +#define FID_CONSOLE_WRITE 0 +#define FID_SET_TIMER 0 + +typedef struct { + long error; + long value; +} sbiret; + +sbiret sbi_ecall6( + int fid, int eid, size_t arg0, size_t arg1, size_t arg2, size_t arg3, size_t arg4, size_t arg5); + +#define sbi_ecall5(fid, eid, a0, a1, a2, a3, a4) sbi_ecall6(fid, eid, a0, a1, a2, a3, a4, 0) +#define sbi_ecall4(fid, eid, a0, a1, a2, a3) sbi_ecall5(fid, eid, a0, a1, a2, a3, 0) +#define sbi_ecall3(fid, eid, a0, a1, a2) sbi_ecall4(fid, eid, a0, a1, a2, 0) +#define sbi_ecall2(fid, eid, a0, a1) sbi_ecall3(fid, eid, a0, a1, 0) +#define sbi_ecall1(fid, eid, a0) sbi_ecall2(fid, eid, a0, 0) +#define sbi_ecall0(fid, eid) sbi_ecall1(fid, eid, 0) + +sbiret sbi_debug_console_write(const char* str, size_t len); +sbiret sbi_set_timer(uint64_t stime_value); + +#endif diff --git a/src/kernel.c b/src/kernel.c index da45d9a..9e930e2 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -1,22 +1,16 @@ +#include "atomic_helpers.h" +#include "sbi.h" #include #include #include -#include "atomic_helpers.h" - -#define DEBUG_ECALL 0x4442434E - -typedef struct { - long error; - long value; -} sbiret; void trap_handler(); void trap_handler_wrapper() __attribute__((naked)); void user_entry(); -unsigned long strlen(const char* str) { - unsigned long len = 0; +size_t strlen(const char* str) { + size_t len = 0; while(str[len] != '\0') { len++; } @@ -28,7 +22,7 @@ int main() { csrw(stvec, trap_handler_wrapper); csrw(sepc, user_entry); - unsigned long sstatus = csrr(sstatus); + size_t sstatus = csrr(sstatus); sstatus |= (1 << 5); csrw(sstatus, sstatus); @@ -36,76 +30,17 @@ int main() { } void user_entry(void) { - while(1) { - __asm__ volatile("ecall"); - __asm__ volatile("unimp"); - } -} - -__attribute__((always_inline)) -inline sbiret sbi_ecall6(unsigned long number, unsigned long arg0, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) { - sbiret ret; - - __asm__ volatile("mv a7, %[number]\n" - "li a6, 0\n" - "mv a0, %[arg0]\n" - "mv a1, %[arg1]\n" - "mv a2, %[arg2]\n" - "mv a3, %[arg3]\n" - "mv a4, %[arg4]\n" - "mv a5, %[arg5]\n" - "ecall\n" - "mv %[err], a0\n" - "mv %[val], a1\n" - : [err] "=r"(ret.error), [val] "=r"(ret.value) - : [number] "r"(number), [arg0] "r"(arg0), [arg1] "r"(arg1), -[arg2] "r"(arg2),[arg3] "r"(arg3), [arg4] "r"(arg4),[arg5] "r"(arg5) - : "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7"); - - return ret; -} - -__attribute__((always_inline)) -inline sbiret sbi_ecall5(unsigned long number, unsigned long arg0, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4) { - return sbi_ecall6(number, arg0, arg1, arg2, arg3, arg4, 0); -} - -__attribute__((always_inline)) -inline sbiret sbi_ecall4(unsigned long number, unsigned long arg0, unsigned long arg1, unsigned long arg2, unsigned long arg3) { - return sbi_ecall5(number, arg0, arg1, arg2, arg3, 0); -} - -__attribute__((always_inline)) -inline sbiret sbi_ecall3(unsigned long number, unsigned long arg0, unsigned long arg1, unsigned long arg2) { - return sbi_ecall4(number, arg0, arg1, arg2, 0); -} - -__attribute__((always_inline)) -inline sbiret sbi_ecall2(unsigned long number, unsigned long arg0, unsigned long arg1) { - return sbi_ecall3(number, arg0, arg1, 0); -} - -__attribute__((always_inline)) -inline sbiret sbi_ecall1(unsigned long number, unsigned long arg0) { - return sbi_ecall2(number, arg0, 0); -} - -__attribute__((always_inline)) -inline sbiret sbi_ecall0(unsigned long number) { - return sbi_ecall1(number, 0); -} - -sbiret console_debug_write(const char* str, unsigned long len) { - return sbi_ecall2(DEBUG_ECALL, len, (unsigned long)str); + sbi_set_timer(1000000); + while(1) { } } int puts(const char* str) { sbiret ret; - if((ret = console_debug_write(str, strlen(str))).error != 0) { + if((ret = sbi_debug_console_write(str, strlen(str))).error != 0) { return -1; } - - if((ret = console_debug_write("\n", 1)).error != 0) { + + if((ret = sbi_debug_console_write("\n", 1)).error != 0) { return -1; } return 0; @@ -117,9 +52,9 @@ void trap_handler_wrapper() { } void trap_handler(void) { - unsigned long sepc = csrr(sepc); - unsigned long scause = csrr(scause); - unsigned long sstatus = csrr(sstatus); + size_t sepc = csrr(sepc); + size_t scause = csrr(scause); + size_t sstatus = csrr(sstatus); if(scause == 8) { puts("hello world"); @@ -127,18 +62,18 @@ void trap_handler(void) { sepc += 4; csrw(sepc, sepc); goto exit; - } - - if(((sstatus >> 8) & 1) == 0) { - sepc += 4; - puts("exception occured in usermode, skipping past"); - csrw(sepc, sepc); - goto exit; } else { - puts("exception occured in supervisor mode, panic"); + if(((sstatus >> 8) & 1) == 0) { + sepc += 4; + puts("exception occured in usermode, skipping past"); + csrw(sepc, sepc); + goto exit; + } else { + puts("exception occured in supervisor mode, panic"); - while(1) { - __asm__ volatile("wfi"); + while(1) { + __asm__ volatile("wfi"); + } } } diff --git a/src/sbi.c b/src/sbi.c new file mode 100644 index 0000000..3ec9dcf --- /dev/null +++ b/src/sbi.c @@ -0,0 +1,27 @@ +#include "sbi.h" + +sbiret sbi_ecall6( + int fid, int eid, size_t arg0, size_t arg1, size_t arg2, size_t arg3, size_t arg4, size_t arg5) { + register size_t a0 __asm__("a0") = arg0; + register size_t a1 __asm__("a1") = arg1; + register size_t a2 __asm__("a2") = arg2; + register size_t a3 __asm__("a3") = arg3; + register size_t a4 __asm__("a4") = arg4; + register size_t a5 __asm__("a5") = arg5; + register size_t a6 __asm__("a6") = fid; + register size_t a7 __asm__("a7") = eid; + + __asm__ volatile("ecall" + : "=r"(a0), "=r"(a1) + : "r"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5), "r"(a6), "r"(a7) + : "memory"); + return (sbiret){ .error = a0, .value = a1 }; +} + +sbiret sbi_debug_console_write(const char* str, size_t len) { + return sbi_ecall2(FID_CONSOLE_WRITE, EID_DEBUG_CONSOLE, len, (size_t)str); +} + +sbiret sbi_set_timer(uint64_t stime_value) { + return sbi_ecall1(FID_SET_TIMER, EID_TIMER, stime_value); +}