feat(hal): Adds hal funcs for cpu.c

This commit is contained in:
Konstantin Kondrashov 2024-03-14 16:21:29 +02:00
parent 0b5a6e33fc
commit 06c28f0ee9
21 changed files with 437 additions and 104 deletions

View File

@ -1,4 +1,4 @@
[codespell] [codespell]
skip = build,*.yuv,components/fatfs/src/*,alice.txt,*.rgb 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 write-changes = true

View File

@ -9,36 +9,19 @@
#include <assert.h> #include <assert.h>
#include "soc/soc.h" #include "soc/soc.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "hal/cpu_utility_ll.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 "esp_bit_defs.h" #include "esp_bit_defs.h"
#include "esp_attr.h" #include "esp_attr.h"
#include "esp_err.h" #include "esp_err.h"
#include "esp_cpu.h" #include "esp_cpu.h"
#if __XTENSA__ #if __XTENSA__
#include "xtensa/config/core-isa.h" #include "xtensa/config/core-isa.h"
#else #else // __riscv
#include "soc/system_reg.h" // For SYSTEM_CPU_PER_CONF_REG
#include "soc/dport_access.h" // For Dport access
#include "riscv/semihosting.h" #include "riscv/semihosting.h"
#endif
#if SOC_CPU_HAS_FLEXIBLE_INTC #if SOC_CPU_HAS_FLEXIBLE_INTC
#include "riscv/instruction_decode.h" #include "riscv/instruction_decode.h"
#endif #endif
#endif // __riscv
/* --------------------------------------------------- CPU Control ----------------------------------------------------- /* --------------------------------------------------- CPU Control -----------------------------------------------------
* *
@ -46,89 +29,24 @@
void esp_cpu_stall(int core_id) 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 SOC_CPU_CORES_NUM > 1 // We don't allow stalling of the current core
#if CONFIG_IDF_TARGET_ESP32P4 assert(core_id >= 0 && core_id < SOC_CPU_CORES_NUM);
//TODO: IDF-7848 cpu_utility_ll_stall_cpu(core_id);
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
#endif // SOC_CPU_CORES_NUM > 1 #endif // SOC_CPU_CORES_NUM > 1
} }
void esp_cpu_unstall(int core_id) 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 SOC_CPU_CORES_NUM > 1 // We don't allow stalling of the current core
#if CONFIG_IDF_TARGET_ESP32P4 assert(core_id >= 0 && core_id < SOC_CPU_CORES_NUM);
//TODO: IDF-7848 cpu_utility_ll_unstall_cpu(core_id);
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
#endif // SOC_CPU_CORES_NUM > 1 #endif // SOC_CPU_CORES_NUM > 1
} }
void esp_cpu_reset(int core_id) 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); assert(core_id >= 0 && core_id < SOC_CPU_CORES_NUM);
#if SOC_CPU_CORES_NUM > 1 cpu_utility_ll_reset_cpu(core_id);
/*
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
} }
void esp_cpu_wait_for_intr(void) void esp_cpu_wait_for_intr(void)
@ -136,15 +54,11 @@ void esp_cpu_wait_for_intr(void)
#if __XTENSA__ #if __XTENSA__
xt_utils_wait_for_intr(); xt_utils_wait_for_intr();
#else #else
//TODO: IDF-7848 if (esp_cpu_dbgr_is_attached() && cpu_utility_ll_wait_mode() == 0) {
#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) {
/* when SYSTEM_CPU_WAIT_MODE_FORCE_ON is disabled in WFI mode SBA access to memory does not work for debugger, /* 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 */ so do not enter that mode when debugger is connected */
return; return;
} }
#endif
rv_utils_wait_for_intr(); rv_utils_wait_for_intr();
#endif // __XTENSA__ #endif // __XTENSA__
} }

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View File

@ -19,10 +19,12 @@
extern "C" { extern "C" {
#endif #endif
#if SOC_CPU_HAS_CSR_PC
/*performance counter*/ /*performance counter*/
#define CSR_PCER_MACHINE 0x7e0 #define CSR_PCER_MACHINE 0x7e0
#define CSR_PCMR_MACHINE 0x7e1 #define CSR_PCMR_MACHINE 0x7e1
#define CSR_PCCR_MACHINE 0x7e2 #define CSR_PCCR_MACHINE 0x7e2
#endif /* SOC_CPU_HAS_CSR_PC */
#if SOC_CPU_HAS_FPU #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) FORCE_INLINE_ATTR uint32_t __attribute__((always_inline)) rv_utils_get_cycle_count(void)
{ {
#if SOC_INT_CLIC_SUPPORTED #if !SOC_CPU_HAS_CSR_PC
//TODO: IDF-7848
return RV_READ_CSR(mcycle); return RV_READ_CSR(mcycle);
#else #else
return RV_READ_CSR(CSR_PCCR_MACHINE); 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) FORCE_INLINE_ATTR void __attribute__((always_inline)) rv_utils_set_cycle_count(uint32_t ccount)
{ {
#if SOC_INT_CLIC_SUPPORTED #if !SOC_CPU_HAS_CSR_PC
//TODO: IDF-7848
RV_WRITE_CSR(mcycle, ccount); RV_WRITE_CSR(mcycle, ccount);
#else #else
RV_WRITE_CSR(CSR_PCCR_MACHINE, ccount); 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 * 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. * operations is forced, making the new threshold active.
* *
* Without this we risk executing the next several instrucitons before getting interrupted * Without this we risk executing the next several instructions before getting interrupted
* This is especially bad if we immediatly enter a new critical section * This is especially bad if we immediately enter a new critical section
*/ */
REG_READ(CLIC_INT_THRESH_REG); 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) 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 /* The code below sets breakpoint which will trigger `Breakpoint` exception
* instead transfering control to debugger. */ * instead transferring control to debugger. */
RV_WRITE_CSR(tselect, bp_num); RV_WRITE_CSR(tselect, bp_num);
RV_WRITE_CSR(tcontrol, TCONTROL_MPTE | TCONTROL_MTE); RV_WRITE_CSR(tcontrol, TCONTROL_MPTE | TCONTROL_MTE);
RV_WRITE_CSR(tdata1, TDATA1_USER | TDATA1_MACHINE | TDATA1_EXECUTE); RV_WRITE_CSR(tdata1, TDATA1_USER | TDATA1_MACHINE | TDATA1_EXECUTE);

View File

@ -235,6 +235,10 @@ config SOC_CPU_HAS_FLEXIBLE_INTC
bool bool
default y default y
config SOC_CPU_HAS_CSR_PC
bool
default y
config SOC_CPU_BREAKPOINTS_NUM config SOC_CPU_BREAKPOINTS_NUM
int int
default 2 default 2

View File

@ -97,6 +97,7 @@
#define SOC_CPU_CORES_NUM (1U) #define SOC_CPU_CORES_NUM (1U)
#define SOC_CPU_INTR_NUM 32 #define SOC_CPU_INTR_NUM 32
#define SOC_CPU_HAS_FLEXIBLE_INTC 1 #define SOC_CPU_HAS_FLEXIBLE_INTC 1
#define SOC_CPU_HAS_CSR_PC 1
#define SOC_CPU_BREAKPOINTS_NUM 2 #define SOC_CPU_BREAKPOINTS_NUM 2
#define SOC_CPU_WATCHPOINTS_NUM 2 #define SOC_CPU_WATCHPOINTS_NUM 2

View File

@ -323,6 +323,10 @@ config SOC_CPU_HAS_FLEXIBLE_INTC
bool bool
default y default y
config SOC_CPU_HAS_CSR_PC
bool
default y
config SOC_CPU_BREAKPOINTS_NUM config SOC_CPU_BREAKPOINTS_NUM
int int
default 8 default 8

View File

@ -129,6 +129,7 @@
#define SOC_CPU_CORES_NUM (1U) #define SOC_CPU_CORES_NUM (1U)
#define SOC_CPU_INTR_NUM 32 #define SOC_CPU_INTR_NUM 32
#define SOC_CPU_HAS_FLEXIBLE_INTC 1 #define SOC_CPU_HAS_FLEXIBLE_INTC 1
#define SOC_CPU_HAS_CSR_PC 1
#define SOC_CPU_BREAKPOINTS_NUM 8 #define SOC_CPU_BREAKPOINTS_NUM 8
#define SOC_CPU_WATCHPOINTS_NUM 8 #define SOC_CPU_WATCHPOINTS_NUM 8

View File

@ -387,6 +387,10 @@ config SOC_INT_PLIC_SUPPORTED
bool bool
default y default y
config SOC_CPU_HAS_CSR_PC
bool
default y
config SOC_CPU_BREAKPOINTS_NUM config SOC_CPU_BREAKPOINTS_NUM
int int
default 4 default 4

View File

@ -145,6 +145,7 @@
#define SOC_CPU_INTR_NUM 32 #define SOC_CPU_INTR_NUM 32
#define SOC_CPU_HAS_FLEXIBLE_INTC 1 #define SOC_CPU_HAS_FLEXIBLE_INTC 1
#define SOC_INT_PLIC_SUPPORTED 1 //riscv platform-level interrupt controller #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_BREAKPOINTS_NUM 4
#define SOC_CPU_WATCHPOINTS_NUM 4 #define SOC_CPU_WATCHPOINTS_NUM 4

View File

@ -375,6 +375,10 @@ config SOC_INT_PLIC_SUPPORTED
bool bool
default y default y
config SOC_CPU_HAS_CSR_PC
bool
default y
config SOC_CPU_BREAKPOINTS_NUM config SOC_CPU_BREAKPOINTS_NUM
int int
default 4 default 4

View File

@ -142,6 +142,7 @@
#define SOC_CPU_INTR_NUM 32 #define SOC_CPU_INTR_NUM 32
#define SOC_CPU_HAS_FLEXIBLE_INTC 1 #define SOC_CPU_HAS_FLEXIBLE_INTC 1
#define SOC_INT_PLIC_SUPPORTED 1 //riscv platform-level interrupt controller #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_BREAKPOINTS_NUM 4
#define SOC_CPU_WATCHPOINTS_NUM 4 #define SOC_CPU_WATCHPOINTS_NUM 4