From 8c64512cabaf36cb355f240fc8964e0b587545e1 Mon Sep 17 00:00:00 2001 From: Zhiyuan Shao Date: Wed, 18 Aug 2021 10:36:55 +0800 Subject: [PATCH] init commit of lab1_2 --- Makefile | 2 +- kernel/machine/minit.c | 10 +++++++ kernel/machine/mtrap.c | 51 ++++++++++++++++++++++++++++++++++ kernel/machine/mtrap_vector.S | 38 +++++++++++++++++++++++++ user/app_helloworld.c | 17 ------------ user/app_illegal_instruction.c | 15 ++++++++++ 6 files changed, 115 insertions(+), 18 deletions(-) create mode 100644 kernel/machine/mtrap.c create mode 100644 kernel/machine/mtrap_vector.S delete mode 100644 user/app_helloworld.c create mode 100644 user/app_illegal_instruction.c diff --git a/Makefile b/Makefile index 9301c4c..3c40d53 100644 --- a/Makefile +++ b/Makefile @@ -69,8 +69,8 @@ USER_CPPS := user/*.c USER_CPPS := $(wildcard $(USER_CPPS)) USER_OBJS := $(addprefix $(OBJ_DIR)/, $(patsubst %.c,%.o,$(USER_CPPS))) -USER_TARGET := $(OBJ_DIR)/app_helloworld +USER_TARGET := $(OBJ_DIR)/app_illegal_instruction #------------------------targets------------------------ $(OBJ_DIR): @-mkdir -p $(OBJ_DIR) diff --git a/kernel/machine/minit.c b/kernel/machine/minit.c index 8baf18d..fb31df8 100644 --- a/kernel/machine/minit.c +++ b/kernel/machine/minit.c @@ -16,11 +16,15 @@ __attribute__((aligned(16))) char stack0[4096 * NCPU]; // sstart is the supervisor state entry point extern void s_start(); // defined in kernel/kernel.c +// M-mode trap entry point +extern void mtrapvec(); // htif is defined in kernel/machine/spike_htif.c, marks the availability of HTIF extern uint64 htif; // g_mem_size is defined in kernel/machine/spike_memory.c, size of the emulated memory extern uint64 g_mem_size; +// g_itrframe is used for saving registers when interrupt hapens in M mode +struct riscv_regs g_itrframe; // // get the information of HTIF (calling interface) and the emulated memory by @@ -73,12 +77,18 @@ void m_start(uintptr_t hartid, uintptr_t dtb) { // init HTIF (Host-Target InterFace) and memory by using the Device Table Blob (DTB) init_dtb(dtb); + // save the address of frame for interrupt in M mode to csr "mscratch". + write_csr(mscratch, &g_itrframe); + // set previous privilege mode to S (Supervisor), and will enter S mode after 'mret' write_csr(mstatus, ((read_csr(mstatus) & ~MSTATUS_MPP_MASK) | MSTATUS_MPP_S)); // set M Exception Program Counter to sstart, for mret (requires gcc -mcmodel=medany) write_csr(mepc, (uint64)s_start); + // setup trap handling vector + write_csr(mtvec, (uint64)mtrapvec); + // delegate all interrupts and exceptions to supervisor mode. delegate_traps(); diff --git a/kernel/machine/mtrap.c b/kernel/machine/mtrap.c new file mode 100644 index 0000000..df8c82e --- /dev/null +++ b/kernel/machine/mtrap.c @@ -0,0 +1,51 @@ +#include "kernel/riscv.h" +#include "kernel/process.h" +#include "spike_interface/spike_utils.h" + +static void handle_instruction_access_fault() { panic("Instruction access fault!"); } + +static void handle_load_access_fault() { panic("Load access fault!"); } + +static void handle_store_access_fault() { panic("Store/AMO access fault!"); } + +static void handle_illegal_instruction() { panic("Illegal instruction!"); } + +static void handle_misaligned_load() { panic("Misaligned Load!"); } + +static void handle_misaligned_store() { panic("Misaligned AMO!"); } + +// +// handle_mtrap calls cooresponding functions to handle an exception of a given type. +// +void handle_mtrap() { + uint64 mcause = read_csr(mcause); + switch (mcause) { + case CAUSE_FETCH_ACCESS: + handle_instruction_access_fault(); + break; + case CAUSE_LOAD_ACCESS: + handle_load_access_fault(); + case CAUSE_STORE_ACCESS: + handle_store_access_fault(); + break; + case CAUSE_ILLEGAL_INSTRUCTION: + // TODO (lab1_2): call handle_illegal_instruction to implement illegal instruction + // interception, and finish lab1_2. + panic( "call handle_illegal_instruction to accomplish illegal instruction interception for lab1_2.\n" ); + + break; + case CAUSE_MISALIGNED_LOAD: + handle_misaligned_load(); + break; + case CAUSE_MISALIGNED_STORE: + handle_misaligned_store(); + break; + + default: + sprint("machine trap(): unexpected mscause %p\n", mcause); + sprint(" mepc=%p mtval=%p\n", read_csr(mepc), read_csr(mtval)); + panic( "unexpected exception happened in M-mode.\n" ); + break; + } +} + diff --git a/kernel/machine/mtrap_vector.S b/kernel/machine/mtrap_vector.S new file mode 100644 index 0000000..c8fef29 --- /dev/null +++ b/kernel/machine/mtrap_vector.S @@ -0,0 +1,38 @@ +#include "util/load_store.S" + +# +# M-mode trap entry point +# +.globl mtrapvec +.align 4 +mtrapvec: + # swap a0 and mscratch + # so that a0 points to interrupt frame + csrrw a0, mscratch, a0 + + # save the registers in interrupt frame + addi t6, a0, 0 + store_all_registers + # save the user a0 in itrframe->a0 + csrr t0, mscratch + sd t0, 72(a0) + + # use stack0 for sp + la sp, stack0 + li a3, 4096 + csrr a4, mhartid + addi a4, a4, 1 + mul a3, a3, a4 + add sp, sp, a3 + + // save the address of interrupt frame in the csr "mscratch" + csrw mscratch, a0 + + call handle_mtrap + + // restore all registers + csrr t6, mscratch + restore_all_registers + + mret + diff --git a/user/app_helloworld.c b/user/app_helloworld.c deleted file mode 100644 index 0702f38..0000000 --- a/user/app_helloworld.c +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Below is the given application for lab1_1. - * - * You can build this app (as well as our PKE OS kernel) by command: - * $ make - * - * Or run this app (with the support from PKE OS kernel) by command: - * $ make run - */ - -#include "user_lib.h" - -int main(void) { - printu("Hello world!\n"); - - exit(0); -} diff --git a/user/app_illegal_instruction.c b/user/app_illegal_instruction.c new file mode 100644 index 0000000..3ff98cb --- /dev/null +++ b/user/app_illegal_instruction.c @@ -0,0 +1,15 @@ +/* + * Below is the given application for lab1_2. + * This app attempts to issue M-mode instruction in U-mode, and consequently raises an exception. + */ + +#include "user_lib.h" +#include "util/types.h" + +int main(void) { + printu("Going to hack the system by running privilege instructions.\n"); + // we are now in U(user)-mode, but the "csrw" instruction requires M-mode privilege. + // Attempting to execute such instruction will raise illegal instruction exception. + asm volatile("csrw sscratch, 0"); + exit(0); +}