Merge branch 'bugfix/esp_idf_zcmp_workaround_v6.0' into 'release/v6.0'

fix(esp_hw_support): resolved setting mie to disable interrupts failed in sleep flow (v6.0)

See merge request espressif/esp-idf!43094
This commit is contained in:
Jiang Jiang Jian
2025-11-11 19:21:08 +08:00
20 changed files with 131 additions and 26 deletions
@@ -83,6 +83,7 @@ STRUCT_BEGIN
STRUCT_FIELD (long, 4, RV_SLP_CTX_MTVAL, mtval) /* Machine Trap Value */
STRUCT_FIELD (long, 4, RV_SLP_CTX_MIE, mie) /* Machine intr enable */
STRUCT_FIELD (long, 4, RV_SLP_CTX_MIP, mip) /* Machine intr pending */
STRUCT_FIELD (long, 4, RV_SLP_CTX_MINTTHRESH, mintthresh) /* Machine intr threshold */
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMUFUNC, pmufunc) /* A field is used to identify whether it is going
* to sleep or has just been awakened. We use the
@@ -173,7 +174,6 @@ STRUCT_BEGIN
STRUCT_FIELD (long, 4, RV_SLP_CTX_MCYCLE, mcycle)
STRUCT_FIELD (long, 4, RV_SLP_CTX_MTVT, mtvt)
STRUCT_FIELD (long, 4, RV_SLP_CTX_MINTTHRESH, mintthresh)
STRUCT_FIELD (long, 4, RV_SLP_CTX_MINTSTATUS, mintstatus)
STRUCT_FIELD (long, 4, RV_SLP_CTX_MXSTATUS, mxstatus)
STRUCT_FIELD (long, 4, RV_SLP_CTX_MHCR, mhcr)
@@ -60,6 +60,20 @@ FORCE_INLINE_ATTR void restore_mstatus(uint32_t mstatus_val)
RV_WRITE_CSR(mstatus, mstatus_val);
}
#if __riscv_zcmp && SOC_CPU_ZCMP_WORKAROUND
FORCE_INLINE_ATTR uint32_t save_mintthresh_and_disable_global_int(void)
{
/* Due to the reason described in IDF-14279, when mie is set to 0, mintthresh needs to be set to 0xff. */
// TODO: IDF-14279 DIG-661
return RV_READ_MINTTHRESH_AND_DISABLE_INTR();
}
FORCE_INLINE_ATTR void restore_mintthresh(uint32_t mintthresh_val)
{
RV_RESTORE_MINTTHRESH(mintthresh_val);
}
#endif
static IRAM_ATTR RvCoreNonCriticalSleepFrame * rv_core_noncritical_regs_save(void)
{
assert(s_cpu_retention.retent.non_critical_frame);
@@ -128,7 +142,6 @@ static IRAM_ATTR RvCoreNonCriticalSleepFrame * rv_core_noncritical_regs_save(voi
frame->mcycle = RV_READ_CSR(mcycle);
frame->mtvt = RV_READ_CSR(CUSTOM_CSR_MTVT);
frame->mintthresh = RV_READ_CSR(CUSTOM_CSR_MINTTHRESH);
frame->mxstatus = RV_READ_CSR(CUSTOM_CSR_MXSTATUS);
frame->mhcr = RV_READ_CSR(CUSTOM_CSR_MHCR);
frame->mhint = RV_READ_CSR(CUSTOM_CSR_MHINT);
@@ -203,7 +216,6 @@ static IRAM_ATTR void rv_core_noncritical_regs_restore(RvCoreNonCriticalSleepFra
RV_WRITE_CSR(mcycle, frame->mcycle);
RV_WRITE_CSR(CUSTOM_CSR_MTVT, frame->mtvt);
RV_WRITE_CSR(CUSTOM_CSR_MINTTHRESH, frame->mintthresh);
RV_WRITE_CSR(CUSTOM_CSR_MXSTATUS, frame->mxstatus);
RV_WRITE_CSR(CUSTOM_CSR_MHCR, frame->mhcr);
RV_WRITE_CSR(CUSTOM_CSR_MHINT, frame->mhint);
@@ -275,14 +287,14 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep,
esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_CPU_TO_MEM_END, (void *)0);
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
/* Minus 2 * sizeof(long) is for bypass `pmufunc` and `frame_crc` field */
update_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_FRMSZ - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
update_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_SZ1 - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
#endif
REG_WRITE(RTC_SLEEP_WAKE_STUB_ADDR_REG, (uint32_t)rv_core_critical_regs_restore);
return (*goto_sleep)(wakeup_opt, reject_opt, lslp_mem_inf_fpu, dslp);
}
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
else {
validate_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_FRMSZ - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
validate_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_SZ1 - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
}
#endif
@@ -294,6 +306,9 @@ esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uin
{
esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_CPU_TO_MEM_START, (void *)0);
uint32_t mstatus = save_mstatus_and_disable_global_int();
#if __riscv_zcmp && SOC_CPU_ZCMP_WORKAROUND
uint32_t mintthresh = save_mintthresh_and_disable_global_int();
#endif
cpu_domain_dev_regs_save(s_cpu_retention.retent.clic_frame);
cpu_domain_dev_regs_save(s_cpu_retention.retent.clint_frame);
@@ -314,6 +329,9 @@ esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uin
cpu_domain_dev_regs_restore(s_cpu_retention.retent.cache_config_frame);
cpu_domain_dev_regs_restore(s_cpu_retention.retent.clint_frame);
cpu_domain_dev_regs_restore(s_cpu_retention.retent.clic_frame);
#if __riscv_zcmp && SOC_CPU_ZCMP_WORKAROUND
restore_mintthresh(mintthresh);
#endif
restore_mstatus(mstatus);
return err;
}
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -8,6 +8,7 @@
#include "rvsleep-frames.h"
#include "soc/soc_caps.h"
#include "sdkconfig.h"
#include "riscv/csr_clic.h"
.section .data1,"aw"
.global rv_core_critical_regs_frame
@@ -91,6 +92,8 @@ rv_core_critical_regs_save:
sw t3, RV_SLP_CTX_MIP(t0)
csrr t1, mepc
sw t1, RV_SLP_CTX_MEPC(t0)
csrr t2, MINTTHRESH_CSR
sw t2, RV_SLP_CTX_MINTTHRESH(t0)
/*
!!! Let idf knows it's going to sleep !!!
@@ -162,6 +165,8 @@ rv_core_critical_regs_restore:
ori t1, t1, 0x3
sw t1, RV_SLP_CTX_PMUFUNC(t0)
lw t2, RV_SLP_CTX_MINTTHRESH(t0)
csrw MINTTHRESH_CSR, t2
lw t2, RV_SLP_CTX_MEPC(t0)
csrw mepc, t2
lw t3, RV_SLP_CTX_MIP(t0)
@@ -295,14 +295,14 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep,
esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_CPU_TO_MEM_END, (void *)0);
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
/* Minus 2 * sizeof(long) is for bypass `pmufunc` and `frame_crc` field */
update_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_FRMSZ - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
update_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_SZ1 - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
#endif
REG_WRITE(RTC_SLEEP_WAKE_STUB_ADDR_REG, (uint32_t)rv_core_critical_regs_restore);
return (*goto_sleep)(wakeup_opt, reject_opt, lslp_mem_inf_fpu, dslp);
}
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
else {
validate_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_FRMSZ - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
validate_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_SZ1 - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
}
#endif
@@ -83,6 +83,7 @@ STRUCT_BEGIN
STRUCT_FIELD (long, 4, RV_SLP_CTX_MTVAL, mtval) /* Machine Trap Value */
STRUCT_FIELD (long, 4, RV_SLP_CTX_MIE, mie) /* Machine intr enable */
STRUCT_FIELD (long, 4, RV_SLP_CTX_MIP, mip) /* Machine intr pending */
STRUCT_FIELD (long, 4, RV_SLP_CTX_MINTTHRESH, mintthresh) /* Machine intr threshold */
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMUFUNC, pmufunc) /* A field is used to identify whether it is going
* to sleep or has just been awakened. We use the
@@ -173,7 +174,6 @@ STRUCT_BEGIN
STRUCT_FIELD (long, 4, RV_SLP_CTX_MCYCLE, mcycle)
STRUCT_FIELD (long, 4, RV_SLP_CTX_MTVT, mtvt)
STRUCT_FIELD (long, 4, RV_SLP_CTX_MINTTHRESH, mintthresh)
STRUCT_FIELD (long, 4, RV_SLP_CTX_MINTSTATUS, mintstatus)
STRUCT_FIELD (long, 4, RV_SLP_CTX_MXSTATUS, mxstatus)
STRUCT_FIELD (long, 4, RV_SLP_CTX_MHCR, mhcr)
@@ -60,6 +60,20 @@ FORCE_INLINE_ATTR void restore_mstatus(uint32_t mstatus_val)
RV_WRITE_CSR(mstatus, mstatus_val);
}
#if __riscv_zcmp && SOC_CPU_ZCMP_WORKAROUND
FORCE_INLINE_ATTR uint32_t save_mintthresh_and_disable_global_int(void)
{
/* Due to the reason described in IDF-14279, when mie is set to 0, mintthresh needs to be set to 0xff. */
// TODO: IDF-14279 DIG-661
return RV_READ_MINTTHRESH_AND_DISABLE_INTR();
}
FORCE_INLINE_ATTR void restore_mintthresh(uint32_t mintthresh_val)
{
RV_RESTORE_MINTTHRESH(mintthresh_val);
}
#endif
static IRAM_ATTR RvCoreNonCriticalSleepFrame * rv_core_noncritical_regs_save(void)
{
assert(s_cpu_retention.retent.non_critical_frame);
@@ -128,7 +142,6 @@ static IRAM_ATTR RvCoreNonCriticalSleepFrame * rv_core_noncritical_regs_save(voi
frame->mcycle = RV_READ_CSR(mcycle);
frame->mtvt = RV_READ_CSR(CUSTOM_CSR_MTVT);
frame->mintthresh = RV_READ_CSR(CUSTOM_CSR_MINTTHRESH);
frame->mxstatus = RV_READ_CSR(CUSTOM_CSR_MXSTATUS);
frame->mhcr = RV_READ_CSR(CUSTOM_CSR_MHCR);
frame->mhint = RV_READ_CSR(CUSTOM_CSR_MHINT);
@@ -203,7 +216,6 @@ static IRAM_ATTR void rv_core_noncritical_regs_restore(RvCoreNonCriticalSleepFra
RV_WRITE_CSR(mcycle, frame->mcycle);
RV_WRITE_CSR(CUSTOM_CSR_MTVT, frame->mtvt);
RV_WRITE_CSR(CUSTOM_CSR_MINTTHRESH, frame->mintthresh);
RV_WRITE_CSR(CUSTOM_CSR_MXSTATUS, frame->mxstatus);
RV_WRITE_CSR(CUSTOM_CSR_MHCR, frame->mhcr);
RV_WRITE_CSR(CUSTOM_CSR_MHINT, frame->mhint);
@@ -275,14 +287,14 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep,
esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_CPU_TO_MEM_END, (void *)0);
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
/* Minus 2 * sizeof(long) is for bypass `pmufunc` and `frame_crc` field */
update_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_FRMSZ - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
update_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_SZ1 - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
#endif
REG_WRITE(RTC_SLEEP_WAKE_STUB_ADDR_REG, (uint32_t)rv_core_critical_regs_restore);
return (*goto_sleep)(wakeup_opt, reject_opt, lslp_mem_inf_fpu, dslp);
}
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
else {
validate_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_FRMSZ - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
validate_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_SZ1 - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
}
#endif
@@ -294,6 +306,9 @@ esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uin
{
esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_CPU_TO_MEM_START, (void *)0);
uint32_t mstatus = save_mstatus_and_disable_global_int();
#if __riscv_zcmp && SOC_CPU_ZCMP_WORKAROUND
uint32_t mintthresh = save_mintthresh_and_disable_global_int();
#endif
cpu_domain_dev_regs_save(s_cpu_retention.retent.clic_frame);
cpu_domain_dev_regs_save(s_cpu_retention.retent.clint_frame);
@@ -314,6 +329,9 @@ esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uin
cpu_domain_dev_regs_restore(s_cpu_retention.retent.cache_config_frame);
cpu_domain_dev_regs_restore(s_cpu_retention.retent.clint_frame);
cpu_domain_dev_regs_restore(s_cpu_retention.retent.clic_frame);
#if __riscv_zcmp && SOC_CPU_ZCMP_WORKAROUND
restore_mintthresh(mintthresh);
#endif
restore_mstatus(mstatus);
return err;
}
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -8,6 +8,7 @@
#include "rvsleep-frames.h"
#include "soc/soc_caps.h"
#include "sdkconfig.h"
#include "riscv/csr_clic.h"
.section .data1,"aw"
.global rv_core_critical_regs_frame
@@ -91,6 +92,8 @@ rv_core_critical_regs_save:
sw t3, RV_SLP_CTX_MIP(t0)
csrr t1, mepc
sw t1, RV_SLP_CTX_MEPC(t0)
csrr t2, MINTTHRESH_CSR
sw t2, RV_SLP_CTX_MINTTHRESH(t0)
/*
!!! Let idf knows it's going to sleep !!!
@@ -162,6 +165,8 @@ rv_core_critical_regs_restore:
ori t1, t1, 0x3
sw t1, RV_SLP_CTX_PMUFUNC(t0)
lw t2, RV_SLP_CTX_MINTTHRESH(t0)
csrw MINTTHRESH_CSR, t2
lw t2, RV_SLP_CTX_MEPC(t0)
csrw mepc, t2
lw t3, RV_SLP_CTX_MIP(t0)
@@ -295,14 +295,14 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep,
esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_CPU_TO_MEM_END, (void *)0);
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
/* Minus 2 * sizeof(long) is for bypass `pmufunc` and `frame_crc` field */
update_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_FRMSZ - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
update_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_SZ1 - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
#endif
REG_WRITE(RTC_SLEEP_WAKE_STUB_ADDR_REG, (uint32_t)rv_core_critical_regs_restore);
return (*goto_sleep)(wakeup_opt, reject_opt, lslp_mem_inf_fpu, dslp);
}
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
else {
validate_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_FRMSZ - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
validate_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_SZ1 - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
}
#endif
@@ -294,14 +294,14 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep,
esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_CPU_TO_MEM_END, (void *)0);
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
/* Minus 2 * sizeof(long) is for bypass `pmufunc` and `frame_crc` field */
update_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_FRMSZ - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
update_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_SZ1 - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
#endif
REG_WRITE(RTC_SLEEP_WAKE_STUB_ADDR_REG, (uint32_t)rv_core_critical_regs_restore);
return (*goto_sleep)(wakeup_opt, reject_opt, lslp_mem_inf_fpu, dslp);
}
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
else {
validate_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_FRMSZ - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
validate_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_SZ1 - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
}
#endif
@@ -83,6 +83,7 @@ STRUCT_BEGIN
STRUCT_FIELD (long, 4, RV_SLP_CTX_MTVAL, mtval) /* Machine Trap Value */
STRUCT_FIELD (long, 4, RV_SLP_CTX_MIE, mie) /* Machine intr enable */
STRUCT_FIELD (long, 4, RV_SLP_CTX_MIP, mip) /* Machine intr pending */
STRUCT_FIELD (long, 4, RV_SLP_CTX_MINTTHRESH, mintthresh) /* Machine intr threshold */
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMUFUNC, pmufunc) /* A field is used to identify whether it is going
* to sleep or has just been awakened. We use the
@@ -197,7 +198,6 @@ STRUCT_BEGIN
STRUCT_FIELD (long, 4, RV_SLP_CTX_MCYCLE, mcycle)
STRUCT_FIELD (long, 4, RV_SLP_CTX_MTVT, mtvt)
STRUCT_FIELD (long, 4, RV_SLP_CTX_MINTTHRESH, mintthresh)
STRUCT_FIELD (long, 4, RV_SLP_CTX_MXSTATUS, mxstatus)
STRUCT_FIELD (long, 4, RV_SLP_CTX_MHCR, mhcr)
STRUCT_FIELD (long, 4, RV_SLP_CTX_MHINT, mhint)
@@ -71,6 +71,20 @@ FORCE_INLINE_ATTR void restore_mstatus(uint32_t mstatus_val)
RV_WRITE_CSR(mstatus, mstatus_val);
}
#if __riscv_zcmp && SOC_CPU_ZCMP_WORKAROUND
FORCE_INLINE_ATTR uint32_t save_mintthresh_and_disable_global_int(void)
{
/* Due to the reason described in IDF-14279, when mie is set to 0, mintthresh needs to be set to 0xff. */
// TODO: IDF-14279 DIG-661
return RV_READ_MINTTHRESH_AND_DISABLE_INTR();
}
FORCE_INLINE_ATTR void restore_mintthresh(uint32_t mintthresh_val)
{
RV_RESTORE_MINTTHRESH(mintthresh_val);
}
#endif
static IRAM_ATTR RvCoreNonCriticalSleepFrame * rv_core_noncritical_regs_save(void)
{
RvCoreNonCriticalSleepFrame *frame = s_cpu_retention.retent.non_critical_frame[esp_cpu_get_core_id()];
@@ -161,7 +175,6 @@ static IRAM_ATTR RvCoreNonCriticalSleepFrame * rv_core_noncritical_regs_save(voi
frame->mcycle = RV_READ_CSR(mcycle);
frame->mtvt = RV_READ_CSR(CUSTOM_CSR_MTVT);
frame->mintthresh = RV_READ_CSR(CUSTOM_CSR_MINTTHRESH);
frame->mxstatus = RV_READ_CSR(CUSTOM_CSR_MXSTATUS);
frame->mhcr = RV_READ_CSR(CUSTOM_CSR_MHCR);
frame->mhint = RV_READ_CSR(CUSTOM_CSR_MHINT);
@@ -261,7 +274,6 @@ static IRAM_ATTR void rv_core_noncritical_regs_restore(void)
RV_WRITE_CSR(mcycle, frame->mcycle);
RV_WRITE_CSR(CUSTOM_CSR_MTVT, frame->mtvt);
RV_WRITE_CSR(CUSTOM_CSR_MINTTHRESH, frame->mintthresh);
RV_WRITE_CSR(CUSTOM_CSR_MXSTATUS, frame->mxstatus);
RV_WRITE_CSR(CUSTOM_CSR_MHCR, frame->mhcr);
RV_WRITE_CSR(CUSTOM_CSR_MHINT, frame->mhint);
@@ -333,6 +345,9 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep,
__attribute__((unused)) uint8_t core_id = esp_cpu_get_core_id();
/* mstatus is core privated CSR, do it near the core critical regs restore */
uint32_t mstatus = save_mstatus_and_disable_global_int();
#if __riscv_zcmp && SOC_CPU_ZCMP_WORKAROUND
uint32_t mintthresh = save_mintthresh_and_disable_global_int();
#endif
rv_core_critical_regs_save();
RvCoreCriticalSleepFrame * frame = s_cpu_retention.retent.critical_frame[core_id];
@@ -340,7 +355,7 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep,
esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_CPU_TO_MEM_END, (void *)0);
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
/* Minus 2 * sizeof(long) is for bypass `pmufunc` and `frame_crc` field */
update_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_FRMSZ - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
update_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_SZ1 - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
#endif
REG_WRITE(RTC_SLEEP_WAKE_STUB_ADDR_REG, (uint32_t)rv_core_critical_regs_restore);
@@ -355,8 +370,11 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep,
}
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
else {
validate_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_FRMSZ - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
validate_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_SZ1 - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
}
#endif
#if __riscv_zcmp && SOC_CPU_ZCMP_WORKAROUND
restore_mintthresh(mintthresh);
#endif
restore_mstatus(mstatus);
return pmu_sleep_finish(dslp);
@@ -481,6 +499,9 @@ static IRAM_ATTR void smp_core_do_retention(void)
if (!smp_skip_retention) {
atomic_store(&s_smp_retention_state[core_id], SMP_BACKUP_START);
uint32_t mstatus = save_mstatus_and_disable_global_int();
#if __riscv_zcmp && SOC_CPU_ZCMP_WORKAROUND
uint32_t mintthresh = save_mintthresh_and_disable_global_int();
#endif
rv_core_noncritical_regs_save();
cpu_domain_dev_regs_save(s_cpu_retention.retent.clint_frame[core_id]);
cpu_domain_dev_regs_save(s_cpu_retention.retent.clic_frame[core_id]);
@@ -508,6 +529,9 @@ static IRAM_ATTR void smp_core_do_retention(void)
cpu_domain_dev_regs_restore(s_cpu_retention.retent.clic_frame[core_id]);
cpu_domain_dev_regs_restore(s_cpu_retention.retent.clint_frame[core_id]);
rv_core_noncritical_regs_restore();
#if __riscv_zcmp && SOC_CPU_ZCMP_WORKAROUND
restore_mintthresh(mintthresh);
#endif
restore_mstatus(mstatus);
atomic_store(&s_smp_retention_state[core_id], SMP_RESTORE_DONE);
}
@@ -8,7 +8,7 @@
#include "rvsleep-frames.h"
#include "freertos/FreeRTOSConfig.h"
#include "sdkconfig.h"
#include "riscv/csr_clic.h"
#include "soc/cache_reg.h"
#define CACHE_MAP_L1_CACHE_MASK (BIT(0) | BIT(1) | BIT(4))
@@ -100,6 +100,8 @@ rv_core_critical_regs_save:
sw t3, RV_SLP_CTX_MIP(t0)
csrr t1, mepc
sw t1, RV_SLP_CTX_MEPC(t0)
csrr t2, MINTTHRESH_CSR
sw t2, RV_SLP_CTX_MINTTHRESH(t0)
/*
!!! Let idf knows it's going to sleep !!!
@@ -166,6 +168,8 @@ rv_core_critical_regs_restore:
ori t1, t1, 0x3
sw t1, RV_SLP_CTX_PMUFUNC(t0)
lw t2, RV_SLP_CTX_MINTTHRESH(t0)
csrw MINTTHRESH_CSR, t2
lw t2, RV_SLP_CTX_MEPC(t0)
csrw mepc, t2
lw t3, RV_SLP_CTX_MIP(t0)
+13
View File
@@ -37,6 +37,9 @@ extern "C" {
#include <sys/param.h>
#include "encoding.h"
#include "esp_assert.h"
#if __riscv_zcmp && SOC_CPU_ZCMP_WORKAROUND
#include "riscv/csr_clic.h"
#endif
/********************************************************
Physical Memory Attributes (PMA) register fields
@@ -224,6 +227,16 @@ extern "C" {
#define RV_READ_MSTATUS_AND_DISABLE_INTR() ({ unsigned long __tmp; \
asm volatile ("csrrci %0, mstatus, 0x8" : "=r"(__tmp)); __tmp; })
#if __riscv_zcmp && SOC_CPU_ZCMP_WORKAROUND
#define RV_READ_MINTTHRESH_AND_DISABLE_INTR() ({ unsigned long __tmp; \
asm volatile ( \
"li t0, 0xff\n\t" \
"csrrw %0, %1, t0" : "=r"(__tmp) : "i"(MINTTHRESH_CSR) : "t0", "memory"); __tmp; })
#define RV_RESTORE_MINTTHRESH(val) \
asm volatile ("csrw %0, %1" :: "i"(MINTTHRESH_CSR), "r"(val) : "memory")
#endif
#define _CSR_STRINGIFY(REG) #REG /* needed so the 'reg' argument can be a macro or a register name */
#ifdef __cplusplus
+2 -2
View File
@@ -182,7 +182,7 @@
.endm
.macro mintthresh_csr_disable reg
#if __riscv_zcmp && INTTHRESH_STANDARD
#if __riscv_zcmp && SOC_CPU_ZCMP_WORKAROUND
/* Workaround for triggering an interrupt even when mstatus.mie is 0, when cm.push is called. */
li t0, 0xff
csrrw \reg, MINTTHRESH_CSR, t0
@@ -190,7 +190,7 @@
.endm
.macro mintthresh_csr_restore reg
#if __riscv_zcmp && INTTHRESH_STANDARD
#if __riscv_zcmp && SOC_CPU_ZCMP_WORKAROUND
csrw MINTTHRESH_CSR, \reg
#endif
.endm
@@ -483,6 +483,10 @@ config SOC_CPU_HAS_LOCKUP_RESET
bool
default y
config SOC_CPU_ZCMP_WORKAROUND
bool
default y
config SOC_DS_SIGNATURE_MAX_BIT_LEN
int
default 3072
@@ -182,6 +182,8 @@
#define SOC_CPU_HAS_LOCKUP_RESET 1
#define SOC_CPU_ZCMP_WORKAROUND 1
/*-------------------------- DIGITAL SIGNATURE CAPS ----------------------------------------*/
/** The maximum length of a Digital Signature in bits. */
#define SOC_DS_SIGNATURE_MAX_BIT_LEN (3072)
@@ -371,6 +371,10 @@ config SOC_CPU_HAS_LOCKUP_RESET
bool
default y
config SOC_CPU_ZCMP_WORKAROUND
bool
default y
config SOC_DMA_CAN_ACCESS_FLASH
bool
default y
@@ -149,6 +149,8 @@
#define SOC_CPU_HAS_LOCKUP_RESET 1
#define SOC_CPU_ZCMP_WORKAROUND 1
/*-------------------------- DMA Common CAPS ----------------------------------------*/
#define SOC_DMA_CAN_ACCESS_FLASH 1 /*!< DMA can access Flash memory */
@@ -239,6 +239,10 @@ config SOC_CPU_HAS_LOCKUP_RESET
bool
default y
config SOC_CPU_ZCMP_WORKAROUND
bool
default y
config SOC_DMA_CAN_ACCESS_FLASH
bool
default y
@@ -175,6 +175,8 @@
#define SOC_HP_CPU_HAS_MULTIPLE_CORES 1 // Convenience boolean macro used to determine if a target has multiple cores.
#define SOC_CPU_HAS_LOCKUP_RESET 1
#define SOC_CPU_ZCMP_WORKAROUND 1
/*-------------------------- DMA Common CAPS ----------------------------------------*/
#define SOC_DMA_CAN_ACCESS_FLASH 1 /*!< DMA can access Flash memory */