From dc5dc571620ba1a2a79a638f3570b49376b2bb55 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Thu, 26 Jun 2025 22:54:56 +0200 Subject: [PATCH] Add exception handling --- common.s | 83 +++++++++++++++------------ kernel.s | 172 +++++++++++++++++++++++++++++++++++++++++++++---------- run.sh | 2 +- 3 files changed, 191 insertions(+), 66 deletions(-) diff --git a/common.s b/common.s index f61321e..f20e0f8 100644 --- a/common.s +++ b/common.s @@ -3,7 +3,7 @@ # obtain one at https://mozilla.org/MPL/2.0/. .global _is_alpha, _is_digit, _is_alnum, _is_upper, _is_lower -.global _write_s, _read_file, _write_error, _write_c, _write_i, _print_i +.global write_s, _read_file, _write_error, write_c, write_i, _print_i .global _memcmp, _memchr, _memmem, _memcpy, _mmap .global _current, _get, _advance, _label_counter .global _divide_by_zero_error, _exit, _strings_index, _string_equal @@ -175,28 +175,44 @@ _is_alnum: addi sp, sp, 16 ret -# Writes a string to the standard output. +# Prints a string. # # Parameters: # a0 - Length of the string. # a1 - String pointer. -.type _write_s, @function -_write_s: +.type write_s, @function +write_s: # Prologue. - addi sp, sp, -8 - sw ra, 4(sp) - sw s0, 0(sp) - addi s0, sp, 8 + addi sp, sp, -32 + sw ra, 28(sp) + sw s0, 24(sp) + addi s0, sp, 32 - mv a2, a0 - li a0, STDOUT - li a7, SYS_WRITE - ecall + sw s1, 20(sp) + sw s2, 16(sp) + + mv s1, a0 + mv s2, a1 + +.Lwrite_s_if: + beqz s1, .Lwrite_s_end + + lw a0, (s2) + call write_c + + addi s1, s1, -1 + addi s2, s2, 1 + + j .Lwrite_s_if + +.Lwrite_s_end: + lw s1, 20(sp) + lw s2, 16(sp) # Epilogue. - lw ra, 4(sp) - lw s0, 0(sp) - addi sp, sp, 8 + lw ra, 28(sp) + lw s0, 24(sp) + addi sp, sp, 32 ret # Reads standard input into a buffer. @@ -308,8 +324,8 @@ _print_i: # # Parameters: # a0 - Whole number. -.type _write_i, @function -_write_i: +.type write_i, @function +write_i: addi sp, sp, -32 sw ra, 28(sp) sw s0, 24(sp) @@ -319,33 +335,28 @@ _write_i: call _print_i addi a1, sp, 0 - call _write_s + call write_s lw ra, 28(sp) lw s0, 24(sp) addi sp, sp, 32 ret -# Writes a character from a0 into the standard output. -.type _write_c, @function -_write_c: - # Prologue - addi sp, sp, -16 - sw ra, 12(sp) - sw s0, 8(sp) - addi s0, sp, 16 +# Prints a character from a0. +# +# Arguments: +# a0 - Character. +.type write_c, @function +write_c: + li a1, 0 + li a2, 0 + li a3, 0 + li a4, 0 + li a5, 0 + li a6, 0 + li a7, 1 # sbi_console_putchar. - sb a0, 4(sp) - li a0, STDOUT - addi a1, sp, 4 - li a2, 1 - li a7, SYS_WRITE ecall - - # Epilogue. - lw ra, 12(sp) - lw s0, 8(sp) - add sp, sp, 16 ret # a0 - Pointer to an array to get the first element. diff --git a/kernel.s b/kernel.s index 37b086d..c069cd8 100644 --- a/kernel.s +++ b/kernel.s @@ -2,7 +2,8 @@ .section .rodata -hello_world: .asciz "\nHello world!\n" +panic_message: .asciz "\nPanic" +.equ PANIC_MESSAGE_SIZE, . - panic_message .section .text @@ -18,21 +19,6 @@ bzero: .Lbzero_end: ret -# Arguments: -# a0 - Character. -.type putchar, @function -putchar: - li a1, 0 - li a2, 0 - li a3, 0 - li a4, 0 - li a5, 0 - li a6, 0 - li a7, 1 # sbi_console_putchar. - - ecall - ret - .type kernel_main, @function kernel_main: # Prologue. @@ -41,28 +27,156 @@ kernel_main: sw s0, 24(sp) addi s0, sp, 32 - sw s1, 20(sp) + la t0, kernel_entry + csrw stvec, t0 - la s1, hello_world - -.Lkernel_main_if: - lw a0, (s1) - beqz a0, .Lkernel_main - - call putchar - addi s1, s1, 1 - - j .Lkernel_main_if + unimp .Lkernel_main: j .Lkernel_main - lw s1, 20(sp) + # Epilogue. + lw ra, 28(sp) + lw s0, 24(sp) + addi sp, sp, 32 + ret + +.balign 4 +.type kernel_entry, @function +kernel_entry: + csrw sscratch, sp + addi sp, sp, -4 * 31 + + sw ra, 0(sp) + sw gp, 4(sp) + sw tp, 8(sp) + sw t0, 12(sp) + sw t1, 16(sp) + sw t2, 20(sp) + sw t3, 24(sp) + sw t4, 28(sp) + sw t5, 32(sp) + sw t6, 36(sp) + sw a0, 40(sp) + sw a1, 44(sp) + sw a2, 48(sp) + sw a3, 52(sp) + sw a4, 56(sp) + sw a5, 60(sp) + sw a6, 64(sp) + sw a7, 68(sp) + sw s0, 72(sp) + sw s1, 76(sp) + sw s2, 80(sp) + sw s3, 84(sp) + sw s4, 88(sp) + sw s5, 92(sp) + sw s6, 96(sp) + sw s7, 100(sp) + sw s8, 104(sp) + sw s9, 108(sp) + sw s10, 112(sp) + sw s11, 116(sp) + + csrr a0, sscratch + sw a0, 120(sp) + + mv a0, sp + call handle_trap + + lw ra, 0(sp) + lw gp, 4(sp) + lw tp, 8(sp) + lw t0, 12(sp) + lw t1, 16(sp) + lw t2, 20(sp) + lw t3, 24(sp) + lw t4, 28(sp) + lw t5, 32(sp) + lw t6, 36(sp) + lw a0, 40(sp) + lw a1, 44(sp) + lw a2, 48(sp) + lw a3, 52(sp) + lw a4, 56(sp) + lw a5, 60(sp) + lw a6, 64(sp) + lw a7, 68(sp) + lw s0, 72(sp) + lw s1, 76(sp) + lw s2, 80(sp) + lw s3, 84(sp) + lw s4, 88(sp) + lw s5, 92(sp) + lw s6, 96(sp) + lw s7, 100(sp) + lw s8, 104(sp) + lw s9, 108(sp) + lw s10, 112(sp) + lw s11, 116(sp) + lw sp, 120(sp) + + sret + +.type handle_trap, @function +handle_trap: + # Prologue. + addi sp, sp, -32 + sw ra, 28(sp) + sw s0, 24(sp) + addi s0, sp, 32 + + csrr t0, scause + csrr t1, stval + csrr t2, sepc + + li a0, PANIC_MESSAGE_SIZE + la a1, panic_message + call write_s + + li a0, ' ' + call write_c + + csrr a0, scause + call write_i + + li a0, ',' + call write_c + + csrr a0, stval + call write_i + + li a0, ',' + call write_c + + csrr a0, sepc + call write_i + + call panic # Epilogue. lw ra, 28(sp) lw s0, 24(sp) - add sp, sp, 32 + addi sp, sp, 32 + ret + +.type panic, @function +panic: + # Prologue. + addi sp, sp, -32 + sw ra, 28(sp) + sw s0, 24(sp) + addi s0, sp, 32 + + li a0, '\n' + call write_c +.Lpanic: + j .Lpanic + + # Epilogue. + lw ra, 28(sp) + lw s0, 24(sp) + addi sp, sp, 32 ret .section .text.boot diff --git a/run.sh b/run.sh index 9406101..3f33714 100755 --- a/run.sh +++ b/run.sh @@ -7,7 +7,7 @@ QEMU=qemu-system-riscv32 # Path to clang and compiler flags CC=../riscv32-ilp32d--glibc/bin/riscv32-linux-gcc -CFLAGS="-O2 -g3 -Wall -march=rv32im -mabi=ilp32 -fno-stack-protector -ffreestanding -nostdlib -static" +CFLAGS="-O2 -g3 -Wall -march=rv32imzicsr -mabi=ilp32 -fno-stack-protector -ffreestanding -nostdlib -static" # Build the kernel $CC $CFLAGS -T kernel.ld -Wl,-Map=kernel.map -o kernel.elf kernel.s common.s