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