kopia lustrzana https://github.com/espressif/esp-idf
psram: support s3 copy flash to psram
rodzic
5daa73d236
commit
44f771c713
|
@ -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);
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_{
|
||||
|
|
Ładowanie…
Reference in New Issue