mirror of
https://github.com/StepanovPlaton/OSin1000Lines.git
synced 2026-04-03 12:20:46 +04:00
Add exception handler
This commit is contained in:
88
src/kernel.c
88
src/kernel.c
@@ -21,9 +21,95 @@ struct sbiret sbi_call(long arg0, long arg1, long arg2, long arg3, long arg4,
|
|||||||
|
|
||||||
void putchar(char ch) { sbi_call(ch, 0, 0, 0, 0, 0, 0, 1); }
|
void putchar(char ch) { sbi_call(ch, 0, 0, 0, 0, 0, 0, 1); }
|
||||||
|
|
||||||
|
__attribute__((naked)) __attribute__((aligned(4))) void kernel_entry(void) {
|
||||||
|
__asm__ __volatile__("csrw sscratch, sp\n"
|
||||||
|
"addi sp, sp, -4 * 31\n"
|
||||||
|
"sw ra, 4 * 0(sp)\n"
|
||||||
|
"sw gp, 4 * 1(sp)\n"
|
||||||
|
"sw tp, 4 * 2(sp)\n"
|
||||||
|
"sw t0, 4 * 3(sp)\n"
|
||||||
|
"sw t1, 4 * 4(sp)\n"
|
||||||
|
"sw t2, 4 * 5(sp)\n"
|
||||||
|
"sw t3, 4 * 6(sp)\n"
|
||||||
|
"sw t4, 4 * 7(sp)\n"
|
||||||
|
"sw t5, 4 * 8(sp)\n"
|
||||||
|
"sw t6, 4 * 9(sp)\n"
|
||||||
|
"sw a0, 4 * 10(sp)\n"
|
||||||
|
"sw a1, 4 * 11(sp)\n"
|
||||||
|
"sw a2, 4 * 12(sp)\n"
|
||||||
|
"sw a3, 4 * 13(sp)\n"
|
||||||
|
"sw a4, 4 * 14(sp)\n"
|
||||||
|
"sw a5, 4 * 15(sp)\n"
|
||||||
|
"sw a6, 4 * 16(sp)\n"
|
||||||
|
"sw a7, 4 * 17(sp)\n"
|
||||||
|
"sw s0, 4 * 18(sp)\n"
|
||||||
|
"sw s1, 4 * 19(sp)\n"
|
||||||
|
"sw s2, 4 * 20(sp)\n"
|
||||||
|
"sw s3, 4 * 21(sp)\n"
|
||||||
|
"sw s4, 4 * 22(sp)\n"
|
||||||
|
"sw s5, 4 * 23(sp)\n"
|
||||||
|
"sw s6, 4 * 24(sp)\n"
|
||||||
|
"sw s7, 4 * 25(sp)\n"
|
||||||
|
"sw s8, 4 * 26(sp)\n"
|
||||||
|
"sw s9, 4 * 27(sp)\n"
|
||||||
|
"sw s10, 4 * 28(sp)\n"
|
||||||
|
"sw s11, 4 * 29(sp)\n"
|
||||||
|
|
||||||
|
"csrr a0, sscratch\n"
|
||||||
|
"sw a0, 4 * 30(sp)\n"
|
||||||
|
|
||||||
|
"mv a0, sp\n"
|
||||||
|
"call handle_trap\n"
|
||||||
|
|
||||||
|
"lw ra, 4 * 0(sp)\n"
|
||||||
|
"lw gp, 4 * 1(sp)\n"
|
||||||
|
"lw tp, 4 * 2(sp)\n"
|
||||||
|
"lw t0, 4 * 3(sp)\n"
|
||||||
|
"lw t1, 4 * 4(sp)\n"
|
||||||
|
"lw t2, 4 * 5(sp)\n"
|
||||||
|
"lw t3, 4 * 6(sp)\n"
|
||||||
|
"lw t4, 4 * 7(sp)\n"
|
||||||
|
"lw t5, 4 * 8(sp)\n"
|
||||||
|
"lw t6, 4 * 9(sp)\n"
|
||||||
|
"lw a0, 4 * 10(sp)\n"
|
||||||
|
"lw a1, 4 * 11(sp)\n"
|
||||||
|
"lw a2, 4 * 12(sp)\n"
|
||||||
|
"lw a3, 4 * 13(sp)\n"
|
||||||
|
"lw a4, 4 * 14(sp)\n"
|
||||||
|
"lw a5, 4 * 15(sp)\n"
|
||||||
|
"lw a6, 4 * 16(sp)\n"
|
||||||
|
"lw a7, 4 * 17(sp)\n"
|
||||||
|
"lw s0, 4 * 18(sp)\n"
|
||||||
|
"lw s1, 4 * 19(sp)\n"
|
||||||
|
"lw s2, 4 * 20(sp)\n"
|
||||||
|
"lw s3, 4 * 21(sp)\n"
|
||||||
|
"lw s4, 4 * 22(sp)\n"
|
||||||
|
"lw s5, 4 * 23(sp)\n"
|
||||||
|
"lw s6, 4 * 24(sp)\n"
|
||||||
|
"lw s7, 4 * 25(sp)\n"
|
||||||
|
"lw s8, 4 * 26(sp)\n"
|
||||||
|
"lw s9, 4 * 27(sp)\n"
|
||||||
|
"lw s10, 4 * 28(sp)\n"
|
||||||
|
"lw s11, 4 * 29(sp)\n"
|
||||||
|
"lw sp, 4 * 30(sp)\n"
|
||||||
|
"sret\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_trap(struct trap_frame *f) {
|
||||||
|
uint32_t scause = READ_CSR(scause);
|
||||||
|
uint32_t stval = READ_CSR(stval);
|
||||||
|
uint32_t user_pc = READ_CSR(sepc);
|
||||||
|
|
||||||
|
PANIC("unexpected trap scause=%x, stval=%x, sepc=%x\n", scause, stval,
|
||||||
|
user_pc);
|
||||||
|
}
|
||||||
|
|
||||||
void kernel_main(void) {
|
void kernel_main(void) {
|
||||||
memset(__bss, 0, (size_t)__bss_end - (size_t)__bss);
|
memset(__bss, 0, (size_t)__bss_end - (size_t)__bss);
|
||||||
|
|
||||||
|
WRITE_CSR(stvec, (uint32_t)kernel_entry);
|
||||||
|
__asm__ __volatile__("unimp");
|
||||||
|
|
||||||
PANIC("booted!");
|
PANIC("booted!");
|
||||||
printf("unreachable here!\n");
|
printf("unreachable here!\n");
|
||||||
}
|
}
|
||||||
@@ -33,4 +119,4 @@ __attribute__((section(".text.boot"))) __attribute__((naked)) void boot(void) {
|
|||||||
"j kernel_main\n"
|
"j kernel_main\n"
|
||||||
:
|
:
|
||||||
: [stack_top] "r"(__stack_top));
|
: [stack_top] "r"(__stack_top));
|
||||||
}
|
}
|
||||||
|
|||||||
49
src/kernel.h
49
src/kernel.h
@@ -14,4 +14,51 @@ struct sbiret {
|
|||||||
printf("PANIC: %s:%d: " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \
|
printf("PANIC: %s:%d: " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \
|
||||||
while (1) { \
|
while (1) { \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
struct trap_frame {
|
||||||
|
uint32_t ra;
|
||||||
|
uint32_t gp;
|
||||||
|
uint32_t tp;
|
||||||
|
uint32_t t0;
|
||||||
|
uint32_t t1;
|
||||||
|
uint32_t t2;
|
||||||
|
uint32_t t3;
|
||||||
|
uint32_t t4;
|
||||||
|
uint32_t t5;
|
||||||
|
uint32_t t6;
|
||||||
|
uint32_t a0;
|
||||||
|
uint32_t a1;
|
||||||
|
uint32_t a2;
|
||||||
|
uint32_t a3;
|
||||||
|
uint32_t a4;
|
||||||
|
uint32_t a5;
|
||||||
|
uint32_t a6;
|
||||||
|
uint32_t a7;
|
||||||
|
uint32_t s0;
|
||||||
|
uint32_t s1;
|
||||||
|
uint32_t s2;
|
||||||
|
uint32_t s3;
|
||||||
|
uint32_t s4;
|
||||||
|
uint32_t s5;
|
||||||
|
uint32_t s6;
|
||||||
|
uint32_t s7;
|
||||||
|
uint32_t s8;
|
||||||
|
uint32_t s9;
|
||||||
|
uint32_t s10;
|
||||||
|
uint32_t s11;
|
||||||
|
uint32_t sp;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
#define READ_CSR(reg) \
|
||||||
|
({ \
|
||||||
|
unsigned long __tmp; \
|
||||||
|
__asm__ __volatile__("csrr %0, " #reg : "=r"(__tmp)); \
|
||||||
|
__tmp; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define WRITE_CSR(reg, value) \
|
||||||
|
do { \
|
||||||
|
uint32_t __tmp = (value); \
|
||||||
|
__asm__ __volatile__("csrw " #reg ", %0" ::"r"(__tmp)); \
|
||||||
|
} while (0)
|
||||||
|
|||||||
3
src/run.sh
Normal file → Executable file
3
src/run.sh
Normal file → Executable file
@@ -1,4 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -xue
|
set -xue
|
||||||
|
|
||||||
qemu-system-riscv32 -machine virt -bios default -nographic -serial mon:stdio --no-reboot -kernel kernel.elf
|
make kernel
|
||||||
|
qemu-system-riscv32 -machine virt -bios default -nographic -serial mon:stdio --no-reboot -kernel kernel.elf
|
||||||
|
|||||||
Reference in New Issue
Block a user