mirror of
https://github.com/espressif/esp-idf.git
synced 2024-09-20 10:46:02 -04:00
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:
commit
61a7a26fc9
@ -23,7 +23,7 @@
|
||||
#include "unity.h"
|
||||
|
||||
#include "bootloader_common.h"
|
||||
#include "../include_bootloader/bootloader_flash.h"
|
||||
#include "../include_bootloader/bootloader_flash_priv.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_ota_ops.h"
|
||||
|
30
components/bootloader_support/include/bootloader_flash.h
Normal file
30
components/bootloader_support/include/bootloader_flash.h
Normal 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
|
||||
|
@ -19,11 +19,27 @@
|
||||
#include <stdint.h>
|
||||
#include <esp_err.h>
|
||||
#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_BLOCK_SIZE 0x10000
|
||||
#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,
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
@ -26,7 +26,7 @@
|
||||
#include "esp_rom_gpio.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "bootloader_flash.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "bootloader_common.h"
|
||||
#include "bootloader_utility.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
|
@ -13,13 +13,29 @@
|
||||
// limitations under the License.
|
||||
#include <stddef.h>
|
||||
|
||||
#include <bootloader_flash.h>
|
||||
#include <bootloader_flash_priv.h>
|
||||
#include <esp_log.h>
|
||||
#include <esp_flash_encrypt.h>
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/spi_flash.h"
|
||||
#include "sdkconfig.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
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/spi_flash.h" //For SPI_Encrypt_Write
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
/* 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);
|
||||
}
|
||||
|
||||
#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
|
@ -17,7 +17,7 @@
|
||||
#include "esp_attr.h"
|
||||
#include "esp_log.h"
|
||||
#include "bootloader_init.h"
|
||||
#include "bootloader_flash.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "bootloader_flash_config.h"
|
||||
#include "bootloader_random.h"
|
||||
#include "bootloader_clock.h"
|
||||
|
@ -51,7 +51,7 @@
|
||||
#include "esp_secure_boot.h"
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "bootloader_flash.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "bootloader_random.h"
|
||||
#include "bootloader_config.h"
|
||||
#include "bootloader_common.h"
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "bootloader_flash_config.h"
|
||||
#include "bootloader_mem.h"
|
||||
#include "bootloader_console.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
|
||||
#include "soc/cpu.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);
|
||||
update_flash_config(&bootloader_image_hdr);
|
||||
//ensure the flash is write-protected
|
||||
bootloader_enable_wp();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
#include <strings.h>
|
||||
|
||||
#include "bootloader_flash.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_flash_partitions.h"
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "bootloader_flash.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "bootloader_random.h"
|
||||
#include "esp_image_format.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);
|
||||
bool efuse_key_read_protected = dis_reg & EFUSE_RD_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
|
||||
&& REG_READ(EFUSE_BLK2_RDATA0_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK2_RDATA1_REG) == 0
|
||||
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "bootloader_flash.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "bootloader_sha.h"
|
||||
#include "bootloader_utility.h"
|
||||
#include "esp_log.h"
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "bootloader_flash_config.h"
|
||||
#include "bootloader_mem.h"
|
||||
#include "bootloader_console.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
|
||||
#include "esp_rom_sys.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);
|
||||
update_flash_config(&bootloader_image_hdr);
|
||||
//ensure the flash is write-protected
|
||||
bootloader_enable_wp();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
#include <strings.h>
|
||||
|
||||
#include "bootloader_flash.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "bootloader_random.h"
|
||||
#include "bootloader_utility.h"
|
||||
#include "esp_image_format.h"
|
||||
@ -299,8 +299,8 @@ static esp_err_t encrypt_bootloader(void)
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to encrypt bootloader in place: 0x%x", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "bootloader encrypted successfully");
|
||||
return err;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include "esp_secure_boot.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
|
||||
#include "bootloader_flash.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "bootloader_sha.h"
|
||||
#include "bootloader_utility.h"
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include "esp_fault.h"
|
||||
#include "bootloader_flash.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "bootloader_sha.h"
|
||||
#include "bootloader_utility.h"
|
||||
#include "esp_log.h"
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include <esp_log.h>
|
||||
#include <esp_attr.h>
|
||||
#include <esp_spi_flash.h>
|
||||
#include <bootloader_flash.h>
|
||||
#include <bootloader_flash_priv.h>
|
||||
#include <bootloader_random.h>
|
||||
#include <bootloader_sha.h>
|
||||
#include "bootloader_util.h"
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <stdint.h>
|
||||
#include "bootloader_flash_config.h"
|
||||
#include "flash_qio_mode.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_rom_efuse.h"
|
||||
@ -22,32 +23,13 @@
|
||||
#include "esp32/rom/spi_flash.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/spi_flash.h"
|
||||
#include "soc/spi_mem_struct.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#include "esp32s3/rom/spi_flash.h"
|
||||
#endif
|
||||
#include "soc/spi_struct.h"
|
||||
#include "soc/spi_reg.h"
|
||||
#include "soc/efuse_periph.h"
|
||||
#include "soc/io_mux_reg.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";
|
||||
|
||||
@ -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.
|
||||
*/
|
||||
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 */
|
||||
extern uint8_t g_rom_spiflash_dummy_len_plus[];
|
||||
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);
|
||||
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)
|
||||
{
|
||||
uint32_t raw_flash_id;
|
||||
@ -206,8 +146,8 @@ void bootloader_enable_qio_mode(void)
|
||||
enable_qio_mode(chip_data[i].read_status_fn,
|
||||
chip_data[i].write_status_fn,
|
||||
chip_data[i].status_qio_bit);
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
spi_flash_wrap_set(FLASH_WRAP_MODE_DISABLE);
|
||||
#if SOC_CACHE_SUPPORT_WRAP
|
||||
bootloader_flash_wrap_set(FLASH_WRAP_MODE_DISABLE);
|
||||
#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);
|
||||
|
||||
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));
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
uint32_t read_status = execute_flash_command(CMD_RDSR, 0, 0, 8);
|
||||
execute_flash_command(CMD_WRDI, 0, 0, 0); /* Exit OTP mode */
|
||||
uint32_t read_status = bootloader_execute_flash_command(CMD_RDSR, 0, 0, 8);
|
||||
bootloader_execute_flash_command(CMD_WRDI, 0, 0, 0); /* Exit OTP mode */
|
||||
return read_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);
|
||||
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);
|
||||
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];
|
||||
bootloader_execute_flash_command(CMD_WRDI, 0, 0, 0); /* Exit OTP mode */
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include "bootloader_sha.h"
|
||||
#include "bootloader_flash.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "bootloader_flash.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "bootloader_sha.h"
|
||||
#include "bootloader_utility.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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
free(sig_be);
|
||||
free(buf);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
|
@ -41,7 +41,7 @@ void esp_efuse_reset(void)
|
||||
|
||||
#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"
|
||||
|
||||
static uint32_t esp_efuse_flash_offset = 0;
|
||||
|
@ -121,6 +121,7 @@ extern "C" {
|
||||
#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_QE BIT9
|
||||
#define ESP_ROM_SPIFLASH_BP_MASK_ISSI (BIT7 | BIT5 | BIT4 | BIT3 | BIT2)
|
||||
|
||||
//Extra dummy for flash read
|
||||
#define ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_20M 0
|
||||
|
@ -40,6 +40,7 @@ typedef struct {
|
||||
#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_QE BIT9
|
||||
#define ESP_ROM_SPIFLASH_BP_MASK_ISSI (BIT7 | BIT5 | BIT4 | BIT3 | BIT2)
|
||||
|
||||
#define FLASH_OP_MODE_RDCMD_DOUT 0x3B
|
||||
#define ESP_ROM_FLASH_SECTOR_SIZE 0x1000
|
||||
|
@ -119,6 +119,7 @@ extern "C" {
|
||||
#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_QE BIT9
|
||||
#define ESP_ROM_SPIFLASH_BP_MASK_ISSI (BIT7 | BIT5 | BIT4 | BIT3 | BIT2)
|
||||
|
||||
#define FLASH_ID_GD25LQ32C 0xC86016
|
||||
|
||||
|
@ -11,3 +11,5 @@
|
||||
#define SOC_SUPPORTS_SECURE_DL_MODE 1
|
||||
#define SOC_RISCV_COPROC_SUPPORTED 1
|
||||
#define SOC_USB_SUPPORTED 1
|
||||
|
||||
#define SOC_CACHE_SUPPORT_WRAP 1
|
@ -8,6 +8,7 @@
|
||||
#define SOC_TWAI_SUPPORTED 1
|
||||
#define SOC_GDMA_SUPPORTED 1
|
||||
#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
|
||||
// Remove them when GDMA driver API is ready
|
||||
|
@ -1,5 +1,3 @@
|
||||
set(priv_requires bootloader_support soc)
|
||||
|
||||
if(BOOTLOADER_BUILD)
|
||||
if (CONFIG_IDF_TARGET_ESP32)
|
||||
# ESP32 Bootloader needs SPIUnlock from this file, but doesn't
|
||||
@ -10,6 +8,7 @@ if(BOOTLOADER_BUILD)
|
||||
set(srcs)
|
||||
endif()
|
||||
set(cache_srcs "")
|
||||
set(priv_requires bootloader_support soc)
|
||||
else()
|
||||
set(cache_srcs
|
||||
"cache_utils.c"
|
||||
|
@ -49,8 +49,9 @@ menu "SPI Flash driver"
|
||||
default y
|
||||
help
|
||||
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
|
||||
where external SPI flash is connected to non-default pins.
|
||||
This option should be enabled, if any one of the following is true: (1) need to write
|
||||
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
|
||||
bool "Writing to dangerous flash regions"
|
||||
|
@ -19,8 +19,14 @@
|
||||
#define SPI_IDX 1
|
||||
#define OTH_IDX 0
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
uint32_t status;
|
||||
uint32_t new_status;
|
||||
|
||||
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) {
|
||||
return ESP_ROM_SPIFLASH_RESULT_ERR;
|
||||
}
|
||||
if (is_issi_chip(&g_rom_spiflash_chip)) {
|
||||
// ISSI chips have different QE position
|
||||
|
||||
/* Clear all bits except QIE, if it is set.
|
||||
(This is different from ROM esp_rom_spiflash_unlock, which keeps all bits as-is.)
|
||||
*/
|
||||
status &= ESP_ROM_SPIFLASH_QE;
|
||||
if (esp_rom_spiflash_read_status(&g_rom_spiflash_chip, &status) != ESP_ROM_SPIFLASH_RESULT_OK) {
|
||||
return ESP_ROM_SPIFLASH_RESULT_ERR;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
REG_WRITE(SPI_CMD_REG(SPI_IDX), SPI_FLASH_WREN);
|
||||
while (REG_READ(SPI_CMD_REG(SPI_IDX)) != 0) {
|
||||
}
|
||||
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, status) != ESP_ROM_SPIFLASH_RESULT_OK) {
|
||||
if (esp_rom_spiflash_write_status(&g_rom_spiflash_chip, new_status) != ESP_ROM_SPIFLASH_RESULT_OK) {
|
||||
return ESP_ROM_SPIFLASH_RESULT_ERR;
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "soc/soc_memory_layout.h"
|
||||
#include "esp32s2/rom/spi_flash.h"
|
||||
#include "esp32s2/rom/cache.h"
|
||||
#include "bootloader_flash.h"
|
||||
#include "hal/spi_flash_hal.h"
|
||||
#include "esp_flash.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)
|
||||
{
|
||||
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;
|
||||
return bootloader_flash_wrap_set(mode);
|
||||
}
|
||||
|
||||
esp_err_t spi_flash_enable_wrap(uint32_t wrap_size)
|
||||
{
|
||||
switch(wrap_size) {
|
||||
case 8:
|
||||
return spi_flash_wrap_set(FLASH_WRAP_MODE_8B);
|
||||
return bootloader_flash_wrap_set(FLASH_WRAP_MODE_8B);
|
||||
case 16:
|
||||
return spi_flash_wrap_set(FLASH_WRAP_MODE_16B);
|
||||
return bootloader_flash_wrap_set(FLASH_WRAP_MODE_16B);
|
||||
case 32:
|
||||
return spi_flash_wrap_set(FLASH_WRAP_MODE_32B);
|
||||
return bootloader_flash_wrap_set(FLASH_WRAP_MODE_32B);
|
||||
case 64:
|
||||
return spi_flash_wrap_set(FLASH_WRAP_MODE_64B);
|
||||
return bootloader_flash_wrap_set(FLASH_WRAP_MODE_64B);
|
||||
default:
|
||||
return ESP_FAIL;
|
||||
}
|
||||
@ -125,7 +100,7 @@ esp_err_t spi_flash_enable_wrap(uint32_t wrap_size)
|
||||
|
||||
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)
|
||||
|
@ -36,8 +36,6 @@
|
||||
#include "esp32s2/rom/spi_flash.h"
|
||||
#include "esp32s2/rom/cache.h"
|
||||
#include "esp32s2/clk.h"
|
||||
#include "soc/spi_mem_reg.h"
|
||||
#include "soc/spi_mem_struct.h"
|
||||
#endif
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "cache_utils.h"
|
||||
@ -777,6 +775,7 @@ void spi_flash_dump_counters(void)
|
||||
|
||||
#endif //CONFIG_SPI_FLASH_ENABLE_COUNTERS
|
||||
|
||||
|
||||
#if defined(CONFIG_SPI_FLASH_USE_LEGACY_IMPL) && defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||
// TODO esp32s2: Remove once ESP32S2 has new SPI Flash API support
|
||||
esp_flash_t *esp_flash_default_chip = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user