Skip to content

Commit

Permalink
Merge branch 'bugfix/fix_flash_encryption_rom_c3_v5.1' into 'release/…
Browse files Browse the repository at this point in the history
…v5.1'

fix(spi_flash): Fix issue that flash encryption failed while rom_impl config is enabled (backport v5.1)

See merge request espressif/esp-idf!29351
  • Loading branch information
jack0c committed Mar 5, 2024
2 parents 44fa82c + 9df0678 commit 8aa5610
Show file tree
Hide file tree
Showing 10 changed files with 217 additions and 153 deletions.
4 changes: 4 additions & 0 deletions components/esp_rom/esp32c3/Kconfig.soc_caps.in
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ config ESP_ROM_HAS_ERASE_0_REGION_BUG
bool
default y

config ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV
bool
default y

config ESP_ROM_GET_CLK_FREQ
bool
default y
Expand Down
1 change: 1 addition & 0 deletions components/esp_rom/esp32c3/esp_rom_caps.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#define ESP_ROM_USB_SERIAL_DEVICE_NUM (3) // UART uses USB_SERIAL_JTAG port in ROM.
#define ESP_ROM_HAS_RETARGETABLE_LOCKING (1) // ROM was built with retargetable locking
#define ESP_ROM_HAS_ERASE_0_REGION_BUG (1) // ROM has esp_flash_erase_region(size=0) bug
#define ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV (1) // `esp_flash_write_encrypted` in ROM has bug.
#define ESP_ROM_GET_CLK_FREQ (1) // Get clk frequency with rom function `ets_get_cpu_frequency`
#define ESP_ROM_NEEDS_SWSETUP_WORKAROUND (1) // ROM uses 32-bit time_t. A workaround is required to prevent printf functions from crashing
#define ESP_ROM_HAS_LAYOUT_TABLE (1) // ROM has the layout table
Expand Down
4 changes: 4 additions & 0 deletions components/esp_rom/esp32s3/Kconfig.soc_caps.in
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ config ESP_ROM_HAS_ERASE_0_REGION_BUG
bool
default y

config ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV
bool
default y

config ESP_ROM_GET_CLK_FREQ
bool
default y
Expand Down
1 change: 1 addition & 0 deletions components/esp_rom/esp32s3/esp_rom_caps.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#define ESP_ROM_USB_OTG_NUM (3) // The serial port ID (UART, USB, ...) of USB_OTG CDC in the ROM.
#define ESP_ROM_USB_SERIAL_DEVICE_NUM (4) // The serial port ID (UART, USB, ...) of USB_SERIAL_JTAG in the ROM.
#define ESP_ROM_HAS_ERASE_0_REGION_BUG (1) // ROM has esp_flash_erase_region(size=0) bug
#define ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV (1) // `esp_flash_write_encrypted` in ROM has bug.
#define ESP_ROM_GET_CLK_FREQ (1) // Get clk frequency with rom function `ets_get_cpu_frequency`
#define ESP_ROM_HAS_HAL_WDT (1) // ROM has the implementation of Watchdog HAL driver
#define ESP_ROM_NEEDS_SWSETUP_WORKAROUND (1) // ROM uses 32-bit time_t. A workaround is required to prevent printf functions from crashing
Expand Down
163 changes: 84 additions & 79 deletions components/spi_flash/esp_flash_api.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -146,12 +146,12 @@ _Static_assert(sizeof(io_mode_str)/IO_STR_LEN == SPI_FLASH_READ_MODE_MAX, "the i

esp_err_t esp_flash_read_chip_id(esp_flash_t* chip, uint32_t* flash_id);

#ifndef CONFIG_SPI_FLASH_ROM_IMPL
#if !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV
static esp_err_t spiflash_start_default(esp_flash_t *chip);
static esp_err_t spiflash_end_default(esp_flash_t *chip, esp_err_t err);
static esp_err_t check_chip_pointer_default(esp_flash_t **inout_chip);
static esp_err_t flash_end_flush_cache(esp_flash_t* chip, esp_err_t err, bool bus_acquired, uint32_t address, uint32_t length);
#endif //CONFIG_SPI_FLASH_ROM_IMPL
#endif // !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV

typedef struct {
esp_err_t (*start)(esp_flash_t *chip);
Expand All @@ -160,7 +160,7 @@ typedef struct {
esp_err_t (*flash_end_flush_cache)(esp_flash_t* chip, esp_err_t err, bool bus_acquired, uint32_t address, uint32_t length);
} rom_spiflash_api_func_t;

#ifndef CONFIG_SPI_FLASH_ROM_IMPL
#if !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV
// These functions can be placed in the ROM. For now we use the code in IDF.
DRAM_ATTR static rom_spiflash_api_func_t default_spiflash_rom_api = {
.start = spiflash_start_default,
Expand All @@ -173,14 +173,14 @@ DRAM_ATTR rom_spiflash_api_func_t *rom_spiflash_api_funcs = &default_spiflash_ro
#else
extern rom_spiflash_api_func_t *esp_flash_api_funcs;
#define rom_spiflash_api_funcs esp_flash_api_funcs
#endif // CONFIG_SPI_FLASH_ROM_IMPL
#endif // !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV

/* Static function to notify OS of a new SPI flash operation.
If returns an error result, caller must abort. If returns ESP_OK, caller must
call rom_spiflash_api_funcs->end() before returning.
*/
#ifndef CONFIG_SPI_FLASH_ROM_IMPL
#if !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV
static esp_err_t IRAM_ATTR spiflash_start_default(esp_flash_t *chip)
{
if (chip->os_func != NULL && chip->os_func->start != NULL) {
Expand Down Expand Up @@ -239,7 +239,7 @@ static IRAM_ATTR esp_err_t flash_end_flush_cache(esp_flash_t* chip, esp_err_t er
}
return rom_spiflash_api_funcs->end(chip, err);
}
#endif //CONFIG_SPI_FLASH_ROM_IMPL
#endif // !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV

/* Top-level API functions, calling into chip_drv functions via chip->drv */

Expand Down Expand Up @@ -1121,6 +1121,82 @@ esp_err_t IRAM_ATTR esp_flash_write(esp_flash_t *chip, const void *buffer, uint3
return err;
}

inline static IRAM_ATTR bool regions_overlap(uint32_t a_start, uint32_t a_len,uint32_t b_start, uint32_t b_len)
{
uint32_t a_end = a_start + a_len;
uint32_t b_end = b_start + b_len;
return (a_end > b_start && b_end > a_start);
}

esp_err_t IRAM_ATTR esp_flash_read_encrypted(esp_flash_t *chip, uint32_t address, void *out_buffer, uint32_t length)
{
esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip);
if (err != ESP_OK) return err;
if (address + length > g_rom_flashchip.chip_size) {
return ESP_ERR_INVALID_SIZE;
}
if (length == 0) {
return ESP_OK;
}
if (out_buffer == NULL) {
return ESP_ERR_INVALID_ARG;
}

COUNTER_START();
const uint8_t *map;
spi_flash_mmap_handle_t map_handle;
size_t map_src = address & ~(SPI_FLASH_MMU_PAGE_SIZE - 1);
size_t map_size = length + (address - map_src);

err = spi_flash_mmap(map_src, map_size, SPI_FLASH_MMAP_DATA, (const void **)&map, &map_handle);
if (err != ESP_OK) {
return err;
}
memcpy(out_buffer, map + (address - map_src), length);
spi_flash_munmap(map_handle);

COUNTER_ADD_BYTES(read, length);
COUNTER_STOP(read);
return err;
}

// test only, non-public
IRAM_ATTR esp_err_t esp_flash_get_io_mode(esp_flash_t* chip, bool* qe)
{
esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip);
VERIFY_CHIP_OP(get_io_mode);
esp_flash_io_mode_t io_mode;

err = rom_spiflash_api_funcs->start(chip);
if (err != ESP_OK) {
return err;
}
err = chip->chip_drv->get_io_mode(chip, &io_mode);
err = rom_spiflash_api_funcs->end(chip, err);
if (err == ESP_OK) {
*qe = (io_mode == SPI_FLASH_QOUT);
}
return err;
}

IRAM_ATTR esp_err_t esp_flash_set_io_mode(esp_flash_t* chip, bool qe)
{
esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip);
VERIFY_CHIP_OP(set_io_mode);

chip->read_mode = (qe? SPI_FLASH_QOUT: SPI_FLASH_SLOWRD);
err = rom_spiflash_api_funcs->start(chip);
if (err != ESP_OK) {
return err;
}
err = chip->chip_drv->set_io_mode(chip);
return rom_spiflash_api_funcs->end(chip, err);
}
#endif //CONFIG_SPI_FLASH_ROM_IMPL

#if !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV
// use `esp_flash_write_encrypted` ROM version not in C3 and S3

esp_err_t IRAM_ATTR esp_flash_write_encrypted(esp_flash_t *chip, uint32_t address, const void *buffer, uint32_t length)
{
esp_err_t ret = ESP_FAIL;
Expand Down Expand Up @@ -1286,78 +1362,7 @@ esp_err_t IRAM_ATTR esp_flash_write_encrypted(esp_flash_t *chip, uint32_t addres
return err;
}

inline static IRAM_ATTR bool regions_overlap(uint32_t a_start, uint32_t a_len,uint32_t b_start, uint32_t b_len)
{
uint32_t a_end = a_start + a_len;
uint32_t b_end = b_start + b_len;
return (a_end > b_start && b_end > a_start);
}

esp_err_t IRAM_ATTR esp_flash_read_encrypted(esp_flash_t *chip, uint32_t address, void *out_buffer, uint32_t length)
{
esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip);
if (err != ESP_OK) return err;
if (address + length > g_rom_flashchip.chip_size) {
return ESP_ERR_INVALID_SIZE;
}
if (length == 0) {
return ESP_OK;
}
if (out_buffer == NULL) {
return ESP_ERR_INVALID_ARG;
}

COUNTER_START();
const uint8_t *map;
spi_flash_mmap_handle_t map_handle;
size_t map_src = address & ~(SPI_FLASH_MMU_PAGE_SIZE - 1);
size_t map_size = length + (address - map_src);

err = spi_flash_mmap(map_src, map_size, SPI_FLASH_MMAP_DATA, (const void **)&map, &map_handle);
if (err != ESP_OK) {
return err;
}
memcpy(out_buffer, map + (address - map_src), length);
spi_flash_munmap(map_handle);

COUNTER_ADD_BYTES(read, length);
COUNTER_STOP(read);
return err;
}

// test only, non-public
IRAM_ATTR esp_err_t esp_flash_get_io_mode(esp_flash_t* chip, bool* qe)
{
esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip);
VERIFY_CHIP_OP(get_io_mode);
esp_flash_io_mode_t io_mode;

err = rom_spiflash_api_funcs->start(chip);
if (err != ESP_OK) {
return err;
}
err = chip->chip_drv->get_io_mode(chip, &io_mode);
err = rom_spiflash_api_funcs->end(chip, err);
if (err == ESP_OK) {
*qe = (io_mode == SPI_FLASH_QOUT);
}
return err;
}

IRAM_ATTR esp_err_t esp_flash_set_io_mode(esp_flash_t* chip, bool qe)
{
esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip);
VERIFY_CHIP_OP(set_io_mode);

chip->read_mode = (qe? SPI_FLASH_QOUT: SPI_FLASH_SLOWRD);
err = rom_spiflash_api_funcs->start(chip);
if (err != ESP_OK) {
return err;
}
err = chip->chip_drv->set_io_mode(chip);
return rom_spiflash_api_funcs->end(chip, err);
}
#endif //CONFIG_SPI_FLASH_ROM_IMPL
#endif // !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV

//init suspend mode cmd, uses internal.
esp_err_t esp_flash_suspend_cmd_init(esp_flash_t* chip)
Expand Down

0 comments on commit 8aa5610

Please sign in to comment.