1 /*
2  * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "sdkconfig.h"
8 #include <stdint.h>
9 
10 #if CONFIG_IDF_TARGET_ARCH_RISCV
11 
12 #if SOC_INT_CLIC_SUPPORTED
13 
14 /**
15  * @brief Checks whether the given interrupt number is reserved either in the given mask or in the
16  *        _mtvt_table, which contains the routines the CPU will jump to when an interrupt or an exception
17  *        occurs, on RISC-V targets.
18  *
19  * @param intr_num  External interrupt number to check, in range 0~32
20  * @param rsvd_mask Reserved interrupt mask, where bit i is 1 if interrupt i is reserved.
21  *
22  * @returns ESP_CPU_INTR_DESC_FLAG_RESVD if the interrupt is reserved, 0 else
23  */
esp_riscv_intr_num_flags(int intr_num,uint32_t rsvd_mask)24 static inline uint32_t esp_riscv_intr_num_flags(int intr_num, uint32_t rsvd_mask)
25 {
26     if (rsvd_mask & BIT(intr_num)) {
27         return ESP_CPU_INTR_DESC_FLAG_RESVD;
28     }
29 
30     extern intptr_t _mtvt_table[48];
31     extern intptr_t _interrupt_handler;
32 
33     /* The first 16 entries of the array are internal interrupt, ignore them  */
34     const intptr_t destination = _mtvt_table[16 + intr_num];
35 
36     return (destination != (intptr_t)&_interrupt_handler) ? ESP_CPU_INTR_DESC_FLAG_RESVD : 0;
37 }
38 
39 
40 
41 #else // !SOC_INT_CLIC_SUPPORTED
42 
43 #include "esp_cpu.h"
44 #include "riscv/instruction_decode.h"
45 
46 /**
47  * @brief Checks whether the given interrupt number is reserved either in the given mask or in the
48  *        _vector_table, which contains the routines the CPU will jump to when an interrupt or an exception
49  *        occurs, on RISC-V targets.
50  *
51  * @param intr_num  Interrupt number to check, in range 0~32
52  * @param rsvd_mask Reserved interrupt mask, where bit i is 1 if interrupt i is reserved.
53  *
54  * @returns ESP_CPU_INTR_DESC_FLAG_RESVD if the interrupt is reserved, 0 else
55  */
esp_riscv_intr_num_flags(int intr_num,uint32_t rsvd_mask)56 static inline uint32_t esp_riscv_intr_num_flags(int intr_num, uint32_t rsvd_mask)
57 {
58     if (rsvd_mask & BIT(intr_num)) {
59         return ESP_CPU_INTR_DESC_FLAG_RESVD;
60     }
61 
62     extern intptr_t _vector_table[32];
63     extern int _interrupt_handler;
64     const intptr_t pc = (intptr_t) &_vector_table[intr_num];
65 
66     /* JAL instructions are relative to the PC they are executed from. */
67     const intptr_t destination = pc + riscv_decode_offset_from_jal_instruction(pc);
68 
69     return (destination != (intptr_t)&_interrupt_handler) ? ESP_CPU_INTR_DESC_FLAG_RESVD : 0;
70 }
71 
72 #endif // SOC_INT_CLIC_SUPPORTED
73 
74 #endif // CONFIG_IDF_TARGET_ARCH_RISCV
75