Merge branch 'feature/flash_mmap_refactor' into 'master'

flash mmap: abstract R/W of MMU table instead of reg access

See merge request espressif/esp-idf!16882
This commit is contained in:
Jiang Jiang Jian 2022-05-29 13:56:37 +08:00
commit f3922f1b7f
21 changed files with 277 additions and 68 deletions

View File

@ -69,6 +69,62 @@ static inline bool mmu_ll_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t
(ADDRESS_IN_DROM0_CACHE(vaddr_start) && ADDRESS_IN_DROM0_CACHE(vaddr_end));
}
/**
* Write to the MMU table to map the virtual memory and the physical memory
*
* @param mmu_id MMU ID
* @param entry_id MMU entry ID
* @param mmu_val Value to be set into an MMU entry, for physical address
* @param target MMU target physical memory.
*/
__attribute__((always_inline))
static inline void mmu_ll_write_entry(uint32_t mmu_id, uint32_t entry_id, uint32_t mmu_val, mmu_target_t target)
{
(void)target;
HAL_ASSERT(entry_id < MMU_ENTRY_NUM);
DPORT_INTERRUPT_DISABLE();
switch (mmu_id) {
case MMU_TABLE_CORE0:
DPORT_WRITE_PERI_REG((uint32_t)&DPORT_PRO_FLASH_MMU_TABLE[entry_id], mmu_val);
break;
case MMU_TABLE_CORE1:
DPORT_WRITE_PERI_REG((uint32_t)&DPORT_APP_FLASH_MMU_TABLE[entry_id], mmu_val);
break;
default:
HAL_ASSERT(false);
}
DPORT_INTERRUPT_RESTORE();
}
/**
* Read the raw value from MMU table
*
* @param mmu_id MMU ID
* @param entry_id MMU entry ID
* @param mmu_val Value to be read from MMU table
*/
__attribute__((always_inline))
static inline uint32_t mmu_ll_read_entry(uint32_t mmu_id, uint32_t entry_id)
{
uint32_t mmu_value;
HAL_ASSERT(entry_id < MMU_ENTRY_NUM);
DPORT_INTERRUPT_DISABLE();
switch (mmu_id) {
case MMU_TABLE_CORE0:
mmu_value = DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_PRO_FLASH_MMU_TABLE[entry_id]);
break;
case MMU_TABLE_CORE1:
mmu_value = DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_APP_FLASH_MMU_TABLE[entry_id]);
break;
default:
HAL_ASSERT(false);
}
DPORT_INTERRUPT_RESTORE();
return mmu_value;
}
/**
* Set MMU table entry as invalid
*
@ -82,14 +138,14 @@ static inline void mmu_ll_set_entry_invalid(uint32_t mmu_id, uint32_t entry_id)
DPORT_INTERRUPT_DISABLE();
switch (mmu_id) {
case 0:
DPORT_WRITE_PERI_REG((uint32_t)&DPORT_PRO_FLASH_MMU_TABLE[entry_id], DPORT_FLASH_MMU_TABLE_INVALID_VAL);
case MMU_TABLE_CORE0:
DPORT_WRITE_PERI_REG((uint32_t)&DPORT_PRO_FLASH_MMU_TABLE[entry_id], MMU_INVALID);
break;
case 1:
DPORT_WRITE_PERI_REG((uint32_t)&DPORT_APP_FLASH_MMU_TABLE[entry_id], DPORT_FLASH_MMU_TABLE_INVALID_VAL);
case MMU_TABLE_CORE1:
DPORT_WRITE_PERI_REG((uint32_t)&DPORT_APP_FLASH_MMU_TABLE[entry_id], MMU_INVALID);
break;
default:
HAL_ASSERT(false && "invalid mmu_id");
HAL_ASSERT(false);
}
DPORT_INTERRUPT_RESTORE();
}
@ -107,6 +163,25 @@ static inline void mmu_ll_unmap_all(uint32_t mmu_id)
}
}
/**
* Get MMU table entry is invalid
*
* @param mmu_id MMU ID
* @param entry_id MMU entry ID
* return ture for MMU entry is invalid, false for valid
*/
__attribute__((always_inline))
static inline bool mmu_ll_get_entry_is_invalid(uint32_t mmu_id, uint32_t entry_id)
{
(void)mmu_id;
DPORT_INTERRUPT_DISABLE();
uint32_t mmu_value = DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_PRO_FLASH_MMU_TABLE[entry_id]);
DPORT_INTERRUPT_RESTORE();
return (mmu_value & MMU_INVALID) ? true : false;
}
#ifdef __cplusplus
}
#endif

View File

@ -147,6 +147,22 @@ static inline void mmu_ll_write_entry(uint32_t mmu_id, uint32_t entry_id, uint32
*(uint32_t *)(DR_REG_MMU_TABLE + entry_id * 4) = mmu_val | MMU_ACCESS_FLASH | MMU_VALID;
}
/**
* Read the raw value from MMU table
*
* @param mmu_id MMU ID
* @param entry_id MMU entry ID
* @param mmu_val Value to be read from MMU table
*/
__attribute__((always_inline))
static inline uint32_t mmu_ll_read_entry(uint32_t mmu_id, uint32_t entry_id)
{
(void)mmu_id;
HAL_ASSERT(entry_id < MMU_ENTRY_NUM);
return *(uint32_t *)(DR_REG_MMU_TABLE + entry_id * 4);
}
/**
* Set MMU table entry as invalid
*
@ -175,6 +191,22 @@ static inline void mmu_ll_unmap_all(uint32_t mmu_id)
}
}
/**
* Get MMU table entry is invalid
*
* @param mmu_id MMU ID
* @param entry_id MMU entry ID
* return ture for MMU entry is invalid, false for valid
*/
__attribute__((always_inline))
static inline bool mmu_ll_get_entry_is_invalid(uint32_t mmu_id, uint32_t entry_id)
{
(void)mmu_id;
HAL_ASSERT(entry_id < MMU_ENTRY_NUM);
return (*(uint32_t *)(DR_REG_MMU_TABLE + entry_id * 4) & MMU_INVALID) ? true : false;
}
#ifdef __cplusplus
}
#endif

View File

@ -114,6 +114,22 @@ static inline void mmu_ll_write_entry(uint32_t mmu_id, uint32_t entry_id, uint32
*(uint32_t *)(DR_REG_MMU_TABLE + entry_id * 4) = mmu_val | MMU_ACCESS_FLASH | MMU_VALID;
}
/**
* Read the raw value from MMU table
*
* @param mmu_id MMU ID
* @param entry_id MMU entry ID
* @param mmu_val Value to be read from MMU table
*/
__attribute__((always_inline))
static inline uint32_t mmu_ll_read_entry(uint32_t mmu_id, uint32_t entry_id)
{
(void)mmu_id;
HAL_ASSERT(entry_id < MMU_ENTRY_NUM);
return *(uint32_t *)(DR_REG_MMU_TABLE + entry_id * 4);
}
/**
* Set MMU table entry as invalid
*
@ -142,6 +158,22 @@ static inline void mmu_ll_unmap_all(uint32_t mmu_id)
}
}
/**
* Get MMU table entry is invalid
*
* @param mmu_id MMU ID
* @param entry_id MMU entry ID
* return ture for MMU entry is invalid, false for valid
*/
__attribute__((always_inline))
static inline bool mmu_ll_get_entry_is_invalid(uint32_t mmu_id, uint32_t entry_id)
{
(void)mmu_id;
HAL_ASSERT(entry_id < MMU_ENTRY_NUM);
return (*(uint32_t *)(DR_REG_MMU_TABLE + entry_id * 4) & MMU_INVALID) ? true : false;
}
#ifdef __cplusplus
}
#endif

View File

@ -114,6 +114,22 @@ static inline void mmu_ll_write_entry(uint32_t mmu_id, uint32_t entry_id, uint32
*(uint32_t *)(DR_REG_MMU_TABLE + entry_id * 4) = mmu_val | MMU_ACCESS_FLASH | MMU_VALID;
}
/**
* Read the raw value from MMU table
*
* @param mmu_id MMU ID
* @param entry_id MMU entry ID
* @param mmu_val Value to be read from MMU table
*/
__attribute__((always_inline))
static inline uint32_t mmu_ll_read_entry(uint32_t mmu_id, uint32_t entry_id)
{
(void)mmu_id;
HAL_ASSERT(entry_id < MMU_ENTRY_NUM);
return *(uint32_t *)(DR_REG_MMU_TABLE + entry_id * 4);
}
/**
* Set MMU table entry as invalid
*
@ -142,6 +158,22 @@ static inline void mmu_ll_unmap_all(uint32_t mmu_id)
}
}
/**
* Get MMU table entry is invalid
*
* @param mmu_id MMU ID
* @param entry_id MMU entry ID
* return ture for MMU entry is invalid, false for valid
*/
__attribute__((always_inline))
static inline bool mmu_ll_get_entry_is_invalid(uint32_t mmu_id, uint32_t entry_id)
{
(void)mmu_id;
HAL_ASSERT(entry_id < MMU_ENTRY_NUM);
return (*(uint32_t *)(DR_REG_MMU_TABLE + entry_id * 4) & MMU_INVALID) ? true : false;
}
#ifdef __cplusplus
}
#endif

View File

@ -138,6 +138,22 @@ static inline void mmu_ll_write_entry(uint32_t mmu_id, uint32_t entry_id, uint32
*(uint32_t *)(DR_REG_MMU_TABLE + entry_id * 4) = mmu_val | target_code | MMU_VALID;
}
/**
* Read the raw value from MMU table
*
* @param mmu_id MMU ID
* @param entry_id MMU entry ID
* @param mmu_val Value to be read from MMU table
*/
__attribute__((always_inline))
static inline uint32_t mmu_ll_read_entry(uint32_t mmu_id, uint32_t entry_id)
{
(void)mmu_id;
HAL_ASSERT(entry_id < MMU_ENTRY_NUM);
return *(uint32_t *)(DR_REG_MMU_TABLE + entry_id * 4);
}
/**
* Set MMU table entry as invalid
*
@ -166,6 +182,22 @@ static inline void mmu_ll_unmap_all(uint32_t mmu_id)
}
}
/**
* Get MMU table entry is invalid
*
* @param mmu_id MMU ID
* @param entry_id MMU entry ID
* return ture for MMU entry is invalid, false for valid
*/
__attribute__((always_inline))
static inline bool mmu_ll_get_entry_is_invalid(uint32_t mmu_id, uint32_t entry_id)
{
(void)mmu_id;
HAL_ASSERT(entry_id < MMU_ENTRY_NUM);
return (*(uint32_t *)(DR_REG_MMU_TABLE + entry_id * 4) & MMU_INVALID) ? true : false;
}
#ifdef __cplusplus
}
#endif

View File

@ -114,6 +114,22 @@ static inline void mmu_ll_write_entry(uint32_t mmu_id, uint32_t entry_id, uint32
*(uint32_t *)(DR_REG_MMU_TABLE + entry_id * 4) = mmu_val | target_code | MMU_VALID;
}
/**
* Read the raw value from MMU table
*
* @param mmu_id MMU ID
* @param entry_id MMU entry ID
* @param mmu_val Value to be read from MMU table
*/
__attribute__((always_inline))
static inline uint32_t mmu_ll_read_entry(uint32_t mmu_id, uint32_t entry_id)
{
(void)mmu_id;
HAL_ASSERT(entry_id < MMU_ENTRY_NUM);
return *(uint32_t *)(DR_REG_MMU_TABLE + entry_id * 4);
}
/**
* Set MMU table entry as invalid
*
@ -142,6 +158,22 @@ static inline void mmu_ll_unmap_all(uint32_t mmu_id)
}
}
/**
* Get MMU table entry is invalid
*
* @param mmu_id MMU ID
* @param entry_id MMU entry ID
* return ture for MMU entry is invalid, false for valid
*/
__attribute__((always_inline))
static inline bool mmu_ll_get_entry_is_invalid(uint32_t mmu_id, uint32_t entry_id)
{
(void)mmu_id;
HAL_ASSERT(entry_id < MMU_ENTRY_NUM);
return (*(uint32_t *)(DR_REG_MMU_TABLE + entry_id * 4) & MMU_INVALID) ? true : false;
}
#ifdef __cplusplus
}
#endif

View File

@ -28,6 +28,14 @@ typedef enum {
MMU_TARGET_PSRAM0,
} mmu_target_t;
/**
* MMU table id
*/
typedef enum {
MMU_TABLE_CORE0,
MMU_TABLE_CORE1,
} mmu_table_id_t;
#ifdef __cplusplus
}
#endif

View File

@ -37,6 +37,8 @@ extern "C" {
#define ADDRESS_IN_DRAM1_CACHE(vaddr) ADDRESS_IN_BUS(DRAM1_CACHE, vaddr)
#define ADDRESS_IN_DROM0_CACHE(vaddr) ADDRESS_IN_BUS(DROM0_CACHE, vaddr)
#define MMU_INVALID BIT(8)
//MMU entry num
#define MMU_ENTRY_NUM 256

View File

@ -21,11 +21,8 @@ extern "C" {
#define SOC_MMU_IROM0_PAGES_END 256
#define SOC_MMU_DROM0_PAGES_START 0
#define SOC_MMU_DROM0_PAGES_END 64
#define SOC_MMU_INVALID_ENTRY_VAL DPORT_FLASH_MMU_TABLE_INVALID_VAL
#define SOC_MMU_ADDR_MASK DPORT_MMU_ADDRESS_MASK
#define SOC_MMU_PAGE_IN_FLASH(page) (page)
#define SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE DPORT_PRO_FLASH_MMU_TABLE
#define SOC_MMU_DPORT_APP_FLASH_MMU_TABLE DPORT_APP_FLASH_MMU_TABLE
#define SOC_MMU_VADDR1_START_ADDR SOC_IROM_MASK_LOW
#define SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE ((SOC_MMU_VADDR1_FIRST_USABLE_ADDR - SOC_MMU_VADDR1_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + SOC_MMU_IROM0_PAGES_START)
#define SOC_MMU_VADDR0_START_ADDR SOC_DROM_LOW

View File

@ -78,8 +78,6 @@ extern "C" {
#define FLASH_MMU_TABLE ((volatile uint32_t*) DR_REG_MMU_TABLE)
#define FLASH_MMU_TABLE_SIZE (ICACHE_MMU_SIZE/sizeof(uint32_t))
#define MMU_TABLE_INVALID_VAL MMU_INVALID
#define FLASH_MMU_TABLE_INVALID_VAL DPORT_MMU_TABLE_INVALID_VAL
/**
* MMU entry valid bit mask for mapping value. For an entry:
* valid bit + value bits

View File

@ -20,10 +20,8 @@ extern "C" {
#define SOC_MMU_IROM0_PAGES_END (CACHE_IROM_MMU_END / sizeof(uint32_t))
#define SOC_MMU_DROM0_PAGES_START (CACHE_DROM_MMU_START / sizeof(uint32_t))
#define SOC_MMU_DROM0_PAGES_END (CACHE_DROM_MMU_END / sizeof(uint32_t))
#define SOC_MMU_INVALID_ENTRY_VAL MMU_TABLE_INVALID_VAL
#define SOC_MMU_ADDR_MASK MMU_VALID_VAL_MASK
#define SOC_MMU_PAGE_IN_FLASH(page) (page) //Always in Flash
#define SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE FLASH_MMU_TABLE
#define SOC_MMU_VADDR1_START_ADDR IRAM0_CACHE_ADDRESS_LOW
#define SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE SOC_MMU_IROM0_PAGES_START
#define SOC_MMU_VADDR0_START_ADDR (SOC_DROM_LOW + (SOC_MMU_DROM0_PAGES_START * SPI_FLASH_MMU_PAGE_SIZE))

View File

@ -73,8 +73,6 @@ extern "C" {
#define FLASH_MMU_TABLE ((volatile uint32_t*) DR_REG_MMU_TABLE)
#define FLASH_MMU_TABLE_SIZE (ICACHE_MMU_SIZE/sizeof(uint32_t))
#define MMU_TABLE_INVALID_VAL 0x100
#define FLASH_MMU_TABLE_INVALID_VAL DPORT_MMU_TABLE_INVALID_VAL
/**
* MMU entry valid bit mask for mapping value. For an entry:
* valid bit + value bits

View File

@ -20,10 +20,8 @@ extern "C" {
#define SOC_MMU_IROM0_PAGES_END (CACHE_IROM_MMU_END / sizeof(uint32_t))
#define SOC_MMU_DROM0_PAGES_START (CACHE_DROM_MMU_START / sizeof(uint32_t))
#define SOC_MMU_DROM0_PAGES_END (CACHE_DROM_MMU_END / sizeof(uint32_t))
#define SOC_MMU_INVALID_ENTRY_VAL MMU_TABLE_INVALID_VAL
#define SOC_MMU_ADDR_MASK MMU_VALID_VAL_MASK
#define SOC_MMU_PAGE_IN_FLASH(page) (page) //Always in Flash
#define SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE FLASH_MMU_TABLE
#define SOC_MMU_VADDR1_START_ADDR IRAM0_CACHE_ADDRESS_LOW
#define SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE SOC_MMU_IROM0_PAGES_START
#define SOC_MMU_VADDR0_START_ADDR (SOC_DROM_LOW + (SOC_MMU_DROM0_PAGES_START * SPI_FLASH_MMU_PAGE_SIZE))

View File

@ -73,8 +73,6 @@ extern "C" {
#define FLASH_MMU_TABLE ((volatile uint32_t*) DR_REG_MMU_TABLE)
#define FLASH_MMU_TABLE_SIZE (ICACHE_MMU_SIZE/sizeof(uint32_t))
#define MMU_TABLE_INVALID_VAL 0x100
#define FLASH_MMU_TABLE_INVALID_VAL DPORT_MMU_TABLE_INVALID_VAL
/**
* MMU entry valid bit mask for mapping value. For an entry:
* valid bit + value bits

View File

@ -20,10 +20,8 @@ extern "C" {
#define SOC_MMU_IROM0_PAGES_END (CACHE_IROM_MMU_END / sizeof(uint32_t))
#define SOC_MMU_DROM0_PAGES_START (CACHE_DROM_MMU_START / sizeof(uint32_t))
#define SOC_MMU_DROM0_PAGES_END (CACHE_DROM_MMU_END / sizeof(uint32_t))
#define SOC_MMU_INVALID_ENTRY_VAL MMU_TABLE_INVALID_VAL
#define SOC_MMU_ADDR_MASK MMU_VALID_VAL_MASK
#define SOC_MMU_PAGE_IN_FLASH(page) (page) //Always in Flash
#define SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE FLASH_MMU_TABLE
#define SOC_MMU_VADDR1_START_ADDR IRAM0_CACHE_ADDRESS_LOW
#define SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE SOC_MMU_IROM0_PAGES_START
#define SOC_MMU_VADDR0_START_ADDR (SOC_DROM_LOW + (SOC_MMU_DROM0_PAGES_START * SPI_FLASH_MMU_PAGE_SIZE))

View File

@ -102,8 +102,6 @@ extern "C" {
#define FLASH_MMU_TABLE ((volatile uint32_t*) DR_REG_MMU_TABLE)
#define FLASH_MMU_TABLE_SIZE (ICACHE_MMU_SIZE/sizeof(uint32_t))
#define MMU_TABLE_INVALID_VAL 0x4000
#define FLASH_MMU_TABLE_INVALID_VAL DPORT_MMU_TABLE_INVALID_VAL
/**
* MMU entry valid bit mask for mapping value. For an entry:
* valid bit + value bits

View File

@ -20,10 +20,8 @@ extern "C" {
#define SOC_MMU_IROM0_PAGES_END (PRO_CACHE_IBUS1_MMU_END / sizeof(uint32_t))
#define SOC_MMU_DROM0_PAGES_START (PRO_CACHE_IBUS2_MMU_START / sizeof(uint32_t))
#define SOC_MMU_DROM0_PAGES_END (PRO_CACHE_IBUS2_MMU_END / sizeof(uint32_t))
#define SOC_MMU_INVALID_ENTRY_VAL MMU_TABLE_INVALID_VAL
#define SOC_MMU_ADDR_MASK MMU_VALID_VAL_MASK
#define SOC_MMU_PAGE_IN_FLASH(page) ((page) | MMU_ACCESS_FLASH)
#define SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE FLASH_MMU_TABLE
#define SOC_MMU_VADDR1_START_ADDR SOC_IROM_MASK_LOW
#define SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE ((SOC_MMU_VADDR1_FIRST_USABLE_ADDR - SOC_MMU_VADDR1_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + SOC_MMU_IROM0_PAGES_START)
#define SOC_MMU_VADDR0_START_ADDR SOC_DROM_LOW

View File

@ -73,8 +73,6 @@ extern "C" {
#define FLASH_MMU_TABLE ((volatile uint32_t*) DR_REG_MMU_TABLE)
#define FLASH_MMU_TABLE_SIZE (ICACHE_MMU_SIZE/sizeof(uint32_t))
#define MMU_TABLE_INVALID_VAL 0x4000
#define FLASH_MMU_TABLE_INVALID_VAL DPORT_MMU_TABLE_INVALID_VAL
/**
* MMU entry valid bit mask for mapping value. For an entry:
* valid bit + value bits

View File

@ -20,10 +20,8 @@ extern "C" {
#define SOC_MMU_IROM0_PAGES_END (CACHE_IROM_MMU_END / sizeof(uint32_t))
#define SOC_MMU_DROM0_PAGES_START (CACHE_DROM_MMU_START / sizeof(uint32_t))
#define SOC_MMU_DROM0_PAGES_END (CACHE_DROM_MMU_END / sizeof(uint32_t))
#define SOC_MMU_INVALID_ENTRY_VAL MMU_TABLE_INVALID_VAL
#define SOC_MMU_ADDR_MASK MMU_VALID_VAL_MASK
#define SOC_MMU_PAGE_IN_FLASH(page) ((page) | MMU_ACCESS_FLASH)
#define SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE FLASH_MMU_TABLE
#define SOC_MMU_VADDR1_START_ADDR IRAM0_CACHE_ADDRESS_LOW
#define SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE SOC_MMU_IROM0_PAGES_START
#define SOC_MMU_VADDR0_START_ADDR (SOC_DROM_LOW + (SOC_MMU_DROM0_PAGES_START * SPI_FLASH_MMU_PAGE_SIZE))

View File

@ -12,16 +12,13 @@
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/semphr.h>
#include "soc/soc.h"
#include "soc/soc_memory_layout.h"
#include "soc/dport_access.h"
#include "sdkconfig.h"
#include "esp_attr.h"
#include "esp_spi_flash.h"
#include "esp_flash_encrypt.h"
#include "esp_rom_spiflash.h"
#include "esp_log.h"
#include "cache_utils.h"
#include "hal/mmu_ll.h"
#if CONFIG_IDF_TARGET_ESP32
#include "soc/dport_reg.h"
@ -87,28 +84,26 @@ static void IRAM_ATTR spi_flash_mmap_init(void)
if (s_mmap_page_refcnt[SOC_MMU_DROM0_PAGES_START] != 0) {
return; /* mmap data already initialised */
}
DPORT_INTERRUPT_DISABLE();
for (int i = 0; i < SOC_MMU_REGIONS_COUNT * SOC_MMU_PAGES_PER_REGION; ++i) {
uint32_t entry_pro = DPORT_SEQUENCE_REG_READ((uint32_t)&SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i]);
uint32_t entry_pro = mmu_ll_read_entry(MMU_TABLE_CORE0, i);
#if !CONFIG_FREERTOS_UNICORE && CONFIG_IDF_TARGET_ESP32
uint32_t entry_app = DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_APP_FLASH_MMU_TABLE[i]);
uint32_t entry_app = mmu_ll_read_entry(MMU_TABLE_CORE1, i);
if (entry_pro != entry_app) {
// clean up entries used by boot loader
entry_pro = SOC_MMU_INVALID_ENTRY_VAL;
SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i] = SOC_MMU_INVALID_ENTRY_VAL;
mmu_ll_set_entry_invalid(MMU_TABLE_CORE0, i);
}
#endif
if ((entry_pro & SOC_MMU_INVALID_ENTRY_VAL) == 0 && (i == SOC_MMU_DROM0_PAGES_START || i == SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE || entry_pro != 0)) {
bool entry_pro_invalid = mmu_ll_get_entry_is_invalid(MMU_TABLE_CORE0, i);
if (!entry_pro_invalid && (i == SOC_MMU_DROM0_PAGES_START || i == SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE || entry_pro != 0)) {
s_mmap_page_refcnt[i] = 1;
} else {
SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i] = SOC_MMU_INVALID_ENTRY_VAL;
mmu_ll_set_entry_invalid(MMU_TABLE_CORE0, i);
#if !CONFIG_FREERTOS_UNICORE && CONFIG_IDF_TARGET_ESP32
DPORT_APP_FLASH_MMU_TABLE[i] = SOC_MMU_INVALID_ENTRY_VAL;
mmu_ll_set_entry_invalid(MMU_TABLE_CORE1, i);
#endif
}
}
DPORT_INTERRUPT_RESTORE();
}
static void IRAM_ATTR get_mmu_region(spi_flash_mmap_memory_t memory, int* out_begin, int* out_size,uint32_t* region_addr)
@ -133,7 +128,7 @@ esp_err_t IRAM_ATTR spi_flash_mmap(size_t src_addr, size_t size, spi_flash_mmap_
if (src_addr & INVALID_PHY_PAGE) {
return ESP_ERR_INVALID_ARG;
}
if (src_addr + size > g_rom_flashchip.chip_size) {
if ((src_addr + size) > spi_flash_get_chip_size()) {
return ESP_ERR_INVALID_ARG;
}
// region which should be mapped
@ -166,7 +161,7 @@ esp_err_t IRAM_ATTR spi_flash_mmap_pages(const int *pages, size_t page_count, sp
return ESP_ERR_INVALID_ARG;
}
for (int i = 0; i < page_count; i++) {
if (pages[i] < 0 || pages[i]*SPI_FLASH_MMU_PAGE_SIZE >= g_rom_flashchip.chip_size) {
if (pages[i] < 0 || pages[i]*SPI_FLASH_MMU_PAGE_SIZE >= spi_flash_get_chip_size()) {
return ESP_ERR_INVALID_ARG;
}
}
@ -197,15 +192,13 @@ esp_err_t IRAM_ATTR spi_flash_mmap_pages(const int *pages, size_t page_count, sp
for (start = region_begin; start < end; ++start) {
int pageno = 0;
int pos;
DPORT_INTERRUPT_DISABLE();
for (pos = start; pos < start + page_count; ++pos, ++pageno) {
int table_val = (int) DPORT_SEQUENCE_REG_READ((uint32_t)&SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[pos]);
int table_val = (int) mmu_ll_read_entry(MMU_TABLE_CORE0, pos);
uint8_t refcnt = s_mmap_page_refcnt[pos];
if (refcnt != 0 && table_val != SOC_MMU_PAGE_IN_FLASH(pages[pageno])) {
break;
}
}
DPORT_INTERRUPT_RESTORE();
// whole mapping range matched, bail out
if (pos - start == page_count) {
break;
@ -217,12 +210,11 @@ esp_err_t IRAM_ATTR spi_flash_mmap_pages(const int *pages, size_t page_count, sp
} else {
// set up mapping using pages
uint32_t pageno = 0;
DPORT_INTERRUPT_DISABLE();
for (int i = start; i != start + page_count; ++i, ++pageno) {
// sanity check: we won't reconfigure entries with non-zero reference count
uint32_t entry_pro = DPORT_SEQUENCE_REG_READ((uint32_t)&SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i]);
uint32_t entry_pro = mmu_ll_read_entry(MMU_TABLE_CORE0, i);
#if !CONFIG_FREERTOS_UNICORE && CONFIG_IDF_TARGET_ESP32
uint32_t entry_app = DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_APP_FLASH_MMU_TABLE[i]);
uint32_t entry_app = mmu_ll_read_entry(MMU_TABLE_CORE1, i);
#endif
assert(s_mmap_page_refcnt[i] == 0 ||
(entry_pro == SOC_MMU_PAGE_IN_FLASH(pages[pageno])
@ -236,9 +228,9 @@ esp_err_t IRAM_ATTR spi_flash_mmap_pages(const int *pages, size_t page_count, sp
|| entry_app != SOC_MMU_PAGE_IN_FLASH(pages[pageno])
#endif
) {
SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i] = SOC_MMU_PAGE_IN_FLASH(pages[pageno]);
mmu_ll_write_entry(MMU_TABLE_CORE0, i, pages[pageno], 0);
#if !CONFIG_FREERTOS_UNICORE && CONFIG_IDF_TARGET_ESP32
DPORT_APP_FLASH_MMU_TABLE[i] = pages[pageno];
mmu_ll_write_entry(MMU_TABLE_CORE1, i, pages[pageno], 0);
#endif
#if !CONFIG_IDF_TARGET_ESP32
@ -249,7 +241,6 @@ esp_err_t IRAM_ATTR spi_flash_mmap_pages(const int *pages, size_t page_count, sp
}
++s_mmap_page_refcnt[i];
}
DPORT_INTERRUPT_RESTORE();
LIST_INSERT_HEAD(&s_mmap_entries_head, new_entry, entries);
new_entry->page = start;
new_entry->count = page_count;
@ -299,9 +290,9 @@ void IRAM_ATTR spi_flash_munmap(spi_flash_mmap_handle_t handle)
for (int i = it->page; i < it->page + it->count; ++i) {
assert(s_mmap_page_refcnt[i] > 0);
if (--s_mmap_page_refcnt[i] == 0) {
SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i] = SOC_MMU_INVALID_ENTRY_VAL;
mmu_ll_set_entry_invalid(MMU_TABLE_CORE0, i);
#if !CONFIG_FREERTOS_UNICORE && CONFIG_IDF_TARGET_ESP32
DPORT_APP_FLASH_MMU_TABLE[i] = SOC_MMU_INVALID_ENTRY_VAL;
mmu_ll_set_entry_invalid(MMU_TABLE_CORE1, i);
#endif
}
}
@ -327,7 +318,7 @@ static uint32_t IRAM_ATTR NOINLINE_ATTR spi_flash_protected_read_mmu_entry(int i
{
uint32_t value;
spi_flash_disable_interrupts_caches_and_other_cpu();
value = DPORT_REG_READ((uint32_t)&SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[index]);
value = mmu_ll_read_entry(MMU_TABLE_CORE0, index);
spi_flash_enable_interrupts_caches_and_other_cpu();
return value;
}
@ -357,13 +348,12 @@ uint32_t IRAM_ATTR spi_flash_mmap_get_free_pages(spi_flash_mmap_memory_t memory)
int region_size; // number of pages to check
uint32_t region_addr; // base address of memory region
get_mmu_region(memory,&region_begin,&region_size,&region_addr);
DPORT_INTERRUPT_DISABLE();
for (int i = region_begin; i < region_begin + region_size; ++i) {
if (s_mmap_page_refcnt[i] == 0 && DPORT_SEQUENCE_REG_READ((uint32_t)&SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i]) == SOC_MMU_INVALID_ENTRY_VAL) {
bool entry_is_invalid = mmu_ll_get_entry_is_invalid(MMU_TABLE_CORE0, i);
if (s_mmap_page_refcnt[i] == 0 && entry_is_invalid) {
count++;
}
}
DPORT_INTERRUPT_RESTORE();
spi_flash_enable_interrupts_caches_and_other_cpu();
return count;
}
@ -400,7 +390,8 @@ size_t spi_flash_cache2phys(const void *cached)
return SPI_FLASH_CACHE2PHYS_FAIL;
}
uint32_t phys_page = spi_flash_protected_read_mmu_entry(cache_page);
if (phys_page == SOC_MMU_INVALID_ENTRY_VAL) {
bool entry_is_invalid = mmu_ll_get_entry_is_invalid(MMU_TABLE_CORE0, cache_page);
if (entry_is_invalid) {
/* page is not mapped */
return SPI_FLASH_CACHE2PHYS_FAIL;
}
@ -426,9 +417,8 @@ const void *IRAM_ATTR spi_flash_phys2cache(size_t phys_offs, spi_flash_mmap_memo
page_delta = SOC_MMU_IROM0_PAGES_START;
}
spi_flash_disable_interrupts_caches_and_other_cpu();
DPORT_INTERRUPT_DISABLE();
for (int i = start; i < end; i++) {
uint32_t mmu_value = DPORT_SEQUENCE_REG_READ((uint32_t)&SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i]);
uint32_t mmu_value = mmu_ll_read_entry(MMU_TABLE_CORE0, i);
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
if (phys_page >= instruction_flash_start_page_get() && phys_page <= instruction_flash_end_page_get()) {
if (mmu_value & MMU_ACCESS_SPIRAM) {
@ -448,12 +438,10 @@ const void *IRAM_ATTR spi_flash_phys2cache(size_t phys_offs, spi_flash_mmap_memo
if (mmu_value == SOC_MMU_PAGE_IN_FLASH(phys_page)) {
i -= page_delta;
intptr_t cache_page = base + (SPI_FLASH_MMU_PAGE_SIZE * i);
DPORT_INTERRUPT_RESTORE();
spi_flash_enable_interrupts_caches_and_other_cpu();
return (const void *) (cache_page | (phys_offs & (SPI_FLASH_MMU_PAGE_SIZE-1)));
}
}
DPORT_INTERRUPT_RESTORE();
spi_flash_enable_interrupts_caches_and_other_cpu();
return NULL;
}
@ -472,10 +460,10 @@ static bool IRAM_ATTR is_page_mapped_in_cache(uint32_t phys_page, const void **o
start[1] = SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE;
end[1] = SOC_MMU_IROM0_PAGES_END;
DPORT_INTERRUPT_DISABLE();
for (int j = 0; j < 2; j++) {
for (int i = start[j]; i < end[j]; i++) {
if (DPORT_SEQUENCE_REG_READ((uint32_t)&SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i]) == SOC_MMU_PAGE_IN_FLASH(phys_page)) {
uint32_t entry_pro = mmu_ll_read_entry(MMU_TABLE_CORE0, i);
if (entry_pro == SOC_MMU_PAGE_IN_FLASH(phys_page)) {
#if !CONFIG_IDF_TARGET_ESP32
if (j == 0) { /* SPI_FLASH_MMAP_DATA */
*out_ptr = (const void *)(SOC_MMU_VADDR0_START_ADDR + SPI_FLASH_MMU_PAGE_SIZE * (i - start[0]));
@ -483,12 +471,10 @@ static bool IRAM_ATTR is_page_mapped_in_cache(uint32_t phys_page, const void **o
*out_ptr = (const void *)(SOC_MMU_VADDR1_FIRST_USABLE_ADDR + SPI_FLASH_MMU_PAGE_SIZE * (i - start[1]));
}
#endif
DPORT_INTERRUPT_RESTORE();
return true;
}
}
}
DPORT_INTERRUPT_RESTORE();
return false;
}
@ -502,6 +488,7 @@ IRAM_ATTR bool spi_flash_check_and_flush_cache(size_t start_addr, size_t length)
length = (length + SPI_FLASH_MMU_PAGE_SIZE - 1) & ~(SPI_FLASH_MMU_PAGE_SIZE-1);
for (uint32_t addr = page_start_addr; addr < page_start_addr + length; addr += SPI_FLASH_MMU_PAGE_SIZE) {
uint32_t page = addr / SPI_FLASH_MMU_PAGE_SIZE;
// TODO: IDF-4969
if (page >= 256) {
return false; /* invalid address */
}

View File

@ -147,7 +147,7 @@ typedef void (*flash_test_func_t)(const esp_partition_t *part);
#else //CONFIG_SPIRAM
#if !CONFIG_IDF_TARGET_ESP32C3
#define FLASH_TEST_CASE_3(STR, FUNC_TO_RUN) \
TEST_CASE(STR", 3 chips", "[esp_flash_3][test_env=UT_T1_ESP_FLASH]") {flash_test_func(FUNC_TO_RUN, TEST_CONFIG_NUM);}
TEST_CASE(STR", 3 chips", "[esp_flash_3][test_env=UT_T1_ESP_FLASH][timeout=35]") {flash_test_func(FUNC_TO_RUN, TEST_CONFIG_NUM);}
#define FLASH_TEST_CASE_3_IGNORE(STR, FUNC_TO_RUN) \
TEST_CASE(STR", 3 chips", "[esp_flash_3][test_env=UT_T1_ESP_FLASH][ignore]") {flash_test_func(FUNC_TO_RUN, TEST_CONFIG_NUM);}