mirror of
https://github.com/espressif/esp-idf.git
synced 2026-06-04 20:26:38 +03:00
change(esp_hw_support): support static and dynamic sleep cpu retention for esp32h21
This commit is contained in:
@@ -18,19 +18,17 @@
|
||||
#include "esp_rom_crc.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "riscv/csr.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/cache_reg.h"
|
||||
#include "soc/intpri_reg.h"
|
||||
#include "soc/plic_reg.h"
|
||||
#include "soc/rtc_periph.h"
|
||||
#include "esp_private/esp_pmu.h"
|
||||
#include "esp_private/sleep_cpu.h"
|
||||
#include "esp_private/sleep_event.h"
|
||||
|
||||
#include "esp32h21/rom/rtc.h"
|
||||
#include "esp32h21/rom/cache.h"
|
||||
#include "rvsleep-frames.h"
|
||||
#include "sleep_cpu_retention.h"
|
||||
|
||||
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
|
||||
#include "esp_private/system_internal.h"
|
||||
@@ -39,30 +37,6 @@
|
||||
|
||||
ESP_LOG_ATTR_TAG(TAG, "sleep");
|
||||
|
||||
typedef struct {
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
} cpu_domain_dev_regs_region_t;
|
||||
|
||||
typedef struct {
|
||||
cpu_domain_dev_regs_region_t *region;
|
||||
int region_num;
|
||||
uint32_t *regs_frame;
|
||||
} cpu_domain_dev_sleep_frame_t;
|
||||
|
||||
/**
|
||||
* Internal structure which holds all requested light sleep cpu retention parameters
|
||||
*/
|
||||
typedef struct {
|
||||
struct {
|
||||
RvCoreCriticalSleepFrame *critical_frame;
|
||||
RvCoreNonCriticalSleepFrame *non_critical_frame;
|
||||
cpu_domain_dev_sleep_frame_t *intpri_frame;
|
||||
cpu_domain_dev_sleep_frame_t *plic_frame;
|
||||
cpu_domain_dev_sleep_frame_t *cache_config_frame;
|
||||
} retent;
|
||||
} sleep_cpu_retention_t;
|
||||
|
||||
static DRAM_ATTR sleep_cpu_retention_t s_cpu_retention;
|
||||
|
||||
#define CUSTOM_CSR_PCER_MACHINE 0x7e0
|
||||
@@ -81,127 +55,6 @@ static DRAM_ATTR sleep_cpu_retention_t s_cpu_retention;
|
||||
|
||||
extern RvCoreCriticalSleepFrame *rv_core_critical_regs_frame;
|
||||
|
||||
static void * cpu_domain_dev_sleep_frame_alloc_and_init(const cpu_domain_dev_regs_region_t *regions, const int region_num)
|
||||
{
|
||||
const int region_sz = sizeof(cpu_domain_dev_regs_region_t) * region_num;
|
||||
int regs_frame_sz = 0;
|
||||
for (int num = 0; num < region_num; num++) {
|
||||
regs_frame_sz += regions[num].end - regions[num].start;
|
||||
}
|
||||
void *frame = heap_caps_malloc(sizeof(cpu_domain_dev_sleep_frame_t) + region_sz + regs_frame_sz, MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL);
|
||||
if (frame) {
|
||||
cpu_domain_dev_regs_region_t *region = (cpu_domain_dev_regs_region_t *)(frame + sizeof(cpu_domain_dev_sleep_frame_t));
|
||||
memcpy(region, regions, region_num * sizeof(cpu_domain_dev_regs_region_t));
|
||||
void *regs_frame = frame + sizeof(cpu_domain_dev_sleep_frame_t) + region_sz;
|
||||
memset(regs_frame, 0, regs_frame_sz);
|
||||
*(cpu_domain_dev_sleep_frame_t *)frame = (cpu_domain_dev_sleep_frame_t) {
|
||||
.region = region,
|
||||
.region_num = region_num,
|
||||
.regs_frame = (uint32_t *)regs_frame
|
||||
};
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
|
||||
static inline void * cpu_domain_intpri_sleep_frame_alloc_and_init(void)
|
||||
{
|
||||
const static cpu_domain_dev_regs_region_t regions[] = {
|
||||
{ .start = INTPRI_CORE0_CPU_INT_ENABLE_REG, .end = INTPRI_CORE0_CPU_INT_TYPE_REG + 4 },
|
||||
{ .start = INTPRI_CORE0_CPU_INT_PRI_0_REG, .end = INTPRI_CORE0_CPU_INT_THRESH_REG + 4 },
|
||||
{ .start = INTPRI_CLOCK_GATE_REG, .end = INTPRI_CORE0_CPU_INT_CLEAR_REG + 4 },
|
||||
};
|
||||
return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0]));
|
||||
}
|
||||
|
||||
static inline void * cpu_domain_cache_config_sleep_frame_alloc_and_init(void)
|
||||
{
|
||||
const static cpu_domain_dev_regs_region_t regions[] = {
|
||||
{ .start = CACHE_L1_CACHE_WRAP_AROUND_CTRL_REG, .end = CACHE_L1_CACHE_WRAP_AROUND_CTRL_REG + 4 }
|
||||
};
|
||||
return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0]));
|
||||
}
|
||||
|
||||
static inline void * cpu_domain_plic_sleep_frame_alloc_and_init(void)
|
||||
{
|
||||
const static cpu_domain_dev_regs_region_t regions[] = {
|
||||
{ .start = PLIC_MXINT_ENABLE_REG, .end = PLIC_MXINT_CLAIM_REG + 4 },
|
||||
{ .start = PLIC_MXINT_CONF_REG, .end = PLIC_MXINT_CONF_REG + 4 },
|
||||
{ .start = PLIC_UXINT_ENABLE_REG, .end = PLIC_UXINT_CLAIM_REG + 4 },
|
||||
{ .start = PLIC_UXINT_CONF_REG, .end = PLIC_UXINT_CONF_REG + 4 }
|
||||
};
|
||||
return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0]));
|
||||
}
|
||||
|
||||
static esp_err_t esp_sleep_cpu_retention_init_impl(void)
|
||||
{
|
||||
if (s_cpu_retention.retent.critical_frame == NULL) {
|
||||
void *frame = heap_caps_calloc(1, RV_SLEEP_CTX_FRMSZ, MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL);
|
||||
if (frame == NULL) {
|
||||
goto err;
|
||||
}
|
||||
s_cpu_retention.retent.critical_frame = (RvCoreCriticalSleepFrame *)frame;
|
||||
rv_core_critical_regs_frame = (RvCoreCriticalSleepFrame *)frame;
|
||||
}
|
||||
if (s_cpu_retention.retent.non_critical_frame == NULL) {
|
||||
void *frame = heap_caps_calloc(1, sizeof(RvCoreNonCriticalSleepFrame), MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL);
|
||||
if (frame == NULL) {
|
||||
goto err;
|
||||
}
|
||||
s_cpu_retention.retent.non_critical_frame = (RvCoreNonCriticalSleepFrame *)frame;
|
||||
}
|
||||
if (s_cpu_retention.retent.intpri_frame == NULL) {
|
||||
void *frame = cpu_domain_intpri_sleep_frame_alloc_and_init();
|
||||
if (frame == NULL) {
|
||||
goto err;
|
||||
}
|
||||
s_cpu_retention.retent.intpri_frame = (cpu_domain_dev_sleep_frame_t *)frame;
|
||||
}
|
||||
if (s_cpu_retention.retent.cache_config_frame == NULL) {
|
||||
void *frame = cpu_domain_cache_config_sleep_frame_alloc_and_init();
|
||||
if (frame == NULL) {
|
||||
goto err;
|
||||
}
|
||||
s_cpu_retention.retent.cache_config_frame = (cpu_domain_dev_sleep_frame_t *)frame;
|
||||
}
|
||||
if (s_cpu_retention.retent.plic_frame == NULL) {
|
||||
void *frame = cpu_domain_plic_sleep_frame_alloc_and_init();
|
||||
if (frame == NULL) {
|
||||
goto err;
|
||||
}
|
||||
s_cpu_retention.retent.plic_frame = (cpu_domain_dev_sleep_frame_t *)frame;
|
||||
}
|
||||
return ESP_OK;
|
||||
err:
|
||||
esp_sleep_cpu_retention_deinit();
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
static esp_err_t esp_sleep_cpu_retention_deinit_impl(void)
|
||||
{
|
||||
if (s_cpu_retention.retent.critical_frame) {
|
||||
heap_caps_free((void *)s_cpu_retention.retent.critical_frame);
|
||||
s_cpu_retention.retent.critical_frame = NULL;
|
||||
rv_core_critical_regs_frame = NULL;
|
||||
}
|
||||
if (s_cpu_retention.retent.non_critical_frame) {
|
||||
heap_caps_free((void *)s_cpu_retention.retent.non_critical_frame);
|
||||
s_cpu_retention.retent.non_critical_frame = NULL;
|
||||
}
|
||||
if (s_cpu_retention.retent.intpri_frame) {
|
||||
heap_caps_free((void *)s_cpu_retention.retent.intpri_frame);
|
||||
s_cpu_retention.retent.intpri_frame = NULL;
|
||||
}
|
||||
if (s_cpu_retention.retent.cache_config_frame) {
|
||||
heap_caps_free((void *)s_cpu_retention.retent.cache_config_frame);
|
||||
s_cpu_retention.retent.cache_config_frame = NULL;
|
||||
}
|
||||
if (s_cpu_retention.retent.plic_frame) {
|
||||
heap_caps_free((void *)s_cpu_retention.retent.plic_frame);
|
||||
s_cpu_retention.retent.plic_frame = NULL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint32_t save_mstatus_and_disable_global_int(void)
|
||||
{
|
||||
return RV_READ_MSTATUS_AND_DISABLE_INTR();
|
||||
@@ -487,12 +340,12 @@ esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uin
|
||||
|
||||
esp_err_t esp_sleep_cpu_retention_init(void)
|
||||
{
|
||||
return esp_sleep_cpu_retention_init_impl();
|
||||
return esp_sleep_cpu_retention_init_impl(& s_cpu_retention);
|
||||
}
|
||||
|
||||
esp_err_t esp_sleep_cpu_retention_deinit(void)
|
||||
{
|
||||
return esp_sleep_cpu_retention_deinit_impl();
|
||||
return esp_sleep_cpu_retention_deinit_impl(& s_cpu_retention);
|
||||
}
|
||||
|
||||
bool cpu_domain_pd_allowed(void)
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "esp_check.h"
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
#include "soc/intpri_reg.h"
|
||||
#include "soc/cache_reg.h"
|
||||
#include "soc/plic_reg.h"
|
||||
#include "esp_sleep.h"
|
||||
|
||||
#include "rvsleep-frames.h"
|
||||
#include "sleep_cpu_retention.h"
|
||||
|
||||
|
||||
extern RvCoreCriticalSleepFrame *rv_core_critical_regs_frame;
|
||||
|
||||
static void * cpu_domain_dev_sleep_frame_alloc_and_init(const cpu_domain_dev_regs_region_t *regions, const int region_num)
|
||||
{
|
||||
const int region_sz = sizeof(cpu_domain_dev_regs_region_t) * region_num;
|
||||
int regs_frame_sz = 0;
|
||||
for (int num = 0; num < region_num; num++) {
|
||||
regs_frame_sz += regions[num].end - regions[num].start;
|
||||
}
|
||||
void *frame = heap_caps_malloc(sizeof(cpu_domain_dev_sleep_frame_t) + region_sz + regs_frame_sz, MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL);
|
||||
if (frame) {
|
||||
cpu_domain_dev_regs_region_t *region = (cpu_domain_dev_regs_region_t *)(frame + sizeof(cpu_domain_dev_sleep_frame_t));
|
||||
memcpy(region, regions, region_num * sizeof(cpu_domain_dev_regs_region_t));
|
||||
void *regs_frame = frame + sizeof(cpu_domain_dev_sleep_frame_t) + region_sz;
|
||||
memset(regs_frame, 0, regs_frame_sz);
|
||||
*(cpu_domain_dev_sleep_frame_t *)frame = (cpu_domain_dev_sleep_frame_t) {
|
||||
.region = region,
|
||||
.region_num = region_num,
|
||||
.regs_frame = (uint32_t *)regs_frame
|
||||
};
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
|
||||
static inline void * cpu_domain_intpri_sleep_frame_alloc_and_init(void)
|
||||
{
|
||||
const static cpu_domain_dev_regs_region_t regions[] = {
|
||||
{ .start = INTPRI_CORE0_CPU_INT_ENABLE_REG, .end = INTPRI_CORE0_CPU_INT_TYPE_REG + 4 },
|
||||
{ .start = INTPRI_CORE0_CPU_INT_PRI_0_REG, .end = INTPRI_CORE0_CPU_INT_THRESH_REG + 4 },
|
||||
{ .start = INTPRI_CLOCK_GATE_REG, .end = INTPRI_CORE0_CPU_INT_CLEAR_REG + 4 },
|
||||
};
|
||||
return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0]));
|
||||
}
|
||||
|
||||
static inline void * cpu_domain_cache_config_sleep_frame_alloc_and_init(void)
|
||||
{
|
||||
const static cpu_domain_dev_regs_region_t regions[] = {
|
||||
{ .start = CACHE_L1_CACHE_WRAP_AROUND_CTRL_REG, .end = CACHE_L1_CACHE_WRAP_AROUND_CTRL_REG + 4 }
|
||||
};
|
||||
return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0]));
|
||||
}
|
||||
|
||||
static inline void * cpu_domain_plic_sleep_frame_alloc_and_init(void)
|
||||
{
|
||||
const static cpu_domain_dev_regs_region_t regions[] = {
|
||||
{ .start = PLIC_MXINT_ENABLE_REG, .end = PLIC_MXINT_CLAIM_REG + 4 },
|
||||
{ .start = PLIC_MXINT_CONF_REG, .end = PLIC_MXINT_CONF_REG + 4 },
|
||||
{ .start = PLIC_UXINT_ENABLE_REG, .end = PLIC_UXINT_CLAIM_REG + 4 },
|
||||
{ .start = PLIC_UXINT_CONF_REG, .end = PLIC_UXINT_CONF_REG + 4 }
|
||||
};
|
||||
return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0]));
|
||||
}
|
||||
|
||||
esp_err_t esp_sleep_cpu_retention_init_impl(sleep_cpu_retention_t *sleep_cpu_retention_ptr)
|
||||
{
|
||||
if (sleep_cpu_retention_ptr->retent.critical_frame == NULL) {
|
||||
void *frame = heap_caps_calloc(1, RV_SLEEP_CTX_FRMSZ, MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL);
|
||||
if (frame == NULL) {
|
||||
goto err;
|
||||
}
|
||||
sleep_cpu_retention_ptr->retent.critical_frame = (RvCoreCriticalSleepFrame *)frame;
|
||||
rv_core_critical_regs_frame = (RvCoreCriticalSleepFrame *)frame;
|
||||
}
|
||||
if (sleep_cpu_retention_ptr->retent.non_critical_frame == NULL) {
|
||||
void *frame = heap_caps_calloc(1, sizeof(RvCoreNonCriticalSleepFrame), MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL);
|
||||
if (frame == NULL) {
|
||||
goto err;
|
||||
}
|
||||
sleep_cpu_retention_ptr->retent.non_critical_frame = (RvCoreNonCriticalSleepFrame *)frame;
|
||||
}
|
||||
if (sleep_cpu_retention_ptr->retent.intpri_frame == NULL) {
|
||||
void *frame = cpu_domain_intpri_sleep_frame_alloc_and_init();
|
||||
if (frame == NULL) {
|
||||
goto err;
|
||||
}
|
||||
sleep_cpu_retention_ptr->retent.intpri_frame = (cpu_domain_dev_sleep_frame_t *)frame;
|
||||
}
|
||||
if (sleep_cpu_retention_ptr->retent.cache_config_frame == NULL) {
|
||||
void *frame = cpu_domain_cache_config_sleep_frame_alloc_and_init();
|
||||
if (frame == NULL) {
|
||||
goto err;
|
||||
}
|
||||
sleep_cpu_retention_ptr->retent.cache_config_frame = (cpu_domain_dev_sleep_frame_t *)frame;
|
||||
}
|
||||
if (sleep_cpu_retention_ptr->retent.plic_frame == NULL) {
|
||||
void *frame = cpu_domain_plic_sleep_frame_alloc_and_init();
|
||||
if (frame == NULL) {
|
||||
goto err;
|
||||
}
|
||||
sleep_cpu_retention_ptr->retent.plic_frame = (cpu_domain_dev_sleep_frame_t *)frame;
|
||||
}
|
||||
return ESP_OK;
|
||||
err:
|
||||
esp_sleep_cpu_retention_deinit();
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
esp_err_t esp_sleep_cpu_retention_deinit_impl(sleep_cpu_retention_t *sleep_cpu_retention_ptr)
|
||||
{
|
||||
if (sleep_cpu_retention_ptr->retent.critical_frame) {
|
||||
heap_caps_free((void *)sleep_cpu_retention_ptr->retent.critical_frame);
|
||||
sleep_cpu_retention_ptr->retent.critical_frame = NULL;
|
||||
rv_core_critical_regs_frame = NULL;
|
||||
}
|
||||
if (sleep_cpu_retention_ptr->retent.non_critical_frame) {
|
||||
heap_caps_free((void *)sleep_cpu_retention_ptr->retent.non_critical_frame);
|
||||
sleep_cpu_retention_ptr->retent.non_critical_frame = NULL;
|
||||
}
|
||||
if (sleep_cpu_retention_ptr->retent.intpri_frame) {
|
||||
heap_caps_free((void *)sleep_cpu_retention_ptr->retent.intpri_frame);
|
||||
sleep_cpu_retention_ptr->retent.intpri_frame = NULL;
|
||||
}
|
||||
if (sleep_cpu_retention_ptr->retent.cache_config_frame) {
|
||||
heap_caps_free((void *)sleep_cpu_retention_ptr->retent.cache_config_frame);
|
||||
sleep_cpu_retention_ptr->retent.cache_config_frame = NULL;
|
||||
}
|
||||
if (sleep_cpu_retention_ptr->retent.plic_frame) {
|
||||
heap_caps_free((void *)sleep_cpu_retention_ptr->retent.plic_frame);
|
||||
sleep_cpu_retention_ptr->retent.plic_frame = NULL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __SLEEP_CPU_RETENTION_H__
|
||||
#define __SLEEP_CPU_RETENTION_H__
|
||||
|
||||
#include "rvsleep-frames.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
} cpu_domain_dev_regs_region_t;
|
||||
|
||||
typedef struct {
|
||||
cpu_domain_dev_regs_region_t *region;
|
||||
int region_num;
|
||||
uint32_t *regs_frame;
|
||||
} cpu_domain_dev_sleep_frame_t;
|
||||
|
||||
/**
|
||||
* Internal structure which holds all requested light sleep cpu retention parameters
|
||||
*/
|
||||
typedef struct {
|
||||
struct {
|
||||
RvCoreCriticalSleepFrame *critical_frame;
|
||||
RvCoreNonCriticalSleepFrame *non_critical_frame;
|
||||
cpu_domain_dev_sleep_frame_t *intpri_frame;
|
||||
cpu_domain_dev_sleep_frame_t *plic_frame;
|
||||
cpu_domain_dev_sleep_frame_t *cache_config_frame;
|
||||
} retent;
|
||||
} sleep_cpu_retention_t;
|
||||
|
||||
esp_err_t esp_sleep_cpu_retention_init_impl(sleep_cpu_retention_t *sleep_cpu_retention_ptr);
|
||||
esp_err_t esp_sleep_cpu_retention_deinit_impl(sleep_cpu_retention_t *sleep_cpu_retention_ptr);
|
||||
|
||||
#endif /* #ifndef __SLEEP_CPU_RETENTION_H__ */
|
||||
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "esp_check.h"
|
||||
|
||||
#include "soc/intpri_reg.h"
|
||||
#include "soc/cache_reg.h"
|
||||
#include "soc/plic_reg.h"
|
||||
|
||||
#include "rvsleep-frames.h"
|
||||
#include "sleep_cpu_retention.h"
|
||||
|
||||
|
||||
extern RvCoreCriticalSleepFrame *rv_core_critical_regs_frame;
|
||||
|
||||
#define R_CONCAT(s1, s2) _R_CONCAT(s1, s2)
|
||||
#define _R_CONCAT(s1, s2) s1 ## s2
|
||||
|
||||
#define CPU_DOMAIN_DEV_SZ0 (CPU_DOMAIN_DEV_END_ADDR0 - CPU_DOMAIN_DEV_START_ADDR0)
|
||||
#define CPU_DOMAIN_DEV_SZ1 (CPU_DOMAIN_DEV_END_ADDR1 - CPU_DOMAIN_DEV_START_ADDR1)
|
||||
#define CPU_DOMAIN_DEV_SZ2 (CPU_DOMAIN_DEV_END_ADDR2 - CPU_DOMAIN_DEV_START_ADDR2)
|
||||
#define CPU_DOMAIN_DEV_SZ3 (CPU_DOMAIN_DEV_END_ADDR3 - CPU_DOMAIN_DEV_START_ADDR3)
|
||||
#define CPU_DOMAIN_DEV_SZ4 (CPU_DOMAIN_DEV_END_ADDR4 - CPU_DOMAIN_DEV_START_ADDR4)
|
||||
#define CPU_DOMAIN_DEV_SZ5 (CPU_DOMAIN_DEV_END_ADDR5 - CPU_DOMAIN_DEV_START_ADDR5)
|
||||
#define CPU_DOMAIN_DEV_SZ6 (CPU_DOMAIN_DEV_END_ADDR6 - CPU_DOMAIN_DEV_START_ADDR6)
|
||||
#define CPU_DOMAIN_DEV_SZ7 (CPU_DOMAIN_DEV_END_ADDR7 - CPU_DOMAIN_DEV_START_ADDR7)
|
||||
|
||||
#define CPU_DOMAIN_DEV_TOTAL_SZ(n) (R_CONCAT(__TOTAL_SZ, n))
|
||||
|
||||
#define __TOTAL_SZ0 (sizeof(cpu_domain_dev_sleep_frame_t))
|
||||
#define __TOTAL_SZ1 ((__TOTAL_SZ0) + (sizeof(cpu_domain_dev_regs_region_t)) + CPU_DOMAIN_DEV_SZ0)
|
||||
#define __TOTAL_SZ2 ((__TOTAL_SZ1) + (sizeof(cpu_domain_dev_regs_region_t)) + CPU_DOMAIN_DEV_SZ1)
|
||||
#define __TOTAL_SZ3 ((__TOTAL_SZ2) + (sizeof(cpu_domain_dev_regs_region_t)) + CPU_DOMAIN_DEV_SZ2)
|
||||
#define __TOTAL_SZ4 ((__TOTAL_SZ3) + (sizeof(cpu_domain_dev_regs_region_t)) + CPU_DOMAIN_DEV_SZ3)
|
||||
#define __TOTAL_SZ5 ((__TOTAL_SZ4) + (sizeof(cpu_domain_dev_regs_region_t)) + CPU_DOMAIN_DEV_SZ4)
|
||||
#define __TOTAL_SZ6 ((__TOTAL_SZ5) + (sizeof(cpu_domain_dev_regs_region_t)) + CPU_DOMAIN_DEV_SZ5)
|
||||
#define __TOTAL_SZ7 ((__TOTAL_SZ6) + (sizeof(cpu_domain_dev_regs_region_t)) + CPU_DOMAIN_DEV_SZ6)
|
||||
#define __TOTAL_SZ8 ((__TOTAL_SZ7) + (sizeof(cpu_domain_dev_regs_region_t)) + CPU_DOMAIN_DEV_SZ7)
|
||||
|
||||
static void * cpu_domain_dev_sleep_frame_init(const cpu_domain_dev_regs_region_t *regions, const int region_num, void * frame)
|
||||
{
|
||||
const int region_sz = sizeof(cpu_domain_dev_regs_region_t) * region_num;
|
||||
int regs_frame_sz = 0;
|
||||
for (int num = 0; num < region_num; num++) {
|
||||
regs_frame_sz += regions[num].end - regions[num].start;
|
||||
}
|
||||
if (frame) {
|
||||
cpu_domain_dev_regs_region_t *region = (cpu_domain_dev_regs_region_t *)(frame + sizeof(cpu_domain_dev_sleep_frame_t));
|
||||
memcpy(region, regions, region_num * sizeof(cpu_domain_dev_regs_region_t));
|
||||
void *regs_frame = frame + sizeof(cpu_domain_dev_sleep_frame_t) + region_sz;
|
||||
memset(regs_frame, 0, regs_frame_sz);
|
||||
*(cpu_domain_dev_sleep_frame_t *)frame = (cpu_domain_dev_sleep_frame_t) {
|
||||
.region = region,
|
||||
.region_num = region_num,
|
||||
.regs_frame = (uint32_t *)regs_frame
|
||||
};
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
|
||||
#undef CPU_DOMAIN_DEV_START_ADDR0
|
||||
#undef CPU_DOMAIN_DEV_END_ADDR0
|
||||
#undef CPU_DOMAIN_DEV_START_ADDR1
|
||||
#undef CPU_DOMAIN_DEV_END_ADDR1
|
||||
#undef CPU_DOMAIN_DEV_START_ADDR2
|
||||
#undef CPU_DOMAIN_DEV_END_ADDR2
|
||||
|
||||
#define CPU_DOMAIN_DEV_START_ADDR0 (INTPRI_CORE0_CPU_INT_ENABLE_REG)
|
||||
#define CPU_DOMAIN_DEV_END_ADDR0 (INTPRI_CORE0_CPU_INT_TYPE_REG + 4)
|
||||
#define CPU_DOMAIN_DEV_START_ADDR1 (INTPRI_CORE0_CPU_INT_PRI_0_REG)
|
||||
#define CPU_DOMAIN_DEV_END_ADDR1 (INTPRI_CORE0_CPU_INT_THRESH_REG + 4)
|
||||
#define CPU_DOMAIN_DEV_START_ADDR2 (INTPRI_CLOCK_GATE_REG)
|
||||
#define CPU_DOMAIN_DEV_END_ADDR2 (INTPRI_CORE0_CPU_INT_CLEAR_REG + 4)
|
||||
|
||||
static void * intpri_sleep_frame_init(void)
|
||||
{
|
||||
const static cpu_domain_dev_regs_region_t regions[] = {
|
||||
{ .start = CPU_DOMAIN_DEV_START_ADDR0, .end = CPU_DOMAIN_DEV_END_ADDR0 },
|
||||
{ .start = CPU_DOMAIN_DEV_START_ADDR1, .end = CPU_DOMAIN_DEV_END_ADDR1 },
|
||||
{ .start = CPU_DOMAIN_DEV_START_ADDR2, .end = CPU_DOMAIN_DEV_END_ADDR2 },
|
||||
};
|
||||
static DRAM_ATTR uint8_t sleep_frame[CPU_DOMAIN_DEV_TOTAL_SZ(3)] __attribute__((aligned(4)));
|
||||
return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0]), sleep_frame);
|
||||
}
|
||||
|
||||
#undef CPU_DOMAIN_DEV_START_ADDR0
|
||||
#undef CPU_DOMAIN_DEV_END_ADDR0
|
||||
|
||||
#define CPU_DOMAIN_DEV_START_ADDR0 (CACHE_L1_CACHE_WRAP_AROUND_CTRL_REG)
|
||||
#define CPU_DOMAIN_DEV_END_ADDR0 (CACHE_L1_CACHE_WRAP_AROUND_CTRL_REG + 4)
|
||||
|
||||
static void * cache_sleep_frame_init(void)
|
||||
{
|
||||
const static cpu_domain_dev_regs_region_t regions[] = {
|
||||
{ .start = CPU_DOMAIN_DEV_START_ADDR0, .end = CPU_DOMAIN_DEV_END_ADDR0 }
|
||||
};
|
||||
static DRAM_ATTR uint8_t sleep_frame[CPU_DOMAIN_DEV_TOTAL_SZ(1)] __attribute__((aligned(4)));
|
||||
return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0]), sleep_frame);
|
||||
}
|
||||
|
||||
#undef CPU_DOMAIN_DEV_START_ADDR0
|
||||
#undef CPU_DOMAIN_DEV_END_ADDR0
|
||||
#undef CPU_DOMAIN_DEV_START_ADDR1
|
||||
#undef CPU_DOMAIN_DEV_END_ADDR1
|
||||
#undef CPU_DOMAIN_DEV_START_ADDR2
|
||||
#undef CPU_DOMAIN_DEV_END_ADDR2
|
||||
#undef CPU_DOMAIN_DEV_START_ADDR3
|
||||
#undef CPU_DOMAIN_DEV_END_ADDR3
|
||||
|
||||
#define CPU_DOMAIN_DEV_START_ADDR0 (PLIC_MXINT_ENABLE_REG)
|
||||
#define CPU_DOMAIN_DEV_END_ADDR0 (PLIC_MXINT_CLAIM_REG + 4)
|
||||
#define CPU_DOMAIN_DEV_START_ADDR1 (PLIC_MXINT_CONF_REG)
|
||||
#define CPU_DOMAIN_DEV_END_ADDR1 (PLIC_MXINT_CONF_REG + 4)
|
||||
#define CPU_DOMAIN_DEV_START_ADDR2 (PLIC_UXINT_ENABLE_REG)
|
||||
#define CPU_DOMAIN_DEV_END_ADDR2 (PLIC_UXINT_CLAIM_REG + 4)
|
||||
#define CPU_DOMAIN_DEV_START_ADDR3 (PLIC_UXINT_CONF_REG)
|
||||
#define CPU_DOMAIN_DEV_END_ADDR3 (PLIC_UXINT_CONF_REG + 4)
|
||||
|
||||
static void * plic_sleep_frame_init(void)
|
||||
{
|
||||
const static cpu_domain_dev_regs_region_t regions[] = {
|
||||
{ .start = PLIC_MXINT_ENABLE_REG, .end = PLIC_MXINT_CLAIM_REG + 4 },
|
||||
{ .start = PLIC_MXINT_CONF_REG, .end = PLIC_MXINT_CONF_REG + 4 },
|
||||
{ .start = PLIC_UXINT_ENABLE_REG, .end = PLIC_UXINT_CLAIM_REG + 4 },
|
||||
{ .start = PLIC_UXINT_CONF_REG, .end = PLIC_UXINT_CONF_REG + 4 }
|
||||
};
|
||||
static DRAM_ATTR uint8_t sleep_frame[CPU_DOMAIN_DEV_TOTAL_SZ(4)] __attribute__((aligned(4)));
|
||||
return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0]), sleep_frame);
|
||||
}
|
||||
|
||||
esp_err_t esp_sleep_cpu_retention_init_impl(sleep_cpu_retention_t *sleep_cpu_retention_ptr)
|
||||
{
|
||||
if (sleep_cpu_retention_ptr->retent.critical_frame == NULL) {
|
||||
static DRAM_ATTR uint8_t rv_core_critical_regs[RV_SLEEP_CTX_FRMSZ] __attribute__((aligned(4)));
|
||||
sleep_cpu_retention_ptr->retent.critical_frame = (RvCoreCriticalSleepFrame *) rv_core_critical_regs;
|
||||
rv_core_critical_regs_frame = (RvCoreCriticalSleepFrame *) rv_core_critical_regs;
|
||||
}
|
||||
if (sleep_cpu_retention_ptr->retent.non_critical_frame == NULL) {
|
||||
static DRAM_ATTR uint8_t rv_core_non_critical_regs[sizeof(RvCoreNonCriticalSleepFrame)] __attribute__((aligned(4)));
|
||||
sleep_cpu_retention_ptr->retent.non_critical_frame = (RvCoreNonCriticalSleepFrame *) rv_core_non_critical_regs;
|
||||
}
|
||||
if (sleep_cpu_retention_ptr->retent.intpri_frame == NULL) {
|
||||
void *frame = intpri_sleep_frame_init();
|
||||
sleep_cpu_retention_ptr->retent.intpri_frame = (cpu_domain_dev_sleep_frame_t *)frame;
|
||||
}
|
||||
if (sleep_cpu_retention_ptr->retent.cache_config_frame == NULL) {
|
||||
void *frame = cache_sleep_frame_init();
|
||||
sleep_cpu_retention_ptr->retent.cache_config_frame = (cpu_domain_dev_sleep_frame_t *)frame;
|
||||
}
|
||||
if (sleep_cpu_retention_ptr->retent.plic_frame == NULL) {
|
||||
void *frame = plic_sleep_frame_init();
|
||||
sleep_cpu_retention_ptr->retent.plic_frame = (cpu_domain_dev_sleep_frame_t *)frame;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_sleep_cpu_retention_deinit_impl(sleep_cpu_retention_t *sleep_cpu_retention_ptr)
|
||||
{
|
||||
if (sleep_cpu_retention_ptr->retent.critical_frame) {
|
||||
sleep_cpu_retention_ptr->retent.critical_frame = NULL;
|
||||
rv_core_critical_regs_frame = NULL;
|
||||
}
|
||||
if (sleep_cpu_retention_ptr->retent.non_critical_frame) {
|
||||
sleep_cpu_retention_ptr->retent.non_critical_frame = NULL;
|
||||
}
|
||||
if (sleep_cpu_retention_ptr->retent.intpri_frame) {
|
||||
sleep_cpu_retention_ptr->retent.intpri_frame = NULL;
|
||||
}
|
||||
if (sleep_cpu_retention_ptr->retent.cache_config_frame) {
|
||||
sleep_cpu_retention_ptr->retent.cache_config_frame = NULL;
|
||||
}
|
||||
if (sleep_cpu_retention_ptr->retent.plic_frame) {
|
||||
sleep_cpu_retention_ptr->retent.plic_frame = NULL;
|
||||
}
|
||||
if (sleep_cpu_retention_ptr->retent.clint_frame) {
|
||||
sleep_cpu_retention_ptr->retent.clint_frame = NULL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <sys/lock.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_ipc_isr.h"
|
||||
@@ -18,19 +19,14 @@
|
||||
#include "esp_rom_crc.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "riscv/csr.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/intpri_reg.h"
|
||||
#include "soc/cache_reg.h"
|
||||
#include "soc/clint_reg.h"
|
||||
#include "soc/clic_reg.h"
|
||||
#include "soc/pcr_reg.h"
|
||||
#include "soc/intpri_reg.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/rtc_periph.h"
|
||||
#include "esp_private/esp_pmu.h"
|
||||
#include "esp_private/sleep_cpu.h"
|
||||
#include "esp_private/sleep_event.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "esp32h4/rom/rtc.h"
|
||||
#include "esp32h4/rom/cache.h"
|
||||
|
||||
Reference in New Issue
Block a user