blob: 449d2ad7b3296888bd19dfaa7bb5a58bf095156c [file] [log] [blame]
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +08001/*
2 * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
7#include <stdio.h>
bangzheng.liu4d71f922022-09-29 16:12:20 +08008#include "interrupt_control_eclic.h"
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +08009#include "common.h"
10#include "riscv_encoding.h"
11#include "register.h"
12
xiaohu.huang38262102022-05-06 22:21:48 +080013// Configure PMP to make all the address space accesable and executable
14void eclic_init(uint32_t num_irq)
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080015{
xiaohu.huang38262102022-05-06 22:21:48 +080016 typedef volatile uint32_t vuint32_t;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080017
xiaohu.huang38262102022-05-06 22:21:48 +080018 //clear cfg register
19 *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_CFG_OFFSET) = 0;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080020
xiaohu.huang38262102022-05-06 22:21:48 +080021 //clear minthresh register
22 *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_MTH_OFFSET) = 0;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080023
xiaohu.huang38262102022-05-06 22:21:48 +080024 //clear all IP/IE/ATTR/CTRL bits for all interrupt sources
25 vuint32_t *ptr;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080026
xiaohu.huang38262102022-05-06 22:21:48 +080027 vuint32_t *base = (vuint32_t *)(ECLIC_ADDR_BASE + ECLIC_INT_IP_OFFSET);
28 vuint32_t *upper = (vuint32_t *)(base + num_irq * 4);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080029
xiaohu.huang38262102022-05-06 22:21:48 +080030 for (ptr = base; ptr < upper; ptr = ptr + 4)
31 *ptr = 0;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080032
xiaohu.huang38262102022-05-06 22:21:48 +080033 clean_int_src();
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080034}
35
36void print_eclic(void)
37{
38 typedef volatile uint32_t vuint32_t;
39
xiaohu.huang38262102022-05-06 22:21:48 +080040 vuint32_t *ptr = (vuint32_t *)(ECLIC_ADDR_BASE + ECLIC_INT_IP_OFFSET + 7 * 4);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080041
xiaohu.huang38262102022-05-06 22:21:48 +080042 printf("\nTIME=0x%lx\n", *ptr);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080043}
44
xiaohu.huang38262102022-05-06 22:21:48 +080045void eclic_enable_interrupt(uint32_t source)
46{
47 *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_INT_IE_OFFSET + source * 4) = 1;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080048}
49
xiaohu.huang38262102022-05-06 22:21:48 +080050void eclic_disable_interrupt(uint32_t source)
51{
52 *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_INT_IE_OFFSET + source * 4) = 0;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080053}
54
xiaohu.huang38262102022-05-06 22:21:48 +080055void eclic_set_pending(uint32_t source)
56{
57 *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_INT_IP_OFFSET + source * 4) = 1;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080058}
59
xiaohu.huang38262102022-05-06 22:21:48 +080060void eclic_clear_pending(uint32_t source)
61{
62 *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_INT_IP_OFFSET + source * 4) = 0;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080063}
64
xiaohu.huang38262102022-05-06 22:21:48 +080065void eclic_set_intctrl(uint32_t source, uint8_t intctrl)
66{
67 *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_INT_CTRL_OFFSET + source * 4) = intctrl;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080068}
69
xiaohu.huang38262102022-05-06 22:21:48 +080070uint8_t eclic_get_intctrl(uint32_t source)
71{
72 return *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_INT_CTRL_OFFSET + source * 4);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080073}
74
xiaohu.huang38262102022-05-06 22:21:48 +080075void eclic_set_intattr(uint32_t source, uint8_t intattr)
76{
77 *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_INT_ATTR_OFFSET + source * 4) = intattr;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080078}
79
xiaohu.huang38262102022-05-06 22:21:48 +080080uint8_t eclic_get_intattr(uint32_t source)
81{
82 return *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_INT_ATTR_OFFSET + source * 4);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080083}
84
xiaohu.huang38262102022-05-06 22:21:48 +080085void eclic_set_cliccfg(uint8_t cliccfg)
86{
87 *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_CFG_OFFSET) = cliccfg;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080088}
89
xiaohu.huang38262102022-05-06 22:21:48 +080090uint8_t eclic_get_cliccfg(void)
91{
92 return *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_CFG_OFFSET);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080093}
94
xiaohu.huang38262102022-05-06 22:21:48 +080095void eclic_set_mth(uint8_t mth)
96{
97 *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_MTH_OFFSET) = mth;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080098}
99
xiaohu.huang38262102022-05-06 22:21:48 +0800100uint8_t eclic_get_mth(void)
101{
102 return *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_MTH_OFFSET);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800103}
104
105//sets nlbits
xiaohu.huang38262102022-05-06 22:21:48 +0800106void eclic_set_nlbits(uint8_t nlbits)
107{
108 //shift nlbits to correct position
109 uint8_t nlbits_shifted = nlbits << ECLIC_CFG_NLBITS_LSB;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800110
xiaohu.huang38262102022-05-06 22:21:48 +0800111 //read the current cliccfg
112 uint8_t old_cliccfg = eclic_get_cliccfg();
113 uint8_t new_cliccfg =
114 (old_cliccfg & (~ECLIC_CFG_NLBITS_MASK)) | (ECLIC_CFG_NLBITS_MASK & nlbits_shifted);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800115
xiaohu.huang38262102022-05-06 22:21:48 +0800116 eclic_set_cliccfg(new_cliccfg);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800117}
118
119//get nlbits
xiaohu.huang38262102022-05-06 22:21:48 +0800120uint8_t eclic_get_nlbits(void)
121{
122 //extract nlbits
123 uint8_t nlbits = eclic_get_cliccfg();
124
125 nlbits = (nlbits & ECLIC_CFG_NLBITS_MASK) >> ECLIC_CFG_NLBITS_LSB;
126 return nlbits;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800127}
128
129//sets an interrupt level based encoding of nlbits and CLICINTCTLBITS
xiaohu.huang38262102022-05-06 22:21:48 +0800130void eclic_set_irq_lvl(uint32_t source, uint8_t lvl)
131{
132 //extract nlbits
133 uint8_t nlbits = eclic_get_nlbits();
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800134
xiaohu.huang38262102022-05-06 22:21:48 +0800135 if (nlbits > CLICINTCTLBITS)
136 nlbits = CLICINTCTLBITS;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800137
xiaohu.huang38262102022-05-06 22:21:48 +0800138 //shift lvl right to mask off unused bits
139 lvl = lvl >> (8 - nlbits);
140 //shift lvl into correct bit position
141 lvl = lvl << (8 - nlbits);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800142
xiaohu.huang38262102022-05-06 22:21:48 +0800143 //write to clicintctrl
144 uint8_t current_intctrl = eclic_get_intctrl(source);
145 //shift intctrl left to mask off unused bits
146 current_intctrl = current_intctrl << nlbits;
147 //shift intctrl into correct bit position
148 current_intctrl = current_intctrl >> nlbits;
149
150 eclic_set_intctrl(source, (current_intctrl | lvl));
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800151}
152
153//gets an interrupt level based encoding of nlbits
xiaohu.huang38262102022-05-06 22:21:48 +0800154uint8_t eclic_get_irq_lvl(uint32_t source)
155{
156 //extract nlbits
157 uint8_t nlbits = eclic_get_nlbits();
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800158
xiaohu.huang38262102022-05-06 22:21:48 +0800159 if (nlbits > CLICINTCTLBITS)
160 nlbits = CLICINTCTLBITS;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800161
xiaohu.huang38262102022-05-06 22:21:48 +0800162 uint8_t intctrl = eclic_get_intctrl(source);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800163
xiaohu.huang38262102022-05-06 22:21:48 +0800164 //shift intctrl
165 intctrl = intctrl >> (8 - nlbits);
166 //shift intctrl
167 uint8_t lvl = intctrl << (8 - nlbits);
168
169 return lvl;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800170}
171
xiaohu.huang38262102022-05-06 22:21:48 +0800172void eclic_set_irq_lvl_abs(uint32_t source, uint8_t lvl_abs)
173{
174 //extract nlbits
175 uint8_t nlbits = eclic_get_nlbits();
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800176
xiaohu.huang38262102022-05-06 22:21:48 +0800177 if (nlbits > CLICINTCTLBITS)
178 nlbits = CLICINTCTLBITS;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800179
xiaohu.huang38262102022-05-06 22:21:48 +0800180 //shift lvl_abs into correct bit position
181 uint8_t lvl = lvl_abs << (8 - nlbits);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800182
xiaohu.huang38262102022-05-06 22:21:48 +0800183 //write to clicintctrl
184 uint8_t current_intctrl = eclic_get_intctrl(source);
185 //shift intctrl left to mask off unused bits
186 current_intctrl = current_intctrl << nlbits;
187 //shift intctrl into correct bit position
188 current_intctrl = current_intctrl >> nlbits;
189
190 eclic_set_intctrl(source, (current_intctrl | lvl));
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800191}
192
xiaohu.huang38262102022-05-06 22:21:48 +0800193uint8_t eclic_get_irq_lvl_abs(uint32_t source)
194{
195 //extract nlbits
196 uint8_t nlbits = eclic_get_nlbits();
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800197
xiaohu.huang38262102022-05-06 22:21:48 +0800198 if (nlbits > CLICINTCTLBITS)
199 nlbits = CLICINTCTLBITS;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800200
xiaohu.huang38262102022-05-06 22:21:48 +0800201 uint8_t intctrl = eclic_get_intctrl(source);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800202
xiaohu.huang38262102022-05-06 22:21:48 +0800203 //shift intctrl
204 intctrl = intctrl >> (8 - nlbits);
205 //shift intctrl
206 uint8_t lvl_abs = intctrl;
207
208 return lvl_abs;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800209}
210
xiaohu.huang38262102022-05-06 22:21:48 +0800211void eclic_set_irq_pri(uint32_t source, uint8_t pri)
212{
213 //extract nlbits
214 uint8_t nlbits = eclic_get_nlbits();
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800215
xiaohu.huang38262102022-05-06 22:21:48 +0800216 if (nlbits > CLICINTCTLBITS)
217 nlbits = CLICINTCTLBITS;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800218
xiaohu.huang38262102022-05-06 22:21:48 +0800219 //write to clicintctrl
220 uint8_t current_intctrl = eclic_get_intctrl(source);
221 //shift intctrl left to mask off unused bits
222 current_intctrl = current_intctrl >> (8 - nlbits);
223 //shift intctrl into correct bit position
224 current_intctrl = current_intctrl << (8 - nlbits);
225
226 eclic_set_intctrl(source, (current_intctrl | pri));
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800227}
228
xiaohu.huang38262102022-05-06 22:21:48 +0800229void eclic_mode_enable(void)
230{
231 uint32_t mtvec_value = read_csr(mtvec);
232
233 mtvec_value = mtvec_value & 0xFFFFFFC0;
234 mtvec_value = mtvec_value | 0x00000003;
235 write_csr(mtvec, mtvec_value);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800236}
237
238//sets vector-mode or non-vector mode
xiaohu.huang38262102022-05-06 22:21:48 +0800239void eclic_set_vmode(uint32_t source)
240{
241 //read the current attr
242 uint8_t old_intattr = eclic_get_intattr(source);
243 // Keep other bits unchanged and only set the LSB bit
244 uint8_t new_intattr = (old_intattr | 0x1);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800245
xiaohu.huang38262102022-05-06 22:21:48 +0800246 eclic_set_intattr(source, new_intattr);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800247}
248
xiaohu.huang38262102022-05-06 22:21:48 +0800249void eclic_set_nonvmode(uint32_t source)
250{
251 //read the current attr
252 uint8_t old_intattr = eclic_get_intattr(source);
253 // Keep other bits unchanged and only clear the LSB bit
254 uint8_t new_intattr = (old_intattr & (~0x1));
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800255
xiaohu.huang38262102022-05-06 22:21:48 +0800256 eclic_set_intattr(source, new_intattr);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800257}
258
259//sets interrupt as level sensitive
260//Bit 1, trig[0], is defined as "edge-triggered" (0: level-triggered, 1: edge-triggered);
261//Bit 2, trig[1], is defined as "negative-edge" (0: positive-edge, 1: negative-edge).
262
xiaohu.huang38262102022-05-06 22:21:48 +0800263void eclic_set_level_trig(uint32_t source)
264{
265 //read the current attr
266 uint8_t old_intattr = eclic_get_intattr(source);
267 // Keep other bits unchanged and only clear the bit 1
268 uint8_t new_intattr = (old_intattr & (~0x2));
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800269
xiaohu.huang38262102022-05-06 22:21:48 +0800270 eclic_set_intattr(source, new_intattr);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800271}
272
xiaohu.huang38262102022-05-06 22:21:48 +0800273void eclic_set_posedge_trig(uint32_t source)
274{
275 //read the current attr
276 uint8_t old_intattr = eclic_get_intattr(source);
277 // Keep other bits unchanged and only set the bit 1
278 uint8_t new_intattr = (old_intattr | 0x2);
279 // Keep other bits unchanged and only clear the bit 2
280 new_intattr = (new_intattr & (~0x4));
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800281
xiaohu.huang38262102022-05-06 22:21:48 +0800282 eclic_set_intattr(source, new_intattr);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800283}
284
xiaohu.huang38262102022-05-06 22:21:48 +0800285void eclic_set_negedge_trig(uint32_t source)
286{
287 //read the current attr
288 uint8_t old_intattr = eclic_get_intattr(source);
289 // Keep other bits unchanged and only set the bit 1
290 uint8_t new_intattr = (old_intattr | 0x2);
291 // Keep other bits unchanged and only set the bit 2
292 new_intattr = (new_intattr | 0x4);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800293
xiaohu.huang38262102022-05-06 22:21:48 +0800294 eclic_set_intattr(source, new_intattr);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800295}
296
297extern void core_wfe(void);
xiaohu.huang38262102022-05-06 22:21:48 +0800298void wfe(void)
299{
300 core_wfe();
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800301}
302
303void clean_int_src(void)
304{
xiaohu.huang38262102022-05-06 22:21:48 +0800305 for (uint32_t i = 0; i < 8; i++)
306 REG32(AOCPU_IRQ_SEL0 + i * 4) = 0;
bangzheng.liu4d71f922022-09-29 16:12:20 +0800307#ifdef AOCPU_IRQ_REG_NONCONTINUOUS
308 for (uint32_t i = 0; i < 8; i++)
309 REG32(AOCPU_IRQ_SEL8 + i * 4) = 0;
310#endif
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800311}
312
313int int_src_sel(uint32_t ulIrq, uint32_t src)
314{
315 uint32_t index;
316
xiaohu.huang38262102022-05-06 22:21:48 +0800317 if (ulIrq < ECLIC_INTERNAL_NUM_INTERRUPTS || ulIrq > ECLIC_NUM_INTERRUPTS) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800318 printf("Error ulIrq!\n");
319 return -1;
320 }
321
bangzheng.liu4d71f922022-09-29 16:12:20 +0800322 if (src > IRQ_NUM_MAX) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800323 printf("Error src!\n");
324 return -2;
325 }
326
327 ulIrq -= ECLIC_INTERNAL_NUM_INTERRUPTS;
328
bangzheng.liu4d71f922022-09-29 16:12:20 +0800329#ifdef AOCPU_IRQ_REG_NONCONTINUOUS
330 index = ulIrq / 2;
331
332 if (ulIrq < 16) {
333 REG32(AOCPU_IRQ_SEL0 + index * 4) &= ~(0x1ff << (ulIrq % 2) * 16);
334 REG32(AOCPU_IRQ_SEL0 + index * 4) |= src << (ulIrq % 2) * 16;
335 } else {
336 REG32(AOCPU_IRQ_SEL8 + index * 4) &= ~(0x1ff << (ulIrq % 2) * 16);
337 REG32(AOCPU_IRQ_SEL8 + index * 4) |= src << (ulIrq % 2)*16;
338 }
339#else
xiaohu.huang38262102022-05-06 22:21:48 +0800340 index = ulIrq / 4;
341 REG32(AOCPU_IRQ_SEL0 + index * 4) &= ~(0xff << (ulIrq % 4) * 8);
342 REG32(AOCPU_IRQ_SEL0 + index * 4) |= src << (ulIrq % 4) * 8;
bangzheng.liu4d71f922022-09-29 16:12:20 +0800343#endif
344
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800345 return 0;
346}
347
348int int_src_clean(uint32_t ulIrq)
349{
350 uint32_t index;
351
xiaohu.huang38262102022-05-06 22:21:48 +0800352 if (ulIrq < ECLIC_INTERNAL_NUM_INTERRUPTS || ulIrq > ECLIC_NUM_INTERRUPTS) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800353 printf("Error ulIrq!\n");
354 return -1;
355 }
356
357 ulIrq -= ECLIC_INTERNAL_NUM_INTERRUPTS;
358
bangzheng.liu4d71f922022-09-29 16:12:20 +0800359#ifdef AOCPU_IRQ_REG_NONCONTINUOUS
360 index = ulIrq / 2;
361
362 if (ulIrq < 16)
363 REG32(AOCPU_IRQ_SEL0 + index * 4) &= ~(0x1ff << (ulIrq % 2) * 16);
364 else
365 REG32(AOCPU_IRQ_SEL8 + index * 4) &= ~(0x1ff << (ulIrq % 2) * 16);
366#else
xiaohu.huang38262102022-05-06 22:21:48 +0800367 index = ulIrq / 4;
368 REG32(AOCPU_IRQ_SEL0 + index * 4) &= ~(0xff << (ulIrq % 4) * 8);
bangzheng.liu4d71f922022-09-29 16:12:20 +0800369#endif
370
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800371 return 0;
372}
373
374/*Just for external interrupt source.
375 *Because int_src_sel() just support external select
376 */
377int eclic_map_interrupt(uint32_t ulIrq, uint32_t src)
378{
379 uint8_t val;
380
381 if (int_src_sel(ulIrq, src)) {
382 printf("Enable %ld irq, %ld src fail!\n", ulIrq, src);
383 return -1;
384 }
385
xiaohu.huang38262102022-05-06 22:21:48 +0800386 val = eclic_get_intattr(ulIrq);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800387 val |= ECLIC_INT_ATTR_MACH_MODE;
388 /*Use edge trig interrupt default*/
389 val |= ECLIC_INT_ATTR_TRIG_EDGE;
390 eclic_set_intattr(ulIrq, val);
391 //eclic_enable_interrupt(ulIrq);
392 return 0;
393}
394
xiaohu.huang38262102022-05-06 22:21:48 +0800395uint32_t eclic_interrupt_inner[SOC_ECLIC_NUM_INTERRUPTS] = { 0 };
396int RegisterIrq(uint32_t int_num, uint32_t int_priority, function_ptr_t handler)
397{
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800398 int irq = 0;
399
xiaohu.huang38262102022-05-06 22:21:48 +0800400 for (irq = ECLIC_INTERNAL_NUM_INTERRUPTS; irq <= ECLIC_NUM_INTERRUPTS; irq++) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800401 if (eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] == 0)
402 break;
403 }
404 if (eclic_map_interrupt(irq, int_num) < 0) {
405 printf("eclic map error.\n");
406 return -1;
407 }
408 eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] = int_num;
409
410 *(&vector_base + irq) = (uint32_t)handler;
411 eclic_set_irq_pri(irq, int_priority);
412
413 return 0;
414}
415
416int UnRegisterIrq(uint32_t ulIrq)
417{
418 int irq = 0;
xiaohu.huang38262102022-05-06 22:21:48 +0800419
420 for (irq = ECLIC_INTERNAL_NUM_INTERRUPTS; irq <= ECLIC_NUM_INTERRUPTS; irq++) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800421 if (eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] == ulIrq)
422 break;
423 }
424 if (irq > ECLIC_NUM_INTERRUPTS) {
425 printf("Error ulIrq!\n");
426 return -1;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800427 }
xiaohu.huang38262102022-05-06 22:21:48 +0800428
429 if (int_src_clean(irq)) {
430 printf("unregister %ld irq, %ld src fail!\n", ulIrq, irq);
431 return -1;
432 }
433 eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] = 0;
434 *(&vector_base + irq) = 0;
435
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800436 return 0;
437}
438
439int EnableIrq(uint32_t ulIrq)
440{
441 int irq = 0;
xiaohu.huang38262102022-05-06 22:21:48 +0800442
443 for (irq = ECLIC_INTERNAL_NUM_INTERRUPTS; irq <= ECLIC_NUM_INTERRUPTS; irq++) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800444 if (eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] == ulIrq)
445 break;
446 }
447 if (irq > ECLIC_NUM_INTERRUPTS) {
448 printf("Error ulIrq!\n");
449 return -1;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800450 }
xiaohu.huang38262102022-05-06 22:21:48 +0800451
452 eclic_enable_interrupt(irq);
453
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800454 return 0;
455}
456
457int DisableIrq(uint32_t ulIrq)
458{
459 int irq = 0;
xiaohu.huang38262102022-05-06 22:21:48 +0800460
461 for (irq = ECLIC_INTERNAL_NUM_INTERRUPTS; irq <= ECLIC_NUM_INTERRUPTS; irq++) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800462 if (eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] == ulIrq)
463 break;
464 }
465 if (irq > ECLIC_NUM_INTERRUPTS) {
466 printf("Error ulIrq!\n");
467 return -1;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800468 }
xiaohu.huang38262102022-05-06 22:21:48 +0800469
470 eclic_disable_interrupt(irq);
471
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800472 return 0;
473}
474
475int SetIrqPriority(uint32_t ulIrq, uint32_t ulProi)
476{
477 int irq = 0;
xiaohu.huang38262102022-05-06 22:21:48 +0800478
479 for (irq = ECLIC_INTERNAL_NUM_INTERRUPTS; irq <= ECLIC_NUM_INTERRUPTS; irq++) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800480 if (eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] == ulIrq)
481 break;
482 }
483 if (irq > ECLIC_NUM_INTERRUPTS) {
484 printf("Error ulIrq!\n");
485 return -1;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800486 }
xiaohu.huang38262102022-05-06 22:21:48 +0800487
488 eclic_set_irq_pri(irq, ulProi);
489
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800490 return 0;
491}
492
493int ClearPendingIrq(uint32_t ulIrq)
494{
495 int irq = 0;
xiaohu.huang38262102022-05-06 22:21:48 +0800496
497 for (irq = ECLIC_INTERNAL_NUM_INTERRUPTS; irq <= ECLIC_NUM_INTERRUPTS; irq++) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800498 if (eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] == ulIrq)
499 break;
500 }
501 if (irq > ECLIC_NUM_INTERRUPTS) {
502 printf("Error ulIrq!\n");
503 return -1;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800504 }
xiaohu.huang38262102022-05-06 22:21:48 +0800505
506 eclic_clear_pending(irq);
507
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800508 return 0;
509}