Merge branch 'bugfix/bootloader_WEL_issi_qe' into 'master'

bootloader: fix flash not protected issue when exit

See merge request espressif/esp-idf!7959
This commit is contained in:
Michael (XIAO Xufeng)
2020-09-19 12:48:55 +08:00
30 changed files with 261 additions and 194 deletions

View File

@@ -23,7 +23,7 @@
#include "unity.h" #include "unity.h"
#include "bootloader_common.h" #include "bootloader_common.h"
#include "../include_bootloader/bootloader_flash.h" #include "../include_bootloader/bootloader_flash_priv.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_ota_ops.h" #include "esp_ota_ops.h"

View File

@@ -0,0 +1,30 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <esp_err.h>
#include <esp_spi_flash.h> /* including in bootloader for error values */
#include "sdkconfig.h"
#include "soc/soc_caps.h"
#if SOC_CACHE_SUPPORT_WRAP
/**
* @brief Set the burst mode setting command for specified wrap mode.
*
* @param mode The specified warp mode.
* @return always ESP_OK
*/
esp_err_t bootloader_flash_wrap_set(spi_flash_wrap_mode_t mode);
#endif

View File

@@ -19,11 +19,27 @@
#include <stdint.h> #include <stdint.h>
#include <esp_err.h> #include <esp_err.h>
#include <esp_spi_flash.h> /* including in bootloader for error values */ #include <esp_spi_flash.h> /* including in bootloader for error values */
#include "sdkconfig.h"
#include "bootloader_flash.h"
#define FLASH_SECTOR_SIZE 0x1000 #define FLASH_SECTOR_SIZE 0x1000
#define FLASH_BLOCK_SIZE 0x10000 #define FLASH_BLOCK_SIZE 0x10000
#define MMAP_ALIGNED_MASK 0x0000FFFF #define MMAP_ALIGNED_MASK 0x0000FFFF
/* SPI commands (actual on-wire commands not SPI controller bitmasks)
Suitable for use with the bootloader_execute_flash_command static function.
*/
#define CMD_RDID 0x9F
#define CMD_WRSR 0x01
#define CMD_WRSR2 0x31 /* Not all SPI flash uses this command */
#define CMD_WREN 0x06
#define CMD_WRDI 0x04
#define CMD_RDSR 0x05
#define CMD_RDSR2 0x35 /* Not all SPI flash uses this command */
#define CMD_OTPEN 0x3A /* Enable OTP mode, not all SPI flash uses this command */
#define CMD_WRAP 0x77 /* Set burst with wrap command */
/* Provide a Flash API for bootloader_support code, /* Provide a Flash API for bootloader_support code,
that can be used from bootloader or app code. that can be used from bootloader or app code.
@@ -136,4 +152,20 @@ static inline uint32_t bootloader_cache_pages_to_map(uint32_t size, uint32_t vad
return (size + (vaddr - (vaddr & MMU_FLASH_MASK)) + MMU_BLOCK_SIZE - 1) / MMU_BLOCK_SIZE; return (size + (vaddr - (vaddr & MMU_FLASH_MASK)) + MMU_BLOCK_SIZE - 1) / MMU_BLOCK_SIZE;
} }
/**
* @brief Execute a user command on the flash
*
* @param command The command value to execute.
* @param mosi_data MOSI data to send
* @param mosi_len Length of MOSI data, in bits
* @param miso_len Length of MISO data to receive, in bits
* @return Received MISO data
*/
uint32_t bootloader_execute_flash_command(uint8_t command, uint32_t mosi_data, uint8_t mosi_len, uint8_t miso_len);
/**
* @brief Enable the flash write protect (WEL bit).
*/
void bootloader_enable_wp(void);
#endif #endif

View File

@@ -26,7 +26,7 @@
#include "esp_rom_gpio.h" #include "esp_rom_gpio.h"
#include "esp_rom_sys.h" #include "esp_rom_sys.h"
#include "esp_flash_partitions.h" #include "esp_flash_partitions.h"
#include "bootloader_flash.h" #include "bootloader_flash_priv.h"
#include "bootloader_common.h" #include "bootloader_common.h"
#include "bootloader_utility.h" #include "bootloader_utility.h"
#include "soc/gpio_periph.h" #include "soc/gpio_periph.h"

View File

@@ -13,13 +13,29 @@
// limitations under the License. // limitations under the License.
#include <stddef.h> #include <stddef.h>
#include <bootloader_flash.h> #include <bootloader_flash_priv.h>
#include <esp_log.h> #include <esp_log.h>
#include <esp_flash_encrypt.h> #include <esp_flash_encrypt.h>
#if CONFIG_IDF_TARGET_ESP32S2 #include "sdkconfig.h"
#include "esp32s2/rom/spi_flash.h" #include "soc/soc_caps.h"
#if CONFIG_IDF_TARGET_ESP32
# include "soc/spi_struct.h"
# include "soc/spi_reg.h"
/* SPI flash controller */
# define SPIFLASH SPI1
#else
# include "soc/spi_mem_struct.h"
# include "soc/spi_mem_reg.h"
/* SPI flash controller */
# define SPIFLASH SPIMEM1
#endif #endif
#if CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/spi_flash.h" //For SPI_Encrypt_Write
#endif
#ifndef BOOTLOADER_BUILD #ifndef BOOTLOADER_BUILD
/* Normal app version maps to esp_spi_flash.h operations... /* Normal app version maps to esp_spi_flash.h operations...
*/ */
@@ -364,4 +380,90 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size)
} }
return spi_to_esp_err(rc); return spi_to_esp_err(rc);
} }
#endif #endif
extern uint8_t g_rom_spiflash_dummy_len_plus[];
uint32_t bootloader_execute_flash_command(uint8_t command, uint32_t mosi_data, uint8_t mosi_len, uint8_t miso_len)
{
uint32_t old_ctrl_reg = SPIFLASH.ctrl.val;
#if CONFIG_IDF_TARGET_ESP32
SPIFLASH.ctrl.val = SPI_WP_REG_M; // keep WP high while idle, otherwise leave DIO mode
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
SPIFLASH.ctrl.val = SPI_MEM_WP_REG_M; // keep WP high while idle, otherwise leave DIO mode
#endif
SPIFLASH.user.usr_dummy = 0;
SPIFLASH.user.usr_addr = 0;
SPIFLASH.user.usr_command = 1;
SPIFLASH.user2.usr_command_bitlen = 7;
SPIFLASH.user2.usr_command_value = command;
SPIFLASH.user.usr_miso = miso_len > 0;
#if CONFIG_IDF_TARGET_ESP32
SPIFLASH.miso_dlen.usr_miso_dbitlen = miso_len ? (miso_len - 1) : 0;
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
SPIFLASH.miso_dlen.usr_miso_bit_len = miso_len ? (miso_len - 1) : 0;
#endif
SPIFLASH.user.usr_mosi = mosi_len > 0;
#if CONFIG_IDF_TARGET_ESP32
SPIFLASH.mosi_dlen.usr_mosi_dbitlen = mosi_len ? (mosi_len - 1) : 0;
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
SPIFLASH.mosi_dlen.usr_mosi_bit_len = mosi_len ? (mosi_len - 1) : 0;
#endif
SPIFLASH.data_buf[0] = mosi_data;
if (g_rom_spiflash_dummy_len_plus[1]) {
/* When flash pins are mapped via GPIO matrix, need a dummy cycle before reading via MISO */
if (miso_len > 0) {
SPIFLASH.user.usr_dummy = 1;
SPIFLASH.user1.usr_dummy_cyclelen = g_rom_spiflash_dummy_len_plus[1] - 1;
} else {
SPIFLASH.user.usr_dummy = 0;
SPIFLASH.user1.usr_dummy_cyclelen = 0;
}
}
SPIFLASH.cmd.usr = 1;
while (SPIFLASH.cmd.usr != 0) {
}
SPIFLASH.ctrl.val = old_ctrl_reg;
return SPIFLASH.data_buf[0];
}
void bootloader_enable_wp(void)
{
bootloader_execute_flash_command(CMD_WRDI, 0, 0, 0); /* Exit OTP mode */
}
#if SOC_CACHE_SUPPORT_WRAP
esp_err_t bootloader_flash_wrap_set(spi_flash_wrap_mode_t mode)
{
uint32_t reg_bkp_ctrl = SPIFLASH.ctrl.val;
uint32_t reg_bkp_usr = SPIFLASH.user.val;
SPIFLASH.user.fwrite_dio = 0;
SPIFLASH.user.fwrite_dual = 0;
SPIFLASH.user.fwrite_qio = 1;
SPIFLASH.user.fwrite_quad = 0;
SPIFLASH.ctrl.fcmd_dual = 0;
SPIFLASH.ctrl.fcmd_quad = 0;
SPIFLASH.user.usr_dummy = 0;
SPIFLASH.user.usr_addr = 1;
SPIFLASH.user.usr_command = 1;
SPIFLASH.user2.usr_command_bitlen = 7;
SPIFLASH.user2.usr_command_value = CMD_WRAP;
SPIFLASH.user1.usr_addr_bitlen = 23;
SPIFLASH.addr = 0;
SPIFLASH.user.usr_miso = 0;
SPIFLASH.user.usr_mosi = 1;
SPIFLASH.mosi_dlen.usr_mosi_bit_len = 7;
SPIFLASH.data_buf[0] = (uint32_t) mode << 4;;
SPIFLASH.cmd.usr = 1;
while(SPIFLASH.cmd.usr != 0)
{ }
SPIFLASH.ctrl.val = reg_bkp_ctrl;
SPIFLASH.user.val = reg_bkp_usr;
return ESP_OK;
}
#endif //SOC_CACHE_SUPPORT_WRAP

View File

@@ -17,7 +17,7 @@
#include "esp_attr.h" #include "esp_attr.h"
#include "esp_log.h" #include "esp_log.h"
#include "bootloader_init.h" #include "bootloader_init.h"
#include "bootloader_flash.h" #include "bootloader_flash_priv.h"
#include "bootloader_flash_config.h" #include "bootloader_flash_config.h"
#include "bootloader_random.h" #include "bootloader_random.h"
#include "bootloader_clock.h" #include "bootloader_clock.h"

View File

@@ -51,7 +51,7 @@
#include "esp_secure_boot.h" #include "esp_secure_boot.h"
#include "esp_flash_encrypt.h" #include "esp_flash_encrypt.h"
#include "esp_flash_partitions.h" #include "esp_flash_partitions.h"
#include "bootloader_flash.h" #include "bootloader_flash_priv.h"
#include "bootloader_random.h" #include "bootloader_random.h"
#include "bootloader_config.h" #include "bootloader_config.h"
#include "bootloader_common.h" #include "bootloader_common.h"

View File

@@ -24,6 +24,7 @@
#include "bootloader_flash_config.h" #include "bootloader_flash_config.h"
#include "bootloader_mem.h" #include "bootloader_mem.h"
#include "bootloader_console.h" #include "bootloader_console.h"
#include "bootloader_flash_priv.h"
#include "soc/cpu.h" #include "soc/cpu.h"
#include "soc/dport_reg.h" #include "soc/dport_reg.h"
@@ -266,6 +267,8 @@ static esp_err_t bootloader_init_spi_flash(void)
print_flash_info(&bootloader_image_hdr); print_flash_info(&bootloader_image_hdr);
update_flash_config(&bootloader_image_hdr); update_flash_config(&bootloader_image_hdr);
//ensure the flash is write-protected
bootloader_enable_wp();
return ESP_OK; return ESP_OK;
} }

View File

@@ -14,7 +14,7 @@
#include <strings.h> #include <strings.h>
#include "bootloader_flash.h" #include "bootloader_flash_priv.h"
#include "esp_image_format.h" #include "esp_image_format.h"
#include "esp_flash_encrypt.h" #include "esp_flash_encrypt.h"
#include "esp_flash_partitions.h" #include "esp_flash_partitions.h"

View File

@@ -28,7 +28,7 @@
#include "sdkconfig.h" #include "sdkconfig.h"
#include "bootloader_flash.h" #include "bootloader_flash_priv.h"
#include "bootloader_random.h" #include "bootloader_random.h"
#include "esp_image_format.h" #include "esp_image_format.h"
#include "esp_secure_boot.h" #include "esp_secure_boot.h"
@@ -322,7 +322,7 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag
uint32_t dis_reg = REG_READ(EFUSE_BLK0_RDATA0_REG); uint32_t dis_reg = REG_READ(EFUSE_BLK0_RDATA0_REG);
bool efuse_key_read_protected = dis_reg & EFUSE_RD_DIS_BLK2; bool efuse_key_read_protected = dis_reg & EFUSE_RD_DIS_BLK2;
bool efuse_key_write_protected = dis_reg & EFUSE_WR_DIS_BLK2; bool efuse_key_write_protected = dis_reg & EFUSE_WR_DIS_BLK2;
if (efuse_key_write_protected == false if (efuse_key_write_protected == false
&& efuse_key_read_protected == false && efuse_key_read_protected == false
&& REG_READ(EFUSE_BLK2_RDATA0_REG) == 0 && REG_READ(EFUSE_BLK2_RDATA0_REG) == 0
&& REG_READ(EFUSE_BLK2_RDATA1_REG) == 0 && REG_READ(EFUSE_BLK2_RDATA1_REG) == 0

View File

@@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
#include "sdkconfig.h" #include "sdkconfig.h"
#include "bootloader_flash.h" #include "bootloader_flash_priv.h"
#include "bootloader_sha.h" #include "bootloader_sha.h"
#include "bootloader_utility.h" #include "bootloader_utility.h"
#include "esp_log.h" #include "esp_log.h"

View File

@@ -27,6 +27,7 @@
#include "bootloader_flash_config.h" #include "bootloader_flash_config.h"
#include "bootloader_mem.h" #include "bootloader_mem.h"
#include "bootloader_console.h" #include "bootloader_console.h"
#include "bootloader_flash_priv.h"
#include "esp_rom_sys.h" #include "esp_rom_sys.h"
#include "esp32s2/rom/cache.h" #include "esp32s2/rom/cache.h"
@@ -214,6 +215,8 @@ static esp_err_t bootloader_init_spi_flash(void)
print_flash_info(&bootloader_image_hdr); print_flash_info(&bootloader_image_hdr);
update_flash_config(&bootloader_image_hdr); update_flash_config(&bootloader_image_hdr);
//ensure the flash is write-protected
bootloader_enable_wp();
return ESP_OK; return ESP_OK;
} }

View File

@@ -14,7 +14,7 @@
#include <strings.h> #include <strings.h>
#include "bootloader_flash.h" #include "bootloader_flash_priv.h"
#include "bootloader_random.h" #include "bootloader_random.h"
#include "bootloader_utility.h" #include "bootloader_utility.h"
#include "esp_image_format.h" #include "esp_image_format.h"
@@ -299,8 +299,8 @@ static esp_err_t encrypt_bootloader(void)
if (err != ESP_OK) { if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to encrypt bootloader in place: 0x%x", err); ESP_LOGE(TAG, "Failed to encrypt bootloader in place: 0x%x", err);
return err; return err;
} }
ESP_LOGI(TAG, "bootloader encrypted successfully"); ESP_LOGI(TAG, "bootloader encrypted successfully");
return err; return err;
} }

View File

@@ -17,7 +17,7 @@
#include "esp_secure_boot.h" #include "esp_secure_boot.h"
#include "soc/efuse_reg.h" #include "soc/efuse_reg.h"
#include "bootloader_flash.h" #include "bootloader_flash_priv.h"
#include "bootloader_sha.h" #include "bootloader_sha.h"
#include "bootloader_utility.h" #include "bootloader_utility.h"

View File

@@ -15,7 +15,7 @@
#include <string.h> #include <string.h>
#include "esp_fault.h" #include "esp_fault.h"
#include "bootloader_flash.h" #include "bootloader_flash_priv.h"
#include "bootloader_sha.h" #include "bootloader_sha.h"
#include "bootloader_utility.h" #include "bootloader_utility.h"
#include "esp_log.h" #include "esp_log.h"

View File

@@ -20,7 +20,7 @@
#include <esp_log.h> #include <esp_log.h>
#include <esp_attr.h> #include <esp_attr.h>
#include <esp_spi_flash.h> #include <esp_spi_flash.h>
#include <bootloader_flash.h> #include <bootloader_flash_priv.h>
#include <bootloader_random.h> #include <bootloader_random.h>
#include <bootloader_sha.h> #include <bootloader_sha.h>
#include "bootloader_util.h" #include "bootloader_util.h"

View File

@@ -15,6 +15,7 @@
#include <stdint.h> #include <stdint.h>
#include "bootloader_flash_config.h" #include "bootloader_flash_config.h"
#include "flash_qio_mode.h" #include "flash_qio_mode.h"
#include "bootloader_flash_priv.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_err.h" #include "esp_err.h"
#include "esp_rom_efuse.h" #include "esp_rom_efuse.h"
@@ -22,32 +23,13 @@
#include "esp32/rom/spi_flash.h" #include "esp32/rom/spi_flash.h"
#elif CONFIG_IDF_TARGET_ESP32S2 #elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/spi_flash.h" #include "esp32s2/rom/spi_flash.h"
#include "soc/spi_mem_struct.h" #elif CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/rom/spi_flash.h"
#endif #endif
#include "soc/spi_struct.h"
#include "soc/spi_reg.h"
#include "soc/efuse_periph.h" #include "soc/efuse_periph.h"
#include "soc/io_mux_reg.h" #include "soc/io_mux_reg.h"
#include "sdkconfig.h" #include "sdkconfig.h"
/* SPI flash controller */
#if CONFIG_IDF_TARGET_ESP32
#define SPIFLASH SPI1
#elif CONFIG_IDF_TARGET_ESP32S2
#define SPIFLASH SPIMEM1
#endif
/* SPI commands (actual on-wire commands not SPI controller bitmasks)
Suitable for use with the execute_flash_command static function.
*/
#define CMD_RDID 0x9F
#define CMD_WRSR 0x01
#define CMD_WRSR2 0x31 /* Not all SPI flash uses this command */
#define CMD_WREN 0x06
#define CMD_WRDI 0x04
#define CMD_RDSR 0x05
#define CMD_RDSR2 0x35 /* Not all SPI flash uses this command */
#define CMD_OTPEN 0x3A /* Enable OTP mode, not all SPI flash uses this command */
static const char *TAG = "qio_mode"; static const char *TAG = "qio_mode";
@@ -124,57 +106,15 @@ static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn,
The command passed here is always the on-the-wire command given to the SPI flash unit. The command passed here is always the on-the-wire command given to the SPI flash unit.
*/ */
static uint32_t execute_flash_command(uint8_t command, uint32_t mosi_data, uint8_t mosi_len, uint8_t miso_len);
/* dummy_len_plus values defined in ROM for SPI flash configuration */ /* dummy_len_plus values defined in ROM for SPI flash configuration */
extern uint8_t g_rom_spiflash_dummy_len_plus[];
uint32_t bootloader_read_flash_id(void) uint32_t bootloader_read_flash_id(void)
{ {
uint32_t id = execute_flash_command(CMD_RDID, 0, 0, 24); uint32_t id = bootloader_execute_flash_command(CMD_RDID, 0, 0, 24);
id = ((id & 0xff) << 16) | ((id >> 16) & 0xff) | (id & 0xff00); id = ((id & 0xff) << 16) | ((id >> 16) & 0xff) | (id & 0xff00);
return id; return id;
} }
#if CONFIG_IDF_TARGET_ESP32S2
#define FLASH_WRAP_CMD 0x77
typedef enum {
FLASH_WRAP_MODE_8B = 0,
FLASH_WRAP_MODE_16B = 2,
FLASH_WRAP_MODE_32B = 4,
FLASH_WRAP_MODE_64B = 6,
FLASH_WRAP_MODE_DISABLE = 1
} spi_flash_wrap_mode_t;
static esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode)
{
uint32_t reg_bkp_ctrl = SPIFLASH.ctrl.val;
uint32_t reg_bkp_usr = SPIFLASH.user.val;
SPIFLASH.user.fwrite_dio = 0;
SPIFLASH.user.fwrite_dual = 0;
SPIFLASH.user.fwrite_qio = 1;
SPIFLASH.user.fwrite_quad = 0;
SPIFLASH.ctrl.fcmd_dual = 0;
SPIFLASH.ctrl.fcmd_quad = 0;
SPIFLASH.user.usr_dummy = 0;
SPIFLASH.user.usr_addr = 1;
SPIFLASH.user.usr_command = 1;
SPIFLASH.user2.usr_command_bitlen = 7;
SPIFLASH.user2.usr_command_value = FLASH_WRAP_CMD;
SPIFLASH.user1.usr_addr_bitlen = 23;
SPIFLASH.addr = 0;
SPIFLASH.user.usr_miso = 0;
SPIFLASH.user.usr_mosi = 1;
SPIFLASH.mosi_dlen.usr_mosi_bit_len = 7;
SPIFLASH.data_buf[0] = (uint32_t) mode << 4;;
SPIFLASH.cmd.usr = 1;
while (SPIFLASH.cmd.usr != 0) {
}
SPIFLASH.ctrl.val = reg_bkp_ctrl;
SPIFLASH.user.val = reg_bkp_usr;
return ESP_OK;
}
#endif
void bootloader_enable_qio_mode(void) void bootloader_enable_qio_mode(void)
{ {
uint32_t raw_flash_id; uint32_t raw_flash_id;
@@ -206,8 +146,8 @@ void bootloader_enable_qio_mode(void)
enable_qio_mode(chip_data[i].read_status_fn, 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 CONFIG_IDF_TARGET_ESP32S2 #if SOC_CACHE_SUPPORT_WRAP
spi_flash_wrap_set(FLASH_WRAP_MODE_DISABLE); bootloader_flash_wrap_set(FLASH_WRAP_MODE_DISABLE);
#endif #endif
} }
@@ -224,7 +164,7 @@ static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn,
ESP_LOGD(TAG, "Initial flash chip status 0x%x", status); ESP_LOGD(TAG, "Initial flash chip status 0x%x", status);
if ((status & (1 << status_qio_bit)) == 0) { if ((status & (1 << status_qio_bit)) == 0) {
execute_flash_command(CMD_WREN, 0, 0, 0); bootloader_execute_flash_command(CMD_WREN, 0, 0, 0);
write_status_fn(status | (1 << status_qio_bit)); write_status_fn(status | (1 << status_qio_bit));
esp_rom_spiflash_wait_idle(&g_rom_flashchip); esp_rom_spiflash_wait_idle(&g_rom_flashchip);
@@ -262,95 +202,48 @@ static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn,
static unsigned read_status_8b_rdsr(void) static unsigned read_status_8b_rdsr(void)
{ {
return execute_flash_command(CMD_RDSR, 0, 0, 8); return bootloader_execute_flash_command(CMD_RDSR, 0, 0, 8);
} }
static unsigned read_status_8b_rdsr2(void) static unsigned read_status_8b_rdsr2(void)
{ {
return execute_flash_command(CMD_RDSR2, 0, 0, 8); return bootloader_execute_flash_command(CMD_RDSR2, 0, 0, 8);
} }
static unsigned read_status_16b_rdsr_rdsr2(void) static unsigned read_status_16b_rdsr_rdsr2(void)
{ {
return execute_flash_command(CMD_RDSR, 0, 0, 8) | (execute_flash_command(CMD_RDSR2, 0, 0, 8) << 8); return bootloader_execute_flash_command(CMD_RDSR, 0, 0, 8) | (bootloader_execute_flash_command(CMD_RDSR2, 0, 0, 8) << 8);
} }
static void write_status_8b_wrsr(unsigned new_status) static void write_status_8b_wrsr(unsigned new_status)
{ {
execute_flash_command(CMD_WRSR, new_status, 8, 0); bootloader_execute_flash_command(CMD_WRSR, new_status, 8, 0);
} }
static void write_status_8b_wrsr2(unsigned new_status) static void write_status_8b_wrsr2(unsigned new_status)
{ {
execute_flash_command(CMD_WRSR2, new_status, 8, 0); bootloader_execute_flash_command(CMD_WRSR2, new_status, 8, 0);
} }
static void write_status_16b_wrsr(unsigned new_status) static void write_status_16b_wrsr(unsigned new_status)
{ {
execute_flash_command(CMD_WRSR, new_status, 16, 0); bootloader_execute_flash_command(CMD_WRSR, new_status, 16, 0);
} }
static unsigned read_status_8b_xmc25qu64a(void) static unsigned read_status_8b_xmc25qu64a(void)
{ {
execute_flash_command(CMD_OTPEN, 0, 0, 0); /* Enter OTP mode */ bootloader_execute_flash_command(CMD_OTPEN, 0, 0, 0); /* Enter OTP mode */
esp_rom_spiflash_wait_idle(&g_rom_flashchip); esp_rom_spiflash_wait_idle(&g_rom_flashchip);
uint32_t read_status = execute_flash_command(CMD_RDSR, 0, 0, 8); uint32_t read_status = bootloader_execute_flash_command(CMD_RDSR, 0, 0, 8);
execute_flash_command(CMD_WRDI, 0, 0, 0); /* Exit OTP mode */ bootloader_execute_flash_command(CMD_WRDI, 0, 0, 0); /* Exit OTP mode */
return read_status; return read_status;
} }
static void write_status_8b_xmc25qu64a(unsigned new_status) static void write_status_8b_xmc25qu64a(unsigned new_status)
{ {
execute_flash_command(CMD_OTPEN, 0, 0, 0); /* Enter OTP mode */ bootloader_execute_flash_command(CMD_OTPEN, 0, 0, 0); /* Enter OTP mode */
esp_rom_spiflash_wait_idle(&g_rom_flashchip); esp_rom_spiflash_wait_idle(&g_rom_flashchip);
execute_flash_command(CMD_WRSR, new_status, 8, 0); bootloader_execute_flash_command(CMD_WRSR, new_status, 8, 0);
esp_rom_spiflash_wait_idle(&g_rom_flashchip); esp_rom_spiflash_wait_idle(&g_rom_flashchip);
execute_flash_command(CMD_WRDI, 0, 0, 0); /* Exit OTP mode */ bootloader_execute_flash_command(CMD_WRDI, 0, 0, 0); /* Exit OTP mode */
}
static uint32_t execute_flash_command(uint8_t command, uint32_t mosi_data, uint8_t mosi_len, uint8_t miso_len)
{
uint32_t old_ctrl_reg = SPIFLASH.ctrl.val;
#if CONFIG_IDF_TARGET_ESP32
SPIFLASH.ctrl.val = SPI_WP_REG_M; // keep WP high while idle, otherwise leave DIO mode
#elif CONFIG_IDF_TARGET_ESP32S2
SPIFLASH.ctrl.val = SPI_MEM_WP_REG_M; // keep WP high while idle, otherwise leave DIO mode
#endif
SPIFLASH.user.usr_dummy = 0;
SPIFLASH.user.usr_addr = 0;
SPIFLASH.user.usr_command = 1;
SPIFLASH.user2.usr_command_bitlen = 7;
SPIFLASH.user2.usr_command_value = command;
SPIFLASH.user.usr_miso = miso_len > 0;
#if CONFIG_IDF_TARGET_ESP32
SPIFLASH.miso_dlen.usr_miso_dbitlen = miso_len ? (miso_len - 1) : 0;
#elif CONFIG_IDF_TARGET_ESP32S2
SPIFLASH.miso_dlen.usr_miso_bit_len = miso_len ? (miso_len - 1) : 0;
#endif
SPIFLASH.user.usr_mosi = mosi_len > 0;
#if CONFIG_IDF_TARGET_ESP32
SPIFLASH.mosi_dlen.usr_mosi_dbitlen = mosi_len ? (mosi_len - 1) : 0;
#elif CONFIG_IDF_TARGET_ESP32S2
SPIFLASH.mosi_dlen.usr_mosi_bit_len = mosi_len ? (mosi_len - 1) : 0;
#endif
SPIFLASH.data_buf[0] = mosi_data;
if (g_rom_spiflash_dummy_len_plus[1]) {
/* When flash pins are mapped via GPIO matrix, need a dummy cycle before reading via MISO */
if (miso_len > 0) {
SPIFLASH.user.usr_dummy = 1;
SPIFLASH.user1.usr_dummy_cyclelen = g_rom_spiflash_dummy_len_plus[1] - 1;
} else {
SPIFLASH.user.usr_dummy = 0;
SPIFLASH.user1.usr_dummy_cyclelen = 0;
}
}
SPIFLASH.cmd.usr = 1;
while (SPIFLASH.cmd.usr != 0) {
}
SPIFLASH.ctrl.val = old_ctrl_reg;
return SPIFLASH.data_buf[0];
} }

View File

@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "bootloader_sha.h" #include "bootloader_sha.h"
#include "bootloader_flash.h" #include "bootloader_flash_priv.h"
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>

View File

@@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
#include "sdkconfig.h" #include "sdkconfig.h"
#include "bootloader_flash.h" #include "bootloader_flash_priv.h"
#include "bootloader_sha.h" #include "bootloader_sha.h"
#include "bootloader_utility.h" #include "bootloader_utility.h"
#include "esp_log.h" #include "esp_log.h"
@@ -325,7 +325,7 @@ esp_err_t esp_secure_boot_verify_rsa_signature_block(const ets_secure_boot_signa
break; break;
} }
} }
free(sig_be); free(sig_be);
free(buf); free(buf);
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32

View File

@@ -41,7 +41,7 @@ void esp_efuse_reset(void)
#ifdef CONFIG_BOOTLOADER_EFUSE_SECURE_VERSION_EMULATE #ifdef CONFIG_BOOTLOADER_EFUSE_SECURE_VERSION_EMULATE
#include "../include_bootloader/bootloader_flash.h" #include "../include_bootloader/bootloader_flash_priv.h"
#include "esp_flash_encrypt.h" #include "esp_flash_encrypt.h"
static uint32_t esp_efuse_flash_offset = 0; static uint32_t esp_efuse_flash_offset = 0;

View File

@@ -121,6 +121,7 @@ extern "C" {
#define ESP_ROM_SPIFLASH_BP2 BIT4 #define ESP_ROM_SPIFLASH_BP2 BIT4
#define ESP_ROM_SPIFLASH_WR_PROTECT (ESP_ROM_SPIFLASH_BP0|ESP_ROM_SPIFLASH_BP1|ESP_ROM_SPIFLASH_BP2) #define ESP_ROM_SPIFLASH_WR_PROTECT (ESP_ROM_SPIFLASH_BP0|ESP_ROM_SPIFLASH_BP1|ESP_ROM_SPIFLASH_BP2)
#define ESP_ROM_SPIFLASH_QE BIT9 #define ESP_ROM_SPIFLASH_QE BIT9
#define ESP_ROM_SPIFLASH_BP_MASK_ISSI (BIT7 | BIT5 | BIT4 | BIT3 | BIT2)
//Extra dummy for flash read //Extra dummy for flash read
#define ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_20M 0 #define ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_20M 0

View File

@@ -40,6 +40,7 @@ typedef struct {
#define ESP_ROM_SPIFLASH_BP2 BIT4 #define ESP_ROM_SPIFLASH_BP2 BIT4
#define ESP_ROM_SPIFLASH_WR_PROTECT (ESP_ROM_SPIFLASH_BP0|ESP_ROM_SPIFLASH_BP1|ESP_ROM_SPIFLASH_BP2) #define ESP_ROM_SPIFLASH_WR_PROTECT (ESP_ROM_SPIFLASH_BP0|ESP_ROM_SPIFLASH_BP1|ESP_ROM_SPIFLASH_BP2)
#define ESP_ROM_SPIFLASH_QE BIT9 #define ESP_ROM_SPIFLASH_QE BIT9
#define ESP_ROM_SPIFLASH_BP_MASK_ISSI (BIT7 | BIT5 | BIT4 | BIT3 | BIT2)
#define FLASH_OP_MODE_RDCMD_DOUT 0x3B #define FLASH_OP_MODE_RDCMD_DOUT 0x3B
#define ESP_ROM_FLASH_SECTOR_SIZE 0x1000 #define ESP_ROM_FLASH_SECTOR_SIZE 0x1000

View File

@@ -119,6 +119,7 @@ extern "C" {
#define ESP_ROM_SPIFLASH_BP2 BIT4 #define ESP_ROM_SPIFLASH_BP2 BIT4
#define ESP_ROM_SPIFLASH_WR_PROTECT (ESP_ROM_SPIFLASH_BP0|ESP_ROM_SPIFLASH_BP1|ESP_ROM_SPIFLASH_BP2) #define ESP_ROM_SPIFLASH_WR_PROTECT (ESP_ROM_SPIFLASH_BP0|ESP_ROM_SPIFLASH_BP1|ESP_ROM_SPIFLASH_BP2)
#define ESP_ROM_SPIFLASH_QE BIT9 #define ESP_ROM_SPIFLASH_QE BIT9
#define ESP_ROM_SPIFLASH_BP_MASK_ISSI (BIT7 | BIT5 | BIT4 | BIT3 | BIT2)
#define FLASH_ID_GD25LQ32C 0xC86016 #define FLASH_ID_GD25LQ32C 0xC86016

View File

@@ -11,3 +11,5 @@
#define SOC_SUPPORTS_SECURE_DL_MODE 1 #define SOC_SUPPORTS_SECURE_DL_MODE 1
#define SOC_RISCV_COPROC_SUPPORTED 1 #define SOC_RISCV_COPROC_SUPPORTED 1
#define SOC_USB_SUPPORTED 1 #define SOC_USB_SUPPORTED 1
#define SOC_CACHE_SUPPORT_WRAP 1

View File

@@ -8,6 +8,7 @@
#define SOC_TWAI_SUPPORTED 1 #define SOC_TWAI_SUPPORTED 1
#define SOC_GDMA_SUPPORTED 1 #define SOC_GDMA_SUPPORTED 1
#define SOC_CPU_CORES_NUM 2 #define SOC_CPU_CORES_NUM 2
#define SOC_CACHE_SUPPORT_WRAP 1
// Attention: These fixed DMA channels are temporarily workaround before we have a centralized DMA controller API to help alloc the channel dynamically // Attention: These fixed DMA channels are temporarily workaround before we have a centralized DMA controller API to help alloc the channel dynamically
// Remove them when GDMA driver API is ready // Remove them when GDMA driver API is ready

View File

@@ -1,5 +1,3 @@
set(priv_requires bootloader_support soc)
if(BOOTLOADER_BUILD) if(BOOTLOADER_BUILD)
if (CONFIG_IDF_TARGET_ESP32) if (CONFIG_IDF_TARGET_ESP32)
# ESP32 Bootloader needs SPIUnlock from this file, but doesn't # ESP32 Bootloader needs SPIUnlock from this file, but doesn't
@@ -10,6 +8,7 @@ if(BOOTLOADER_BUILD)
set(srcs) set(srcs)
endif() endif()
set(cache_srcs "") set(cache_srcs "")
set(priv_requires bootloader_support soc)
else() else()
set(cache_srcs set(cache_srcs
"cache_utils.c" "cache_utils.c"

View File

@@ -49,8 +49,9 @@ menu "SPI Flash driver"
default y default y
help help
Enable this flag to use patched versions of SPI flash ROM driver functions. Enable this flag to use patched versions of SPI flash ROM driver functions.
This option is needed to write to flash on ESP32-D2WD, and any configuration This option should be enabled, if any one of the following is true: (1) need to write
where external SPI flash is connected to non-default pins. to flash on ESP32-D2WD; (2) main SPI flash is connected to non-default pins; (3) main
SPI flash chip is manufactured by ISSI.
choice SPI_FLASH_DANGEROUS_WRITE choice SPI_FLASH_DANGEROUS_WRITE
bool "Writing to dangerous flash regions" bool "Writing to dangerous flash regions"

View File

@@ -19,8 +19,14 @@
#define SPI_IDX 1 #define SPI_IDX 1
#define OTH_IDX 0 #define OTH_IDX 0
extern esp_rom_spiflash_chip_t g_rom_spiflash_chip; extern esp_rom_spiflash_chip_t g_rom_spiflash_chip;
static inline bool is_issi_chip(const esp_rom_spiflash_chip_t* chip)
{
return (((chip->device_id >> 16)&0xff) == 0x9D);
}
esp_rom_spiflash_result_t esp_rom_spiflash_wait_idle(esp_rom_spiflash_chip_t *spi) esp_rom_spiflash_result_t esp_rom_spiflash_wait_idle(esp_rom_spiflash_chip_t *spi)
{ {
uint32_t status; uint32_t status;
@@ -59,25 +65,43 @@ esp_rom_spiflash_result_t esp_rom_spiflash_wait_idle(esp_rom_spiflash_chip_t *sp
esp_rom_spiflash_result_t esp_rom_spiflash_unlock(void) esp_rom_spiflash_result_t esp_rom_spiflash_unlock(void)
{ {
uint32_t status; uint32_t status;
uint32_t new_status;
esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip); esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip);
if (esp_rom_spiflash_read_statushigh(&g_rom_spiflash_chip, &status) != ESP_ROM_SPIFLASH_RESULT_OK) { if (is_issi_chip(&g_rom_spiflash_chip)) {
return ESP_ROM_SPIFLASH_RESULT_ERR; // ISSI chips have different QE position
}
/* Clear all bits except QIE, if it is set. if (esp_rom_spiflash_read_status(&g_rom_spiflash_chip, &status) != ESP_ROM_SPIFLASH_RESULT_OK) {
(This is different from ROM esp_rom_spiflash_unlock, which keeps all bits as-is.) return ESP_ROM_SPIFLASH_RESULT_ERR;
*/ }
status &= ESP_ROM_SPIFLASH_QE;
/* Clear all bits in the mask.
(This is different from ROM esp_rom_spiflash_unlock, which keeps all bits as-is.)
*/
new_status = status & (~ESP_ROM_SPIFLASH_BP_MASK_ISSI);
// Skip if nothing needs to be cleared. Otherwise will waste time waiting for the flash to clear nothing.
if (new_status == status) return ESP_ROM_SPIFLASH_RESULT_OK;
CLEAR_PERI_REG_MASK(SPI_CTRL_REG(SPI_IDX), SPI_WRSR_2B);
} else {
if (esp_rom_spiflash_read_statushigh(&g_rom_spiflash_chip, &status) != ESP_ROM_SPIFLASH_RESULT_OK) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
/* Clear all bits except QE, if it is set.
(This is different from ROM esp_rom_spiflash_unlock, which keeps all bits as-is.)
*/
new_status = status & ESP_ROM_SPIFLASH_QE;
SET_PERI_REG_MASK(SPI_CTRL_REG(SPI_IDX), SPI_WRSR_2B);
}
esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip); esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip);
REG_WRITE(SPI_CMD_REG(SPI_IDX), SPI_FLASH_WREN); REG_WRITE(SPI_CMD_REG(SPI_IDX), SPI_FLASH_WREN);
while (REG_READ(SPI_CMD_REG(SPI_IDX)) != 0) { while (REG_READ(SPI_CMD_REG(SPI_IDX)) != 0) {
} }
esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip); esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip);
SET_PERI_REG_MASK(SPI_CTRL_REG(SPI_IDX), SPI_WRSR_2B); if (esp_rom_spiflash_write_status(&g_rom_spiflash_chip, new_status) != ESP_ROM_SPIFLASH_RESULT_OK) {
if (esp_rom_spiflash_write_status(&g_rom_spiflash_chip, status) != ESP_ROM_SPIFLASH_RESULT_OK) {
return ESP_ROM_SPIFLASH_RESULT_ERR; return ESP_ROM_SPIFLASH_RESULT_ERR;
} }

View File

@@ -20,6 +20,7 @@
#include "soc/soc_memory_layout.h" #include "soc/soc_memory_layout.h"
#include "esp32s2/rom/spi_flash.h" #include "esp32s2/rom/spi_flash.h"
#include "esp32s2/rom/cache.h" #include "esp32s2/rom/cache.h"
#include "bootloader_flash.h"
#include "hal/spi_flash_hal.h" #include "hal/spi_flash_hal.h"
#include "esp_flash.h" #include "esp_flash.h"
#include "esp_log.h" #include "esp_log.h"
@@ -76,48 +77,22 @@ esp_rom_spiflash_result_t IRAM_ATTR spi_flash_write_encrypted_chip(size_t dest_a
} }
} }
#define FLASH_WRAP_CMD 0x77
esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode) esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode)
{ {
uint32_t reg_bkp_ctrl = SPIFLASH.ctrl.val; return bootloader_flash_wrap_set(mode);
uint32_t reg_bkp_usr = SPIFLASH.user.val;
SPIFLASH.user.fwrite_dio = 0;
SPIFLASH.user.fwrite_dual = 0;
SPIFLASH.user.fwrite_qio = 1;
SPIFLASH.user.fwrite_quad = 0;
SPIFLASH.ctrl.fcmd_dual = 0;
SPIFLASH.ctrl.fcmd_quad = 0;
SPIFLASH.user.usr_dummy = 0;
SPIFLASH.user.usr_addr = 1;
SPIFLASH.user.usr_command = 1;
SPIFLASH.user2.usr_command_bitlen = 7;
SPIFLASH.user2.usr_command_value = FLASH_WRAP_CMD;
SPIFLASH.user1.usr_addr_bitlen = 23;
SPIFLASH.addr = 0;
SPIFLASH.user.usr_miso = 0;
SPIFLASH.user.usr_mosi = 1;
SPIFLASH.mosi_dlen.usr_mosi_bit_len = 7;
SPIFLASH.data_buf[0] = (uint32_t) mode << 4;;
SPIFLASH.cmd.usr = 1;
while(SPIFLASH.cmd.usr != 0)
{ }
SPIFLASH.ctrl.val = reg_bkp_ctrl;
SPIFLASH.user.val = reg_bkp_usr;
return ESP_OK;
} }
esp_err_t spi_flash_enable_wrap(uint32_t wrap_size) esp_err_t spi_flash_enable_wrap(uint32_t wrap_size)
{ {
switch(wrap_size) { switch(wrap_size) {
case 8: case 8:
return spi_flash_wrap_set(FLASH_WRAP_MODE_8B); return bootloader_flash_wrap_set(FLASH_WRAP_MODE_8B);
case 16: case 16:
return spi_flash_wrap_set(FLASH_WRAP_MODE_16B); return bootloader_flash_wrap_set(FLASH_WRAP_MODE_16B);
case 32: case 32:
return spi_flash_wrap_set(FLASH_WRAP_MODE_32B); return bootloader_flash_wrap_set(FLASH_WRAP_MODE_32B);
case 64: case 64:
return spi_flash_wrap_set(FLASH_WRAP_MODE_64B); return bootloader_flash_wrap_set(FLASH_WRAP_MODE_64B);
default: default:
return ESP_FAIL; return ESP_FAIL;
} }
@@ -125,7 +100,7 @@ esp_err_t spi_flash_enable_wrap(uint32_t wrap_size)
void spi_flash_disable_wrap(void) void spi_flash_disable_wrap(void)
{ {
spi_flash_wrap_set(FLASH_WRAP_MODE_DISABLE); bootloader_flash_wrap_set(FLASH_WRAP_MODE_DISABLE);
} }
bool spi_flash_support_wrap_size(uint32_t wrap_size) bool spi_flash_support_wrap_size(uint32_t wrap_size)

View File

@@ -36,8 +36,6 @@
#include "esp32s2/rom/spi_flash.h" #include "esp32s2/rom/spi_flash.h"
#include "esp32s2/rom/cache.h" #include "esp32s2/rom/cache.h"
#include "esp32s2/clk.h" #include "esp32s2/clk.h"
#include "soc/spi_mem_reg.h"
#include "soc/spi_mem_struct.h"
#endif #endif
#include "esp_flash_partitions.h" #include "esp_flash_partitions.h"
#include "cache_utils.h" #include "cache_utils.h"
@@ -777,6 +775,7 @@ void spi_flash_dump_counters(void)
#endif //CONFIG_SPI_FLASH_ENABLE_COUNTERS #endif //CONFIG_SPI_FLASH_ENABLE_COUNTERS
#if defined(CONFIG_SPI_FLASH_USE_LEGACY_IMPL) && defined(CONFIG_IDF_TARGET_ESP32S2) #if defined(CONFIG_SPI_FLASH_USE_LEGACY_IMPL) && defined(CONFIG_IDF_TARGET_ESP32S2)
// TODO esp32s2: Remove once ESP32S2 has new SPI Flash API support // TODO esp32s2: Remove once ESP32S2 has new SPI Flash API support
esp_flash_t *esp_flash_default_chip = NULL; esp_flash_t *esp_flash_default_chip = NULL;