mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
feat(hal): Adds hal funcs for cpu.c
This commit is contained in:
parent
0b5a6e33fc
commit
06c28f0ee9
@ -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
|
||||
|
@ -9,36 +9,19 @@
|
||||
#include <assert.h>
|
||||
#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__
|
||||
}
|
||||
|
70
components/hal/esp32/include/hal/cpu_utility_ll.h
Normal file
70
components/hal/esp32/include/hal/cpu_utility_ll.h
Normal file
@ -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
|
30
components/hal/esp32c2/include/hal/cpu_utility_ll.h
Normal file
30
components/hal/esp32c2/include/hal/cpu_utility_ll.h
Normal file
@ -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
|
30
components/hal/esp32c3/include/hal/cpu_utility_ll.h
Normal file
30
components/hal/esp32c3/include/hal/cpu_utility_ll.h
Normal file
@ -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
|
30
components/hal/esp32c5/include/hal/cpu_utility_ll.h
Normal file
30
components/hal/esp32c5/include/hal/cpu_utility_ll.h
Normal file
@ -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
|
30
components/hal/esp32c6/include/hal/cpu_utility_ll.h
Normal file
30
components/hal/esp32c6/include/hal/cpu_utility_ll.h
Normal file
@ -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
|
30
components/hal/esp32c61/include/hal/cpu_utility_ll.h
Normal file
30
components/hal/esp32c61/include/hal/cpu_utility_ll.h
Normal file
@ -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
|
30
components/hal/esp32h2/include/hal/cpu_utility_ll.h
Normal file
30
components/hal/esp32h2/include/hal/cpu_utility_ll.h
Normal file
@ -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
|
55
components/hal/esp32p4/include/hal/cpu_utility_ll.h
Normal file
55
components/hal/esp32p4/include/hal/cpu_utility_ll.h
Normal file
@ -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
|
24
components/hal/esp32s2/include/hal/cpu_utility_ll.h
Normal file
24
components/hal/esp32s2/include/hal/cpu_utility_ll.h
Normal file
@ -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
|
70
components/hal/esp32s3/include/hal/cpu_utility_ll.h
Normal file
70
components/hal/esp32s3/include/hal/cpu_utility_ll.h
Normal file
@ -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
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user