did something idk
This commit is contained in:
parent
61e8950b2e
commit
1e02ebb0c6
10 changed files with 85 additions and 91 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
kernel.elf
|
kernel.elf
|
||||||
|
.cache/
|
||||||
*.o
|
*.o
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -2,7 +2,7 @@ TOOLCHAIN = riscv64-linux-gnu-
|
||||||
QEMU=qemu-system-riscv64
|
QEMU=qemu-system-riscv64
|
||||||
KERNEL = kernel.elf
|
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
|
LDFLAGS=-T linker.ld --no-dynamic-linker -m elf64lriscv -static -nostdlib
|
||||||
QEMUFLAGS=-nographic -serial mon:stdio --no-reboot
|
QEMUFLAGS=-nographic -serial mon:stdio --no-reboot
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,14 @@
|
||||||
|
|
||||||
#define csrr(reg) \
|
#define csrr(reg) \
|
||||||
({ \
|
({ \
|
||||||
uintptr_t temp; \
|
long temp; \
|
||||||
__asm__ volatile("csrr %0, " #reg : "=r"(temp)); \
|
__asm__ volatile("csrr %0, " #reg : "=r"(temp)); \
|
||||||
temp; \
|
temp; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define csrw(reg, val) \
|
#define csrw(reg, val) \
|
||||||
({ \
|
({ \
|
||||||
uintptr_t temp = (uintptr_t)val; \
|
long temp = (long)val; \
|
||||||
__asm__ volatile("csrw " #reg ", %0" ::"r"(temp)); \
|
__asm__ volatile("csrw " #reg ", %0" ::"r"(temp)); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
31
include/sbi.h
Normal file
31
include/sbi.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef SBI_H
|
||||||
|
#define SBI_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#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
|
111
src/kernel.c
111
src/kernel.c
|
@ -1,22 +1,16 @@
|
||||||
|
#include "atomic_helpers.h"
|
||||||
|
#include "sbi.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "atomic_helpers.h"
|
|
||||||
|
|
||||||
#define DEBUG_ECALL 0x4442434E
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
long error;
|
|
||||||
long value;
|
|
||||||
} sbiret;
|
|
||||||
|
|
||||||
void trap_handler();
|
void trap_handler();
|
||||||
void trap_handler_wrapper() __attribute__((naked));
|
void trap_handler_wrapper() __attribute__((naked));
|
||||||
|
|
||||||
void user_entry();
|
void user_entry();
|
||||||
|
|
||||||
unsigned long strlen(const char* str) {
|
size_t strlen(const char* str) {
|
||||||
unsigned long len = 0;
|
size_t len = 0;
|
||||||
while(str[len] != '\0') {
|
while(str[len] != '\0') {
|
||||||
len++;
|
len++;
|
||||||
}
|
}
|
||||||
|
@ -28,7 +22,7 @@ int main() {
|
||||||
csrw(stvec, trap_handler_wrapper);
|
csrw(stvec, trap_handler_wrapper);
|
||||||
csrw(sepc, user_entry);
|
csrw(sepc, user_entry);
|
||||||
|
|
||||||
unsigned long sstatus = csrr(sstatus);
|
size_t sstatus = csrr(sstatus);
|
||||||
sstatus |= (1 << 5);
|
sstatus |= (1 << 5);
|
||||||
csrw(sstatus, sstatus);
|
csrw(sstatus, sstatus);
|
||||||
|
|
||||||
|
@ -36,76 +30,17 @@ int main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void user_entry(void) {
|
void user_entry(void) {
|
||||||
while(1) {
|
sbi_set_timer(1000000);
|
||||||
__asm__ volatile("ecall");
|
while(1) { }
|
||||||
__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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int puts(const char* str) {
|
int puts(const char* str) {
|
||||||
sbiret ret;
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((ret = console_debug_write("\n", 1)).error != 0) {
|
if((ret = sbi_debug_console_write("\n", 1)).error != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -117,9 +52,9 @@ void trap_handler_wrapper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void trap_handler(void) {
|
void trap_handler(void) {
|
||||||
unsigned long sepc = csrr(sepc);
|
size_t sepc = csrr(sepc);
|
||||||
unsigned long scause = csrr(scause);
|
size_t scause = csrr(scause);
|
||||||
unsigned long sstatus = csrr(sstatus);
|
size_t sstatus = csrr(sstatus);
|
||||||
|
|
||||||
if(scause == 8) {
|
if(scause == 8) {
|
||||||
puts("hello world");
|
puts("hello world");
|
||||||
|
@ -127,18 +62,18 @@ void trap_handler(void) {
|
||||||
sepc += 4;
|
sepc += 4;
|
||||||
csrw(sepc, sepc);
|
csrw(sepc, sepc);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
|
||||||
|
|
||||||
if(((sstatus >> 8) & 1) == 0) {
|
|
||||||
sepc += 4;
|
|
||||||
puts("exception occured in usermode, skipping past");
|
|
||||||
csrw(sepc, sepc);
|
|
||||||
goto exit;
|
|
||||||
} else {
|
} 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) {
|
while(1) {
|
||||||
__asm__ volatile("wfi");
|
__asm__ volatile("wfi");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
27
src/sbi.c
Normal file
27
src/sbi.c
Normal file
|
@ -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);
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue