mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
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:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user