blob: a1d83c825632780af207407ccaa74ebdcdc482f0 [file] [log] [blame]
xiaohu.huang797c4c12024-01-24 18:52:43 +08001/*
2 * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
7#include <stdio.h>
8#include "exception_handler.h"
9#include "riscv_encoding.h"
10#include "interrupt_control_eclic.h"
shijie.xiong1038db02024-02-01 14:16:05 +080011#ifdef CONFIG_DEBUG_COREDUMP
12#include "coredump.h"
13#endif
xiaohu.huang797c4c12024-01-24 18:52:43 +080014
shijie.xiong1038db02024-02-01 14:16:05 +080015#if __riscv_xlen == 64
16 #define portWORD_SIZE 8
17#elif __riscv_xlen == 32
18 #define portWORD_SIZE 4
19#else
20 #error Assembler did not define __riscv_xlen
21#endif
22
23static void dump_stack(uint32_t sp)
xiaohu.huang797c4c12024-01-24 18:52:43 +080024{
shijie.xiong1038db02024-02-01 14:16:05 +080025 // print x1
26 printf("x%-2d: %08x,", 1, *(unsigned int *)(sp + 1 * portWORD_SIZE));
xiaohu.huang797c4c12024-01-24 18:52:43 +080027
shijie.xiong1038db02024-02-01 14:16:05 +080028 // print x5-x31
29 for (int i = 5; i < 32; i++) {
30 if (i % 2)
31 printf("x%-2d: %08x\n", i,
32 *(unsigned int *)(sp + ((i - 3) * portWORD_SIZE)));
33 else
34 printf("x%-2d: %08x,", i,
35 *(unsigned int *)(sp + ((i - 3) * portWORD_SIZE)));
36 }
37}
38
39static uint32_t handle_exception(uint32_t mcause, uint32_t sp)
40{
41 uint8_t exception_type;
42 uint32_t mstatus_mps_bits;
43
44 clear_csr(mstatus, MSTATUS_MIE);
45
46 exception_type = (mcause & 0x1f);
47 mstatus_mps_bits = ((read_csr(mstatus) & MSTATUS_MPS) >> MSTATUS_MPS_LSB);
48 // 0 means prior status is normal,2 EXCEPTION,3 NMI,1 int
49 printf("exception mstatus.MPS %lx\n", mstatus_mps_bits);
50 // exception position
51 printf("exception mepc %lx\n", read_csr(mepc));
52 // exception instruction
53 printf("exception mtval %lx\n", read_csr(mbadaddr));
54 printf("exception mcause %lx\n", mcause);
55
56 switch (exception_type) {
57 case 0:
58 printf("Instruction address misaligned!\n");
59 break;
60
61 case 1:
62 printf("Instruction access fault!\n");
63 break;
64
65 case 2:
66 printf("Illegal instruction\n");
67 break;
68
69 case 3:
70 printf("Breakpoint\n");
71 break;
72
73 case 4:
74 printf("Load address misaligned\n");
75 break;
76
77 case 5:
78 printf("Load access fault\n");
79 break;
80
81 case 6:
82 printf("Store/AMO address misaligned\n");
83 break;
84
85 case 7:
86 printf("Store/AMO access fault\n");
87 break;
88
89 case 11:
90 printf("Environment call from M-mode\n");
91 break;
92
93 default:
94 printf("unknown exception: %lx ", exception_type);
95 break;
96 }
97
98 dump_stack(sp);
99
100#ifdef CONFIG_DEBUG_COREDUMP
101 coredump(0, (void *)sp);
102#endif
103
104 do {
105 } while (1);
xiaohu.huang797c4c12024-01-24 18:52:43 +0800106
107 return 0;
108}
109
shijie.xiong1038db02024-02-01 14:16:05 +0800110static uint32_t handle_nmi(uint32_t mcause, uint32_t sp)
xiaohu.huang797c4c12024-01-24 18:52:43 +0800111{
shijie.xiong1038db02024-02-01 14:16:05 +0800112 printf("nmi mepc ", read_csr(mepc));
113 printf("nmi mtval ", read_csr(mbadaddr));
114 printf("nmi mcause ", mcause);
xiaohu.huang797c4c12024-01-24 18:52:43 +0800115 return 0;
116}
117
118uint32_t interrupt_register_exception(uint32_t mcause, uint32_t sp)
119{
120 return handle_exception(mcause, sp);
121}
122
123uint32_t interrupt_register_nmi(uint32_t mcause, uint32_t sp)
124{
shijie.xiong1038db02024-02-01 14:16:05 +0800125 return handle_nmi(mcause, sp);
xiaohu.huang797c4c12024-01-24 18:52:43 +0800126}