• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include "hpm_common.h"
9 #include "hpm_soc.h"
10 
11 /********************** MCAUSE exception types **************************************/
12 #define MCAUSE_INSTR_ADDR_MISALIGNED (0U)       //!< Instruction Address misaligned
13 #define MCAUSE_INSTR_ACCESS_FAULT (1U)          //!< Instruction access fault
14 #define MCAUSE_ILLEGAL_INSTR (2U)               //!< Illegal instruction
15 #define MCAUSE_BREAKPOINT (3U)                  //!< Breakpoint
16 #define MCAUSE_LOAD_ADDR_MISALIGNED (4U)        //!< Load address misaligned
17 #define MCAUSE_LOAD_ACCESS_FAULT (5U)           //!< Load access fault
18 #define MCAUSE_STORE_AMO_ADDR_MISALIGNED (6U)   //!< Store/AMO address misaligned
19 #define MCAUSE_STORE_AMO_ACCESS_FAULT (7U)      //!< Store/AMO access fault
20 #define MCAUSE_ECALL_FROM_USER_MODE (8U)        //!< Environment call from User mode
21 #define MCAUSE_ECALL_FROM_SUPERVISOR_MODE (9U)  //!< Environment call from Supervisor mode
22 #define MCAUSE_ECALL_FROM_MACHINE_MODE (11U)    //!< Environment call from machine mode
23 #define MCAUSE_INSTR_PAGE_FAULT (12U)           //!< Instruction page fault
24 #define MCAUSE_LOAD_PAGE_FAULT (13)             //!< Load page fault
25 #define MCAUSE_STORE_AMO_PAGE_FAULT (15U)       //!< Store/AMO page fault
26 
27 #define IRQ_S_SOFT          	1
28 #define IRQ_H_SOFT          	2
29 #define IRQ_M_SOFT          	3
30 #define IRQ_S_TIMER         	5
31 #define IRQ_H_TIMER         	6
32 #define IRQ_M_TIMER         	7
33 #define IRQ_S_EXT           	9
34 #define IRQ_H_EXT           	10
35 #define IRQ_M_EXT           	11
36 #define IRQ_COP             	12
37 #define IRQ_HOST            	13
38 
39 
40 
mchtmr_isr(void)41 __attribute__((weak)) void mchtmr_isr(void)
42 {
43 }
44 
swi_isr(void)45 __attribute__((weak)) void swi_isr(void)
46 {
47 }
48 
syscall_handler(long n,long a0,long a1,long a2,long a3)49 __attribute__((weak)) void syscall_handler(long n, long a0, long a1, long a2, long a3)
50 {
51 }
52 
exception_handler(long cause,long epc)53 __attribute__((weak)) long exception_handler(long cause, long epc)
54 {
55     switch (cause) {
56         case MCAUSE_INSTR_ADDR_MISALIGNED:
57             break;
58         case MCAUSE_INSTR_ACCESS_FAULT:
59             break;
60         case MCAUSE_ILLEGAL_INSTR:
61             break;
62         case MCAUSE_BREAKPOINT:
63             break;
64         case MCAUSE_LOAD_ADDR_MISALIGNED:
65             break;
66         case MCAUSE_LOAD_ACCESS_FAULT:
67             break;
68         case MCAUSE_STORE_AMO_ADDR_MISALIGNED:
69             break;
70         case MCAUSE_STORE_AMO_ACCESS_FAULT:
71             break;
72         case MCAUSE_ECALL_FROM_USER_MODE:
73             break;
74         case MCAUSE_ECALL_FROM_SUPERVISOR_MODE:
75             break;
76         case MCAUSE_ECALL_FROM_MACHINE_MODE:
77             break;
78         case MCAUSE_INSTR_PAGE_FAULT:
79             break;
80         case MCAUSE_LOAD_PAGE_FAULT:
81             break;
82         case MCAUSE_STORE_AMO_PAGE_FAULT:
83             break;
84         default:
85             break;
86     }
87     /* Unhandled Trap */
88     return epc;
89 }
90 
91 #ifndef CONFIG_FREERTOS
92 void irq_handler_trap(void) __attribute__ ((section(".isr_vector"), interrupt("machine"), aligned(4)));
93 #else
94 void irq_handler_trap(void) __attribute__ ((section(".isr_vector")));
95 #endif
irq_handler_trap(void)96 void irq_handler_trap(void)
97 {
98     long mcause = read_csr(CSR_MCAUSE);
99     long mepc = read_csr(CSR_MEPC);
100     long mstatus = read_csr(CSR_MSTATUS);
101 #if SUPPORT_PFT_ARCH
102     long mxstatus = read_csr(CSR_MXSTATUS);
103 #endif
104 #ifdef __riscv_dsp
105     int ucode = read_csr(CSR_UCODE);
106 #endif
107 #ifdef __riscv_flen
108     int fcsr = read_fcsr();
109 #endif
110 
111     /* clobbers list for ecall */
112 #ifdef __riscv_32e
113     __asm volatile("" : : :"t0", "a0", "a1", "a2", "a3");
114 #else
115     __asm volatile("" : : :"a7", "a0", "a1", "a2", "a3");
116 #endif
117 
118     /* Do your trap handling */
119     if ((mcause & CSR_MCAUSE_INTERRUPT_MASK) && ((mcause & CSR_MCAUSE_EXCEPTION_CODE_MASK) == IRQ_M_TIMER)) {
120         /* Machine timer interrupt */
121         mchtmr_isr();
122     }
123 #ifdef USE_NONVECTOR_MODE
124     else if ((mcause & CSR_MCAUSE_INTERRUPT_MASK) && ((mcause & CSR_MCAUSE_EXCEPTION_CODE_MASK) == IRQ_M_EXT)) {
125 
126         typedef void(*isr_func_t)(void);
127 
128         /* Machine-level interrupt from PLIC */
129         uint32_t irq_index = __plic_claim_irq(HPM_PLIC_BASE, HPM_PLIC_TARGET_M_MODE);
130         if (irq_index) {
131         /* Workaround: irq number returned by __plic_claim_irq might be 0, which is caused by plic. So skip invalid irq_index as a workaround */
132 #ifndef DISABLE_IRQ_PREEMPTIVE
133             enable_global_irq(CSR_MSTATUS_MIE_MASK);
134 #endif
135             ((isr_func_t)__vector_table[irq_index])();
136             __plic_complete_irq(HPM_PLIC_BASE, HPM_PLIC_TARGET_M_MODE, irq_index);
137         }
138 
139     }
140 #endif
141 
142     else if ((mcause & CSR_MCAUSE_INTERRUPT_MASK) && ((mcause & CSR_MCAUSE_EXCEPTION_CODE_MASK) == IRQ_M_SOFT)) {
143         /* Machine SWI interrupt */
144         intc_m_claim_swi();
145         swi_isr();
146         intc_m_complete_swi();
147     } else if (!(mcause & CSR_MCAUSE_INTERRUPT_MASK) && ((mcause & CSR_MCAUSE_EXCEPTION_CODE_MASK) == MCAUSE_ECALL_FROM_MACHINE_MODE)) {
148         /* Machine Syscal call */
149         __asm volatile(
150         "mv a4, a3\n"
151         "mv a3, a2\n"
152         "mv a2, a1\n"
153         "mv a1, a0\n"
154         #ifdef __riscv_32e
155         "mv a0, t0\n"
156         #else
157         "mv a0, a7\n"
158         #endif
159         "jalr %0\n"
160         : :"r"(syscall_handler) : "a4"
161         );
162         mepc += 4;
163     } else {
164         mepc = exception_handler(mcause, mepc);
165     }
166 
167     /* Restore CSR */
168     write_csr(CSR_MSTATUS, mstatus);
169     write_csr(CSR_MEPC, mepc);
170 #if SUPPORT_PFT_ARCH
171     write_csr(CSR_MXSTATUS, mxstatus);
172 #endif
173 #ifdef __riscv_dsp
174     write_csr(CSR_UCODE, ucode);
175 #endif
176 #ifdef __riscv_flen
177     write_fcsr(fcsr);
178 #endif
179 }
180