blob: a1d83c825632780af207407ccaa74ebdcdc482f0 [file] [log] [blame] [edit]
/*
* Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
*
* SPDX-License-Identifier: MIT
*/
#include <stdio.h>
#include "exception_handler.h"
#include "riscv_encoding.h"
#include "interrupt_control_eclic.h"
#ifdef CONFIG_DEBUG_COREDUMP
#include "coredump.h"
#endif
#if __riscv_xlen == 64
#define portWORD_SIZE 8
#elif __riscv_xlen == 32
#define portWORD_SIZE 4
#else
#error Assembler did not define __riscv_xlen
#endif
static void dump_stack(uint32_t sp)
{
// print x1
printf("x%-2d: %08x,", 1, *(unsigned int *)(sp + 1 * portWORD_SIZE));
// print x5-x31
for (int i = 5; i < 32; i++) {
if (i % 2)
printf("x%-2d: %08x\n", i,
*(unsigned int *)(sp + ((i - 3) * portWORD_SIZE)));
else
printf("x%-2d: %08x,", i,
*(unsigned int *)(sp + ((i - 3) * portWORD_SIZE)));
}
}
static uint32_t handle_exception(uint32_t mcause, uint32_t sp)
{
uint8_t exception_type;
uint32_t mstatus_mps_bits;
clear_csr(mstatus, MSTATUS_MIE);
exception_type = (mcause & 0x1f);
mstatus_mps_bits = ((read_csr(mstatus) & MSTATUS_MPS) >> MSTATUS_MPS_LSB);
// 0 means prior status is normal,2 EXCEPTION,3 NMI,1 int
printf("exception mstatus.MPS %lx\n", mstatus_mps_bits);
// exception position
printf("exception mepc %lx\n", read_csr(mepc));
// exception instruction
printf("exception mtval %lx\n", read_csr(mbadaddr));
printf("exception mcause %lx\n", mcause);
switch (exception_type) {
case 0:
printf("Instruction address misaligned!\n");
break;
case 1:
printf("Instruction access fault!\n");
break;
case 2:
printf("Illegal instruction\n");
break;
case 3:
printf("Breakpoint\n");
break;
case 4:
printf("Load address misaligned\n");
break;
case 5:
printf("Load access fault\n");
break;
case 6:
printf("Store/AMO address misaligned\n");
break;
case 7:
printf("Store/AMO access fault\n");
break;
case 11:
printf("Environment call from M-mode\n");
break;
default:
printf("unknown exception: %lx ", exception_type);
break;
}
dump_stack(sp);
#ifdef CONFIG_DEBUG_COREDUMP
coredump(0, (void *)sp);
#endif
do {
} while (1);
return 0;
}
static uint32_t handle_nmi(uint32_t mcause, uint32_t sp)
{
printf("nmi mepc ", read_csr(mepc));
printf("nmi mtval ", read_csr(mbadaddr));
printf("nmi mcause ", mcause);
return 0;
}
uint32_t interrupt_register_exception(uint32_t mcause, uint32_t sp)
{
return handle_exception(mcause, sp);
}
uint32_t interrupt_register_nmi(uint32_t mcause, uint32_t sp)
{
return handle_nmi(mcause, sp);
}