From 06c28f0ee9a880f78b329ab2431ed439cff320dc Mon Sep 17 00:00:00 2001 From: Konstantin Kondrashov Date: Thu, 14 Mar 2024 16:21:29 +0200 Subject: [PATCH] feat(hal): Adds hal funcs for cpu.c --- .codespellrc | 2 +- components/esp_hw_support/cpu.c | 104 ++---------------- .../hal/esp32/include/hal/cpu_utility_ll.h | 70 ++++++++++++ .../hal/esp32c2/include/hal/cpu_utility_ll.h | 30 +++++ .../hal/esp32c3/include/hal/cpu_utility_ll.h | 30 +++++ .../hal/esp32c5/include/hal/cpu_utility_ll.h | 30 +++++ .../hal/esp32c6/include/hal/cpu_utility_ll.h | 30 +++++ .../hal/esp32c61/include/hal/cpu_utility_ll.h | 30 +++++ .../hal/esp32h2/include/hal/cpu_utility_ll.h | 30 +++++ .../hal/esp32p4/include/hal/cpu_utility_ll.h | 55 +++++++++ .../hal/esp32s2/include/hal/cpu_utility_ll.h | 24 ++++ .../hal/esp32s3/include/hal/cpu_utility_ll.h | 70 ++++++++++++ components/riscv/include/riscv/rv_utils.h | 16 +-- .../esp32c2/include/soc/Kconfig.soc_caps.in | 4 + components/soc/esp32c2/include/soc/soc_caps.h | 1 + .../esp32c3/include/soc/Kconfig.soc_caps.in | 4 + components/soc/esp32c3/include/soc/soc_caps.h | 1 + .../esp32c6/include/soc/Kconfig.soc_caps.in | 4 + components/soc/esp32c6/include/soc/soc_caps.h | 1 + .../esp32h2/include/soc/Kconfig.soc_caps.in | 4 + components/soc/esp32h2/include/soc/soc_caps.h | 1 + 21 files changed, 437 insertions(+), 104 deletions(-) create mode 100644 components/hal/esp32/include/hal/cpu_utility_ll.h create mode 100644 components/hal/esp32c2/include/hal/cpu_utility_ll.h create mode 100644 components/hal/esp32c3/include/hal/cpu_utility_ll.h create mode 100644 components/hal/esp32c5/include/hal/cpu_utility_ll.h create mode 100644 components/hal/esp32c6/include/hal/cpu_utility_ll.h create mode 100644 components/hal/esp32c61/include/hal/cpu_utility_ll.h create mode 100644 components/hal/esp32h2/include/hal/cpu_utility_ll.h create mode 100644 components/hal/esp32p4/include/hal/cpu_utility_ll.h create mode 100644 components/hal/esp32s2/include/hal/cpu_utility_ll.h create mode 100644 components/hal/esp32s3/include/hal/cpu_utility_ll.h diff --git a/.codespellrc b/.codespellrc index 617cef4221..42f363c725 100644 --- a/.codespellrc +++ b/.codespellrc @@ -1,4 +1,4 @@ [codespell] skip = build,*.yuv,components/fatfs/src/*,alice.txt,*.rgb -ignore-words-list = ser,dout,rsource,fram,inout,shs,ans,aci +ignore-words-list = ser,dout,rsource,fram,inout,shs,ans,aci,unstall,unstalling write-changes = true diff --git a/components/esp_hw_support/cpu.c b/components/esp_hw_support/cpu.c index 3b14d65c75..0bcfcfcb7e 100644 --- a/components/esp_hw_support/cpu.c +++ b/components/esp_hw_support/cpu.c @@ -9,36 +9,19 @@ #include #include "soc/soc.h" #include "soc/soc_caps.h" - -// TODO: IDF-5645 -#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C61 -#include "soc/lp_aon_reg.h" -#include "soc/pcr_reg.h" -#define SYSTEM_CPU_PER_CONF_REG PCR_CPU_WAITI_CONF_REG -#define SYSTEM_CPU_WAIT_MODE_FORCE_ON PCR_CPU_WAIT_MODE_FORCE_ON -#elif CONFIG_IDF_TARGET_ESP32P4 -#include "soc/lp_clkrst_reg.h" -#include "soc/pmu_reg.h" -#else -#include "soc/rtc_cntl_reg.h" -#endif - -#include "hal/soc_hal.h" +#include "hal/cpu_utility_ll.h" #include "esp_bit_defs.h" #include "esp_attr.h" #include "esp_err.h" #include "esp_cpu.h" #if __XTENSA__ #include "xtensa/config/core-isa.h" -#else -#include "soc/system_reg.h" // For SYSTEM_CPU_PER_CONF_REG -#include "soc/dport_access.h" // For Dport access +#else // __riscv #include "riscv/semihosting.h" -#endif #if SOC_CPU_HAS_FLEXIBLE_INTC #include "riscv/instruction_decode.h" #endif - +#endif // __riscv /* --------------------------------------------------- CPU Control ----------------------------------------------------- * @@ -46,89 +29,24 @@ void esp_cpu_stall(int core_id) { - assert(core_id >= 0 && core_id < SOC_CPU_CORES_NUM); #if SOC_CPU_CORES_NUM > 1 // We don't allow stalling of the current core -#if CONFIG_IDF_TARGET_ESP32P4 - //TODO: IDF-7848 - if (core_id == 0) { - REG_SET_FIELD(PMU_CPU_SW_STALL_REG, PMU_HPCORE0_SW_STALL_CODE, 0x86); - } else { - REG_SET_FIELD(PMU_CPU_SW_STALL_REG, PMU_HPCORE1_SW_STALL_CODE, 0x86); - } -#else - /* - We need to write the value "0x86" to stall a particular core. The write location is split into two separate - bit fields named "c0" and "c1", and the two fields are located in different registers. Each core has its own pair of - "c0" and "c1" bit fields. - - Note: This function can be called when the cache is disabled. We use "ternary if" instead of an array so that the - "rodata" of the register masks/shifts will be stored in this function's "rodata" section, instead of the source - file's "rodata" section (see IDF-5214). - */ - int rtc_cntl_c0_m = (core_id == 0) ? RTC_CNTL_SW_STALL_PROCPU_C0_M : RTC_CNTL_SW_STALL_APPCPU_C0_M; - int rtc_cntl_c0_s = (core_id == 0) ? RTC_CNTL_SW_STALL_PROCPU_C0_S : RTC_CNTL_SW_STALL_APPCPU_C0_S; - int rtc_cntl_c1_m = (core_id == 0) ? RTC_CNTL_SW_STALL_PROCPU_C1_M : RTC_CNTL_SW_STALL_APPCPU_C1_M; - int rtc_cntl_c1_s = (core_id == 0) ? RTC_CNTL_SW_STALL_PROCPU_C1_S : RTC_CNTL_SW_STALL_APPCPU_C1_S; - CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, rtc_cntl_c0_m); - SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, 2 << rtc_cntl_c0_s); - CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, rtc_cntl_c1_m); - SET_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, 0x21 << rtc_cntl_c1_s); -#endif // CONFIG_IDF_TARGET_ESP32P4 + assert(core_id >= 0 && core_id < SOC_CPU_CORES_NUM); + cpu_utility_ll_stall_cpu(core_id); #endif // SOC_CPU_CORES_NUM > 1 } void esp_cpu_unstall(int core_id) { - assert(core_id >= 0 && core_id < SOC_CPU_CORES_NUM); #if SOC_CPU_CORES_NUM > 1 // We don't allow stalling of the current core -#if CONFIG_IDF_TARGET_ESP32P4 - //TODO: IDF-7848 - int pmu_core_stall_mask = (core_id == 0) ? PMU_HPCORE0_SW_STALL_CODE_M : PMU_HPCORE1_SW_STALL_CODE_M; - CLEAR_PERI_REG_MASK(PMU_CPU_SW_STALL_REG, pmu_core_stall_mask); -#else - /* - We need to write clear the value "0x86" to uninstall a particular core. The location of this value is split into - two separate bit fields named "c0" and "c1", and the two fields are located in different registers. Each core has - its own pair of "c0" and "c1" bit fields. - - Note: This function can be called when the cache is disabled. We use "ternary if" instead of an array so that the - "rodata" of the register masks/shifts will be stored in this function's "rodata" section, instead of the source - file's "rodata" section (see IDF-5214). - */ - int rtc_cntl_c0_m = (core_id == 0) ? RTC_CNTL_SW_STALL_PROCPU_C0_M : RTC_CNTL_SW_STALL_APPCPU_C0_M; - int rtc_cntl_c1_m = (core_id == 0) ? RTC_CNTL_SW_STALL_PROCPU_C1_M : RTC_CNTL_SW_STALL_APPCPU_C1_M; - CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, rtc_cntl_c0_m); - CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, rtc_cntl_c1_m); -#endif // CONFIG_IDF_TARGET_ESP32P4 + assert(core_id >= 0 && core_id < SOC_CPU_CORES_NUM); + cpu_utility_ll_unstall_cpu(core_id); #endif // SOC_CPU_CORES_NUM > 1 } void esp_cpu_reset(int core_id) { -#if CONFIG_IDF_TARGET_ESP32P4 - //TODO: IDF-7848 - if (core_id == 0) - REG_SET_BIT(LP_CLKRST_HPCPU_RESET_CTRL0_REG, LP_CLKRST_HPCORE0_SW_RESET); - else - REG_SET_BIT(LP_CLKRST_HPCPU_RESET_CTRL0_REG, LP_CLKRST_HPCORE1_SW_RESET); -#else -#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C61 // TODO: IDF-5645 - SET_PERI_REG_MASK(LP_AON_CPUCORE0_CFG_REG, LP_AON_CPU_CORE0_SW_RESET); -#else assert(core_id >= 0 && core_id < SOC_CPU_CORES_NUM); -#if SOC_CPU_CORES_NUM > 1 - /* - Note: This function can be called when the cache is disabled. We use "ternary if" instead of an array so that the - "rodata" of the register masks/shifts will be stored in this function's "rodata" section, instead of the source - file's "rodata" section (see IDF-5214). - */ - int rtc_cntl_rst_m = (core_id == 0) ? RTC_CNTL_SW_PROCPU_RST_M : RTC_CNTL_SW_APPCPU_RST_M; -#else // SOC_CPU_CORES_NUM > 1 - int rtc_cntl_rst_m = RTC_CNTL_SW_PROCPU_RST_M; -#endif // SOC_CPU_CORES_NUM > 1 - SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, rtc_cntl_rst_m); -#endif -#endif // CONFIG_IDF_TARGET_ESP32P4 + cpu_utility_ll_reset_cpu(core_id); } void esp_cpu_wait_for_intr(void) @@ -136,15 +54,11 @@ void esp_cpu_wait_for_intr(void) #if __XTENSA__ xt_utils_wait_for_intr(); #else -//TODO: IDF-7848 -#if !CONFIG_IDF_TARGET_ESP32P4 - // TODO: IDF-5645 (better to implement with ll) C6 register names converted in the #include section at the top - if (esp_cpu_dbgr_is_attached() && DPORT_REG_GET_BIT(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPU_WAIT_MODE_FORCE_ON) == 0) { + if (esp_cpu_dbgr_is_attached() && cpu_utility_ll_wait_mode() == 0) { /* when SYSTEM_CPU_WAIT_MODE_FORCE_ON is disabled in WFI mode SBA access to memory does not work for debugger, so do not enter that mode when debugger is connected */ return; } -#endif rv_utils_wait_for_intr(); #endif // __XTENSA__ } diff --git a/components/hal/esp32/include/hal/cpu_utility_ll.h b/components/hal/esp32/include/hal/cpu_utility_ll.h new file mode 100644 index 0000000000..91d762bc27 --- /dev/null +++ b/components/hal/esp32/include/hal/cpu_utility_ll.h @@ -0,0 +1,70 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include "soc/soc.h" +#include "soc/soc_caps.h" +#include "soc/rtc_cntl_reg.h" +#include "esp_attr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +FORCE_INLINE_ATTR void cpu_utility_ll_reset_cpu(uint32_t cpu_no) +{ + /* + Note: This function can be called when the cache is disabled. We use "ternary if" instead of an array so that the + "rodata" of the register masks/shifts will be stored in this function's "rodata" section, instead of the source + file's "rodata" section (see IDF-5214). + */ + uint32_t rtc_cntl_rst = (cpu_no == 0) ? RTC_CNTL_SW_PROCPU_RST_M : RTC_CNTL_SW_APPCPU_RST_M; + SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, rtc_cntl_rst); +} + +#if SOC_CPU_CORES_NUM > 1 // We only allow stalling/unstalling of other cores +FORCE_INLINE_ATTR void cpu_utility_ll_stall_cpu(uint32_t cpu_no) +{ + /* + We need to write the value "0x86" to stall a particular core. The write location is split into two separate + bit fields named "c0" and "c1", and the two fields are located in different registers. Each core has its own pair of + "c0" and "c1" bit fields. + + Note: This function can be called when the cache is disabled. We use "ternary if" instead of an array so that the + "rodata" of the register masks/shifts will be stored in this function's "rodata" section, instead of the source + file's "rodata" section (see IDF-5214). + */ + uint32_t rtc_cntl_c0_m = (cpu_no == 0) ? RTC_CNTL_SW_STALL_PROCPU_C0_M : RTC_CNTL_SW_STALL_APPCPU_C0_M; + uint32_t rtc_cntl_c0_s = (cpu_no == 0) ? RTC_CNTL_SW_STALL_PROCPU_C0_S : RTC_CNTL_SW_STALL_APPCPU_C0_S; + uint32_t rtc_cntl_c1_m = (cpu_no == 0) ? RTC_CNTL_SW_STALL_PROCPU_C1_M : RTC_CNTL_SW_STALL_APPCPU_C1_M; + uint32_t rtc_cntl_c1_s = (cpu_no == 0) ? RTC_CNTL_SW_STALL_PROCPU_C1_S : RTC_CNTL_SW_STALL_APPCPU_C1_S; + CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, rtc_cntl_c0_m); + SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, 2 << rtc_cntl_c0_s); + CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, rtc_cntl_c1_m); + SET_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, 0x21 << rtc_cntl_c1_s); +} + +FORCE_INLINE_ATTR void cpu_utility_ll_unstall_cpu(uint32_t cpu_no) +{ + /* + We need to write clear the value "0x86" to unstall a particular core. The location of this value is split into + two separate bit fields named "c0" and "c1", and the two fields are located in different registers. Each core has + its own pair of "c0" and "c1" bit fields. + + Note: This function can be called when the cache is disabled. We use "ternary if" instead of an array so that the + "rodata" of the register masks/shifts will be stored in this function's "rodata" section, instead of the source + file's "rodata" section (see IDF-5214). + */ + uint32_t rtc_cntl_c0 = (cpu_no == 0) ? RTC_CNTL_SW_STALL_PROCPU_C0_M : RTC_CNTL_SW_STALL_APPCPU_C0_M; + CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, rtc_cntl_c0); + int rtc_cntl_c1 = (cpu_no == 0) ? RTC_CNTL_SW_STALL_PROCPU_C1_M : RTC_CNTL_SW_STALL_APPCPU_C1_M; + CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, rtc_cntl_c1); +} +#endif // SOC_CPU_CORES_NUM > 1 + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c2/include/hal/cpu_utility_ll.h b/components/hal/esp32c2/include/hal/cpu_utility_ll.h new file mode 100644 index 0000000000..9f1f6ebe47 --- /dev/null +++ b/components/hal/esp32c2/include/hal/cpu_utility_ll.h @@ -0,0 +1,30 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include "soc/soc.h" +#include "soc/rtc_cntl_reg.h" +#include "soc/system_reg.h" +#include "esp_attr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +FORCE_INLINE_ATTR void cpu_utility_ll_reset_cpu(uint32_t cpu_no) +{ + (void) cpu_no; + SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_PROCPU_RST); +} + +FORCE_INLINE_ATTR uint32_t cpu_utility_ll_wait_mode(void) +{ + return REG_GET_BIT(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPU_WAIT_MODE_FORCE_ON); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c3/include/hal/cpu_utility_ll.h b/components/hal/esp32c3/include/hal/cpu_utility_ll.h new file mode 100644 index 0000000000..9f1f6ebe47 --- /dev/null +++ b/components/hal/esp32c3/include/hal/cpu_utility_ll.h @@ -0,0 +1,30 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include "soc/soc.h" +#include "soc/rtc_cntl_reg.h" +#include "soc/system_reg.h" +#include "esp_attr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +FORCE_INLINE_ATTR void cpu_utility_ll_reset_cpu(uint32_t cpu_no) +{ + (void) cpu_no; + SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_PROCPU_RST); +} + +FORCE_INLINE_ATTR uint32_t cpu_utility_ll_wait_mode(void) +{ + return REG_GET_BIT(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPU_WAIT_MODE_FORCE_ON); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c5/include/hal/cpu_utility_ll.h b/components/hal/esp32c5/include/hal/cpu_utility_ll.h new file mode 100644 index 0000000000..ca6d4d4cac --- /dev/null +++ b/components/hal/esp32c5/include/hal/cpu_utility_ll.h @@ -0,0 +1,30 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include "soc/soc.h" +#include "soc/lp_aon_reg.h" +#include "soc/pcr_reg.h" +#include "esp_attr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +FORCE_INLINE_ATTR void cpu_utility_ll_reset_cpu(uint32_t cpu_no) +{ + (void) cpu_no; + SET_PERI_REG_MASK(LP_AON_CPUCORE0_CFG_REG, LP_AON_CPU_CORE0_SW_RESET); +} + +FORCE_INLINE_ATTR uint32_t cpu_utility_ll_wait_mode(void) +{ + return REG_GET_BIT(PCR_CPU_WAITI_CONF_REG, PCR_CPU_WAIT_MODE_FORCE_ON); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/cpu_utility_ll.h b/components/hal/esp32c6/include/hal/cpu_utility_ll.h new file mode 100644 index 0000000000..ca6d4d4cac --- /dev/null +++ b/components/hal/esp32c6/include/hal/cpu_utility_ll.h @@ -0,0 +1,30 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include "soc/soc.h" +#include "soc/lp_aon_reg.h" +#include "soc/pcr_reg.h" +#include "esp_attr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +FORCE_INLINE_ATTR void cpu_utility_ll_reset_cpu(uint32_t cpu_no) +{ + (void) cpu_no; + SET_PERI_REG_MASK(LP_AON_CPUCORE0_CFG_REG, LP_AON_CPU_CORE0_SW_RESET); +} + +FORCE_INLINE_ATTR uint32_t cpu_utility_ll_wait_mode(void) +{ + return REG_GET_BIT(PCR_CPU_WAITI_CONF_REG, PCR_CPU_WAIT_MODE_FORCE_ON); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c61/include/hal/cpu_utility_ll.h b/components/hal/esp32c61/include/hal/cpu_utility_ll.h new file mode 100644 index 0000000000..ca6d4d4cac --- /dev/null +++ b/components/hal/esp32c61/include/hal/cpu_utility_ll.h @@ -0,0 +1,30 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include "soc/soc.h" +#include "soc/lp_aon_reg.h" +#include "soc/pcr_reg.h" +#include "esp_attr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +FORCE_INLINE_ATTR void cpu_utility_ll_reset_cpu(uint32_t cpu_no) +{ + (void) cpu_no; + SET_PERI_REG_MASK(LP_AON_CPUCORE0_CFG_REG, LP_AON_CPU_CORE0_SW_RESET); +} + +FORCE_INLINE_ATTR uint32_t cpu_utility_ll_wait_mode(void) +{ + return REG_GET_BIT(PCR_CPU_WAITI_CONF_REG, PCR_CPU_WAIT_MODE_FORCE_ON); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32h2/include/hal/cpu_utility_ll.h b/components/hal/esp32h2/include/hal/cpu_utility_ll.h new file mode 100644 index 0000000000..ca6d4d4cac --- /dev/null +++ b/components/hal/esp32h2/include/hal/cpu_utility_ll.h @@ -0,0 +1,30 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include "soc/soc.h" +#include "soc/lp_aon_reg.h" +#include "soc/pcr_reg.h" +#include "esp_attr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +FORCE_INLINE_ATTR void cpu_utility_ll_reset_cpu(uint32_t cpu_no) +{ + (void) cpu_no; + SET_PERI_REG_MASK(LP_AON_CPUCORE0_CFG_REG, LP_AON_CPU_CORE0_SW_RESET); +} + +FORCE_INLINE_ATTR uint32_t cpu_utility_ll_wait_mode(void) +{ + return REG_GET_BIT(PCR_CPU_WAITI_CONF_REG, PCR_CPU_WAIT_MODE_FORCE_ON); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32p4/include/hal/cpu_utility_ll.h b/components/hal/esp32p4/include/hal/cpu_utility_ll.h new file mode 100644 index 0000000000..5c6b606488 --- /dev/null +++ b/components/hal/esp32p4/include/hal/cpu_utility_ll.h @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include "soc/soc.h" +#include "soc/soc_caps.h" +#include "soc/lp_clkrst_struct.h" +#include "soc/pmu_struct.h" +#include "soc/hp_system_reg.h" +#include "esp_attr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +FORCE_INLINE_ATTR void cpu_utility_ll_reset_cpu(uint32_t cpu_no) +{ + if (cpu_no == 0) { + LP_AON_CLKRST.hpcpu_reset_ctrl0.hpcore0_sw_reset = 1; + } else { + LP_AON_CLKRST.hpcpu_reset_ctrl0.hpcore1_sw_reset = 1; + } +} + +#if SOC_CPU_CORES_NUM > 1 // We only allow stalling/unstalling of other cores +FORCE_INLINE_ATTR void cpu_utility_ll_stall_cpu(uint32_t cpu_no) +{ + if (cpu_no == 0) { + PMU.cpu_sw_stall.hpcore0_stall_code = 0x86; + } else { + PMU.cpu_sw_stall.hpcore1_stall_code = 0x86; + } +} + +FORCE_INLINE_ATTR void cpu_utility_ll_unstall_cpu(uint32_t cpu_no) +{ + if (cpu_no == 0) { + PMU.cpu_sw_stall.hpcore0_stall_code = 0xFF; + } else { + PMU.cpu_sw_stall.hpcore1_stall_code = 0xFF; + } +} +#endif // SOC_CPU_CORES_NUM > 1 + +FORCE_INLINE_ATTR uint32_t cpu_utility_ll_wait_mode(void) +{ + return REG_GET_BIT(HP_SYSTEM_CPU_WAITI_CONF_REG, HP_SYSTEM_CPU_WAIT_MODE_FORCE_ON); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32s2/include/hal/cpu_utility_ll.h b/components/hal/esp32s2/include/hal/cpu_utility_ll.h new file mode 100644 index 0000000000..b642446455 --- /dev/null +++ b/components/hal/esp32s2/include/hal/cpu_utility_ll.h @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include "soc/soc.h" +#include "soc/rtc_cntl_reg.h" +#include "esp_attr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +FORCE_INLINE_ATTR void cpu_utility_ll_reset_cpu(uint32_t cpu_no) +{ + (void) cpu_no; + SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_PROCPU_RST); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32s3/include/hal/cpu_utility_ll.h b/components/hal/esp32s3/include/hal/cpu_utility_ll.h new file mode 100644 index 0000000000..91d762bc27 --- /dev/null +++ b/components/hal/esp32s3/include/hal/cpu_utility_ll.h @@ -0,0 +1,70 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include "soc/soc.h" +#include "soc/soc_caps.h" +#include "soc/rtc_cntl_reg.h" +#include "esp_attr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +FORCE_INLINE_ATTR void cpu_utility_ll_reset_cpu(uint32_t cpu_no) +{ + /* + Note: This function can be called when the cache is disabled. We use "ternary if" instead of an array so that the + "rodata" of the register masks/shifts will be stored in this function's "rodata" section, instead of the source + file's "rodata" section (see IDF-5214). + */ + uint32_t rtc_cntl_rst = (cpu_no == 0) ? RTC_CNTL_SW_PROCPU_RST_M : RTC_CNTL_SW_APPCPU_RST_M; + SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, rtc_cntl_rst); +} + +#if SOC_CPU_CORES_NUM > 1 // We only allow stalling/unstalling of other cores +FORCE_INLINE_ATTR void cpu_utility_ll_stall_cpu(uint32_t cpu_no) +{ + /* + We need to write the value "0x86" to stall a particular core. The write location is split into two separate + bit fields named "c0" and "c1", and the two fields are located in different registers. Each core has its own pair of + "c0" and "c1" bit fields. + + Note: This function can be called when the cache is disabled. We use "ternary if" instead of an array so that the + "rodata" of the register masks/shifts will be stored in this function's "rodata" section, instead of the source + file's "rodata" section (see IDF-5214). + */ + uint32_t rtc_cntl_c0_m = (cpu_no == 0) ? RTC_CNTL_SW_STALL_PROCPU_C0_M : RTC_CNTL_SW_STALL_APPCPU_C0_M; + uint32_t rtc_cntl_c0_s = (cpu_no == 0) ? RTC_CNTL_SW_STALL_PROCPU_C0_S : RTC_CNTL_SW_STALL_APPCPU_C0_S; + uint32_t rtc_cntl_c1_m = (cpu_no == 0) ? RTC_CNTL_SW_STALL_PROCPU_C1_M : RTC_CNTL_SW_STALL_APPCPU_C1_M; + uint32_t rtc_cntl_c1_s = (cpu_no == 0) ? RTC_CNTL_SW_STALL_PROCPU_C1_S : RTC_CNTL_SW_STALL_APPCPU_C1_S; + CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, rtc_cntl_c0_m); + SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, 2 << rtc_cntl_c0_s); + CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, rtc_cntl_c1_m); + SET_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, 0x21 << rtc_cntl_c1_s); +} + +FORCE_INLINE_ATTR void cpu_utility_ll_unstall_cpu(uint32_t cpu_no) +{ + /* + We need to write clear the value "0x86" to unstall a particular core. The location of this value is split into + two separate bit fields named "c0" and "c1", and the two fields are located in different registers. Each core has + its own pair of "c0" and "c1" bit fields. + + Note: This function can be called when the cache is disabled. We use "ternary if" instead of an array so that the + "rodata" of the register masks/shifts will be stored in this function's "rodata" section, instead of the source + file's "rodata" section (see IDF-5214). + */ + uint32_t rtc_cntl_c0 = (cpu_no == 0) ? RTC_CNTL_SW_STALL_PROCPU_C0_M : RTC_CNTL_SW_STALL_APPCPU_C0_M; + CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, rtc_cntl_c0); + int rtc_cntl_c1 = (cpu_no == 0) ? RTC_CNTL_SW_STALL_PROCPU_C1_M : RTC_CNTL_SW_STALL_APPCPU_C1_M; + CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, rtc_cntl_c1); +} +#endif // SOC_CPU_CORES_NUM > 1 + +#ifdef __cplusplus +} +#endif diff --git a/components/riscv/include/riscv/rv_utils.h b/components/riscv/include/riscv/rv_utils.h index 722489b765..8da17ec510 100644 --- a/components/riscv/include/riscv/rv_utils.h +++ b/components/riscv/include/riscv/rv_utils.h @@ -19,10 +19,12 @@ extern "C" { #endif +#if SOC_CPU_HAS_CSR_PC /*performance counter*/ #define CSR_PCER_MACHINE 0x7e0 #define CSR_PCMR_MACHINE 0x7e1 #define CSR_PCCR_MACHINE 0x7e2 +#endif /* SOC_CPU_HAS_CSR_PC */ #if SOC_CPU_HAS_FPU @@ -97,8 +99,7 @@ FORCE_INLINE_ATTR void *rv_utils_get_sp(void) FORCE_INLINE_ATTR uint32_t __attribute__((always_inline)) rv_utils_get_cycle_count(void) { -#if SOC_INT_CLIC_SUPPORTED - //TODO: IDF-7848 +#if !SOC_CPU_HAS_CSR_PC return RV_READ_CSR(mcycle); #else return RV_READ_CSR(CSR_PCCR_MACHINE); @@ -107,8 +108,7 @@ FORCE_INLINE_ATTR uint32_t __attribute__((always_inline)) rv_utils_get_cycle_cou FORCE_INLINE_ATTR void __attribute__((always_inline)) rv_utils_set_cycle_count(uint32_t ccount) { -#if SOC_INT_CLIC_SUPPORTED - //TODO: IDF-7848 +#if !SOC_CPU_HAS_CSR_PC RV_WRITE_CSR(mcycle, ccount); #else RV_WRITE_CSR(CSR_PCCR_MACHINE, ccount); @@ -238,8 +238,8 @@ FORCE_INLINE_ATTR void __attribute__((always_inline)) rv_utils_restore_intlevel_ * By executing ~8 nop instructions, or by performing a memory load right now, the previous memory write * operations is forced, making the new threshold active. * - * Without this we risk executing the next several instrucitons before getting interrupted - * This is especially bad if we immediatly enter a new critical section + * Without this we risk executing the next several instructions before getting interrupted + * This is especially bad if we immediately enter a new critical section */ REG_READ(CLIC_INT_THRESH_REG); } @@ -353,8 +353,8 @@ FORCE_INLINE_ATTR void rv_utils_disable_fpu(void) FORCE_INLINE_ATTR void rv_utils_set_breakpoint(int bp_num, uint32_t bp_addr) { - /* The code bellow sets breakpoint which will trigger `Breakpoint` exception - * instead transfering control to debugger. */ + /* The code below sets breakpoint which will trigger `Breakpoint` exception + * instead transferring control to debugger. */ RV_WRITE_CSR(tselect, bp_num); RV_WRITE_CSR(tcontrol, TCONTROL_MPTE | TCONTROL_MTE); RV_WRITE_CSR(tdata1, TDATA1_USER | TDATA1_MACHINE | TDATA1_EXECUTE); diff --git a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in index 6ec5f77a73..8070cc1caa 100644 --- a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in @@ -235,6 +235,10 @@ config SOC_CPU_HAS_FLEXIBLE_INTC bool default y +config SOC_CPU_HAS_CSR_PC + bool + default y + config SOC_CPU_BREAKPOINTS_NUM int default 2 diff --git a/components/soc/esp32c2/include/soc/soc_caps.h b/components/soc/esp32c2/include/soc/soc_caps.h index 5c37049f98..fbc241ce76 100644 --- a/components/soc/esp32c2/include/soc/soc_caps.h +++ b/components/soc/esp32c2/include/soc/soc_caps.h @@ -97,6 +97,7 @@ #define SOC_CPU_CORES_NUM (1U) #define SOC_CPU_INTR_NUM 32 #define SOC_CPU_HAS_FLEXIBLE_INTC 1 +#define SOC_CPU_HAS_CSR_PC 1 #define SOC_CPU_BREAKPOINTS_NUM 2 #define SOC_CPU_WATCHPOINTS_NUM 2 diff --git a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in index 768f815ee0..114b541887 100644 --- a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in @@ -323,6 +323,10 @@ config SOC_CPU_HAS_FLEXIBLE_INTC bool default y +config SOC_CPU_HAS_CSR_PC + bool + default y + config SOC_CPU_BREAKPOINTS_NUM int default 8 diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index bf66d1a0d1..721fa33383 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -129,6 +129,7 @@ #define SOC_CPU_CORES_NUM (1U) #define SOC_CPU_INTR_NUM 32 #define SOC_CPU_HAS_FLEXIBLE_INTC 1 +#define SOC_CPU_HAS_CSR_PC 1 #define SOC_CPU_BREAKPOINTS_NUM 8 #define SOC_CPU_WATCHPOINTS_NUM 8 diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index f60c1bf901..3c1dd57518 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -387,6 +387,10 @@ config SOC_INT_PLIC_SUPPORTED bool default y +config SOC_CPU_HAS_CSR_PC + bool + default y + config SOC_CPU_BREAKPOINTS_NUM int default 4 diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index f1387e3a62..1d5380c8ff 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -145,6 +145,7 @@ #define SOC_CPU_INTR_NUM 32 #define SOC_CPU_HAS_FLEXIBLE_INTC 1 #define SOC_INT_PLIC_SUPPORTED 1 //riscv platform-level interrupt controller +#define SOC_CPU_HAS_CSR_PC 1 #define SOC_CPU_BREAKPOINTS_NUM 4 #define SOC_CPU_WATCHPOINTS_NUM 4 diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index f80723f609..ffccb5477e 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -375,6 +375,10 @@ config SOC_INT_PLIC_SUPPORTED bool default y +config SOC_CPU_HAS_CSR_PC + bool + default y + config SOC_CPU_BREAKPOINTS_NUM int default 4 diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index b4bba2c1dc..7940868d6c 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -142,6 +142,7 @@ #define SOC_CPU_INTR_NUM 32 #define SOC_CPU_HAS_FLEXIBLE_INTC 1 #define SOC_INT_PLIC_SUPPORTED 1 //riscv platform-level interrupt controller +#define SOC_CPU_HAS_CSR_PC 1 #define SOC_CPU_BREAKPOINTS_NUM 4 #define SOC_CPU_WATCHPOINTS_NUM 4