psram: support s3 copy flash to psram

pull/7436/merge
Armando 2022-05-09 16:44:02 +08:00
rodzic 5daa73d236
commit 44f771c713
10 zmienionych plików z 416 dodań i 186 usunięć

Wyświetl plik

@ -17,9 +17,6 @@ extern "C" {
esp_err_t mmu_map_psram(uint32_t start_paddr, uint32_t map_length, uint32_t *out_start_vaddr);
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
extern int _instruction_reserved_start;
extern int _instruction_reserved_end;
esp_err_t mmu_config_psram_text_segment(uint32_t start_page, uint32_t psram_size, uint32_t *out_page);
/**
@ -45,9 +42,6 @@ int instruction_flash2spiram_offset(void);
#endif
#if CONFIG_SPIRAM_RODATA
extern int _rodata_reserved_start;
extern int _rodata_reserved_end;
esp_err_t mmu_config_psram_rodata_segment(uint32_t start_page, uint32_t psram_size, uint32_t *out_page);
/**

Wyświetl plik

@ -0,0 +1,71 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <sys/param.h>
#include "esp_err.h"
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
#endif
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
esp_err_t mmu_config_psram_text_segment(uint32_t start_page, uint32_t psram_size, uint32_t *out_page);
/**
* @brief Get the start page number of the instruction in SPI flash
*
* @return start page number
*/
uint32_t instruction_flash_start_page_get(void);
/**
* @brief Get the end page number of the instruction in SPI flash
*
* @return end page number
*/
uint32_t instruction_flash_end_page_get(void);
/**
* @brief Get the offset of instruction from SPI flash to SPI RAM
*
* @return instruction offset
*/
int instruction_flash2spiram_offset(void);
#endif
#if CONFIG_SPIRAM_RODATA
esp_err_t mmu_config_psram_rodata_segment(uint32_t start_page, uint32_t psram_size, uint32_t *out_page);
/**
* @brief Get the start page number of the rodata in SPI flash
*
* @return start page number
*/
uint32_t rodata_flash_start_page_get(void);
/**
* @brief Get the end page number of the rodata in SPI flash
*
* @return end page number
*/
uint32_t rodata_flash_end_page_get(void);
/**
* @brief Get the offset number of rodata from SPI flash to SPI RAM
*
* @return rodata offset
*/
int rodata_flash2spiram_offset(void);
#endif
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -76,53 +76,6 @@ esp_err_t esp_spiram_reserve_dma_pool(size_t size);
*/
bool esp_spiram_is_initialized(void);
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
extern int _instruction_reserved_start, _instruction_reserved_end;
/**
* @brief Get the start page number of the instruction in SPI flash
*
* @return start page number
*/
uint32_t instruction_flash_start_page_get(void);
/**
* @brief Get the end page number of the instruction in SPI flash
*
* @return end page number
*/
uint32_t instruction_flash_end_page_get(void);
/**
* @brief Get the offset of instruction from SPI flash to SPI RAM
*
* @return instruction offset
*/
int instruction_flash2spiram_offset(void);
#endif
#if CONFIG_SPIRAM_RODATA
extern int _rodata_reserved_start, _rodata_reserved_end;
/**
* @brief Get the start page number of the rodata in SPI flash
*
* @return start page number
*/
uint32_t rodata_flash_start_page_get(void);
/**
* @brief Get the end page number of the rodata in SPI flash
*
* @return end page number
*/
uint32_t rodata_flash_end_page_get(void);
/**
* @brief Get the offset number of rodata from SPI flash to SPI RAM
*
* @return rodata offset
*/
int rodata_flash2spiram_offset(void);
#endif
#ifdef __cplusplus
}

Wyświetl plik

@ -15,8 +15,9 @@ entries:
spiram_psram (noflash)
if SPIRAM_MODE_OCT = y:
opiram_psram (noflash)
if IDF_TARGET_ESP32S2 = y && SPIRAM:
mmu_psram (noflash)
if SPIRAM:
if IDF_TARGET_ESP32S2 = y || IDF_TARGET_ESP32S3 = y:
mmu_psram (noflash)
if PERIPH_CTRL_FUNC_IN_IRAM = y:
periph_ctrl: periph_module_reset (noflash)
periph_ctrl: wifi_module_enable (noflash)

Wyświetl plik

@ -20,6 +20,9 @@ const static char *TAG = "mmu_psram";
//------------------------------------Copy Flash .text to PSRAM-------------------------------------//
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
extern int _instruction_reserved_start;
extern int _instruction_reserved_end;
static uint32_t instruction_in_spiram;
static uint32_t instr_start_page;
static uint32_t instr_end_page;
@ -34,6 +37,9 @@ uint32_t instruction_flash_end_page_get(void);
//------------------------------------Copy Flash .rodata to PSRAM-------------------------------------//
#if CONFIG_SPIRAM_RODATA
extern int _rodata_reserved_start;
extern int _rodata_reserved_end;
static uint32_t rodata_in_spiram;
static int rodata_flash2spiram_offs;
static uint32_t rodata_start_page;

Wyświetl plik

@ -18,7 +18,7 @@ if(NOT BOOTLOADER_BUILD)
"esp_crypto_lock.c")
if(CONFIG_SPIRAM)
list(APPEND srcs "spiram.c")
list(APPEND srcs "spiram.c" "mmu_psram.c")
if(CONFIG_SPIRAM_MODE_QUAD)
list(APPEND srcs "spiram_psram.c")

Wyświetl plik

@ -0,0 +1,276 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <sys/param.h>
#include "esp_attr.h"
#include "esp_log.h"
#include "esp_private/mmu_psram.h"
#include "esp32s3/rom/cache.h"
#include "esp32s3/rom/ets_sys.h"
#include "soc/ext_mem_defs.h"
#include "soc/extmem_reg.h"
#define MMU_PAGE_SIZE 0x10000
#define MMU_PAGE_TO_BYTES(page_id) ((page_id) * MMU_PAGE_SIZE)
#define BYTES_TO_MMU_PAGE(bytes) ((bytes) / MMU_PAGE_SIZE)
const static char *TAG = "mmu_psram";
//------------------------------------Copy Flash .text to PSRAM-------------------------------------//
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
extern int _instruction_reserved_start;
extern int _instruction_reserved_end;
static uint32_t instruction_in_spiram;
static uint32_t instr_start_page;
static uint32_t instr_end_page;
static int instr_flash2spiram_offs;
uint32_t esp_spiram_instruction_access_enabled(void);
int instruction_flash2spiram_offset(void);
uint32_t instruction_flash_start_page_get(void);
uint32_t instruction_flash_end_page_get(void);
#endif //CONFIG_SPIRAM_FETCH_INSTRUCTIONS
//------------------------------------Copy Flash .rodata to PSRAM-------------------------------------//
#if CONFIG_SPIRAM_RODATA
extern int _rodata_reserved_start;
extern int _rodata_reserved_end;
static uint32_t rodata_in_spiram;
static int rodata_flash2spiram_offs;
static uint32_t rodata_start_page;
static uint32_t rodata_end_page;
uint32_t esp_spiram_rodata_access_enabled(void);
int rodata_flash2spiram_offset(void);
uint32_t rodata_flash_start_page_get(void);
uint32_t rodata_flash_end_page_get(void);
#endif //#if CONFIG_SPIRAM_RODATA
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS || CONFIG_SPIRAM_RODATA
//TODO IDF-4387
static uint32_t page0_mapped = 0;
static uint32_t page0_page = INVALID_PHY_PAGE;
#endif //#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS || CONFIG_SPIRAM_RODATA
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
esp_err_t mmu_config_psram_text_segment(uint32_t start_page, uint32_t psram_size, uint32_t *out_page)
{
uint32_t page_id = start_page;
/**
* TODO IDF-4387
* `Cache_Count_Flash_Pages` seems give wrong results. Need to confirm this.
* FOR NOW, leave these logics just as it used to be.
*/
uint32_t flash_pages = 0;
flash_pages += Cache_Count_Flash_Pages(CACHE_IBUS, &page0_mapped);
if ((flash_pages + page_id) > BYTES_TO_MMU_PAGE(psram_size)) {
ESP_EARLY_LOGE(TAG, "PSRAM space not enough for the Flash instructions, need %d B, from %d B to %d B",
MMU_PAGE_TO_BYTES(flash_pages), MMU_PAGE_TO_BYTES(start_page), MMU_PAGE_TO_BYTES(flash_pages + page_id));
return ESP_FAIL;
}
//Enable DBUS, which is used for copying FLASH .text to PSRAM
REG_CLR_BIT(EXTMEM_DCACHE_CTRL1_REG, EXTMEM_DCACHE_SHUT_CORE0_BUS);
#if !CONFIG_FREERTOS_UNICORE
REG_CLR_BIT(EXTMEM_DCACHE_CTRL1_REG, EXTMEM_DCACHE_SHUT_CORE1_BUS);
#endif
// uint32_t instr_page_cnt = ((uint32_t)&_instruction_reserved_end - (uint32_t)&_instruction_reserved_start + MMU_PAGE_SIZE - 1) / MMU_PAGE_SIZE;
// uint32_t instr_mmu_offset = ((uint32_t)&_instruction_reserved_start & MMU_VADDR_MASK) / MMU_PAGE_SIZE;
// instr_start_page = ((volatile uint32_t *)(DR_REG_MMU_TABLE + PRO_CACHE_IBUS0_MMU_START))[instr_mmu_offset];
// instr_start_page &= MMU_VALID_VAL_MASK;
// instr_end_page = instr_start_page + instr_page_cnt - 1;
// instr_flash2spiram_offs = instr_start_page - page_id;
// ESP_EARLY_LOGV(TAG, "Instructions from flash page%d copy to SPIRAM page%d, Offset: %d", instr_start_page, page_id, instr_flash2spiram_offs);
ets_printf(DRAM_STR("_instruction_reserved_end addr is %x\n"), (uint32_t)&_instruction_reserved_start);
uint32_t instr_page_cnt = ((uint32_t)&_instruction_reserved_end - SOC_IROM_LOW + MMU_PAGE_SIZE - 1) / MMU_PAGE_SIZE;
instr_start_page = *(volatile uint32_t *)(DR_REG_MMU_TABLE + CACHE_IROM_MMU_START);
instr_start_page &= MMU_VALID_VAL_MASK;
instr_end_page = instr_start_page + instr_page_cnt - 1;
instr_flash2spiram_offs = instr_start_page - page_id;
ESP_EARLY_LOGE(TAG, "Instructions from flash page%d copy to SPIRAM page%d, Offset: %d", instr_start_page, page_id, instr_flash2spiram_offs);
// page_id = Cache_Flash_To_SPIRAM_Copy(PRO_CACHE_IBUS0, IRAM0_ADDRESS_LOW, page_id, &page0_page);
// page_id = Cache_Flash_To_SPIRAM_Copy(PRO_CACHE_IBUS1, IRAM1_ADDRESS_LOW, page_id, &page0_page);
// instruction_in_spiram = 1;
// ESP_EARLY_LOGV(TAG, "after copy instruction, page_id is %d", page_id);
// ESP_EARLY_LOGI(TAG, "Instructions copied and mapped to SPIRAM");
page_id = Cache_Flash_To_SPIRAM_Copy(CACHE_IBUS, IRAM0_CACHE_ADDRESS_LOW, page_id, &page0_page);
instruction_in_spiram = 1;
ESP_EARLY_LOGV(TAG, "after copy instruction, page_id is %d", page_id);
ESP_EARLY_LOGI(TAG, "Instructions copied and mapped to SPIRAM");
/**
* Disable DRAM0_BUS.
* .text (instructions) are mapped in `Cache_Flash_To_SPIRAM_Copy` to both `PRO_CACHE_IBUS0` and `PRO_CACHE_IBUS1`.
*
* For now, this bus (DRAM0) is only used for copying, so can be disabled. If it is used later, other code
* should be responsible for enabling it.
*/
REG_SET_BIT(EXTMEM_DCACHE_CTRL1_REG, EXTMEM_DCACHE_SHUT_CORE0_BUS);
#if !CONFIG_FREERTOS_UNICORE
REG_SET_BIT(EXTMEM_DCACHE_CTRL1_REG, EXTMEM_DCACHE_SHUT_CORE1_BUS);
#endif
*out_page = page_id - start_page;
return ESP_OK;
}
#endif //#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
#if CONFIG_SPIRAM_RODATA
esp_err_t mmu_config_psram_rodata_segment(uint32_t start_page, uint32_t psram_size, uint32_t *out_page)
{
uint32_t page_id = start_page;
/**
* TODO IDF-4387
* `Cache_Count_Flash_Pages` seems give wrong results. Need to confirm this.
* FOR NOW, leave these logics just as it used to be.
*/
uint32_t flash_pages = 0;
flash_pages += Cache_Count_Flash_Pages(CACHE_DBUS, &page0_mapped);
if ((flash_pages + page_id) > BYTES_TO_MMU_PAGE(psram_size)) {
ESP_EARLY_LOGE(TAG, "SPI RAM space not enough for the instructions, need to copy to %d B.", MMU_PAGE_TO_BYTES(flash_pages + page_id));
return ESP_FAIL;
}
//Enable DBUS, which is used for copying FLASH .text to PSRAM
REG_CLR_BIT(EXTMEM_DCACHE_CTRL1_REG, EXTMEM_DCACHE_SHUT_CORE0_BUS);
#if !CONFIG_FREERTOS_UNICORE
REG_CLR_BIT(EXTMEM_DCACHE_CTRL1_REG, EXTMEM_DCACHE_SHUT_CORE1_BUS);
#endif
// uint32_t rodata_page_cnt = ((uint32_t)&_rodata_reserved_end - (uint32_t)&_rodata_reserved_start + MMU_PAGE_SIZE - 1) / MMU_PAGE_SIZE;
// uint32_t rodata_mmu_offset = ((uint32_t)&_rodata_reserved_start & MMU_VADDR_MASK) / MMU_PAGE_SIZE;
// rodata_start_page = ((volatile uint32_t *)(DR_REG_MMU_TABLE + PRO_CACHE_IBUS2_MMU_START))[rodata_mmu_offset];
// rodata_start_page &= MMU_VALID_VAL_MASK;
// rodata_end_page = rodata_start_page + rodata_page_cnt - 1;
// rodata_flash2spiram_offs = rodata_start_page - page_id;
// ESP_EARLY_LOGV(TAG, "Rodata from flash page%d copy to SPIRAM page%d, Offset: %d", rodata_start_page, page_id, rodata_flash2spiram_offs);
uint32_t rodata_page_cnt = ((uint32_t)&_rodata_reserved_end - ((uint32_t)&_rodata_reserved_start & ~ (MMU_PAGE_SIZE - 1)) + MMU_PAGE_SIZE - 1) / MMU_PAGE_SIZE;
rodata_start_page = *(volatile uint32_t *)(DR_REG_MMU_TABLE + CACHE_DROM_MMU_START);
rodata_start_page &= MMU_VALID_VAL_MASK;
rodata_end_page = rodata_start_page + rodata_page_cnt - 1;
rodata_flash2spiram_offs = rodata_start_page - page_id;
ESP_EARLY_LOGE(TAG, "Rodata from flash page%d copy to SPIRAM page%d, Offset: %d", rodata_start_page, page_id, rodata_flash2spiram_offs);
// page_id = Cache_Flash_To_SPIRAM_Copy(PRO_CACHE_IBUS2, DROM0_ADDRESS_LOW, page_id, &page0_page);
// page_id = Cache_Flash_To_SPIRAM_Copy(PRO_CACHE_DBUS0, DRAM0_ADDRESS_LOW, page_id, &page0_page);
// page_id = Cache_Flash_To_SPIRAM_Copy(PRO_CACHE_DBUS1, DRAM1_ADDRESS_LOW, page_id, &page0_page);
// page_id = Cache_Flash_To_SPIRAM_Copy(PRO_CACHE_DBUS2, DPORT_ADDRESS_LOW, page_id, &page0_page);
// rodata_in_spiram = 1;
// ESP_EARLY_LOGV(TAG, "after copy rodata, page_id is %d", page_id);
// ESP_EARLY_LOGI(TAG, "Read only data copied and mapped to SPIRAM");
page_id = Cache_Flash_To_SPIRAM_Copy(CACHE_DBUS, DRAM0_CACHE_ADDRESS_LOW, page_id, &page0_page);
rodata_in_spiram = 1;
ESP_EARLY_LOGV(TAG, "after copy rodata, page_id is %d", page_id);
ESP_EARLY_LOGI(TAG, "Read only data copied and mapped to SPIRAM");
/**
* Disable DRAM0_BUS.
* .text (instructions) are mapped in `Cache_Flash_To_SPIRAM_Copy` to both `PRO_CACHE_IBUS0` and `PRO_CACHE_IBUS1`.
*
* For now, this bus (DRAM0) is only used for copying, so can be disabled. If it is used later, other code
* should be responsible for enabling it.
*/
REG_SET_BIT(EXTMEM_DCACHE_CTRL1_REG, EXTMEM_DCACHE_SHUT_CORE0_BUS);
#if !CONFIG_FREERTOS_UNICORE
REG_SET_BIT(EXTMEM_DCACHE_CTRL1_REG, EXTMEM_DCACHE_SHUT_CORE1_BUS);
#endif
*out_page = page_id - start_page;
return ESP_OK;
}
#endif //#if CONFIG_SPIRAM_RODATA
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
uint32_t esp_spiram_instruction_access_enabled(void)
{
return instruction_in_spiram;
}
int instruction_flash2spiram_offset(void)
{
return instr_flash2spiram_offs;
}
uint32_t instruction_flash_start_page_get(void)
{
return instr_start_page;
}
uint32_t instruction_flash_end_page_get(void)
{
return instr_end_page;
}
#endif //CONFIG_SPIRAM_FETCH_INSTRUCTIONS
#if CONFIG_SPIRAM_RODATA
uint32_t esp_spiram_rodata_access_enabled(void)
{
return rodata_in_spiram;
}
int rodata_flash2spiram_offset(void)
{
return rodata_flash2spiram_offs;
}
uint32_t rodata_flash_start_page_get(void)
{
return rodata_start_page;
}
uint32_t rodata_flash_end_page_get(void)
{
return rodata_end_page;
}
#endif //#if CONFIG_SPIRAM_RODATA

Wyświetl plik

@ -24,12 +24,14 @@
#include "spiram_psram.h"
#include "hal/mmu_hal.h"
#include "hal/cache_ll.h"
#include "esp_private/mmu_psram.h"
#define PSRAM_MODE PSRAM_VADDR_MODE_NORMAL
#define MMU_PAGE_SIZE (0x10000)
#define ALIGN_UP_BY(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
#define MMU_PAGE_TO_BYTES(page_id) ((page_id) << 16)
#if CONFIG_SPIRAM_SPEED_40M
#define PSRAM_SPEED PSRAM_CACHE_S40M
@ -83,12 +85,51 @@ esp_err_t esp_spiram_init(void)
ESP_EARLY_LOGI(TAG, "Found %dMB SPI RAM device", psram_physical_size / (1024 * 1024));
ESP_EARLY_LOGI(TAG, "Speed: %dMHz", CONFIG_SPIRAM_SPEED);
uint32_t psram_available_size = 0;
ret = psram_get_available_size(&psram_available_size);
assert(ret == ESP_OK);
__attribute__((unused)) uint32_t total_available_size = psram_available_size;
/**
* TODO IDF-4318
* Add these feature here:
* - Copy Flash text into PSRAM
* - Copy Flash rodata into PSRAM
* `start_page` is the psram physical address in MMU page size.
* MMU page size on ESP32S2 is 64KB
* e.g.: psram physical address 16 is in page 0
*
* Here we plan to copy FLASH instructions to psram physical address 0, which is the No.0 page.
*/
uint32_t start_page = 0;
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS || CONFIG_SPIRAM_RODATA
uint32_t used_page = 0;
#endif
//------------------------------------Copy Flash .text to PSRAM-------------------------------------//
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
ret = mmu_config_psram_text_segment(start_page, total_available_size, &used_page);
if (ret != ESP_OK) {
ESP_EARLY_LOGE(TAG, "No enough psram memory for instructon!");
abort();
}
start_page += used_page;
psram_available_size -= MMU_PAGE_TO_BYTES(used_page);
ESP_EARLY_LOGV(TAG, "after copy .text, used page is %d, start_page is %d, psram_available_size is %d B", used_page, start_page, psram_available_size);
#endif //#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
//------------------------------------Copy Flash .rodata to PSRAM-------------------------------------//
#if CONFIG_SPIRAM_RODATA
ret = mmu_config_psram_rodata_segment(start_page, total_available_size, &used_page);
if (ret != ESP_OK) {
ESP_EARLY_LOGE(TAG, "No enough psram memory for rodata!");
abort();
}
start_page += used_page;
psram_available_size -= MMU_PAGE_TO_BYTES(used_page);
ESP_EARLY_LOGV(TAG, "after copy .rodata, used page is %d, start_page is %d, psram_available_size is %d B", used_page, start_page, psram_available_size);
#endif //#if CONFIG_SPIRAM_RODATA
//----------------------------------Map the PSRAM physical range to MMU-----------------------------//
uint32_t vaddr_start = 0;
extern uint32_t _rodata_reserved_end;
@ -96,10 +137,6 @@ esp_err_t esp_spiram_init(void)
vaddr_start = rodata_end_aligned;
ESP_EARLY_LOGV(TAG, "rodata_end_aligned is 0x%x bytes", rodata_end_aligned);
uint32_t psram_available_size = 0;
ret = psram_get_available_size(&psram_available_size);
assert(ret == ESP_OK);
if (vaddr_start + psram_available_size > DRAM0_CACHE_ADDRESS_HIGH) {
//Decide these logics when there's a real PSRAM with larger size
ESP_EARLY_LOGE(TAG, "Virtual address not enough for PSRAM!");
@ -108,7 +145,7 @@ esp_err_t esp_spiram_init(void)
//On ESP32S3, MMU is shared for both of the cores. Note this when porting `spiram.c`
uint32_t actual_mapped_len = 0;
mmu_hal_map_region(0, MMU_TARGET_PSRAM0, vaddr_start, 0, psram_available_size, &actual_mapped_len);
mmu_hal_map_region(0, MMU_TARGET_PSRAM0, vaddr_start, MMU_PAGE_TO_BYTES(start_page), psram_available_size, &actual_mapped_len);
ESP_EARLY_LOGV(TAG, "actual_mapped_len is 0x%x bytes", actual_mapped_len);
cache_bus_mask_t bus_mask = cache_ll_l1_get_bus(0, vaddr_start, actual_mapped_len);
@ -204,108 +241,6 @@ esp_err_t esp_spiram_reserve_dma_pool(size_t size)
return heap_caps_add_region_with_caps(caps, (intptr_t) dma_heap, (intptr_t) dma_heap + size);
}
//TODO IDF-4318
// static uint32_t pages_for_flash = 0;
static uint32_t instruction_in_spiram = 0;
static uint32_t rodata_in_spiram = 0;
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
static int instr_flash2spiram_offs = 0;
static uint32_t instr_start_page = 0;
static uint32_t instr_end_page = 0;
#endif
#if CONFIG_SPIRAM_RODATA
static int rodata_flash2spiram_offs = 0;
static uint32_t rodata_start_page = 0;
static uint32_t rodata_end_page = 0;
#endif
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS || CONFIG_SPIRAM_RODATA
// Helper macro to make a MMU entry invalid
#define INVALID_PHY_PAGE 0xffff
static uint32_t page0_mapped = 0;
static uint32_t page0_page = INVALID_PHY_PAGE;
#endif
uint32_t esp_spiram_instruction_access_enabled(void)
{
return instruction_in_spiram;
}
uint32_t esp_spiram_rodata_access_enabled(void)
{
return rodata_in_spiram;
}
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
esp_err_t esp_spiram_enable_instruction_access(void)
{
//TODO IDF-4318, `pages_for_flash` will be overwritten, however it influences the psram size to be added to the heap allocator.
abort();
}
#endif
#if CONFIG_SPIRAM_RODATA
esp_err_t esp_spiram_enable_rodata_access(void)
{
//TODO IDF-4318, `pages_for_flash` will be overwritten, however it influences the psram size to be added to the heap allocator.
abort();
}
#endif
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
void instruction_flash_page_info_init(void)
{
uint32_t instr_page_cnt = ((uint32_t)&_instruction_reserved_end - SOC_IROM_LOW + MMU_PAGE_SIZE - 1) / MMU_PAGE_SIZE;
instr_start_page = *(volatile uint32_t *)(DR_REG_MMU_TABLE + CACHE_IROM_MMU_START);
instr_start_page &= MMU_VALID_VAL_MASK;
instr_end_page = instr_start_page + instr_page_cnt - 1;
}
uint32_t IRAM_ATTR instruction_flash_start_page_get(void)
{
return instr_start_page;
}
uint32_t IRAM_ATTR instruction_flash_end_page_get(void)
{
return instr_end_page;
}
int IRAM_ATTR instruction_flash2spiram_offset(void)
{
return instr_flash2spiram_offs;
}
#endif
#if CONFIG_SPIRAM_RODATA
void rodata_flash_page_info_init(void)
{
uint32_t rodata_page_cnt = ((uint32_t)&_rodata_reserved_end - ((uint32_t)&_rodata_reserved_start & ~ (MMU_PAGE_SIZE - 1)) + MMU_PAGE_SIZE - 1) / MMU_PAGE_SIZE;
rodata_start_page = *(volatile uint32_t *)(DR_REG_MMU_TABLE + CACHE_DROM_MMU_START);
rodata_start_page &= MMU_VALID_VAL_MASK;
rodata_end_page = rodata_start_page + rodata_page_cnt - 1;
}
uint32_t IRAM_ATTR rodata_flash_start_page_get(void)
{
return rodata_start_page;
}
uint32_t IRAM_ATTR rodata_flash_end_page_get(void)
{
return rodata_end_page;
}
int IRAM_ATTR rodata_flash2spiram_offset(void)
{
return rodata_flash2spiram_offs;
}
#endif
/*
Before flushing the cache, if psram is enabled as a memory-mapped thing, we need to write back the data in the cache to the psram first,
otherwise it will get lost. For now, we just read 64/128K of random PSRAM memory to do this.

Wyświetl plik

@ -37,6 +37,7 @@
#include "esp32s3/rtc.h"
#include "esp32s3/rom/cache.h"
#include "esp32s3/spiram.h"
#include "esp_private/mmu_psram.h"
#include "esp_memprot.h"
#include "soc/assist_debug_reg.h"
#include "soc/system_reg.h"
@ -444,26 +445,8 @@ void IRAM_ATTR call_start_cpu0(void)
#endif //CONFIG_IDF_TARGET_ESP32, //TODO: IDF-4382
#endif //CONFIG_SPIRAM_MEMTEST
//TODO: IDF-4382
#if CONFIG_IDF_TARGET_ESP32S3
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
extern void instruction_flash_page_info_init(void);
instruction_flash_page_info_init();
#endif
#if CONFIG_SPIRAM_RODATA
extern void rodata_flash_page_info_init(void);
rodata_flash_page_info_init();
#endif
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
extern void esp_spiram_enable_instruction_access(void);
esp_spiram_enable_instruction_access();
#endif
#if CONFIG_SPIRAM_RODATA
extern void esp_spiram_enable_rodata_access(void);
esp_spiram_enable_rodata_access();
#endif
int s_instr_flash2spiram_off = 0;
int s_rodata_flash2spiram_off = 0;
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS

Wyświetl plik

@ -31,6 +31,7 @@
#include "soc/extmem_reg.h"
#elif CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/rom/cache.h"
#include "esp_private/mmu_psram.h"
#include "esp32s3/spiram.h"
#include "soc/extmem_reg.h"
#elif CONFIG_IDF_TARGET_ESP32C3
@ -52,6 +53,16 @@
#define PAGES_LIMIT ((SOC_MMU_IROM0_PAGES_END > SOC_MMU_DROM0_PAGES_END) ? SOC_MMU_IROM0_PAGES_END:SOC_MMU_DROM0_PAGES_END)
#define INVALID_PHY_PAGE(page_size) ((page_size) - 1)
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
extern int _instruction_reserved_start;
extern int _instruction_reserved_end;
#endif
#if CONFIG_SPIRAM_RODATA
extern int _rodata_reserved_start;
extern int _rodata_reserved_end;
#endif
#if !CONFIG_SPI_FLASH_ROM_IMPL
typedef struct mmap_entry_{