1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 * Description: RISCV31 Core interrupt handler
15 *
16 * Create: 2021-07-24
17 */
18 #include "interrupt_handler.h"
19 #include "vectors.h"
20 #include "arch_encoding.h"
21
22 #define INT_NUM_MAX 0xFFF
23
24 /* Number of running interrupts, Used to determine whether an interrupt is running */
25 uint32_t g_interrupt_running = 0;
26
27 /* Assembly function declaration */
28 uint32_t global_interrupt_lock(void);
29 void global_interrupt_restore(uint32_t);
30
31 /*lint -e40 -e718 -e746*/
interrupt_count_get(void)32 uint32_t interrupt_count_get(void)
33 {
34 return g_interrupt_running;
35 }
36
nmi_default_handler(void)37 void nmi_default_handler(void)
38 {
39 clear_csr(mie, MIP_NMIE);
40 g_interrupt_running++;
41 if (((isr_function *)(isr_get_ramexceptiontable_addr()))[IRQ_COP] != default_handler) {
42 ((isr_function *)(isr_get_ramexceptiontable_addr()))[IRQ_COP]();
43 }
44 set_csr(mie, MIP_NMIE);
45 g_interrupt_running--;
46 }
47
interrupt0_handler(void)48 void interrupt0_handler(void)
49 {
50 clear_csr(mie, MIP_LOCIE0);
51 g_interrupt_running++;
52 if (((isr_function *)(isr_get_ramexceptiontable_addr()))[IRQ_LOCIE0] != default_handler) {
53 ((isr_function *)(isr_get_ramexceptiontable_addr()))[IRQ_LOCIE0]();
54 }
55 set_csr(mie, MIP_LOCIE0);
56 g_interrupt_running--;
57 }
58
interrupt1_handler(void)59 void interrupt1_handler(void)
60 {
61 clear_csr(mie, MIP_LOCIE1);
62 g_interrupt_running++;
63 if (((isr_function *)(isr_get_ramexceptiontable_addr()))[IRQ_LOCIE1] != default_handler) {
64 ((isr_function *)(isr_get_ramexceptiontable_addr()))[IRQ_LOCIE1]();
65 }
66 set_csr(mie, MIP_LOCIE1);
67 g_interrupt_running--;
68 }
69
interrupt2_handler(void)70 void interrupt2_handler(void)
71 {
72 clear_csr(mie, MIP_LOCIE2);
73 g_interrupt_running++;
74 if (((isr_function *)(isr_get_ramexceptiontable_addr()))[IRQ_LOCIE2] != default_handler) {
75 ((isr_function *)(isr_get_ramexceptiontable_addr()))[IRQ_LOCIE2]();
76 }
77 set_csr(mie, MIP_LOCIE2);
78 g_interrupt_running--;
79 }
80
interrupt3_handler(void)81 void interrupt3_handler(void)
82 {
83 clear_csr(mie, MIP_LOCIE3);
84 g_interrupt_running++;
85 if (((isr_function *)(isr_get_ramexceptiontable_addr()))[IRQ_LOCIE3] != default_handler) {
86 ((isr_function *)(isr_get_ramexceptiontable_addr()))[IRQ_LOCIE3]();
87 }
88 set_csr(mie, MIP_LOCIE3);
89 g_interrupt_running--;
90 }
91
interrupt4_handler(void)92 void interrupt4_handler(void)
93 {
94 clear_csr(mie, MIP_LOCIE4);
95 g_interrupt_running++;
96 if (((isr_function *)(isr_get_ramexceptiontable_addr()))[IRQ_LOCIE4] != default_handler) {
97 ((isr_function *)(isr_get_ramexceptiontable_addr()))[IRQ_LOCIE4]();
98 }
99 set_csr(mie, MIP_LOCIE4);
100 g_interrupt_running--;
101 }
102
interrupt5_handler(void)103 void interrupt5_handler(void)
104 {
105 clear_csr(mie, MIP_LOCIE5);
106 g_interrupt_running++;
107 if (((isr_function *)(isr_get_ramexceptiontable_addr()))[IRQ_LOCIE5] != default_handler) {
108 ((isr_function *)(isr_get_ramexceptiontable_addr()))[IRQ_LOCIE5]();
109 }
110 set_csr(mie, MIP_LOCIE5);
111 g_interrupt_running--;
112 }
113
local_interrupt_handler(void)114 void local_interrupt_handler(void)
115 {
116 uint32_t interrupt_index;
117 uint32_t status_save;
118
119 status_save = global_interrupt_lock();
120 g_interrupt_running++;
121 global_interrupt_restore(status_save);
122
123 interrupt_index = interrupt_number_get();
124 if (((isr_function *)(isr_get_ramexceptiontable_addr()))[interrupt_index] != reserve_handler) {
125 ((isr_function *)(isr_get_ramexceptiontable_addr()))[interrupt_index]();
126 }
127
128 status_save = global_interrupt_lock();
129 g_interrupt_running--;
130 global_interrupt_restore(status_save);
131 }
132
local_interrupt_priority_init(void)133 void local_interrupt_priority_init(void)
134 {
135 /* The priorities of all interrupts are initialized to 1. */
136 write_custom_csr_val(LOCIPRI0, LOCIPRI_DEFAULT_VAL);
137 write_custom_csr_val(LOCIPRI1, LOCIPRI_DEFAULT_VAL);
138 write_custom_csr_val(LOCIPRI2, LOCIPRI_DEFAULT_VAL);
139 write_custom_csr_val(LOCIPRI3, LOCIPRI_DEFAULT_VAL);
140 write_custom_csr_val(LOCIPRI4, LOCIPRI_DEFAULT_VAL);
141 write_custom_csr_val(LOCIPRI5, LOCIPRI_DEFAULT_VAL);
142 write_custom_csr_val(LOCIPRI6, LOCIPRI_DEFAULT_VAL);
143 write_custom_csr_val(LOCIPRI7, LOCIPRI_DEFAULT_VAL);
144 write_custom_csr_val(LOCIPRI8, LOCIPRI_DEFAULT_VAL);
145 write_custom_csr_val(LOCIPRI9, LOCIPRI_DEFAULT_VAL);
146 write_custom_csr_val(LOCIPRI10, LOCIPRI_DEFAULT_VAL);
147 write_custom_csr_val(LOCIPRI11, LOCIPRI_DEFAULT_VAL);
148 write_custom_csr_val(LOCIPRI12, LOCIPRI_DEFAULT_VAL);
149 write_custom_csr_val(LOCIPRI13, LOCIPRI_DEFAULT_VAL);
150 write_custom_csr_val(LOCIPRI14, LOCIPRI_DEFAULT_VAL);
151 write_custom_csr_val(LOCIPRI15, LOCIPRI_DEFAULT_VAL);
152 return;
153 }
154
interrupt_number_get(void)155 uint32_t interrupt_number_get(void)
156 {
157 return (read_custom_csr(MCAUSE) & INT_NUM_MAX);
158 }
159 /*lint +e40 +e718 +e746*/