diff --git a/components/esp_hw_support/include/esp_cpu.h b/components/esp_hw_support/include/esp_cpu.h index 2f81e3f293..f64c37191f 100644 --- a/components/esp_hw_support/include/esp_cpu.h +++ b/components/esp_hw_support/include/esp_cpu.h @@ -233,6 +233,20 @@ FORCE_INLINE_ATTR void esp_cpu_intr_set_ivt_addr(const void *ivt_addr) #endif } +#if CONFIG_IDF_TARGET_ESP32P4 +//TODO: IDF-7863 +//"MTVT is only implemented in RISC-V arch" +/** + * @brief Set the base address of the current CPU's Interrupt Vector Table (MTVT) + * + * @param ivt_addr Interrupt Vector Table's base address + */ +FORCE_INLINE_ATTR void esp_cpu_intr_set_mtvt_addr(const void *mtvt_addr) +{ + rv_utils_set_mtvt((uint32_t)mtvt_addr); +} +#endif //#if CONFIG_IDF_TARGET_ESP32P4 + #if SOC_CPU_HAS_FLEXIBLE_INTC /** * @brief Set the interrupt type of a particular interrupt diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index a9579cd88c..bca7937f79 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -115,6 +115,9 @@ extern int _rodata_reserved_start; extern int _rodata_reserved_end; extern int _vector_table; +#if SOC_INT_CLIC_SUPPORTED +extern int _mtvt_table; +#endif static const char *TAG = "cpu_start"; @@ -140,7 +143,15 @@ static void core_intr_matrix_clear(void) uint32_t core_id = esp_cpu_get_core_id(); for (int i = 0; i < ETS_MAX_INTR_SOURCE; i++) { +#if CONFIG_IDF_TARGET_ESP32P4 + if (core_id == 0) { + REG_WRITE(INTERRUPT_CORE0_LP_RTC_INT_MAP_REG + 4 * i, 0); + } else { + REG_WRITE(INTERRUPT_CORE1_LP_RTC_INT_MAP_REG + 4 * i, 0); + } +#else esp_rom_route_intr_matrix(core_id, i, ETS_INVALID_INUM); +#endif } } @@ -157,6 +168,10 @@ void IRAM_ATTR call_start_cpu1(void) #endif //#if SOC_BRANCH_PREDICTOR_SUPPORTED esp_cpu_intr_set_ivt_addr(&_vector_table); +#if SOC_INT_CLIC_SUPPORTED + //TODO: IDF-7863 + esp_cpu_intr_set_mtvt_addr(&_mtvt_table); +#endif ets_set_appcpu_boot_addr(0); @@ -326,6 +341,10 @@ void IRAM_ATTR call_start_cpu0(void) #endif // Move exception vectors to IRAM esp_cpu_intr_set_ivt_addr(&_vector_table); +#if SOC_INT_CLIC_SUPPORTED + //TODO: IDF-7863 + esp_cpu_intr_set_mtvt_addr(&_mtvt_table); +#endif rst_reas[0] = esp_rom_get_reset_reason(0); #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE diff --git a/components/riscv/include/riscv/rv_utils.h b/components/riscv/include/riscv/rv_utils.h index e1525bd764..baa5b7de26 100644 --- a/components/riscv/include/riscv/rv_utils.h +++ b/components/riscv/include/riscv/rv_utils.h @@ -85,10 +85,23 @@ FORCE_INLINE_ATTR void __attribute__((always_inline)) rv_utils_set_cycle_count(u // ---------------- Interrupt Descriptors ------------------ // --------------- Interrupt Configuration ----------------- +#if SOC_INT_CLIC_SUPPORTED +//TODO: IDF-7863 +FORCE_INLINE_ATTR void rv_utils_set_mtvt(uint32_t mtvt_val) +{ +#define MTVT 0x307 + RV_WRITE_CSR(MTVT, mtvt_val); +} +#endif FORCE_INLINE_ATTR void rv_utils_set_mtvec(uint32_t mtvec_val) { +#if SOC_INT_CLIC_SUPPORTED + //TODO: IDF-7863 + mtvec_val |= 3; +#else mtvec_val |= 1; // Set MODE field to treat MTVEC as a vector base address +#endif RV_WRITE_CSR(mtvec, mtvec_val); } diff --git a/components/riscv/vectors.S b/components/riscv/vectors.S index b475910ad5..b3c59c8e98 100644 --- a/components/riscv/vectors.S +++ b/components/riscv/vectors.S @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -117,12 +117,23 @@ * only uses the 24 MSBs of the MTVEC, i.e. (MTVEC & 0xffffff00). */ + /** + * TODO: IDF-7863, P4, see jira to know what changed and what need to be checked + */ + +#if SOC_INT_CLIC_SUPPORTED + .balign 0x40 +#else .balign 0x100 +#endif .global _vector_table .type _vector_table, @function _vector_table: .option push .option norvc +#if SOC_INT_CLIC_SUPPORTED + j _trap_handler +#else j _panic_handler /* exception handler, entry 0 */ #if ETS_INT_WDT_INUM != 24 #error "ETS_INT_WDT_INUM expected to be 24" @@ -145,10 +156,41 @@ _vector_table: .rept (ETS_MAX_INUM - ETS_ASSIST_DEBUG_INUM) j _interrupt_handler /* remain entries are identical, all pointing to the interrupt handler */ .endr - +#endif .option pop .size _vector_table, .-_vector_table +#if SOC_INT_CLIC_SUPPORTED + .balign 0x40 + .global _mtvt_table + .type _mtvt_table, @function +_mtvt_table: + .option push + .option norvc + .rept 48 + .word _interrupt_handler + .endr + .option pop + .size _mtvt_table, .-_mtvt_table +#endif + +#if SOC_INT_CLIC_SUPPORTED + .type _trap_handler, @function +_trap_handler: + addi sp, sp, -RV_STK_FRMSZ + sw t0, RV_STK_T0(sp) + sw t1, RV_STK_T1(sp) + csrr t0, mcause + li t1, 0x80000000 + bltu t0, t1, _panic_handler + lw t0, RV_STK_T0(sp) + lw t1, RV_STK_T1(sp) + addi sp, sp, RV_STK_FRMSZ + //ESP32P4-TODO: ETS_T1_WDT_INUM/ETS_CACHEERR_INUM/ETS_MEMPROT_ERR_INUM + j _interrupt_handler + .size _trap_handler, .-_trap_handler +#endif + /* Exception handler.*/ .type _panic_handler, @function _panic_handler: @@ -182,6 +224,15 @@ _panic_handler: mv a0, sp csrr a1, mcause + /* + * MINHV[30]: CPU is fetching vector interrupt entry address or not + * MPP[29:28]: MSTATUS.MPP[1:0] + * MPIL[23:16]: interrupt level before entrering interrupt isr + */ +#if SOC_INT_CLIC_SUPPORTED + la t1, 0x80000fff + and a1, a1, t1 +#endif /* Branches instructions don't accept immediates values, so use t1 to * store our comparator */ li t0, 0x80000000 @@ -256,6 +307,7 @@ _interrupt_handler: csrr s1, mcause csrr s2, mstatus +#if !SOC_INT_CLIC_SUPPORTED /* Save the interrupt threshold level */ li t0, INTERRUPT_CORE0_CPU_INT_THRESH_REG lw s3, 0(t0) @@ -270,6 +322,7 @@ _interrupt_handler: addi t2, t2, 1 /* t2 = t2 +1 */ sw t2, 0(t0) /* INTERRUPT_CORE0_CPU_INT_THRESH_REG = t2 */ fence +#endif li t0, 0x8 csrrs t0, mstatus, t0 @@ -295,7 +348,11 @@ _interrupt_handler: mv a0, sp /* argument 1, stack pointer */ mv a1, s1 /* argument 2, interrupt number (mcause) */ /* mask off the interrupt flag of mcause */ +#if !SOC_INT_CLIC_SUPPORTED li t0, 0x7fffffff +#else + li t0, 0x00000fff +#endif and a1, a1, t0 jal _global_interrupt_handler @@ -305,11 +362,17 @@ _interrupt_handler: csrrc t0, mstatus, t0 /* MIE cleared. Nested interrupts are disabled */ +#if !SOC_INT_CLIC_SUPPORTED /* restore the interrupt threshold level */ li t0, INTERRUPT_CORE0_CPU_INT_THRESH_REG sw s3, 0(t0) fence +#endif +#if SOC_INT_CLIC_SUPPORTED + /* Yield to the next task is needed: */ + mv a0, sp +#endif call rtos_int_exit /* restore the rest of the registers */