summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/riscv/include/arch/exception.h2
-rw-r--r--src/arch/riscv/trap_handler.c29
-rw-r--r--src/arch/riscv/trap_util.S2
3 files changed, 31 insertions, 2 deletions
diff --git a/src/arch/riscv/include/arch/exception.h b/src/arch/riscv/include/arch/exception.h
index 4318cba8b6..28b9279707 100644
--- a/src/arch/riscv/include/arch/exception.h
+++ b/src/arch/riscv/include/arch/exception.h
@@ -55,7 +55,7 @@ static inline void exception_init(void)
void trap_handler(trapframe* tf);
void handle_supervisor_call(trapframe* tf);
-//void handleMisalignedLoad(trapframe *tf);
+void handleMisalignedLoad(trapframe *tf);
void handle_misaligned_store(trapframe *tf);
#endif
diff --git a/src/arch/riscv/trap_handler.c b/src/arch/riscv/trap_handler.c
index d4c9b87352..61480379b2 100644
--- a/src/arch/riscv/trap_handler.c
+++ b/src/arch/riscv/trap_handler.c
@@ -162,6 +162,35 @@ void trap_handler(trapframe *tf) {
while(1);
}
+void handleMisalignedLoad(trapframe *tf) {
+ printk(BIOS_DEBUG, "Trapframe ptr: %p\n", tf);
+ printk(BIOS_DEBUG, "Stored sp: %p\n", (void*) tf->gpr[2]);
+ insn_t faultingInstruction = 0;
+ uintptr_t faultingInstructionAddr = tf->epc;
+ asm("move t0, %0" : /* No outputs */ : "r"(faultingInstructionAddr));
+ asm("lw t0, 0(t0)");
+ asm("move %0, t0" : "=r"(faultingInstruction));
+ printk(BIOS_DEBUG, "Faulting instruction: 0x%x\n", faultingInstruction);
+ insn_t widthMask = 0x7000;
+ insn_t memWidth = (faultingInstruction & widthMask) >> 12;
+ insn_t destMask = 0xF80;
+ insn_t destRegister = (faultingInstruction & destMask) >> 7;
+ printk(BIOS_DEBUG, "Width: 0x%x\n", memWidth);
+ if (memWidth == 3) {
+ // load double, handle the issue
+ void* badAddress = (void*) tf->badvaddr;
+ memcpy(&(tf->gpr[destRegister]), badAddress, 8);
+ } else {
+ // panic, this should not have happened
+ printk(BIOS_DEBUG, "Code should not reach this path, misaligned on a non-64 bit store/load\n");
+ while(1);
+ }
+
+ // return to where we came from
+ write_csr(mepc, read_csr(mepc) + 4);
+ asm volatile("j machine_call_return");
+}
+
void handle_misaligned_store(trapframe *tf) {
printk(BIOS_DEBUG, "Trapframe ptr: %p\n", tf);
printk(BIOS_DEBUG, "Stored sp: %p\n", (void*) tf->gpr[2]);
diff --git a/src/arch/riscv/trap_util.S b/src/arch/riscv/trap_util.S
index 9701aaf1f6..274dca6960 100644
--- a/src/arch/riscv/trap_util.S
+++ b/src/arch/riscv/trap_util.S
@@ -112,7 +112,7 @@
supervisor_trap_entry:
csrw mscratch, sp
# load in the top of the machine stack
- la sp, 0x80FFF0
+ la sp, 0x80FFF0 - 64
1:addi sp,sp,-320
save_tf
move a0,sp