Skip to content
Snippets Groups Projects
Commit a39c9b6a authored by Anna Lyons's avatar Anna Lyons
Browse files

RISC-V: handle all faults

This change alters RISC-V fault handling to pass all non-VM faults as
user exceptions. As we cannot guarantee what the hardware will send us
in the scause register, we must handle all possible values.

It also makes fault handling more consistent with other architectures in
c_traps.c.
parent 63ed19c9
No related branches found
No related tags found
No related merge requests found
......@@ -51,13 +51,17 @@ enum vm_fault_type {
RISCVInstructionAccessFault = 1,
RISCVInstructionIllegal = 2,
RISCVBreakpoint = 3,
/* reserved */
RISCVLoadAccessFault = 5,
RISCVAddressMisaligned = 6,
RISCVStoreAccessFault = 7,
RISCVEnvCall = 8,
/* 9-11 reserved */
RISCVInstructionPageFault = 12,
RISCVLoadPageFault = 13,
/* 14 - reserved */
RISCVStorePageFault = 15
/* >= 16 reserved */
};
typedef uint32_t vm_fault_type_t;
......
......@@ -115,7 +115,22 @@ c_handle_exception(void)
c_entry_hook();
handle_exception();
word_t scause = read_scause();
switch (scause) {
/* vm faults */
case RISCVInstructionAccessFault:
case RISCVLoadAccessFault:
case RISCVStoreAccessFault:
case RISCVLoadPageFault:
case RISCVStorePageFault:
case RISCVInstructionPageFault:
handleVMFaultEvent(scause);
break;
/* user level exceptions */
default:
handleUserLevelFault(scause, read_sbadaddr());
break;
}
restore_user_context();
UNREACHABLE();
......
......@@ -16,95 +16,10 @@
* Copyright 2015, 2016 Hesham Almatary <heshamelmatary@gmail.com>
*/
#include <stdint.h>
#include <util.h>
#include <machine/io.h>
#include <plat/machine/devices.h>
#include <arch/machine.h>
#include <arch/sbi.h>
#include <arch/kernel/traps.h>
static inline void print_format_cause(int cause_num)
{
switch (cause_num) {
case RISCVInstructionMisaligned:
printf("Instruction address misaligned\n");
break;
case RISCVInstructionAccessFault:
printf("Instruction access fault\n");
break;
case RISCVInstructionIllegal:
printf("Illegal instruction\n");
break;
case RISCVBreakpoint:
printf("Breakpoint\n");
break;
case RISCVLoadAccessFault:
printf("Load access fault\n");
break;
case RISCVAddressMisaligned:
printf("AMO address misaligned\n");
break;
case RISCVStoreAccessFault:
printf("Store/AMO access fault\n");
break;
case RISCVEnvCall:
printf("Environment call\n");
break;
case RISCVInstructionPageFault:
printf("Instruction page fault\n");
break;
case RISCVLoadPageFault:
printf("Load page fault\n");
break;
case RISCVStorePageFault:
printf("Store page fault\n");
break;
default:
printf("Reserved cause %d\n", cause_num);
break;
}
}
void handle_exception(void)
{
word_t scause = read_scause();
/* handleVMFaultEvent
* */
switch (scause) {
case RISCVInstructionAccessFault:
case RISCVLoadAccessFault:
case RISCVStoreAccessFault:
case RISCVInstructionPageFault:
case RISCVLoadPageFault:
case RISCVStorePageFault:
handleVMFaultEvent(scause);
break;
case RISCVInstructionIllegal:
handleUserLevelFault(0, 0);
break;
default:
print_format_cause(read_scause());
printf("sepc = %p\n", (void*)(word_t)read_sepc());
printf("sbadaddr = %p\n", (void*)(word_t)read_sbadaddr());
printf("sstatus = %p\n", (void*)(word_t)read_sstatus());
printf("Halt!\n");
printf("Register Context Dump \n");
register word_t UNUSED thread_context asm("t0");
for (int i = 0; i < 32; i++) {
printf("x%d = %p\n", i, (void*) * (((word_t *) thread_context) + i));
}
halt();
}
}
#ifdef CONFIG_PRINTING
#if defined(CONFIG_PRINTING) || defined(CONFIG_DEBUG)
void
putDebugChar(unsigned char c)
{
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment