Merge branch 'feature/cache_32M_map' into 'master'

spi_flash: 32M bits address flash cache map

Closes IDF-7119 and IDF-4693

See merge request espressif/esp-idf!23021
pull/11218/head
C.S.M 2023-04-14 16:01:25 +08:00
commit 247cc7dd87
14 zmienionych plików z 243 dodań i 57 usunięć

Wyświetl plik

@ -54,6 +54,13 @@ esp_err_t bootloader_flash_reset_chip(void);
*/
bool bootloader_flash_is_octal_mode_enabled(void);
/**
* @brief Get the spi flash working mode.
*
* @return The mode of flash working mode, see `esp_rom_spiflash_read_mode_t`
*/
esp_rom_spiflash_read_mode_t bootloader_flash_get_spi_mode(void);
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -109,6 +109,17 @@ extern const bootloader_qio_info_t __attribute__((weak)) bootloader_flash_qe_sup
*/
esp_err_t __attribute__((weak)) bootloader_flash_unlock(void);
#if CONFIG_SPI_FLASH_32BIT_ADDR_ENABLE
/**
* @brief Enable 32bits address flash(larger than 16MB) can map to cache.
*
* @param flash_mode SPI flash working mode.
*
* @note This can be overridden because it's attribute weak.
*/
void __attribute__((weak)) bootloader_flash_32bits_address_map_enable(esp_rom_spiflash_read_mode_t flash_mode);
#endif
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -52,6 +52,10 @@ extern "C" {
#define CMD_RESUME 0x7A /* Resume command to clear flash suspend bit */
#define CMD_RESETEN 0x66
#define CMD_RESET 0x99
#define CMD_FASTRD_QIO_4B 0xEC
#define CMD_FASTRD_QUAD_4B 0x6C
#define CMD_FASTRD_DIO_4B 0xBC
#define CMD_FASTRD_DUAL_4B 0x3C
/* Provide a Flash API for bootloader_support code,

Wyświetl plik

@ -123,6 +123,10 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size)
#include "hal/mmu_hal.h"
#include "hal/mmu_ll.h"
#include "hal/cache_hal.h"
#if CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/rom/opi_flash.h"
#endif
static const char *TAG = "bootloader_flash";
#if CONFIG_IDF_TARGET_ESP32
@ -409,6 +413,45 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size)
return spi_to_esp_err(rc);
}
#if CONFIG_SPI_FLASH_32BIT_ADDR_ENABLE
void bootloader_flash_32bits_address_map_enable(esp_rom_spiflash_read_mode_t flash_mode)
{
esp_rom_opiflash_spi0rd_t cache_rd = {};
switch (flash_mode) {
case ESP_ROM_SPIFLASH_DOUT_MODE:
cache_rd.addr_bit_len = 32;
cache_rd.dummy_bit_len = 8;
cache_rd.cmd = CMD_FASTRD_DUAL_4B;
cache_rd.cmd_bit_len = 8;
break;
case ESP_ROM_SPIFLASH_DIO_MODE:
cache_rd.addr_bit_len = 32;
cache_rd.dummy_bit_len = 4;
cache_rd.cmd = CMD_FASTRD_DIO_4B;
cache_rd.cmd_bit_len = 8;
break;
case ESP_ROM_SPIFLASH_QOUT_MODE:
cache_rd.addr_bit_len = 32;
cache_rd.dummy_bit_len = 8;
cache_rd.cmd = CMD_FASTRD_QUAD_4B;
cache_rd.cmd_bit_len = 8;
break;
case ESP_ROM_SPIFLASH_QIO_MODE:
cache_rd.addr_bit_len = 32;
cache_rd.dummy_bit_len = 6;
cache_rd.cmd = CMD_FASTRD_QIO_4B;
cache_rd.cmd_bit_len = 8;
break;
default:
assert(false);
break;
}
cache_hal_disable(CACHE_TYPE_ALL);
esp_rom_opiflash_cache_mode_config(flash_mode, &cache_rd);
cache_hal_enable(CACHE_TYPE_ALL);
}
#endif
#endif // BOOTLOADER_BUILD
@ -755,3 +798,40 @@ bool IRAM_ATTR bootloader_flash_is_octal_mode_enabled(void)
return false;
#endif
}
esp_rom_spiflash_read_mode_t bootloader_flash_get_spi_mode(void)
{
esp_rom_spiflash_read_mode_t spi_mode = ESP_ROM_SPIFLASH_FASTRD_MODE;
#if CONFIG_IDF_TARGET_ESP32
uint32_t spi_ctrl = REG_READ(SPI_CTRL_REG(0));
if (spi_ctrl & SPI_FREAD_QIO) {
spi_mode = ESP_ROM_SPIFLASH_QIO_MODE;
} else if (spi_ctrl & SPI_FREAD_QUAD) {
spi_mode = ESP_ROM_SPIFLASH_QOUT_MODE;
} else if (spi_ctrl & SPI_FREAD_DIO) {
spi_mode = ESP_ROM_SPIFLASH_DIO_MODE;
} else if (spi_ctrl & SPI_FREAD_DUAL) {
spi_mode = ESP_ROM_SPIFLASH_DOUT_MODE;
} else if (spi_ctrl & SPI_FASTRD_MODE) {
spi_mode = ESP_ROM_SPIFLASH_FASTRD_MODE;
} else {
spi_mode = ESP_ROM_SPIFLASH_SLOWRD_MODE;
}
#else
uint32_t spi_ctrl = REG_READ(SPI_MEM_CTRL_REG(0));
if (spi_ctrl & SPI_MEM_FREAD_QIO) {
spi_mode = ESP_ROM_SPIFLASH_QIO_MODE;
} else if (spi_ctrl & SPI_MEM_FREAD_QUAD) {
spi_mode = ESP_ROM_SPIFLASH_QOUT_MODE;
} else if (spi_ctrl & SPI_MEM_FREAD_DIO) {
spi_mode = ESP_ROM_SPIFLASH_DIO_MODE;
} else if (spi_ctrl & SPI_MEM_FREAD_DUAL) {
spi_mode = ESP_ROM_SPIFLASH_DOUT_MODE;
} else if (spi_ctrl & SPI_MEM_FASTRD_MODE) {
spi_mode = ESP_ROM_SPIFLASH_FASTRD_MODE;
} else {
spi_mode = ESP_ROM_SPIFLASH_SLOWRD_MODE;
}
#endif
return spi_mode;
}

Wyświetl plik

@ -308,19 +308,26 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr)
/* SPI mode could have been set to QIO during boot already,
so test the SPI registers not the flash header */
uint32_t spi_ctrl = REG_READ(SPI_CTRL_REG(0));
if (spi_ctrl & SPI_FREAD_QIO) {
esp_rom_spiflash_read_mode_t spi_mode = bootloader_flash_get_spi_mode();
switch (spi_mode) {
case ESP_ROM_SPIFLASH_QIO_MODE:
str = "QIO";
} else if (spi_ctrl & SPI_FREAD_QUAD) {
break;
case ESP_ROM_SPIFLASH_QOUT_MODE:
str = "QOUT";
} else if (spi_ctrl & SPI_FREAD_DIO) {
break;
case ESP_ROM_SPIFLASH_DIO_MODE:
str = "DIO";
} else if (spi_ctrl & SPI_FREAD_DUAL) {
break;
case ESP_ROM_SPIFLASH_DOUT_MODE:
str = "DOUT";
} else if (spi_ctrl & SPI_FASTRD_MODE) {
break;
case ESP_ROM_SPIFLASH_FASTRD_MODE:
str = "FAST READ";
} else {
break;
default:
str = "SLOW READ";
break;
}
ESP_EARLY_LOGI(TAG, "SPI Mode : %s", str);

Wyświetl plik

@ -163,19 +163,26 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr)
/* SPI mode could have been set to QIO during boot already,
so test the SPI registers not the flash header */
uint32_t spi_ctrl = REG_READ(SPI_MEM_CTRL_REG(0));
if (spi_ctrl & SPI_MEM_FREAD_QIO) {
esp_rom_spiflash_read_mode_t spi_mode = bootloader_flash_get_spi_mode();
switch (spi_mode) {
case ESP_ROM_SPIFLASH_QIO_MODE:
str = "QIO";
} else if (spi_ctrl & SPI_MEM_FREAD_QUAD) {
break;
case ESP_ROM_SPIFLASH_QOUT_MODE:
str = "QOUT";
} else if (spi_ctrl & SPI_MEM_FREAD_DIO) {
break;
case ESP_ROM_SPIFLASH_DIO_MODE:
str = "DIO";
} else if (spi_ctrl & SPI_MEM_FREAD_DUAL) {
break;
case ESP_ROM_SPIFLASH_DOUT_MODE:
str = "DOUT";
} else if (spi_ctrl & SPI_MEM_FASTRD_MODE) {
break;
case ESP_ROM_SPIFLASH_FASTRD_MODE:
str = "FAST READ";
} else {
break;
default:
str = "SLOW READ";
break;
}
ESP_EARLY_LOGI(TAG, "SPI Mode : %s", str);

Wyświetl plik

@ -174,19 +174,26 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr)
/* SPI mode could have been set to QIO during boot already,
so test the SPI registers not the flash header */
uint32_t spi_ctrl = REG_READ(SPI_MEM_CTRL_REG(0));
if (spi_ctrl & SPI_MEM_FREAD_QIO) {
esp_rom_spiflash_read_mode_t spi_mode = bootloader_flash_get_spi_mode();
switch (spi_mode) {
case ESP_ROM_SPIFLASH_QIO_MODE:
str = "QIO";
} else if (spi_ctrl & SPI_MEM_FREAD_QUAD) {
break;
case ESP_ROM_SPIFLASH_QOUT_MODE:
str = "QOUT";
} else if (spi_ctrl & SPI_MEM_FREAD_DIO) {
break;
case ESP_ROM_SPIFLASH_DIO_MODE:
str = "DIO";
} else if (spi_ctrl & SPI_MEM_FREAD_DUAL) {
break;
case ESP_ROM_SPIFLASH_DOUT_MODE:
str = "DOUT";
} else if (spi_ctrl & SPI_MEM_FASTRD_MODE) {
break;
case ESP_ROM_SPIFLASH_FASTRD_MODE:
str = "FAST READ";
} else {
break;
default:
str = "SLOW READ";
break;
}
ESP_EARLY_LOGI(TAG, "SPI Mode : %s", str);

Wyświetl plik

@ -139,19 +139,26 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr)
/* SPI mode could have been set to QIO during boot already,
so test the SPI registers not the flash header */
uint32_t spi_ctrl = REG_READ(SPI_MEM_CTRL_REG(0));
if (spi_ctrl & SPI_MEM_FREAD_QIO) {
esp_rom_spiflash_read_mode_t spi_mode = bootloader_flash_get_spi_mode();
switch (spi_mode) {
case ESP_ROM_SPIFLASH_QIO_MODE:
str = "QIO";
} else if (spi_ctrl & SPI_MEM_FREAD_QUAD) {
break;
case ESP_ROM_SPIFLASH_QOUT_MODE:
str = "QOUT";
} else if (spi_ctrl & SPI_MEM_FREAD_DIO) {
break;
case ESP_ROM_SPIFLASH_DIO_MODE:
str = "DIO";
} else if (spi_ctrl & SPI_MEM_FREAD_DUAL) {
break;
case ESP_ROM_SPIFLASH_DOUT_MODE:
str = "DOUT";
} else if (spi_ctrl & SPI_MEM_FASTRD_MODE) {
break;
case ESP_ROM_SPIFLASH_FASTRD_MODE:
str = "FAST READ";
} else {
break;
default:
str = "SLOW READ";
break;
}
ESP_EARLY_LOGI(TAG, "SPI Mode : %s", str);

Wyświetl plik

@ -146,19 +146,26 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr)
/* SPI mode could have been set to QIO during boot already,
so test the SPI registers not the flash header */
uint32_t spi_ctrl = REG_READ(SPI_MEM_CTRL_REG(0));
if (spi_ctrl & SPI_MEM_FREAD_QIO) {
esp_rom_spiflash_read_mode_t spi_mode = bootloader_flash_get_spi_mode();
switch (spi_mode) {
case ESP_ROM_SPIFLASH_QIO_MODE:
str = "QIO";
} else if (spi_ctrl & SPI_MEM_FREAD_QUAD) {
break;
case ESP_ROM_SPIFLASH_QOUT_MODE:
str = "QOUT";
} else if (spi_ctrl & SPI_MEM_FREAD_DIO) {
break;
case ESP_ROM_SPIFLASH_DIO_MODE:
str = "DIO";
} else if (spi_ctrl & SPI_MEM_FREAD_DUAL) {
break;
case ESP_ROM_SPIFLASH_DOUT_MODE:
str = "DOUT";
} else if (spi_ctrl & SPI_MEM_FASTRD_MODE) {
break;
case ESP_ROM_SPIFLASH_FASTRD_MODE:
str = "FAST READ";
} else {
break;
default:
str = "SLOW READ";
break;
}
ESP_EARLY_LOGI(TAG, "SPI Mode : %s", str);

Wyświetl plik

@ -173,19 +173,26 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr)
/* SPI mode could have been set to QIO during boot already,
so test the SPI registers not the flash header */
uint32_t spi_ctrl = REG_READ(SPI_MEM_CTRL_REG(0));
if (spi_ctrl & SPI_MEM_FREAD_QIO) {
esp_rom_spiflash_read_mode_t spi_mode = bootloader_flash_get_spi_mode();
switch (spi_mode) {
case ESP_ROM_SPIFLASH_QIO_MODE:
str = "QIO";
} else if (spi_ctrl & SPI_MEM_FREAD_QUAD) {
break;
case ESP_ROM_SPIFLASH_QOUT_MODE:
str = "QOUT";
} else if (spi_ctrl & SPI_MEM_FREAD_DIO) {
break;
case ESP_ROM_SPIFLASH_DIO_MODE:
str = "DIO";
} else if (spi_ctrl & SPI_MEM_FREAD_DUAL) {
break;
case ESP_ROM_SPIFLASH_DOUT_MODE:
str = "DOUT";
} else if (spi_ctrl & SPI_MEM_FASTRD_MODE) {
break;
case ESP_ROM_SPIFLASH_FASTRD_MODE:
str = "FAST READ";
} else {
break;
default:
str = "SLOW READ";
break;
}
ESP_EARLY_LOGI(TAG, "SPI Mode : %s", str);

Wyświetl plik

@ -188,19 +188,26 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr)
/* SPI mode could have been set to QIO during boot already,
so test the SPI registers not the flash header */
uint32_t spi_ctrl = REG_READ(SPI_MEM_CTRL_REG(0));
if (spi_ctrl & SPI_MEM_FREAD_QIO) {
esp_rom_spiflash_read_mode_t spi_mode = bootloader_flash_get_spi_mode();
switch (spi_mode) {
case ESP_ROM_SPIFLASH_QIO_MODE:
str = "QIO";
} else if (spi_ctrl & SPI_MEM_FREAD_QUAD) {
break;
case ESP_ROM_SPIFLASH_QOUT_MODE:
str = "QOUT";
} else if (spi_ctrl & SPI_MEM_FREAD_DIO) {
break;
case ESP_ROM_SPIFLASH_DIO_MODE:
str = "DIO";
} else if (spi_ctrl & SPI_MEM_FREAD_DUAL) {
break;
case ESP_ROM_SPIFLASH_DOUT_MODE:
str = "DOUT";
} else if (spi_ctrl & SPI_MEM_FASTRD_MODE) {
break;
case ESP_ROM_SPIFLASH_FASTRD_MODE:
str = "FAST READ";
} else {
break;
default:
str = "SLOW READ";
break;
}
ESP_EARLY_LOGI(TAG, "SPI Mode : %s", str);

Wyświetl plik

@ -195,19 +195,26 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr)
/* SPI mode could have been set to QIO during boot already,
so test the SPI registers not the flash header */
uint32_t spi_ctrl = REG_READ(SPI_MEM_CTRL_REG(0));
if (spi_ctrl & SPI_MEM_FREAD_QIO) {
esp_rom_spiflash_read_mode_t spi_mode = bootloader_flash_get_spi_mode();
switch (spi_mode) {
case ESP_ROM_SPIFLASH_QIO_MODE:
str = "QIO";
} else if (spi_ctrl & SPI_MEM_FREAD_QUAD) {
break;
case ESP_ROM_SPIFLASH_QOUT_MODE:
str = "QOUT";
} else if (spi_ctrl & SPI_MEM_FREAD_DIO) {
break;
case ESP_ROM_SPIFLASH_DIO_MODE:
str = "DIO";
} else if (spi_ctrl & SPI_MEM_FREAD_DUAL) {
break;
case ESP_ROM_SPIFLASH_DOUT_MODE:
str = "DOUT";
} else if (spi_ctrl & SPI_MEM_FASTRD_MODE) {
break;
case ESP_ROM_SPIFLASH_FASTRD_MODE:
str = "FAST READ";
} else {
break;
default:
str = "SLOW READ";
break;
}
ESP_EARLY_LOGI(TAG, "SPI Mode : %s", str);
@ -272,7 +279,9 @@ esp_err_t bootloader_init_spi_flash(void)
bootloader_enable_qio_mode();
}
#endif
#if CONFIG_SPI_FLASH_32BIT_ADDR_ENABLE
bootloader_flash_32bits_address_map_enable(bootloader_flash_get_spi_mode());
#endif
print_flash_info(&bootloader_image_hdr);
update_flash_config(&bootloader_image_hdr);
//ensure the flash is write-protected

Wyświetl plik

@ -310,4 +310,22 @@ menu "SPI Flash driver"
help
This option is invisible, and will be selected automatically
when ``ESPTOOLPY_FLASHFREQ_120M`` is selected.
config SPI_FLASH_32BIT_ADDRESS
bool
default y if ESPTOOLPY_FLASHSIZE_32MB || ESPTOOLPY_FLASHSIZE_64MB || ESPTOOLPY_FLASHSIZE_128MB
default n
help
This is a helper config for 32bits address flash. Invisible for users.
config SPI_FLASH_32BIT_ADDR_ENABLE
bool "Enable 32-bit-address (over 16MB) SPI Flash access"
depends on SPI_FLASH_32BIT_ADDRESS && !ESPTOOLPY_OCT_FLASH && IDF_TARGET_ESP32S3 && IDF_EXPERIMENTAL_FEATURES
default n
help
Enabling this option allows the CPU to access 32-bit-address flash beyond 16M range.
1. This option only valid for 4-line flash. Octal flash doesn't need this.
2. This option is experimental, which means it can't use on all flash chips stable, for more
information, please contact Espressif Business support.
endmenu

Wyświetl plik

@ -123,3 +123,11 @@ Flash Chips List:
1. W25Q256
2. GD25Q256
.. important::
Over 16 MBytes space on flash mentioned above can be only used for `data saving`, like file system. If your data / instructions over 16 MBytes spaces need to be mapped to MMU (so as to be accessed by the CPU), please enable the config `IDF_EXPERIMENTAL_FEATURES` and `CONFIG_SPI_FLASH_32BIT_ADDRESS` and read the limitations following:
1. This option only valid for 4-line flash. Octal flash doesn't need this.
2. Only MMU on ESP chip that supports mapping to a range over 16MB memory supports this config. (Only ESP32S3 supports this up to now)
3. This option is experimental, which means it can't use on all flash chips stable, for more information, please contact Espressif Business support.