diff --git a/components/bt/controller/esp32c3/bt.c b/components/bt/controller/esp32c3/bt.c index 1c3c3e8f77..dadb5c49ac 100644 --- a/components/bt/controller/esp32c3/bt.c +++ b/components/bt/controller/esp32c3/bt.c @@ -463,9 +463,8 @@ static void interrupt_set_wrapper(int cpu_no, int intr_source, int intr_num, int { esp_rom_route_intr_matrix(cpu_no, intr_source, intr_num); #if __riscv - esprv_intc_int_set_priority(intr_num, intr_prio); - //esprv_intc_int_enable_level(1 << intr_num); - esprv_intc_int_set_type(intr_num, 0); + esprv_int_set_priority(intr_num, intr_prio); + esprv_int_set_type(intr_num, 0); #endif } diff --git a/components/esp_hw_support/include/esp_cpu.h b/components/esp_hw_support/include/esp_cpu.h index e4e43236c5..c0b84749bf 100644 --- a/components/esp_hw_support/include/esp_cpu.h +++ b/components/esp_hw_support/include/esp_cpu.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -261,7 +261,7 @@ FORCE_INLINE_ATTR void esp_cpu_intr_set_type(int intr_num, esp_cpu_intr_type_t i { assert(intr_num >= 0 && intr_num < SOC_CPU_INTR_NUM); enum intr_type type = (intr_type == ESP_CPU_INTR_TYPE_LEVEL) ? INTR_TYPE_LEVEL : INTR_TYPE_EDGE; - esprv_intc_int_set_type(intr_num, type); + esprv_int_set_type(intr_num, type); } /** @@ -276,7 +276,7 @@ FORCE_INLINE_ATTR void esp_cpu_intr_set_type(int intr_num, esp_cpu_intr_type_t i FORCE_INLINE_ATTR esp_cpu_intr_type_t esp_cpu_intr_get_type(int intr_num) { assert(intr_num >= 0 && intr_num < SOC_CPU_INTR_NUM); - enum intr_type type = esprv_intc_int_get_type(intr_num); + enum intr_type type = esprv_int_get_type(intr_num); return (type == INTR_TYPE_LEVEL) ? ESP_CPU_INTR_TYPE_LEVEL : ESP_CPU_INTR_TYPE_EDGE; } @@ -291,7 +291,7 @@ FORCE_INLINE_ATTR esp_cpu_intr_type_t esp_cpu_intr_get_type(int intr_num) FORCE_INLINE_ATTR void esp_cpu_intr_set_priority(int intr_num, int intr_priority) { assert(intr_num >= 0 && intr_num < SOC_CPU_INTR_NUM); - esprv_intc_int_set_priority(intr_num, intr_priority); + esprv_int_set_priority(intr_num, intr_priority); } /** @@ -306,7 +306,7 @@ FORCE_INLINE_ATTR void esp_cpu_intr_set_priority(int intr_num, int intr_priority FORCE_INLINE_ATTR int esp_cpu_intr_get_priority(int intr_num) { assert(intr_num >= 0 && intr_num < SOC_CPU_INTR_NUM); - return esprv_intc_int_get_priority(intr_num); + return esprv_int_get_priority(intr_num); } #endif // SOC_CPU_HAS_FLEXIBLE_INTC diff --git a/components/esp_hw_support/port/esp32c3/esp_memprot.c b/components/esp_hw_support/port/esp32c3/esp_memprot.c index fc315281ae..6b11d1fd27 100644 --- a/components/esp_hw_support/port/esp32c3/esp_memprot.c +++ b/components/esp_hw_support/port/esp32c3/esp_memprot.c @@ -630,8 +630,8 @@ static esp_err_t esp_mprot_set_intr_matrix(const esp_mprot_mem_t mem_type) } /* Set the type and priority to cache error interrupts. */ - esprv_intc_int_set_type(ETS_MEMPROT_ERR_INUM, INTR_TYPE_LEVEL); - esprv_intc_int_set_priority(ETS_MEMPROT_ERR_INUM, SOC_INTERRUPT_LEVEL_MEDIUM); + esprv_int_set_type(ETS_MEMPROT_ERR_INUM, INTR_TYPE_LEVEL); + esprv_int_set_priority(ETS_MEMPROT_ERR_INUM, SOC_INTERRUPT_LEVEL_MEDIUM); ESP_INTR_ENABLE(ETS_MEMPROT_ERR_INUM); diff --git a/components/esp_system/hw_stack_guard.c b/components/esp_system/hw_stack_guard.c index 6789093f1a..0c460de7c0 100644 --- a/components/esp_system/hw_stack_guard.c +++ b/components/esp_system/hw_stack_guard.c @@ -40,8 +40,8 @@ ESP_SYSTEM_INIT_FN(esp_hw_stack_guard_init, SECONDARY, ESP_SYSTEM_INIT_ALL_CORES /* enable interrup routine */ esp_rom_route_intr_matrix(core_id, ETS_ASSIST_DEBUG_INTR_SOURCE, ETS_ASSIST_DEBUG_INUM); - esprv_intc_int_set_type(ETS_ASSIST_DEBUG_INUM, INTR_TYPE_LEVEL); - esprv_intc_int_set_priority(ETS_ASSIST_DEBUG_INUM, SOC_INTERRUPT_LEVEL_MEDIUM); + esprv_int_set_type(ETS_ASSIST_DEBUG_INUM, INTR_TYPE_LEVEL); + esprv_int_set_priority(ETS_ASSIST_DEBUG_INUM, SOC_INTERRUPT_LEVEL_MEDIUM); ESP_INTR_ENABLE(ETS_ASSIST_DEBUG_INUM); return ESP_OK; diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index 7c5ee01583..d0109db8e0 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -68,13 +68,16 @@ #elif CONFIG_IDF_TARGET_ESP32P4 #include "esp32p4/rtc.h" #include "soc/hp_sys_clkrst_reg.h" -#include "soc/interrupt_core0_reg.h" -#include "soc/interrupt_core1_reg.h" #include "soc/keymng_reg.h" #endif #include "esp_private/rtc_clk.h" #include "esp_private/esp_ldo_psram.h" + +#if SOC_INT_CLIC_SUPPORTED +#include "hal/interrupt_clic_ll.h" +#endif // SOC_INT_CLIC_SUPPORTED + #include "esp_private/esp_mmu_map_private.h" #if CONFIG_SPIRAM #include "esp_psram.h" @@ -159,21 +162,17 @@ 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, ETS_INVALID_INUM); - } else { - REG_WRITE(INTERRUPT_CORE1_LP_RTC_INT_MAP_REG + 4 * i, ETS_INVALID_INUM); - } +#if SOC_INT_CLIC_SUPPORTED + interrupt_clic_ll_route(core_id, i, ETS_INVALID_INUM); #else esp_rom_route_intr_matrix(core_id, i, ETS_INVALID_INUM); -#endif // CONFIG_IDF_TARGET_ESP32P4 +#endif // SOC_INT_CLIC_SUPPORTED } #if SOC_INT_CLIC_SUPPORTED for (int i = 0; i < 32; i++) { /* Set all the CPU interrupt lines to vectored by default, as it is on other RISC-V targets */ - esprv_intc_int_set_vectored(i, true); + esprv_int_set_vectored(i, true); } #endif // SOC_INT_CLIC_SUPPORTED diff --git a/components/esp_system/port/soc/esp32c2/cache_err_int.c b/components/esp_system/port/soc/esp32c2/cache_err_int.c index 8215353313..8c4a06d06e 100644 --- a/components/esp_system/port/soc/esp32c2/cache_err_int.c +++ b/components/esp_system/port/soc/esp32c2/cache_err_int.c @@ -166,8 +166,8 @@ void esp_cache_err_int_init(void) esp_rom_route_intr_matrix(core_id, ETS_CACHE_CORE0_ACS_INTR_SOURCE, ETS_CACHEERR_INUM); /* Set the type and priority to cache error interrupts. */ - esprv_intc_int_set_type(ETS_CACHEERR_INUM, INTR_TYPE_LEVEL); - esprv_intc_int_set_priority(ETS_CACHEERR_INUM, SOC_INTERRUPT_LEVEL_MEDIUM); + esprv_int_set_type(ETS_CACHEERR_INUM, INTR_TYPE_LEVEL); + esprv_int_set_priority(ETS_CACHEERR_INUM, SOC_INTERRUPT_LEVEL_MEDIUM); ESP_DRAM_LOGV(TAG, "access error intr clr & ena mask is: 0x%x", CACHE_LL_L1_ACCESS_EVENT_MASK); /* On the hardware side, start by clearing all the bits reponsible for cache access error */ diff --git a/components/esp_system/port/soc/esp32c3/cache_err_int.c b/components/esp_system/port/soc/esp32c3/cache_err_int.c index 28f9877cd2..46301e66a6 100644 --- a/components/esp_system/port/soc/esp32c3/cache_err_int.c +++ b/components/esp_system/port/soc/esp32c3/cache_err_int.c @@ -165,8 +165,8 @@ void esp_cache_err_int_init(void) esp_rom_route_intr_matrix(core_id, ETS_CACHE_CORE0_ACS_INTR_SOURCE, ETS_CACHEERR_INUM); /* Set the type and priority to cache error interrupts. */ - esprv_intc_int_set_type(ETS_CACHEERR_INUM, INTR_TYPE_LEVEL); - esprv_intc_int_set_priority(ETS_CACHEERR_INUM, SOC_INTERRUPT_LEVEL_MEDIUM); + esprv_int_set_type(ETS_CACHEERR_INUM, INTR_TYPE_LEVEL); + esprv_int_set_priority(ETS_CACHEERR_INUM, SOC_INTERRUPT_LEVEL_MEDIUM); ESP_DRAM_LOGV(TAG, "access error intr clr & ena mask is: 0x%x", CACHE_LL_L1_ACCESS_EVENT_MASK); /* On the hardware side, start by clearing all the bits reponsible for cache access error */ diff --git a/components/esp_system/port/soc/esp32c6/cache_err_int.c b/components/esp_system/port/soc/esp32c6/cache_err_int.c index 7f4eda7112..78cefafe94 100644 --- a/components/esp_system/port/soc/esp32c6/cache_err_int.c +++ b/components/esp_system/port/soc/esp32c6/cache_err_int.c @@ -57,8 +57,8 @@ void esp_cache_err_int_init(void) esp_rom_route_intr_matrix(core_id, ETS_CACHE_INTR_SOURCE, ETS_CACHEERR_INUM); /* Set the type and priority to cache error interrupts. */ - esprv_intc_int_set_type(ETS_CACHEERR_INUM, INTR_TYPE_LEVEL); - esprv_intc_int_set_priority(ETS_CACHEERR_INUM, SOC_INTERRUPT_LEVEL_MEDIUM); + esprv_int_set_type(ETS_CACHEERR_INUM, INTR_TYPE_LEVEL); + esprv_int_set_priority(ETS_CACHEERR_INUM, SOC_INTERRUPT_LEVEL_MEDIUM); ESP_DRAM_LOGV(TAG, "access error intr clr & ena mask is: 0x%x", CACHE_LL_L1_ACCESS_EVENT_MASK); /* On the hardware side, start by clearing all the bits reponsible for cache access error */ diff --git a/components/esp_system/port/soc/esp32h2/cache_err_int.c b/components/esp_system/port/soc/esp32h2/cache_err_int.c index e989d69ce0..770b411948 100644 --- a/components/esp_system/port/soc/esp32h2/cache_err_int.c +++ b/components/esp_system/port/soc/esp32h2/cache_err_int.c @@ -56,8 +56,8 @@ void esp_cache_err_int_init(void) esp_rom_route_intr_matrix(core_id, ETS_CACHE_INTR_SOURCE, ETS_CACHEERR_INUM); /* Set the type and priority to cache error interrupts. */ - esprv_intc_int_set_type(ETS_CACHEERR_INUM, INTR_TYPE_LEVEL); - esprv_intc_int_set_priority(ETS_CACHEERR_INUM, SOC_INTERRUPT_LEVEL_MEDIUM); + esprv_int_set_type(ETS_CACHEERR_INUM, INTR_TYPE_LEVEL); + esprv_int_set_priority(ETS_CACHEERR_INUM, SOC_INTERRUPT_LEVEL_MEDIUM); ESP_DRAM_LOGV(TAG, "access error intr clr & ena mask is: 0x%x", CACHE_LL_L1_ACCESS_EVENT_MASK); /* On the hardware side, start by clearing all the bits reponsible for cache access error */ diff --git a/components/esp_system/port/soc/esp32p4/cache_err_int.c b/components/esp_system/port/soc/esp32p4/cache_err_int.c index 5024e47083..c1a20bbee1 100644 --- a/components/esp_system/port/soc/esp32p4/cache_err_int.c +++ b/components/esp_system/port/soc/esp32p4/cache_err_int.c @@ -52,8 +52,8 @@ void esp_cache_err_int_init(void) esp_rom_route_intr_matrix(core_id, ETS_CACHE_INTR_SOURCE, ETS_CACHEERR_INUM); /* Set the type and priority to cache error interrupts. */ - esprv_intc_int_set_type(ETS_CACHEERR_INUM, INTR_TYPE_LEVEL); - esprv_intc_int_set_priority(ETS_CACHEERR_INUM, SOC_INTERRUPT_LEVEL_MEDIUM); + esprv_int_set_type(ETS_CACHEERR_INUM, INTR_TYPE_LEVEL); + esprv_int_set_priority(ETS_CACHEERR_INUM, SOC_INTERRUPT_LEVEL_MEDIUM); ESP_DRAM_LOGV(TAG, "access error intr clr & ena mask is: 0x%x", CACHE_LL_L1_ACCESS_EVENT_MASK); /* On the hardware side, start by clearing all the bits reponsible for cache access error */ diff --git a/components/esp_wifi/esp32c2/esp_adapter.c b/components/esp_wifi/esp32c2/esp_adapter.c index 70a8dbf924..22bdb6e44c 100644 --- a/components/esp_wifi/esp32c2/esp_adapter.c +++ b/components/esp_wifi/esp32c2/esp_adapter.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -105,9 +105,9 @@ static void wifi_delete_queue_wrapper(void *queue) static void set_intr_wrapper(int32_t cpu_no, uint32_t intr_source, uint32_t intr_num, int32_t intr_prio) { - intr_matrix_route(intr_source, intr_num); - esprv_intc_int_set_priority(intr_num, intr_prio); - esprv_intc_int_set_type(intr_num, INTR_TYPE_LEVEL); + esp_rom_route_intr_matrix(cpu_no, intr_source, intr_num); + esprv_int_set_priority(intr_num, intr_prio); + esprv_int_set_type(intr_num, INTR_TYPE_LEVEL); } static void clear_intr_wrapper(uint32_t intr_source, uint32_t intr_num) @@ -122,12 +122,12 @@ static void set_isr_wrapper(int32_t n, void *f, void *arg) static void enable_intr_wrapper(uint32_t intr_mask) { - esprv_intc_int_enable(intr_mask); + esprv_int_enable(intr_mask); } static void disable_intr_wrapper(uint32_t intr_mask) { - esprv_intc_int_disable(intr_mask); + esprv_int_disable(intr_mask); } static bool IRAM_ATTR is_from_isr_wrapper(void) diff --git a/components/esp_wifi/esp32c3/esp_adapter.c b/components/esp_wifi/esp32c3/esp_adapter.c index d48431ab32..6e7defd326 100644 --- a/components/esp_wifi/esp32c3/esp_adapter.c +++ b/components/esp_wifi/esp32c3/esp_adapter.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -108,9 +108,9 @@ static void wifi_delete_queue_wrapper(void *queue) static void set_intr_wrapper(int32_t cpu_no, uint32_t intr_source, uint32_t intr_num, int32_t intr_prio) { - intr_matrix_route(intr_source, intr_num); - esprv_intc_int_set_priority(intr_num, intr_prio); - esprv_intc_int_set_type(intr_num, INTR_TYPE_LEVEL); + esp_rom_route_intr_matrix(cpu_no, intr_source, intr_num); + esprv_int_set_priority(intr_num, intr_prio); + esprv_int_set_type(intr_num, INTR_TYPE_LEVEL); } static void clear_intr_wrapper(uint32_t intr_source, uint32_t intr_num) @@ -125,12 +125,12 @@ static void set_isr_wrapper(int32_t n, void *f, void *arg) static void enable_intr_wrapper(uint32_t intr_mask) { - esprv_intc_int_enable(intr_mask); + esprv_int_enable(intr_mask); } static void disable_intr_wrapper(uint32_t intr_mask) { - esprv_intc_int_disable(intr_mask); + esprv_int_disable(intr_mask); } static bool IRAM_ATTR is_from_isr_wrapper(void) diff --git a/components/esp_wifi/esp32c6/esp_adapter.c b/components/esp_wifi/esp32c6/esp_adapter.c index f61e946f2f..7dc32f83f0 100644 --- a/components/esp_wifi/esp32c6/esp_adapter.c +++ b/components/esp_wifi/esp32c6/esp_adapter.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -111,9 +111,9 @@ static void wifi_delete_queue_wrapper(void *queue) static void set_intr_wrapper(int32_t cpu_no, uint32_t intr_source, uint32_t intr_num, int32_t intr_prio) { - intr_matrix_route(intr_source, intr_num); - esprv_intc_int_set_priority(intr_num, intr_prio); - esprv_intc_int_set_type(intr_num, INTR_TYPE_LEVEL); + esp_rom_route_intr_matrix(cpu_no, intr_source, intr_num); + esprv_int_set_priority(intr_num, intr_prio); + esprv_int_set_type(intr_num, INTR_TYPE_LEVEL); } static void clear_intr_wrapper(uint32_t intr_source, uint32_t intr_num) @@ -128,12 +128,12 @@ static void set_isr_wrapper(int32_t n, void *f, void *arg) static void enable_intr_wrapper(uint32_t intr_mask) { - esprv_intc_int_enable(intr_mask); + esprv_int_enable(intr_mask); } static void disable_intr_wrapper(uint32_t intr_mask) { - esprv_intc_int_disable(intr_mask); + esprv_int_disable(intr_mask); } static bool IRAM_ATTR is_from_isr_wrapper(void) diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c index 69eae28ab4..e6fe3258b4 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c @@ -286,7 +286,7 @@ BaseType_t xPortStartScheduler(void) /* Setup the hardware to generate the tick. */ vPortSetupTimer(); - esprv_intc_int_set_threshold(1); /* set global INTC masking level */ + esprv_int_set_threshold(1); /* set global INTC masking level */ rv_utils_intr_global_enable(); vPortYield(); diff --git a/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c b/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c index 3f986644c1..a3ab0cd127 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c +++ b/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c @@ -145,7 +145,7 @@ BaseType_t xPortStartScheduler(void) /* Setup the hardware to generate the tick. */ vPortSetupTimer(); - esprv_intc_int_set_threshold(RVHAL_INTR_ENABLE_THRESH); /* set global interrupt masking level */ + esprv_int_set_threshold(RVHAL_INTR_ENABLE_THRESH); /* set global interrupt masking level */ rv_utils_intr_global_enable(); vPortYield(); diff --git a/components/freertos/test_apps/freertos/performance/test_isr_latency.c b/components/freertos/test_apps/freertos/performance/test_isr_latency.c index 2375516162..7cd155a331 100644 --- a/components/freertos/test_apps/freertos/performance/test_isr_latency.c +++ b/components/freertos/test_apps/freertos/performance/test_isr_latency.c @@ -23,8 +23,8 @@ #define TEST_CLR_INT_MASK(mask) xt_set_intclear(mask) #elif CONFIG_IDF_TARGET_ARCH_RISCV #include "riscv/interrupt.h" -#define TEST_SET_INT_MASK(mask) esprv_intc_int_enable(mask) -#define TEST_CLR_INT_MASK(mask) esprv_intc_int_disable(mask) +#define TEST_SET_INT_MASK(mask) esprv_int_enable(mask) +#define TEST_CLR_INT_MASK(mask) esprv_int_disable(mask) #endif #ifndef __riscv // TODO: IDF-4416 diff --git a/components/hal/esp32/include/hal/crosscore_int_ll.h b/components/hal/esp32/include/hal/crosscore_int_ll.h index dbb61887ef..3cff9d6e37 100644 --- a/components/hal/esp32/include/hal/crosscore_int_ll.h +++ b/components/hal/esp32/include/hal/crosscore_int_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/hal/esp32c2/include/hal/crosscore_int_ll.h b/components/hal/esp32c2/include/hal/crosscore_int_ll.h index f2a9f7e1b8..71e3a53251 100644 --- a/components/hal/esp32c2/include/hal/crosscore_int_ll.h +++ b/components/hal/esp32c2/include/hal/crosscore_int_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/hal/esp32c3/include/hal/crosscore_int_ll.h b/components/hal/esp32c3/include/hal/crosscore_int_ll.h index f2a9f7e1b8..71e3a53251 100644 --- a/components/hal/esp32c3/include/hal/crosscore_int_ll.h +++ b/components/hal/esp32c3/include/hal/crosscore_int_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/hal/esp32c6/include/hal/crosscore_int_ll.h b/components/hal/esp32c6/include/hal/crosscore_int_ll.h index eb845e246a..c76790d756 100644 --- a/components/hal/esp32c6/include/hal/crosscore_int_ll.h +++ b/components/hal/esp32c6/include/hal/crosscore_int_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/hal/esp32h2/include/hal/crosscore_int_ll.h b/components/hal/esp32h2/include/hal/crosscore_int_ll.h index eb845e246a..c76790d756 100644 --- a/components/hal/esp32h2/include/hal/crosscore_int_ll.h +++ b/components/hal/esp32h2/include/hal/crosscore_int_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/hal/esp32p4/include/hal/crosscore_int_ll.h b/components/hal/esp32p4/include/hal/crosscore_int_ll.h index 0a22adcd44..41ebccc75c 100644 --- a/components/hal/esp32p4/include/hal/crosscore_int_ll.h +++ b/components/hal/esp32p4/include/hal/crosscore_int_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/hal/esp32s2/include/hal/crosscore_int_ll.h b/components/hal/esp32s2/include/hal/crosscore_int_ll.h index a4e52fa3a3..bf79b5f90d 100644 --- a/components/hal/esp32s2/include/hal/crosscore_int_ll.h +++ b/components/hal/esp32s2/include/hal/crosscore_int_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/hal/esp32s3/include/hal/crosscore_int_ll.h b/components/hal/esp32s3/include/hal/crosscore_int_ll.h index da4e463488..5ce6e34e1d 100644 --- a/components/hal/esp32s3/include/hal/crosscore_int_ll.h +++ b/components/hal/esp32s3/include/hal/crosscore_int_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/hal/include/hal/interrupt_clic_ll.h b/components/hal/include/hal/interrupt_clic_ll.h new file mode 100644 index 0000000000..e4125ac68c --- /dev/null +++ b/components/hal/include/hal/interrupt_clic_ll.h @@ -0,0 +1,104 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "hal/assert.h" +#include "esp_attr.h" +#include "soc/soc.h" +#include "soc/soc_caps.h" +#include "soc/reg_base.h" + + +#if SOC_INT_CLIC_SUPPORTED + +#include "soc/clic_reg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define RV_TOTAL_INT_COUNT 48 + +/** + * @brief Route any interrupt source to any CPU interrupt, including internal ones + * + * @param core_id CPU core to map the interrupt in (ignored on single-core targets) + * @param intr_src Interrupt source to map + * @param rv_int_num Destination CPU interrupt source, which can be an internal or an external interrupt. + */ +FORCE_INLINE_ATTR void interrupt_clic_ll_route(uint32_t core_id, int intr_src, int intr_num) +{ + HAL_ASSERT(intr_num < RV_TOTAL_INT_COUNT); + +#if SOC_CPU_CORES_NUM > 1 + if (core_id == 0) { + REG_WRITE(DR_REG_INTERRUPT_CORE0_BASE + 4 * intr_src, intr_num); + } else { + REG_WRITE(DR_REG_INTERRUPT_CORE1_BASE + 4 * intr_src, intr_num); + } +#else + REG_WRITE(DR_REG_INTERRUPT_CORE0_BASE + 4 * intr_src, intr_num); +#endif // SOC_CPU_CORES_NUM > 1 +} + + +/** + * @brief Get the type for the given interrupt + * + * @param rv_int_num Interrupt number to get the type of. It can be an internal or an external interrupt. + * + * @return 0 for level-triggered type, 1 for edge-triggered interrupt type + */ +FORCE_INLINE_ATTR int interrupt_clic_ll_get_type(int rv_int_num) +{ + return REG_GET_FIELD(CLIC_INT_CTRL_REG(rv_int_num), CLIC_INT_ATTR_TRIG) & 1; +} + + +/** + * @brief Get the priority for the given interrupt + * + * @param rv_int_num Interrupt number to get the priority of. It can be an internal or an external interrupt. + * + * @return interrupt priority, between 0 and 7 + */ +FORCE_INLINE_ATTR int interrupt_clic_ll_get_priority(int rv_int_num) +{ + const uint32_t priority = REG_GET_FIELD(CLIC_INT_CTRL_REG(rv_int_num), CLIC_INT_CTL); + return (priority >> (8 - NLBITS)); +} + + +/** + * @brief Check if an interrupt is vectored + * + * @param rv_int_num Interrupt number to check. It can be an internal or an external interrupt. + * + * @return true if the interrupt is vectored, false else + */ +FORCE_INLINE_ATTR bool interrupt_clic_ll_is_vectored(int rv_int_num) +{ + const uint32_t shv = REG_GET_FIELD(CLIC_INT_CTRL_REG(rv_int_num), CLIC_INT_ATTR_SHV); + return shv != 0; +} + + +/** + * @brief Set an interrupt to vectored or non-vectored + * + * @param rv_int_num Interrupt number to modify. It can be an internal or an external interrupt. + * @param vectored True to set the interrupt to vectored, false to set it to non vectored. + * + */ +FORCE_INLINE_ATTR void interrupt_clic_ll_set_vectored(int rv_int_num, bool vectored) +{ + REG_SET_FIELD(CLIC_INT_CTRL_REG(rv_int_num), CLIC_INT_ATTR_SHV, vectored ? 1 : 0); +} + +#ifdef __cplusplus +} +#endif + +#endif // SOC_INT_PLIC_SUPPORTED diff --git a/components/hal/include/hal/interrupt_intc_ll.h b/components/hal/include/hal/interrupt_intc_ll.h new file mode 100644 index 0000000000..67572a23da --- /dev/null +++ b/components/hal/include/hal/interrupt_intc_ll.h @@ -0,0 +1,75 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "esp_attr.h" +#include "soc/soc.h" +#include "soc/soc_caps.h" +#include "soc/reg_base.h" + +/* Do not use INTC on targets that have harware CLIC */ +#if SOC_CPU_HAS_FLEXIBLE_INTC && !SOC_INT_CLIC_SUPPORTED + +#include "soc/interrupt_reg.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief Route any interrupt source to any CPU interrupt, including internal ones + * + * @param intr_src Interrupt source to map + * @param rv_int_num Destination CPU interrupt source, which can be an internal or an external interrupt. + */ +FORCE_INLINE_ATTR void interrupt_intc_ll_route(int intr_src, int intr_num) +{ + REG_WRITE(DR_REG_INTERRUPT_BASE + 4 * intr_src, intr_num); +} + + +/** + * @brief Get interrupt enable mask + * + * @return interrupt enable mask, bit i is 1 if interrupt i is enabled, 0 if interrupt i is disabled + */ +FORCE_INLINE_ATTR uint32_t interrupt_intc_ll_get_unmask(void) +{ + return REG_READ(INTERRUPT_CORE0_CPU_INT_ENABLE_REG); +} + + +/** + * @brief Get the type for the given interrupt + * + * @param rv_int_num Interrupt number to get the type of. It can be an internal or an external interrupt. + * + * @return 0 for level-triggered type, 1 for edge-triggered interrupt type + */ +FORCE_INLINE_ATTR int interrupt_intc_ll_get_type(int rv_int_num) +{ + uint32_t intr_type_reg = REG_READ(INTERRUPT_CORE0_CPU_INT_TYPE_REG); + return (intr_type_reg & (1 << rv_int_num)); +} + + +/** + * @brief Get the priority for the given interrupt + * + * @param rv_int_num Interrupt number to get the priority of. It can be an internal or an external interrupt. + * + * @return interrupt priority, between 0 and 7 + */ +FORCE_INLINE_ATTR int interrupt_intc_ll_get_priority(int rv_int_num) +{ + return REG_READ(INTERRUPT_PRIO_REG(rv_int_num)); +} + + +#ifdef __cplusplus +} +#endif + +#endif // SOC_CPU_HAS_FLEXIBLE_INTC diff --git a/components/hal/include/hal/interrupt_plic_ll.h b/components/hal/include/hal/interrupt_plic_ll.h new file mode 100644 index 0000000000..3862df0734 --- /dev/null +++ b/components/hal/include/hal/interrupt_plic_ll.h @@ -0,0 +1,76 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "esp_attr.h" +#include "soc/soc.h" +#include "soc/soc_caps.h" +#include "soc/reg_base.h" + +#if SOC_INT_PLIC_SUPPORTED + +#include "soc/interrupt_reg.h" +#include "soc/plic_reg.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief Route any interrupt source to any CPU interrupt, including internal ones + * + * @param intr_src Interrupt source to map + * @param rv_int_num Destination CPU interrupt source, which can be an internal or an external interrupt. + */ +FORCE_INLINE_ATTR void interrupt_plic_ll_route(int intr_src, int intr_num) +{ + REG_WRITE(DR_REG_INTERRUPT_MATRIX_BASE + 4 * intr_src, intr_num); +} + + +/** + * @brief Get interrupt enable mask + * + * @return interrupt enable mask, bit i is 1 if interrupt i is enabled, 0 if interrupt i is disabled + */ +FORCE_INLINE_ATTR uint32_t interrupt_plic_ll_get_unmask(void) +{ + return REG_READ(PLIC_MXINT_ENABLE_REG); +} + + +/** + * @brief Get the type for the given interrupt + * + * @param rv_int_num Interrupt number to get the type of. It can be an internal or an external interrupt. + * + * @return 0 for level-triggered type, 1 for edge-triggered interrupt type + */ +FORCE_INLINE_ATTR int interrupt_plic_ll_get_type(int rv_int_num) +{ + uint32_t intr_type_reg = REG_READ(PLIC_MXINT_TYPE_REG); + return (intr_type_reg & (1 << rv_int_num)); +} + + +/** + * @brief Get the priority for the given interrupt + * + * @param rv_int_num Interrupt number to get the priority of. It can be an internal or an external interrupt. + * + * @return interrupt priority, between 0 and 7 + */ +FORCE_INLINE_ATTR int interrupt_plic_ll_get_priority(int rv_int_num) +{ + return REG_READ(INTERRUPT_PRIO_REG(rv_int_num)); +} + + +#ifdef __cplusplus +} +#endif + +#endif // SOC_INT_PLIC_SUPPORTED diff --git a/components/riscv/CMakeLists.txt b/components/riscv/CMakeLists.txt index 8d6a3b7100..96914d9bee 100644 --- a/components/riscv/CMakeLists.txt +++ b/components/riscv/CMakeLists.txt @@ -16,9 +16,11 @@ else() "vectors.S") if(CONFIG_SOC_INT_CLIC_SUPPORTED) - list(APPEND srcs "vectors_clic.S") + list(APPEND srcs "interrupt_clic.c" "vectors_clic.S") + elseif(CONFIG_SOC_INT_PLIC_SUPPORTED) + list(APPEND srcs "interrupt_plic.c" "vectors_intc.S") else() - list(APPEND srcs "vectors_intc.S") + list(APPEND srcs "interrupt_intc.c" "vectors_intc.S") endif() endif() @@ -26,3 +28,5 @@ idf_component_register(SRCS "${srcs}" LDFRAGMENTS linker.lf INCLUDE_DIRS "include" PRIV_REQUIRES ${priv_requires}) + +target_linker_script(${COMPONENT_LIB} INTERFACE "ld/rom.api.ld") diff --git a/components/riscv/include/esp_private/interrupt_clic.h b/components/riscv/include/esp_private/interrupt_clic.h new file mode 100644 index 0000000000..4d6c0b97c4 --- /dev/null +++ b/components/riscv/include/esp_private/interrupt_clic.h @@ -0,0 +1,35 @@ +/* + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + + +#include +#include +#include "esp_attr.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * If the target is using the CLIC as the interrupt controller, we have 32 external interrupt lines and 16 internal + * lines. Let's consider the internal ones reserved and not mappable to any handler. + */ +#define RV_EXTERNAL_INT_COUNT 32 +#define RV_EXTERNAL_INT_OFFSET 16 + + +FORCE_INLINE_ATTR void assert_valid_rv_int_num(int rv_int_num) +{ + assert(rv_int_num < RV_EXTERNAL_INT_COUNT && "Invalid CPU interrupt number"); +} + + +#ifdef __cplusplus +} +#endif diff --git a/components/riscv/include/esp_private/interrupt_deprecated.h b/components/riscv/include/esp_private/interrupt_deprecated.h new file mode 100644 index 0000000000..6e1c6f87dc --- /dev/null +++ b/components/riscv/include/esp_private/interrupt_deprecated.h @@ -0,0 +1,112 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "riscv/interrupt.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*************************** Former API / Backport compatibility ***************************/ + + +/** + * @brief Enable interrupts from interrupt controller. + * + * @param uint32_t unmask, unmask bits for interrupts, each bit for an interrupt + * + * return none + */ +void esprv_intc_int_enable(uint32_t unmask) __attribute__((deprecated("please use esprv_int_enable instead"))); + +/** + * @brief Disable interrupts from interrupt controller. + * + * @param uint32_t mask, mask bits for interrupts, each bit for an interrupt + * + * return none + */ +void esprv_intc_int_disable(uint32_t mask) __attribute__((deprecated("please use esprv_int_disable instead"))); + +/** + * @brief Set interrupt type + * + * Set the type of a particular interrupt (level or edge). + * - Level interrupts are cleared automatically once their interrupt source has + * been cleared + * - Edge interrupts must be cleared by software when they are handled. + * + * @param intr_num Interrupt number + * @param type Interrupt type + */ +void esprv_intc_int_set_type(int intr_num, enum intr_type type) __attribute__((deprecated("please use esprv_int_set_type instead"))); + +/** + * @brief Get the current type of an interrupt + * + * Get the current type of a particular interrupt (level or edge). An interrupt's + * type can be set by calling esprv_intc_int_set_type(). + * + * @param intr_num Interrupt number + * @return Interrupt type + */ +static inline __attribute__((deprecated("please use esprv_int_get_type instead"))) enum intr_type esprv_intc_int_get_type(int intr_num) +{ + return esprv_int_get_type(intr_num); +} + +/** + * Set interrupt priority in the interrupt controller + * @param rv_int_num CPU interrupt number + * @param priority Interrupt priority level, 1 to 7 + */ +void esprv_intc_int_set_priority(int rv_int_num, int priority) __attribute__((deprecated("please use esprv_int_set_priority instead"))); + +/** + * @brief Get the current priority of an interrupt + * + * Get the current priority of an interrupt. + * + * @param rv_int_num CPU interrupt number + * @return Interrupt priority level, 1 to 7 + */ +static inline __attribute__((deprecated("please use esprv_int_get_priority instead"))) int esprv_intc_int_get_priority(int rv_int_num) +{ + return esprv_int_get_priority(rv_int_num); +} + +/** + * Set interrupt priority threshold. + * Interrupts with priority levels lower than the threshold are masked. + * + * @param priority_threshold Interrupt priority threshold, 0 to 7 + */ +void esprv_intc_int_set_threshold(int priority_threshold) __attribute__((deprecated("please use esprv_int_set_threshold instead"))); + +/** + * @brief Get interrupt unmask + * @param none + * @return uint32_t interrupt unmask + */ +static inline __attribute__((deprecated("please use esprv_get_interrupt_unmask instead"))) uint32_t esprv_intc_get_interrupt_unmask(void) +{ + return esprv_get_interrupt_unmask(); +} + +/** + * @brief Route the peripheral interrupt signal to the CPU + * @param periph_intr_source Peripheral interrupt number, one of ETS_XXX_SOURCE + * @param rv_int_num CPU interrupt number + */ +void intr_matrix_route(int periph_intr_source, int rv_int_num) __attribute__((deprecated("please use esp_rom_route_intr_matrix instead"))); + +#ifdef __cplusplus +} +#endif diff --git a/components/riscv/include/esp_private/interrupt_intc.h b/components/riscv/include/esp_private/interrupt_intc.h new file mode 100644 index 0000000000..5db32428ac --- /dev/null +++ b/components/riscv/include/esp_private/interrupt_intc.h @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + + +#include +#include +#include "esp_attr.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * In the case of INTC, all the interrupt lines are dedicated to external peripherals, so the offset is 0 + */ +#define RV_EXTERNAL_INT_COUNT 32 +#define RV_EXTERNAL_INT_OFFSET 0 + + +FORCE_INLINE_ATTR void assert_valid_rv_int_num(int rv_int_num) +{ + assert(rv_int_num != 0 && "Invalid CPU interrupt number"); +} + + +#ifdef __cplusplus +} +#endif diff --git a/components/riscv/include/esp_private/interrupt_plic.h b/components/riscv/include/esp_private/interrupt_plic.h new file mode 100644 index 0000000000..667863538d --- /dev/null +++ b/components/riscv/include/esp_private/interrupt_plic.h @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + + +#include +#include +#include "esp_attr.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * In the case of PLIC, all the interrupt lines are dedicated to external peripherals, so the offset is 0 + */ +#define RV_EXTERNAL_INT_COUNT 32 +#define RV_EXTERNAL_INT_OFFSET 0 + + +FORCE_INLINE_ATTR void assert_valid_rv_int_num(int rv_int_num) +{ + assert(rv_int_num != 0 && "Invalid CPU interrupt number"); +} + + +#ifdef __cplusplus +} +#endif diff --git a/components/riscv/include/riscv/interrupt.h b/components/riscv/include/riscv/interrupt.h index faccbf6a17..c993572bc5 100644 --- a/components/riscv/include/riscv/interrupt.h +++ b/components/riscv/include/riscv/interrupt.h @@ -1,21 +1,32 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once -#include - #ifdef __cplusplus extern "C" { #endif + enum intr_type { INTR_TYPE_LEVEL = 0, INTR_TYPE_EDGE }; + +#include +#include "soc/soc_caps.h" + +#if SOC_INT_CLIC_SUPPORTED +#include "esp_private/interrupt_clic.h" +#elif SOC_INT_PLIC_SUPPORTED +#include "esp_private/interrupt_plic.h" +#else +#include "esp_private/interrupt_intc.h" +#endif + /*************************** Software interrupt dispatcher ***************************/ /** Callback type of the interrupt handler */ @@ -40,16 +51,6 @@ intr_handler_t intr_handler_get(int rv_int_num); */ void *intr_handler_get_arg(int rv_int_num); -/*************************** Interrupt matrix ***************************/ - -/** - * this function will be removed in later, please use `intr_matrix_set` instead - * Route the peripheral interrupt signal to the CPU - * @param periph_intr_source Peripheral interrupt number, one of ETS_XXX_SOURCE - * @param rv_int_num CPU interrupt number - */ -void intr_matrix_route(int periph_intr_source, int rv_int_num); - /*************************** ESP-RV Interrupt Controller ***************************/ /** @@ -59,7 +60,7 @@ void intr_matrix_route(int periph_intr_source, int rv_int_num); * * return none */ -void esprv_intc_int_enable(uint32_t unmask); +void esprv_int_enable(uint32_t unmask); /** * @brief Disable interrupts from interrupt controller. @@ -68,7 +69,7 @@ void esprv_intc_int_enable(uint32_t unmask); * * return none */ -void esprv_intc_int_disable(uint32_t mask); +void esprv_int_disable(uint32_t mask); /** * @brief Set interrupt type @@ -81,25 +82,25 @@ void esprv_intc_int_disable(uint32_t mask); * @param intr_num Interrupt number * @param type Interrupt type */ -void esprv_intc_int_set_type(int intr_num, enum intr_type type); +void esprv_int_set_type(int intr_num, enum intr_type type); /** * @brief Get the current type of an interrupt * * Get the current type of a particular interrupt (level or edge). An interrupt's - * type can be set by calling esprv_intc_int_set_type(). + * type can be set by calling esprv_int_set_type(). * * @param intr_num Interrupt number * @return Interrupt type */ -enum intr_type esprv_intc_int_get_type(int intr_num); +enum intr_type esprv_int_get_type(int intr_num); /** * Set interrupt priority in the interrupt controller * @param rv_int_num CPU interrupt number * @param priority Interrupt priority level, 1 to 7 */ -void esprv_intc_int_set_priority(int rv_int_num, int priority); +void esprv_int_set_priority(int rv_int_num, int priority); /** * @brief Get the current priority of an interrupt @@ -109,7 +110,7 @@ void esprv_intc_int_set_priority(int rv_int_num, int priority); * @param rv_int_num CPU interrupt number * @return Interrupt priority level, 1 to 7 */ -int esprv_intc_int_get_priority(int rv_int_num); +int esprv_int_get_priority(int rv_int_num); /** * Set interrupt priority threshold. @@ -117,14 +118,14 @@ int esprv_intc_int_get_priority(int rv_int_num); * * @param priority_threshold Interrupt priority threshold, 0 to 7 */ -void esprv_intc_int_set_threshold(int priority_threshold); +void esprv_int_set_threshold(int priority_threshold); /** * @brief Get interrupt unmask * @param none * @return uint32_t interrupt unmask */ -uint32_t esprv_intc_get_interrupt_unmask(void); +uint32_t esprv_get_interrupt_unmask(void); /** * @brief Check if the given interrupt is hardware vectored @@ -133,7 +134,7 @@ uint32_t esprv_intc_get_interrupt_unmask(void); * * @return true if the interrupt is vectored, false if it is not. */ -bool esprv_intc_int_is_vectored(int rv_int_num); +bool esprv_int_is_vectored(int rv_int_num); /** * @brief Set interrupt vectored @@ -143,7 +144,13 @@ bool esprv_intc_int_is_vectored(int rv_int_num); * @param rv_int_num Interrupt number * @param vectored True to set it to vectored, false to set it to non-vectored */ -void esprv_intc_int_set_vectored(int rv_int_num, bool vectored); +void esprv_int_set_vectored(int rv_int_num, bool vectored); + + +/** + * Include the deprecated functions last since they will alias the functions declared above + */ +#include "esp_private/interrupt_deprecated.h" #ifdef __cplusplus } diff --git a/components/riscv/include/riscv/rv_utils.h b/components/riscv/include/riscv/rv_utils.h index b2906739f6..82df03daf9 100644 --- a/components/riscv/include/riscv/rv_utils.h +++ b/components/riscv/include/riscv/rv_utils.h @@ -159,7 +159,7 @@ FORCE_INLINE_ATTR void rv_utils_intr_enable(uint32_t intr_mask) { // Disable all interrupts to make updating of the interrupt mask atomic. unsigned old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE); - esprv_intc_int_enable(intr_mask); + esprv_int_enable(intr_mask); RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE); } @@ -167,7 +167,7 @@ FORCE_INLINE_ATTR void rv_utils_intr_disable(uint32_t intr_mask) { // Disable all interrupts to make updating of the interrupt mask atomic. unsigned old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE); - esprv_intc_int_disable(intr_mask); + esprv_int_disable(intr_mask); RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE); } diff --git a/components/riscv/interrupt.c b/components/riscv/interrupt.c index 6e3650a344..5d1c8f91c4 100644 --- a/components/riscv/interrupt.c +++ b/components/riscv/interrupt.c @@ -1,48 +1,15 @@ /* - * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include -#include #include "soc/soc.h" #include "riscv/interrupt.h" -#include "soc/interrupt_reg.h" -#include "riscv/csr.h" -#include "esp_attr.h" #include "riscv/rv_utils.h" -#if SOC_INT_CLIC_SUPPORTED - -/** - * If the target is using the CLIC as the interrupt controller, we have 32 external interrupt lines and 16 internal - * lines. Let's consider the internal ones reserved and not mappable to any handler. - */ -#define RV_EXTERNAL_INT_COUNT 32 -#define RV_EXTERNAL_INT_OFFSET (CLIC_EXT_INTR_NUM_OFFSET) - -#else // !SOC_INT_CLIC_SUPPORTED - -/** - * In the case of INTC, all the interrupt lines are dedicated to external peripherals, so the offset is 0. - * In the case of PLIC, the reserved interrupts are not contiguous, moreover, they are already marked as - * unusable by the interrupt allocator, so the offset can also be 0 here. - */ -#define RV_EXTERNAL_INT_COUNT 32 -#define RV_EXTERNAL_INT_OFFSET 0 - -/* Since DR_REG_INTERRUPT_CORE0_BASE is not defined on some single-core targets, use the former - * DR_REG_INTERRUPT_BASE macro instead. */ -#ifndef DR_REG_INTERRUPT_CORE0_BASE -#define DR_REG_INTERRUPT_CORE0_BASE DR_REG_INTERRUPT_BASE -#endif // DR_REG_INTERRUPT_CORE0_BASE - - -#endif // SOC_INT_CLIC_SUPPORTED - - typedef struct { intr_handler_t handler; void *arg; @@ -51,15 +18,6 @@ typedef struct { static intr_handler_item_t s_intr_handlers[SOC_CPU_CORES_NUM][RV_EXTERNAL_INT_COUNT]; -static inline void assert_valid_rv_int_num(int rv_int_num) -{ -#if !SOC_INT_CLIC_SUPPORTED - assert(rv_int_num != 0 && "Invalid CPU interrupt number"); -#endif - assert(rv_int_num < RV_EXTERNAL_INT_COUNT && "Invalid CPU interrupt number"); -} - - static intr_handler_item_t* intr_get_item(int int_no) { assert_valid_rv_int_num(int_no); @@ -106,77 +64,6 @@ void _global_interrupt_handler(intptr_t sp, int mcause) } } -/*************************** RISC-V interrupt enable/disable ***************************/ - -void intr_matrix_route(int intr_src, int intr_num) -{ - assert_valid_rv_int_num(intr_num); - - if (rv_utils_get_core_id() == 0) { - REG_WRITE(DR_REG_INTERRUPT_CORE0_BASE + 4 * intr_src, intr_num + RV_EXTERNAL_INT_OFFSET); - } -#if SOC_CPU_CORES_NUM > 1 - else { - REG_WRITE(DR_REG_INTERRUPT_CORE1_BASE + 4 * intr_src, intr_num + RV_EXTERNAL_INT_OFFSET); - } -#endif // SOC_CPU_CORES_NUM > 1 -} - -// CLIC for each interrupt line provides a IE register -// this api is not used -#if !SOC_INT_CLIC_SUPPORTED -uint32_t esprv_intc_get_interrupt_unmask(void) -{ - return REG_READ(INTERRUPT_CORE0_CPU_INT_ENABLE_REG); -} -#endif - -/*************************** ESP-RV Interrupt Controller ***************************/ - - -#if SOC_INT_CLIC_SUPPORTED - -enum intr_type esprv_intc_int_get_type(int rv_int_num) -{ - uint32_t intr_type_reg = REG_GET_FIELD(CLIC_INT_CTRL_REG(rv_int_num + RV_EXTERNAL_INT_OFFSET), CLIC_INT_ATTR_TRIG); - return (intr_type_reg & 1) ? INTR_TYPE_EDGE : INTR_TYPE_LEVEL; -} - -int esprv_intc_int_get_priority(int rv_int_num) -{ - uint32_t intr_priority_reg = REG_GET_FIELD(CLIC_INT_CTRL_REG(rv_int_num + RV_EXTERNAL_INT_OFFSET), CLIC_INT_CTL); - return (intr_priority_reg >> (8 - NLBITS)); -} - - -bool esprv_intc_int_is_vectored(int rv_int_num) -{ - const uint32_t shv = REG_GET_FIELD(CLIC_INT_CTRL_REG(rv_int_num + RV_EXTERNAL_INT_OFFSET), CLIC_INT_ATTR_SHV); - return shv != 0; -} - -void esprv_intc_int_set_vectored(int rv_int_num, bool vectored) -{ - REG_SET_FIELD(CLIC_INT_CTRL_REG(rv_int_num + RV_EXTERNAL_INT_OFFSET), CLIC_INT_ATTR_SHV, vectored ? 1 : 0); -} - - -#else // !SOC_INT_CLIC_SUPPORTED - -enum intr_type esprv_intc_int_get_type(int rv_int_num) -{ - uint32_t intr_type_reg = REG_READ(INTERRUPT_CORE0_CPU_INT_TYPE_REG); - return (intr_type_reg & (1 << rv_int_num)) ? INTR_TYPE_EDGE : INTR_TYPE_LEVEL; -} - -int esprv_intc_int_get_priority(int rv_int_num) -{ - uint32_t intr_priority_reg = REG_READ(INTC_INT_PRIO_REG(rv_int_num)); - return intr_priority_reg; -} - -#endif // SOC_INT_CLIC_SUPPORTED - /*************************** Exception names. Used in .gdbinit file. ***************************/ const char *riscv_excp_names[16] __attribute__((used)) = { diff --git a/components/riscv/interrupt_clic.c b/components/riscv/interrupt_clic.c new file mode 100644 index 0000000000..d6a98618f4 --- /dev/null +++ b/components/riscv/interrupt_clic.c @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "riscv/rv_utils.h" +#include "hal/interrupt_clic_ll.h" +#include "esp_private/interrupt_clic.h" + + +void intr_matrix_route(int intr_src, int intr_num) +{ + assert_valid_rv_int_num(intr_num); + + const int core_id = rv_utils_get_core_id(); + interrupt_clic_ll_route(core_id, intr_src, intr_num + RV_EXTERNAL_INT_OFFSET); +} + + +enum intr_type esprv_int_get_type(int rv_int_num) +{ + return interrupt_clic_ll_get_type(rv_int_num + RV_EXTERNAL_INT_OFFSET) ? INTR_TYPE_EDGE : INTR_TYPE_LEVEL; +} + + +int esprv_int_get_priority(int rv_int_num) +{ + return interrupt_clic_ll_get_priority(rv_int_num + RV_EXTERNAL_INT_OFFSET); +} + + +bool esprv_int_is_vectored(int rv_int_num) +{ + return interrupt_clic_ll_is_vectored(rv_int_num + RV_EXTERNAL_INT_OFFSET); +} + + +void esprv_int_set_vectored(int rv_int_num, bool vectored) +{ + interrupt_clic_ll_set_vectored(rv_int_num + RV_EXTERNAL_INT_OFFSET, vectored); +} diff --git a/components/riscv/interrupt_intc.c b/components/riscv/interrupt_intc.c new file mode 100644 index 0000000000..2bd816d10f --- /dev/null +++ b/components/riscv/interrupt_intc.c @@ -0,0 +1,40 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "riscv/interrupt.h" +#include "esp_private/interrupt_intc.h" +#include "hal/interrupt_intc_ll.h" + + +void intr_matrix_route(int intr_src, int intr_num) +{ + assert_valid_rv_int_num(intr_num); + interrupt_intc_ll_route(intr_src, intr_num); +} + + +uint32_t esprv_get_interrupt_unmask(void) +{ + return interrupt_intc_ll_get_unmask(); +} + + +enum intr_type esprv_int_get_type(int rv_int_num) +{ + return interrupt_intc_ll_get_type(rv_int_num) ? INTR_TYPE_EDGE : INTR_TYPE_LEVEL; +} + + +int esprv_int_get_priority(int rv_int_num) +{ + return interrupt_intc_ll_get_priority(rv_int_num); +} + + +bool esprv_int_is_vectored(int rv_int_num) +{ + return true; +} diff --git a/components/riscv/interrupt_plic.c b/components/riscv/interrupt_plic.c new file mode 100644 index 0000000000..86b99cb616 --- /dev/null +++ b/components/riscv/interrupt_plic.c @@ -0,0 +1,40 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "riscv/interrupt.h" +#include "esp_private/interrupt_plic.h" +#include "hal/interrupt_plic_ll.h" + + +void intr_matrix_route(int intr_src, int intr_num) +{ + assert_valid_rv_int_num(intr_num); + interrupt_plic_ll_route(intr_src, intr_num); +} + + +uint32_t esprv_get_interrupt_unmask(void) +{ + return interrupt_plic_ll_get_unmask(); +} + + +enum intr_type esprv_int_get_type(int rv_int_num) +{ + return interrupt_plic_ll_get_type(rv_int_num) ? INTR_TYPE_EDGE : INTR_TYPE_LEVEL; +} + + +int esprv_int_get_priority(int rv_int_num) +{ + return interrupt_plic_ll_get_priority(rv_int_num); +} + + +bool esprv_int_is_vectored(int rv_int_num) +{ + return true; +} diff --git a/components/riscv/ld/rom.api.ld b/components/riscv/ld/rom.api.ld new file mode 100644 index 0000000000..e179b7f939 --- /dev/null +++ b/components/riscv/ld/rom.api.ld @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* The interrupt API functions are implemented in ROM under the deprecated names, define the aliases */ +PROVIDE ( esprv_int_set_priority = esprv_intc_int_set_priority ); +PROVIDE ( esprv_int_set_threshold = esprv_intc_int_set_threshold ); +PROVIDE ( esprv_int_enable = esprv_intc_int_enable ); +PROVIDE ( esprv_int_disable = esprv_intc_int_disable ); +PROVIDE ( esprv_int_set_type = esprv_intc_int_set_type ); diff --git a/components/riscv/vectors.S b/components/riscv/vectors.S index 274c296231..6c4e931f28 100644 --- a/components/riscv/vectors.S +++ b/components/riscv/vectors.S @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -316,9 +316,9 @@ _interrupt_handler: li t2, VECTORS_MCAUSE_REASON_MASK and t1, s1, t2 /* t1 = mcause & mask */ slli t1, t1, 2 /* t1 = mcause * 4 */ - li t2, INTC_INT_PRIO_REG(0) - add t1, t2, t1 /* t1 = INTC_INT_PRIO_REG + 4 * mcause */ - lw t2, 0(t1) /* t2 = INTC_INT_PRIO_REG[mcause] */ + li t2, INTERRUPT_PRIO_REG(0) + add t1, t2, t1 /* t1 = INTERRUPT_PRIO_REG + 4 * mcause */ + lw t2, 0(t1) /* t2 = INTERRUPT_PRIO_REG[mcause] */ addi t2, t2, 1 /* t2 = t2 +1 */ sw t2, 0(t0) /* INTERRUPT_CURRENT_CORE_INT_THRESH_REG = t2 */ fence diff --git a/components/soc/esp32c2/include/soc/interrupt_reg.h b/components/soc/esp32c2/include/soc/interrupt_reg.h index d3b35f8d9f..749a2e9216 100644 --- a/components/soc/esp32c2/include/soc/interrupt_reg.h +++ b/components/soc/esp32c2/include/soc/interrupt_reg.h @@ -3,6 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#pragma once + #include "interrupt_core0_reg.h" #define INTERRUPT_CURRENT_CORE_INT_THRESH_REG INTERRUPT_CORE0_CPU_INT_THRESH_REG +#define INTERRUPT_PRIO_REG(n) (INTERRUPT_CORE0_CPU_INT_PRI_0_REG + (n)*4) diff --git a/components/soc/esp32c3/include/soc/interrupt_reg.h b/components/soc/esp32c3/include/soc/interrupt_reg.h index d3b35f8d9f..749a2e9216 100644 --- a/components/soc/esp32c3/include/soc/interrupt_reg.h +++ b/components/soc/esp32c3/include/soc/interrupt_reg.h @@ -3,6 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#pragma once + #include "interrupt_core0_reg.h" #define INTERRUPT_CURRENT_CORE_INT_THRESH_REG INTERRUPT_CORE0_CPU_INT_THRESH_REG +#define INTERRUPT_PRIO_REG(n) (INTERRUPT_CORE0_CPU_INT_PRI_0_REG + (n)*4) diff --git a/components/soc/esp32c5/include/soc/interrupt_reg.h b/components/soc/esp32c5/include/soc/interrupt_reg.h index c2ee2f9e2f..e52f9270de 100644 --- a/components/soc/esp32c5/include/soc/interrupt_reg.h +++ b/components/soc/esp32c5/include/soc/interrupt_reg.h @@ -1,22 +1,25 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ -#include "soc/reg_base.h" -#include "soc/interrupt_matrix_reg.h" + #include "soc/clic_reg.h" #include "soc/soc_caps.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * ESP32C5 uses the CLIC controller as the interrupt controller (SOC_INT_CLIC_SUPPORTED = y) - * - * The memory map for interrupt registers is on a per-core basis, CLIC_INT_THRESH_REG points to - * the current core interrupt register, whereas CLIC_INT_THRESH_REG + DUALCORE_CLIC_CTRL_OFF points - * to the other core registers, regardless of the core we are currently running on. */ #define INTERRUPT_CURRENT_CORE_INT_THRESH_REG (CLIC_INT_THRESH_REG) #define INTERRUPT_OTHER_CORE_INT_THRESH_REG (CLIC_INT_THRESH_REG + DUALCORE_CLIC_CTRL_OFF) #define INTERRUPT_CORE0_CPU_INT_THRESH_REG INTERRUPT_CURRENT_CORE_INT_THRESH_REG + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c6/include/soc/interrupt_reg.h b/components/soc/esp32c6/include/soc/interrupt_reg.h index e7233dd3ea..50f8a6e1c6 100644 --- a/components/soc/esp32c6/include/soc/interrupt_reg.h +++ b/components/soc/esp32c6/include/soc/interrupt_reg.h @@ -1,20 +1,25 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ +#pragma once #include "soc/interrupt_matrix_reg.h" #include "soc/intpri_reg.h" #include "soc/plic_reg.h" #include "soc/soc_caps.h" -// ESP32C6 should use the PLIC controller as the interrupt controller instead of INTC (SOC_INT_PLIC_SUPPORTED = y) -#define INTERRUPT_CURRENT_CORE_INT_THRESH_REG INTERRUPT_CORE0_CPU_INT_THRESH_REG -#define INTERRUPT_CORE0_CPU_INT_ENABLE_REG PLIC_MXINT_ENABLE_REG -#define INTERRUPT_CORE0_CPU_INT_THRESH_REG PLIC_MXINT_THRESH_REG -#define INTERRUPT_CORE0_CPU_INT_CLEAR_REG PLIC_MXINT_CLEAR_REG -#define INTERRUPT_CORE0_CPU_INT_TYPE_REG PLIC_MXINT_TYPE_REG -#define INTC_INT_PRIO_REG(n) (PLIC_MXINT0_PRI_REG + (n)*4) +#define INTERRUPT_PRIO_REG(n) (PLIC_MXINT0_PRI_REG + (n)*4) +#define INTERRUPT_CURRENT_CORE_INT_THRESH_REG PLIC_MXINT_THRESH_REG -#define DR_REG_INTERRUPT_BASE DR_REG_INTERRUPT_MATRIX_BASE +/** + * ESP32C6 should use the PLIC controller as the interrupt controller instead of INTC (SOC_INT_PLIC_SUPPORTED = y) + * Keep the following macros for backward compatibility reasons + */ +#define INTERRUPT_CORE0_CPU_INT_ENABLE_REG PLIC_MXINT_ENABLE_REG +#define INTERRUPT_CORE0_CPU_INT_THRESH_REG PLIC_MXINT_THRESH_REG +#define INTERRUPT_CORE0_CPU_INT_CLEAR_REG PLIC_MXINT_CLEAR_REG +#define INTERRUPT_CORE0_CPU_INT_TYPE_REG PLIC_MXINT_TYPE_REG +#define INTC_INT_PRIO_REG(n) (PLIC_MXINT0_PRI_REG + (n)*4) +#define DR_REG_INTERRUPT_BASE DR_REG_INTERRUPT_MATRIX_BASE diff --git a/components/soc/esp32h2/include/soc/interrupt_reg.h b/components/soc/esp32h2/include/soc/interrupt_reg.h index f6d745adcd..1eb4721c84 100644 --- a/components/soc/esp32h2/include/soc/interrupt_reg.h +++ b/components/soc/esp32h2/include/soc/interrupt_reg.h @@ -1,18 +1,24 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ +#pragma once #include "interrupt_matrix_reg.h" #include "plic_reg.h" #include "soc/soc_caps.h" -// ESP32H2 should use the PLIC controller as the interrupt controller instead of INTC (SOC_INT_PLIC_SUPPORTED = y) -#define INTERRUPT_CURRENT_CORE_INT_THRESH_REG INTERRUPT_CORE0_CPU_INT_THRESH_REG -#define INTERRUPT_CORE0_CPU_INT_ENABLE_REG PLIC_MXINT_ENABLE_REG -#define INTERRUPT_CORE0_CPU_INT_THRESH_REG PLIC_MXINT_THRESH_REG -#define INTERRUPT_CORE0_CPU_INT_CLEAR_REG PLIC_MXINT_CLEAR_REG -#define INTERRUPT_CORE0_CPU_INT_TYPE_REG PLIC_MXINT_TYPE_REG -#define INTC_INT_PRIO_REG(n) (PLIC_MXINT0_PRI_REG + (n)*4) -#define DR_REG_INTERRUPT_BASE DR_REG_INTERRUPT_MATRIX_BASE +#define INTERRUPT_PRIO_REG(n) (PLIC_MXINT0_PRI_REG + (n)*4) +#define INTERRUPT_CURRENT_CORE_INT_THRESH_REG PLIC_MXINT_THRESH_REG + +/** + * ESP32H2 should use the PLIC controller as the interrupt controller instead of INTC (SOC_INT_PLIC_SUPPORTED = y) + * Keep the following macros for backward compatibility reasons + */ +#define INTERRUPT_CORE0_CPU_INT_ENABLE_REG PLIC_MXINT_ENABLE_REG +#define INTERRUPT_CORE0_CPU_INT_THRESH_REG PLIC_MXINT_THRESH_REG +#define INTERRUPT_CORE0_CPU_INT_CLEAR_REG PLIC_MXINT_CLEAR_REG +#define INTERRUPT_CORE0_CPU_INT_TYPE_REG PLIC_MXINT_TYPE_REG +#define INTC_INT_PRIO_REG(n) (PLIC_MXINT0_PRI_REG + (n)*4) +#define DR_REG_INTERRUPT_BASE DR_REG_INTERRUPT_MATRIX_BASE diff --git a/components/soc/esp32p4/include/soc/interrupt_reg.h b/components/soc/esp32p4/include/soc/interrupt_reg.h index 6309c53f9f..2f2aabe539 100644 --- a/components/soc/esp32p4/include/soc/interrupt_reg.h +++ b/components/soc/esp32p4/include/soc/interrupt_reg.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,9 +22,8 @@ extern "C" { #define INTERRUPT_CURRENT_CORE_INT_THRESH_REG (CLIC_INT_THRESH_REG) #define INTERRUPT_OTHER_CORE_INT_THRESH_REG (CLIC_INT_THRESH_REG + DUALCORE_CLIC_CTRL_OFF) - -#define INTERRUPT_CORE0_CPU_INT_THRESH_REG (rv_utils_get_core_id() == 0 ? INTERRUPT_CURRENT_CORE_INT_THRESH_REG : INTERRUPT_OTHER_CORE_INT_THRESH_REG) -#define INTERRUPT_CORE1_CPU_INT_THRESH_REG (rv_utils_get_core_id() == 1 ? INTERRUPT_CURRENT_CORE_INT_THRESH_REG : INTERRUPT_OTHER_CORE_INT_THRESH_REG) +#define INTERRUPT_CORE0_CPU_INT_THRESH_REG (rv_utils_get_core_id() == 0 ? INTERRUPT_CURRENT_CORE_INT_THRESH_REG : INTERRUPT_OTHER_CORE_INT_THRESH_REG) +#define INTERRUPT_CORE1_CPU_INT_THRESH_REG (rv_utils_get_core_id() == 1 ? INTERRUPT_CURRENT_CORE_INT_THRESH_REG : INTERRUPT_OTHER_CORE_INT_THRESH_REG) #ifdef __cplusplus