1 /*
2 * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <stdint.h>
7 #include <stddef.h>
8 #include <assert.h>
9 #include "soc/soc.h"
10 #include "riscv/interrupt.h"
11 #include "soc/interrupt_reg.h"
12 #include "riscv/csr.h"
13 #include "esp_attr.h"
14
15 #define RV_INT_COUNT 32
16
assert_valid_rv_int_num(int rv_int_num)17 static inline void assert_valid_rv_int_num(int rv_int_num)
18 {
19 assert(rv_int_num != 0 && rv_int_num < RV_INT_COUNT && "Invalid CPU interrupt number");
20 }
21
22 /*************************** Software interrupt dispatcher ***************************/
23
24
25 typedef struct {
26 intr_handler_t handler;
27 void *arg;
28 } intr_handler_item_t;
29
30 static intr_handler_item_t s_intr_handlers[32];
31
intr_handler_set(int int_no,intr_handler_t fn,void * arg)32 void intr_handler_set(int int_no, intr_handler_t fn, void *arg)
33 {
34 assert_valid_rv_int_num(int_no);
35
36 s_intr_handlers[int_no] = (intr_handler_item_t) {
37 .handler = fn,
38 .arg = arg
39 };
40 }
41
intr_handler_get(int rv_int_num)42 intr_handler_t intr_handler_get(int rv_int_num)
43 {
44 return s_intr_handlers[rv_int_num].handler;
45 }
46
intr_handler_get_arg(int rv_int_num)47 void *intr_handler_get_arg(int rv_int_num)
48 {
49 return s_intr_handlers[rv_int_num].arg;
50 }
51
52 /* called from vectors.S */
_global_interrupt_handler(intptr_t sp,int mcause)53 void _global_interrupt_handler(intptr_t sp, int mcause)
54 {
55 intr_handler_item_t it = s_intr_handlers[mcause];
56 if (it.handler) {
57 (*it.handler)(it.arg);
58 }
59 }
60
61 /*************************** RISC-V interrupt enable/disable ***************************/
62
intr_matrix_route(int intr_src,int intr_num)63 void intr_matrix_route(int intr_src, int intr_num)
64 {
65 assert(intr_num != 0);
66
67 REG_WRITE(DR_REG_INTERRUPT_BASE + 4 * intr_src, intr_num);
68 }
69
esprv_intc_get_interrupt_unmask(void)70 uint32_t esprv_intc_get_interrupt_unmask(void)
71 {
72 return REG_READ(INTERRUPT_CORE0_CPU_INT_ENABLE_REG);
73 }
74
75 /*************************** ESP-RV Interrupt Controller ***************************/
76
esprv_intc_int_get_type(int intr_num)77 enum intr_type esprv_intc_int_get_type(int intr_num)
78 {
79 uint32_t intr_type_reg = REG_READ(INTERRUPT_CORE0_CPU_INT_TYPE_REG);
80 return (intr_type_reg & (1 << intr_num)) ? INTR_TYPE_EDGE : INTR_TYPE_LEVEL;
81 }
82
esprv_intc_int_get_priority(int rv_int_num)83 int esprv_intc_int_get_priority(int rv_int_num)
84 {
85 uint32_t intr_priority_reg = REG_READ(INTC_INT_PRIO_REG(rv_int_num));
86 return intr_priority_reg;
87 }
88
89 /*************************** Exception names. Used in .gdbinit file. ***************************/
90
91 const char *riscv_excp_names[16] __attribute__((used)) = {
92 "misaligned_fetch",
93 "fault_fetch",
94 "illegal_instruction",
95 "breakpoint",
96 "misaligned_load",
97 "fault_load",
98 "misaligned_store",
99 "fault_store",
100 "user_ecall",
101 "supervisor_ecall",
102 "hypervisor_ecall",
103 "machine_ecall",
104 "exec_page_fault",
105 "load_page_fault",
106 "reserved",
107 "store_page_fault"
108 };
109