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