first commit
This commit is contained in:
commit
61e8950b2e
11 changed files with 252 additions and 0 deletions
BIN
.cache/clangd/index/atomic_helpers.h.32E35DD60967E074.idx
Normal file
BIN
.cache/clangd/index/atomic_helpers.h.32E35DD60967E074.idx
Normal file
Binary file not shown.
BIN
.cache/clangd/index/atomic_helpers.h.5A95DDE70BB8C83F.idx
Normal file
BIN
.cache/clangd/index/atomic_helpers.h.5A95DDE70BB8C83F.idx
Normal file
Binary file not shown.
BIN
.cache/clangd/index/kernel.c.888550018A9D5949.idx
Normal file
BIN
.cache/clangd/index/kernel.c.888550018A9D5949.idx
Normal file
Binary file not shown.
BIN
.cache/clangd/index/kernel.c.D9A3E99583D1279A.idx
Normal file
BIN
.cache/clangd/index/kernel.c.D9A3E99583D1279A.idx
Normal file
Binary file not shown.
25
.clang-format
Normal file
25
.clang-format
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
BasedOnStyle: WebKit
|
||||||
|
IndentWidth: 4
|
||||||
|
TabWidth: 4
|
||||||
|
UseTab: Never
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignTrailingComments: true
|
||||||
|
ColumnLimit: 105
|
||||||
|
BreakBeforeBraces: Attach
|
||||||
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: false
|
||||||
|
AllowShortLambdasOnASingleLine: false
|
||||||
|
PointerAlignment: Left
|
||||||
|
SpaceBeforeParens: Never
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInConditionalStatement: false
|
||||||
|
SpacesInContainerLiterals: false
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
SpacesBeforeTrailingComments: 2
|
||||||
|
PenaltyBreakAssignment: 1000
|
||||||
|
NamespaceIndentation: All
|
||||||
|
|
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
compile_commands.json
|
||||||
|
kernel.elf
|
||||||
|
*.o
|
34
Makefile
Normal file
34
Makefile
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
TOOLCHAIN = riscv64-linux-gnu-
|
||||||
|
QEMU=qemu-system-riscv64
|
||||||
|
KERNEL = kernel.elf
|
||||||
|
|
||||||
|
CFLAGS=-march=rv64i_zicsr_d -mabi=lp64d -Wall -Wextra -Werror -O2 -g -Iinclude
|
||||||
|
LDFLAGS=-T linker.ld --no-dynamic-linker -m elf64lriscv -static -nostdlib
|
||||||
|
QEMUFLAGS=-nographic -serial mon:stdio --no-reboot
|
||||||
|
|
||||||
|
CFILES = $(shell find -L -type f -name "*.c")
|
||||||
|
SFILES = $(shell find -L -type f -iname "*.s")
|
||||||
|
OBJ := $(addsuffix .o,$(CFILES)) $(addsuffix .o,$(SFILES))
|
||||||
|
|
||||||
|
$(KERNEL): $(OBJ) linker.ld
|
||||||
|
${TOOLCHAIN}ld $(LDFLAGS) -o $(KERNEL) $(OBJ)
|
||||||
|
|
||||||
|
%.c.o: %.c
|
||||||
|
$(TOOLCHAIN)gcc $(CFLAGS) -o $@ -c $<
|
||||||
|
|
||||||
|
%.s.o: %.s
|
||||||
|
$(TOOLCHAIN)gcc $(CFLAGS) -o $@ -c $<
|
||||||
|
|
||||||
|
%.S.o: %.S
|
||||||
|
$(TOOLCHAIN)gcc $(CFLAGS) -o $@ -c $<
|
||||||
|
|
||||||
|
run: $(KERNEL)
|
||||||
|
qemu-system-riscv64 $(QEMUFLAGS) -kernel $(KERNEL)
|
||||||
|
|
||||||
|
run-debug: $(KERNEL)
|
||||||
|
$(QEMU) -monitor none -s -S -kernel $(KERNEL) &
|
||||||
|
$(TOOLCHAIN)gdb $(KERNEL) -q -ex "target remote :1234" -ex "b *_start" -ex "c" -tui
|
||||||
|
killall $(QEMU)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm $(OBJ) $(KERNEL)
|
17
include/atomic_helpers.h
Normal file
17
include/atomic_helpers.h
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#ifndef ATOMIC_HELPERS_H
|
||||||
|
#define ATOMIC_HELPERS_H
|
||||||
|
|
||||||
|
#define csrr(reg) \
|
||||||
|
({ \
|
||||||
|
uintptr_t temp; \
|
||||||
|
__asm__ volatile("csrr %0, " #reg : "=r"(temp)); \
|
||||||
|
temp; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define csrw(reg, val) \
|
||||||
|
({ \
|
||||||
|
uintptr_t temp = (uintptr_t)val; \
|
||||||
|
__asm__ volatile("csrw " #reg ", %0" ::"r"(temp)); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#endif
|
9
linker.ld
Normal file
9
linker.ld
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
MEMORY {
|
||||||
|
rom (rwx) : ORIGIN = 0x80200000, LENGTH = 512K
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
.init : {
|
||||||
|
*(.init)
|
||||||
|
} > rom
|
||||||
|
}
|
17
src/entry.s
Normal file
17
src/entry.s
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
.global _start
|
||||||
|
.global sret_wrapper
|
||||||
|
.extern main
|
||||||
|
|
||||||
|
.section .bss
|
||||||
|
stack: .space 4096
|
||||||
|
stack_top:
|
||||||
|
|
||||||
|
.section .init
|
||||||
|
_start:
|
||||||
|
la sp, stack_top
|
||||||
|
mv s0, sp
|
||||||
|
call main
|
||||||
|
sret
|
||||||
|
.loop:
|
||||||
|
wfi
|
||||||
|
j .loop
|
147
src/kernel.c
Normal file
147
src/kernel.c
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.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_wrapper() __attribute__((naked));
|
||||||
|
|
||||||
|
void user_entry();
|
||||||
|
|
||||||
|
unsigned long strlen(const char* str) {
|
||||||
|
unsigned long len = 0;
|
||||||
|
while(str[len] != '\0') {
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
csrw(stvec, trap_handler_wrapper);
|
||||||
|
csrw(sepc, user_entry);
|
||||||
|
|
||||||
|
unsigned long sstatus = csrr(sstatus);
|
||||||
|
sstatus |= (1 << 5);
|
||||||
|
csrw(sstatus, sstatus);
|
||||||
|
|
||||||
|
// _start in entry.s will do the sret
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
int puts(const char* str) {
|
||||||
|
sbiret ret;
|
||||||
|
if((ret = console_debug_write(str, strlen(str))).error != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((ret = console_debug_write("\n", 1)).error != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void trap_handler_wrapper() {
|
||||||
|
__asm__ volatile("call trap_handler\n"
|
||||||
|
"sret");
|
||||||
|
}
|
||||||
|
|
||||||
|
void trap_handler(void) {
|
||||||
|
unsigned long sepc = csrr(sepc);
|
||||||
|
unsigned long scause = csrr(scause);
|
||||||
|
unsigned long sstatus = csrr(sstatus);
|
||||||
|
|
||||||
|
if(scause == 8) {
|
||||||
|
puts("hello world");
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
__asm__ volatile("wfi");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue