mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-31 19:24:33 +02:00
Merge branch 'feature/flash_qio_wp_pin' into 'master'
bootloader: Flash QIO configuration feature & fix See merge request !895
This commit is contained in:
@@ -28,8 +28,22 @@ config LOG_BOOTLOADER_LEVEL
|
|||||||
default 4 if LOG_BOOTLOADER_LEVEL_DEBUG
|
default 4 if LOG_BOOTLOADER_LEVEL_DEBUG
|
||||||
default 5 if LOG_BOOTLOADER_LEVEL_VERBOSE
|
default 5 if LOG_BOOTLOADER_LEVEL_VERBOSE
|
||||||
|
|
||||||
endmenu
|
config BOOTLOADER_SPI_WP_PIN
|
||||||
|
int "SPI Flash WP Pin when customising pins via efuse (read help)"
|
||||||
|
range 0 33
|
||||||
|
default 7
|
||||||
|
depends on FLASHMODE_QIO || FLASHMODE_QOUT
|
||||||
|
help
|
||||||
|
This value is ignored unless flash mode is set to QIO or QOUT *and* the SPI flash pins have been
|
||||||
|
overriden by setting the efuses SPI_PAD_CONFIG_xxx.
|
||||||
|
|
||||||
|
When this is the case, the Efuse config only defines 3 of the 4 Quad I/O data pins. The WP pin (aka ESP32
|
||||||
|
pin "SD_DATA_3" or SPI flash pin "IO2") is not specified in Efuse. That pin number is compiled into the bootloader
|
||||||
|
instead.
|
||||||
|
|
||||||
|
The default value (GPIO 7) is correct for WP pin on ESP32-D2WD integrated flash.
|
||||||
|
|
||||||
|
endmenu # Bootloader
|
||||||
|
|
||||||
|
|
||||||
menu "Security features"
|
menu "Security features"
|
||||||
@@ -212,6 +226,5 @@ config SECURE_BOOT_TEST_MODE
|
|||||||
This option is for testing purposes only - it completely disables secure boot protection.
|
This option is for testing purposes only - it completely disables secure boot protection.
|
||||||
|
|
||||||
|
|
||||||
endmenu # potentially insecure
|
endmenu # Potentially Insecure
|
||||||
|
endmenu # Security features
|
||||||
endmenu
|
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "flash_qio_mode.h"
|
#include "flash_qio_mode.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
#include "esp_err.h"
|
||||||
#include "rom/spi_flash.h"
|
#include "rom/spi_flash.h"
|
||||||
#include "rom/efuse.h"
|
#include "rom/efuse.h"
|
||||||
#include "soc/spi_struct.h"
|
#include "soc/spi_struct.h"
|
||||||
@@ -35,9 +36,6 @@
|
|||||||
#define CMD_RDSR 0x05
|
#define CMD_RDSR 0x05
|
||||||
#define CMD_RDSR2 0x35 /* Not all SPI flash uses this command */
|
#define CMD_RDSR2 0x35 /* Not all SPI flash uses this command */
|
||||||
|
|
||||||
|
|
||||||
#define ESP32_D2WD_WP_GPIO 7 /* ESP32-D2WD has this GPIO wired to WP pin of flash */
|
|
||||||
|
|
||||||
static const char *TAG = "qio_mode";
|
static const char *TAG = "qio_mode";
|
||||||
|
|
||||||
typedef unsigned (*read_status_fn_t)();
|
typedef unsigned (*read_status_fn_t)();
|
||||||
@@ -67,6 +65,12 @@ static void write_status_8b_wrsr2(unsigned new_status);
|
|||||||
/* Write 16 bit status using WRSR */
|
/* Write 16 bit status using WRSR */
|
||||||
static void write_status_16b_wrsr(unsigned new_status);
|
static void write_status_16b_wrsr(unsigned new_status);
|
||||||
|
|
||||||
|
#define ESP32_D2WD_WP_GPIO 7 /* ESP32-D2WD has this GPIO wired to WP pin of flash */
|
||||||
|
|
||||||
|
#ifndef CONFIG_BOOTLOADER_SPI_WP_PIN // Set in menuconfig if SPI flasher config is set to a quad mode
|
||||||
|
#define CONFIG_BOOTLOADER_SPI_WP_PIN ESP32_D2WD_WP_GPIO
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Array of known flash chips and data to enable Quad I/O mode
|
/* Array of known flash chips and data to enable Quad I/O mode
|
||||||
|
|
||||||
Manufacturer & flash ID can be tested by running "esptool.py
|
Manufacturer & flash ID can be tested by running "esptool.py
|
||||||
@@ -96,7 +100,7 @@ const static qio_info_t chip_data[] = {
|
|||||||
|
|
||||||
#define NUM_CHIPS (sizeof(chip_data) / sizeof(qio_info_t))
|
#define NUM_CHIPS (sizeof(chip_data) / sizeof(qio_info_t))
|
||||||
|
|
||||||
static void enable_qio_mode(read_status_fn_t read_status_fn,
|
static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn,
|
||||||
write_status_fn_t write_status_fn,
|
write_status_fn_t write_status_fn,
|
||||||
uint8_t status_qio_bit);
|
uint8_t status_qio_bit);
|
||||||
|
|
||||||
@@ -112,6 +116,7 @@ extern uint8_t g_rom_spiflash_dummy_len_plus[];
|
|||||||
|
|
||||||
void bootloader_enable_qio_mode(void)
|
void bootloader_enable_qio_mode(void)
|
||||||
{
|
{
|
||||||
|
uint32_t old_ctrl_reg;
|
||||||
uint32_t raw_flash_id;
|
uint32_t raw_flash_id;
|
||||||
uint8_t mfg_id;
|
uint8_t mfg_id;
|
||||||
uint16_t flash_id;
|
uint16_t flash_id;
|
||||||
@@ -122,7 +127,8 @@ void bootloader_enable_qio_mode(void)
|
|||||||
|
|
||||||
/* Set up some of the SPIFLASH user/ctrl variables which don't change
|
/* Set up some of the SPIFLASH user/ctrl variables which don't change
|
||||||
while we're probing using execute_flash_command() */
|
while we're probing using execute_flash_command() */
|
||||||
SPIFLASH.ctrl.val = 0;
|
old_ctrl_reg = SPIFLASH.ctrl.val;
|
||||||
|
SPIFLASH.ctrl.val = SPI_WP_REG; // keep WP high while idle, otherwise leave DIO mode
|
||||||
SPIFLASH.user.usr_dummy = 0;
|
SPIFLASH.user.usr_dummy = 0;
|
||||||
SPIFLASH.user.usr_addr = 0;
|
SPIFLASH.user.usr_addr = 0;
|
||||||
SPIFLASH.user.usr_command = 1;
|
SPIFLASH.user.usr_command = 1;
|
||||||
@@ -147,12 +153,16 @@ void bootloader_enable_qio_mode(void)
|
|||||||
ESP_LOGI(TAG, "Enabling default flash chip QIO");
|
ESP_LOGI(TAG, "Enabling default flash chip QIO");
|
||||||
}
|
}
|
||||||
|
|
||||||
enable_qio_mode(chip_data[i].read_status_fn,
|
esp_err_t res = enable_qio_mode(chip_data[i].read_status_fn,
|
||||||
chip_data[i].write_status_fn,
|
chip_data[i].write_status_fn,
|
||||||
chip_data[i].status_qio_bit);
|
chip_data[i].status_qio_bit);
|
||||||
|
if (res != ESP_OK) {
|
||||||
|
// Restore SPI flash CTRL setting, to keep us in DIO/DOUT mode
|
||||||
|
SPIFLASH.ctrl.val = old_ctrl_reg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void enable_qio_mode(read_status_fn_t read_status_fn,
|
static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn,
|
||||||
write_status_fn_t write_status_fn,
|
write_status_fn_t write_status_fn,
|
||||||
uint8_t status_qio_bit)
|
uint8_t status_qio_bit)
|
||||||
{
|
{
|
||||||
@@ -160,15 +170,16 @@ static void enable_qio_mode(read_status_fn_t read_status_fn,
|
|||||||
const uint32_t spiconfig = ets_efuse_get_spiconfig();
|
const uint32_t spiconfig = ets_efuse_get_spiconfig();
|
||||||
|
|
||||||
if (spiconfig != EFUSE_SPICONFIG_SPI_DEFAULTS && spiconfig != EFUSE_SPICONFIG_HSPI_DEFAULTS) {
|
if (spiconfig != EFUSE_SPICONFIG_SPI_DEFAULTS && spiconfig != EFUSE_SPICONFIG_HSPI_DEFAULTS) {
|
||||||
// spiconfig specifies a custom efuse pin configuration. This config defines all pins -except- WP.
|
// spiconfig specifies a custom efuse pin configuration. This config defines all pins -except- WP,
|
||||||
|
// which is compiled into the bootloader instead.
|
||||||
//
|
//
|
||||||
// For now, in this situation we only support Quad I/O mode for ESP32-D2WD where WP pin is known.
|
// Most commonly an overriden pin mapping means ESP32-D2WD. Warn if chip is ESP32-D2WD
|
||||||
|
// but someone has changed the WP pin assignment from that chip's WP pin.
|
||||||
uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_RESERVE);
|
uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_RESERVE);
|
||||||
uint32_t pkg_ver = chip_ver & 0x7;
|
uint32_t pkg_ver = chip_ver & 0x7;
|
||||||
const uint32_t PKG_VER_ESP32_D2WD = 2; // TODO: use chip detection API once available
|
const int PKG_VER_ESP32_D2WD = 2; // TODO: use chip detection API once available
|
||||||
if (pkg_ver != PKG_VER_ESP32_D2WD) {
|
if (pkg_ver == PKG_VER_ESP32_D2WD && CONFIG_BOOTLOADER_SPI_WP_PIN != ESP32_D2WD_WP_GPIO) {
|
||||||
ESP_LOGE(TAG, "Quad I/O is only supported for standard pin numbers or ESP32-D2WD. Falling back to Dual I/O.");
|
ESP_LOGW(TAG, "Chip is ESP32-D2WD but flash WP pin is different value to internal flash");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,7 +198,7 @@ static void enable_qio_mode(read_status_fn_t read_status_fn,
|
|||||||
ESP_LOGD(TAG, "Updated flash chip status 0x%x", status);
|
ESP_LOGD(TAG, "Updated flash chip status 0x%x", status);
|
||||||
if ((status & (1<<status_qio_bit)) == 0) {
|
if ((status & (1<<status_qio_bit)) == 0) {
|
||||||
ESP_LOGE(TAG, "Failed to set QIE bit, not enabling QIO mode");
|
ESP_LOGE(TAG, "Failed to set QIE bit, not enabling QIO mode");
|
||||||
return;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -205,7 +216,9 @@ static void enable_qio_mode(read_status_fn_t read_status_fn,
|
|||||||
|
|
||||||
esp_rom_spiflash_config_readmode(mode);
|
esp_rom_spiflash_config_readmode(mode);
|
||||||
|
|
||||||
esp_rom_spiflash_select_qio_pins(ESP32_D2WD_WP_GPIO, spiconfig);
|
esp_rom_spiflash_select_qio_pins(CONFIG_BOOTLOADER_SPI_WP_PIN, spiconfig);
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned read_status_8b_rdsr()
|
static unsigned read_status_8b_rdsr()
|
||||||
|
Reference in New Issue
Block a user