From e4b44f34888fcf575a4eabaf53c5130f4fbd4ee6 Mon Sep 17 00:00:00 2001 From: "Michael (XIAO Xufeng)" Date: Tue, 10 Sep 2019 14:34:06 +0800 Subject: [PATCH 1/4] esp_flash: fix coredump for legacy spi flash API When legacy mode is used, the coredump still fails during linking because "esp_flash_init_default_chip", "esp_flash_app_init" and "esp_flash_default_chip " are not compiled and linked. Instead of using ``if`` macros in callers, these functions are protected by ``if`` macros in the header, and also not compiled in the sources. "esp_flash_default_chip" variable is compiled with safe default value. --- components/esp32/cpu_start.c | 2 +- components/spi_flash/CMakeLists.txt | 13 ++-- components/spi_flash/esp_flash_api.c | 15 ++-- components/spi_flash/esp_flash_spi_init.c | 35 ++++++---- components/spi_flash/include/esp_flash.h | 27 -------- .../spi_flash/include/esp_flash_internal.h | 68 +++++++++++++++++++ 6 files changed, 106 insertions(+), 54 deletions(-) create mode 100644 components/spi_flash/include/esp_flash_internal.h diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 221cb1debd..b55753a6dc 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -43,7 +43,7 @@ #include "sdkconfig.h" #include "esp_system.h" #include "esp_spi_flash.h" -#include "esp_flash.h" +#include "esp_flash_internal.h" #include "nvs_flash.h" #include "esp_event.h" #include "esp_spi_flash.h" diff --git a/components/spi_flash/CMakeLists.txt b/components/spi_flash/CMakeLists.txt index 1a09d3e69f..878b3c8cf9 100644 --- a/components/spi_flash/CMakeLists.txt +++ b/components/spi_flash/CMakeLists.txt @@ -4,21 +4,24 @@ if(BOOTLOADER_BUILD) # need other parts of this component set(srcs "spi_flash_rom_patch.c") else() - set(srcs + set(srcs "cache_utils.c" "flash_mmap.c" "flash_ops.c" "partition.c" "spi_flash_rom_patch.c" + ) + # New implementation + list(APPEND srcs "spi_flash_chip_drivers.c" "spi_flash_chip_generic.c" "spi_flash_chip_issi.c" "spi_flash_os_func_app.c" "spi_flash_os_func_noos.c" - "memspi_host_driver.c") - if(NOT CONFIG_SPI_FLASH_USE_LEGACY_IMPL) - list(APPEND srcs "esp_flash_api.c" "esp_flash_spi_init.c") - endif() + "memspi_host_driver.c" + "esp_flash_api.c" + "esp_flash_spi_init.c" + ) set(priv_requires bootloader_support app_update soc) endif() diff --git a/components/spi_flash/esp_flash_api.c b/components/spi_flash/esp_flash_api.c index 146ebd12f8..b350e3d0fb 100644 --- a/components/spi_flash/esp_flash_api.c +++ b/components/spi_flash/esp_flash_api.c @@ -294,14 +294,15 @@ esp_err_t IRAM_ATTR esp_flash_erase_region(esp_flash_t *chip, uint32_t start, ui return ESP_ERR_INVALID_ARG; } - esp_err_t err = spiflash_start(chip); - if (err != ESP_OK) { - return err; - } - + esp_err_t err = ESP_OK; // Check for write protected regions overlapping the erase region if (chip->chip_drv->get_protected_regions != NULL && chip->chip_drv->num_protectable_regions > 0) { + + err = spiflash_start(chip); + if (err != ESP_OK) { + return err; + } uint64_t protected = 0; err = chip->chip_drv->get_protected_regions(chip, &protected); if (err == ESP_OK && protected != 0) { @@ -313,10 +314,10 @@ esp_err_t IRAM_ATTR esp_flash_erase_region(esp_flash_t *chip, uint32_t start, ui } } } + // Don't lock the SPI flash for the entire erase, as this may be very long + err = spiflash_end(chip, err); } - // Don't lock the SPI flash for the entire erase, as this may be very long - err = spiflash_end(chip, err); while (err == ESP_OK && len >= sector_size) { err = spiflash_start(chip); diff --git a/components/spi_flash/esp_flash_spi_init.c b/components/spi_flash/esp_flash_spi_init.c index ecd5666860..dda02130d0 100644 --- a/components/spi_flash/esp_flash_spi_init.c +++ b/components/spi_flash/esp_flash_spi_init.c @@ -23,7 +23,7 @@ #include "hal/spi_types.h" #include "driver/spi_common.h" -static const char TAG[] = "spi_flash"; +__attribute__((unused)) static const char TAG[] = "spi_flash"; #ifdef CONFIG_ESPTOOLPY_FLASHFREQ_80M #define DEFAULT_FLASH_SPEED ESP_FLASH_80MHZ @@ -49,6 +49,18 @@ static const char TAG[] = "spi_flash"; #define DEFAULT_FLASH_MODE SPI_FLASH_FASTRD #endif +#define ESP_FLASH_HOST_CONFIG_DEFAULT() (memspi_host_config_t){ \ + .host_id = SPI_HOST,\ + .speed = DEFAULT_FLASH_SPEED, \ + .cs_num = 0, \ + .iomux = false, \ + .input_delay_ns = 0,\ +} + + +esp_flash_t *esp_flash_default_chip = NULL; + + static IRAM_ATTR void cs_initialize(esp_flash_t *chip, const esp_flash_spi_device_config_t *config, bool use_iomux) { //Not using spicommon_cs_initialize since we don't want to put the whole @@ -151,29 +163,22 @@ esp_err_t spi_bus_remove_flash_device(esp_flash_t *chip) return ESP_OK; } -#define ESP_FLASH_HOST_CONFIG_DEFAULT() (memspi_host_config_t){ \ - .host_id = SPI_HOST,\ - .speed = DEFAULT_FLASH_SPEED, \ - .cs_num = 0, \ - .iomux = false, \ - .input_delay_ns = 0,\ -} - -static DRAM_ATTR spi_flash_host_driver_t esp_flash_default_host_drv = ESP_FLASH_DEFAULT_HOST_DRIVER(); - -static DRAM_ATTR memspi_host_data_t default_driver_data; /* The default (ie initial boot) no-OS ROM esp_flash_os_functions_t */ extern const esp_flash_os_functions_t esp_flash_noos_functions; +#ifndef CONFIG_SPI_FLASH_USE_LEGACY_IMPL + +static DRAM_ATTR memspi_host_data_t default_driver_data; +static DRAM_ATTR spi_flash_host_driver_t esp_flash_default_host_drv = ESP_FLASH_DEFAULT_HOST_DRIVER(); + + static DRAM_ATTR esp_flash_t default_chip = { .read_mode = DEFAULT_FLASH_MODE, .host = &esp_flash_default_host_drv, .os_func = &esp_flash_noos_functions, }; -esp_flash_t *esp_flash_default_chip = NULL; - esp_err_t esp_flash_init_default_chip() { memspi_host_config_t cfg = ESP_FLASH_HOST_CONFIG_DEFAULT(); @@ -204,3 +209,5 @@ esp_err_t esp_flash_app_init() { return esp_flash_init_os_functions(&default_chip, 0); } + +#endif diff --git a/components/spi_flash/include/esp_flash.h b/components/spi_flash/include/esp_flash.h index 95d815b7b5..e5a3a18309 100644 --- a/components/spi_flash/include/esp_flash.h +++ b/components/spi_flash/include/esp_flash.h @@ -265,33 +265,6 @@ esp_err_t esp_flash_write_encrypted(esp_flash_t *chip, uint32_t address, const v */ extern esp_flash_t *esp_flash_default_chip; -/** @brief Initialise the default SPI flash chip - * - * Called by OS startup code. You do not need to call this in your own applications. - */ -esp_err_t esp_flash_init_default_chip(); - -/** - * Enable OS-level SPI flash protections in IDF - * - * Called by OS startup code. You do not need to call this in your own applications. - * - * @return ESP_OK if success, otherwise failed. See return value of ``esp_flash_init_os_functions``. - */ -esp_err_t esp_flash_app_init(); - -/** - * Enable OS-level SPI flash for a specific chip. - * - * @param chip The chip to init os functions. - * @param host_id Which SPI host to use, 1 for SPI1, 2 for SPI2 (HSPI), 3 for SPI3 (VSPI) - * - * @return - * - ESP_OK if success - * - ESP_ERR_INVALID_ARG if host_id is invalid - */ -esp_err_t esp_flash_init_os_functions(esp_flash_t *chip, int host_id); - #ifdef __cplusplus } diff --git a/components/spi_flash/include/esp_flash_internal.h b/components/spi_flash/include/esp_flash_internal.h new file mode 100644 index 0000000000..b0d35f371c --- /dev/null +++ b/components/spi_flash/include/esp_flash_internal.h @@ -0,0 +1,68 @@ +// Copyright 2015-2019 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 +#include +#include "sdkconfig.h" + +#include "esp_flash.h" + +/** Internal API, don't use in the applications */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @brief Initialise the default SPI flash chip + * + * Called by OS startup code. You do not need to call this in your own applications. + */ +#ifdef CONFIG_SPI_FLASH_USE_LEGACY_IMPL +#define esp_flash_init_default_chip(...) ({ESP_OK;}) +#else +esp_err_t esp_flash_init_default_chip(void); +#endif + +/** + * Enable OS-level SPI flash protections in IDF + * + * Called by OS startup code. You do not need to call this in your own applications. + * + * @return ESP_OK if success, otherwise failed. See return value of ``esp_flash_init_os_functions``. + */ +#ifdef CONFIG_SPI_FLASH_USE_LEGACY_IMPL +#define esp_flash_app_init(...) ({ESP_OK;}) +#else +esp_err_t esp_flash_app_init(void); +#endif + +/** + * Initialize OS-level functions for a specific chip. + * + * @param chip The chip to init os functions. + * @param host_id Which SPI host to use, 1 for SPI1, 2 for SPI2 (HSPI), 3 for SPI3 (VSPI) + * + * @return + * - ESP_OK if success + * - ESP_ERR_INVALID_ARG if host_id is invalid + */ +esp_err_t esp_flash_init_os_functions(esp_flash_t *chip, int host_id); + + +#ifdef __cplusplus +} +#endif From d3b54ec84aafd973ce5be2480ff989dbe05b00be Mon Sep 17 00:00:00 2001 From: "Michael (XIAO Xufeng)" Date: Thu, 12 Sep 2019 02:41:00 +0800 Subject: [PATCH 2/4] esp_flash: fix the coredump issue During coredump, dangerous-area-checking should be disabled, and cache disabling should be replaced by a safer version. Dangerous-area-checking used to be in the HAL, but it seems to be more fit to os functions. So it's moved to os functions. Interfaces are provided to switch between os functions during coredump. --- components/espcoredump/src/core_dump_flash.c | 4 +- components/soc/include/hal/spi_flash_types.h | 5 --- components/spi_flash/esp_flash_api.c | 14 ++++++- components/spi_flash/esp_flash_spi_init.c | 3 +- components/spi_flash/include/esp_flash.h | 3 ++ .../spi_flash/include/esp_flash_internal.h | 32 ++++++++++++++++ .../spi_flash/include/memspi_host_driver.h | 12 ------ components/spi_flash/memspi_host_driver.c | 12 ------ components/spi_flash/spi_flash_os_func_app.c | 37 +++++++++++++++++-- components/spi_flash/spi_flash_os_func_noos.c | 17 +++++++-- 10 files changed, 100 insertions(+), 39 deletions(-) diff --git a/components/espcoredump/src/core_dump_flash.c b/components/espcoredump/src/core_dump_flash.c index dd48d5ba8e..ce7ebef4b9 100644 --- a/components/espcoredump/src/core_dump_flash.c +++ b/components/espcoredump/src/core_dump_flash.c @@ -15,6 +15,7 @@ #include "esp32/rom/crc.h" #include "esp_partition.h" #include "esp_core_dump_priv.h" +#include "esp_flash_internal.h" const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_flash"; @@ -50,7 +51,7 @@ static inline core_dump_crc_t esp_core_dump_calc_flash_config_crc(void) return crc32_le(0, (uint8_t const *)&s_core_flash_config.partition, sizeof(s_core_flash_config.partition)); } -void esp_core_dump_flash_init() +void esp_core_dump_flash_init(void) { const esp_partition_t *core_part; @@ -216,6 +217,7 @@ void esp_core_dump_to_flash(XtExcFrame *frame) /* init non-OS flash access critical section */ spi_flash_guard_set(&g_flash_guard_no_os_ops); + esp_flash_app_disable_protect(true); memset(&wr_cfg, 0, sizeof(wr_cfg)); wr_cfg.prepare = esp_core_dump_flash_write_prepare; diff --git a/components/soc/include/hal/spi_flash_types.h b/components/soc/include/hal/spi_flash_types.h index 7babeee0c9..c19eee1ed0 100644 --- a/components/soc/include/hal/spi_flash_types.h +++ b/components/soc/include/hal/spi_flash_types.h @@ -142,11 +142,6 @@ struct spi_flash_host_driver_t { * modified, the cache needs to be flushed. Left NULL if not supported. */ esp_err_t (*flush_cache)(spi_flash_host_driver_t* driver, uint32_t addr, uint32_t size); - /** - * Check if the given region is protected (e.g. is the bootloader). Left - * NULL if current host doesn't need protection. - */ - bool (*region_protected)(spi_flash_host_driver_t* driver, uint32_t addr, uint32_t size); }; #ifdef __cplusplus diff --git a/components/spi_flash/esp_flash_api.c b/components/spi_flash/esp_flash_api.c index b350e3d0fb..ae907b4fb8 100644 --- a/components/spi_flash/esp_flash_api.c +++ b/components/spi_flash/esp_flash_api.c @@ -22,6 +22,7 @@ #include "esp_log.h" #include "sdkconfig.h" #include "esp_heap_caps.h" +#include "esp_flash_internal.h" static const char TAG[] = "spi_flash"; @@ -42,7 +43,7 @@ static const char TAG[] = "spi_flash"; #define CHECK_WRITE_ADDRESS(CHIP, ADDR, SIZE) #else /* FAILS or ABORTS */ #define CHECK_WRITE_ADDRESS(CHIP, ADDR, SIZE) do { \ - if (CHIP && CHIP->host->region_protected && CHIP->host->region_protected(CHIP->host, ADDR, SIZE)) { \ + if (CHIP && CHIP->os_func->region_protected && CHIP->os_func->region_protected(CHIP->os_func_data, ADDR, SIZE)) { \ UNSAFE_WRITE_ADDRESS; \ } \ } while(0) @@ -600,6 +601,17 @@ inline static IRAM_ATTR bool regions_overlap(uint32_t a_start, uint32_t a_len,ui } +#ifndef CONFIG_SPI_FLASH_USE_LEGACY_IMPL +esp_err_t esp_flash_app_disable_protect(bool disable) +{ + if (disable) { + return esp_flash_app_disable_os_functions(esp_flash_default_chip); + } else { + return esp_flash_app_init_os_functions(esp_flash_default_chip); + } +} +#endif + /*------------------------------------------------------------------------------ Adapter layer to original api before IDF v4.0 ------------------------------------------------------------------------------*/ diff --git a/components/spi_flash/esp_flash_spi_init.c b/components/spi_flash/esp_flash_spi_init.c index dda02130d0..0839d90181 100644 --- a/components/spi_flash/esp_flash_spi_init.c +++ b/components/spi_flash/esp_flash_spi_init.c @@ -22,6 +22,7 @@ #include "esp_heap_caps.h" #include "hal/spi_types.h" #include "driver/spi_common.h" +#include "esp_flash_internal.h" __attribute__((unused)) static const char TAG[] = "spi_flash"; @@ -207,7 +208,7 @@ esp_err_t esp_flash_init_default_chip() esp_err_t esp_flash_app_init() { - return esp_flash_init_os_functions(&default_chip, 0); + return esp_flash_app_init_os_functions(&default_chip); } #endif diff --git a/components/spi_flash/include/esp_flash.h b/components/spi_flash/include/esp_flash.h index e5a3a18309..51cfe99972 100644 --- a/components/spi_flash/include/esp_flash.h +++ b/components/spi_flash/include/esp_flash.h @@ -45,6 +45,9 @@ typedef struct { /** Called after completing any flash operation. */ esp_err_t (*end)(void *arg); + /** Called before any erase/write operations to check whether the region is limited by the OS */ + esp_err_t (*region_protected)(void* arg, size_t start_addr, size_t size); + /** Delay for at least 'ms' milliseconds. Called in between 'start' and 'end'. */ esp_err_t (*delay_ms)(void *arg, unsigned ms); } esp_flash_os_functions_t; diff --git a/components/spi_flash/include/esp_flash_internal.h b/components/spi_flash/include/esp_flash_internal.h index b0d35f371c..0496f5649c 100644 --- a/components/spi_flash/include/esp_flash_internal.h +++ b/components/spi_flash/include/esp_flash_internal.h @@ -50,6 +50,19 @@ esp_err_t esp_flash_init_default_chip(void); esp_err_t esp_flash_app_init(void); #endif +/** + * Disable OS-level SPI flash protections in IDF + * + * Called by the IDF internal code (e.g. coredump). You do not need to call this in your own applications. + * + * @return always ESP_OK. + */ +#ifdef CONFIG_SPI_FLASH_USE_LEGACY_IMPL +#define esp_flash_app_disable_protect(...) ({ESP_OK;}) +#else +esp_err_t esp_flash_app_disable_protect(bool disable); +#endif + /** * Initialize OS-level functions for a specific chip. * @@ -62,6 +75,25 @@ esp_err_t esp_flash_app_init(void); */ esp_err_t esp_flash_init_os_functions(esp_flash_t *chip, int host_id); +/** + * Initialize OS-level functions for the main flash chip. + * + * @param chip The chip to init os functions. Only pointer to the default chip is supported now. + * + * @return always ESP_OK + */ +esp_err_t esp_flash_app_init_os_functions(esp_flash_t* chip); + +/** + * Disable OS-level functions for the main flash chip during special phases (e.g. coredump) + * + * @param chip The chip to init os functions. Only "esp_flash_default_chip" is supported now. + * + * @return always ESP_OK + */ +esp_err_t esp_flash_app_disable_os_functions(esp_flash_t* chip); + + #ifdef __cplusplus } diff --git a/components/spi_flash/include/memspi_host_driver.h b/components/spi_flash/include/memspi_host_driver.h index 434361d970..cb0f3e9d9e 100644 --- a/components/spi_flash/include/memspi_host_driver.h +++ b/components/spi_flash/include/memspi_host_driver.h @@ -35,7 +35,6 @@ .configure_host_read_mode = spi_flash_hal_configure_host_read_mode, \ .poll_cmd_done = spi_flash_hal_poll_cmd_done, \ .flush_cache = memspi_host_flush_cache, \ - .region_protected = memspi_region_protected, \ } /// configuration for the memspi host @@ -100,14 +99,3 @@ esp_err_t memspi_host_read_status_hs(spi_flash_host_driver_t *driver, uint8_t *o * @return always ESP_OK. */ esp_err_t memspi_host_flush_cache(spi_flash_host_driver_t* driver, uint32_t addr, uint32_t size); - -/** - * Check if the given region is protected. - * - * @param driver The driver context. - * @param addr Start address of the region. - * @param size Size of the region to check. - * - * @return true if protected, otherwise false. - */ -bool memspi_region_protected(spi_flash_host_driver_t* driver, uint32_t addr, uint32_t size); \ No newline at end of file diff --git a/components/spi_flash/memspi_host_driver.c b/components/spi_flash/memspi_host_driver.c index 871616386f..85b31998a0 100644 --- a/components/spi_flash/memspi_host_driver.c +++ b/components/spi_flash/memspi_host_driver.c @@ -34,7 +34,6 @@ esp_err_t memspi_host_init_pointers(spi_flash_host_driver_t *host, memspi_host_d //some functions are not required if not SPI1 if (data->spi != &SPI1) { host->flush_cache = NULL; - host->region_protected = NULL; } return ESP_OK; } @@ -87,15 +86,4 @@ esp_err_t memspi_host_flush_cache(spi_flash_host_driver_t* driver, uint32_t addr spi_flash_check_and_flush_cache(addr, size); } return ESP_OK; -} - -bool memspi_region_protected(spi_flash_host_driver_t* driver, uint32_t addr, uint32_t size) -{ - if (((memspi_host_data_t*)(driver->driver_data))->spi != &SPI1) { - return false; - } - if (!esp_partition_main_flash_region_safe(addr, size)) { - return true; - } - return false; } \ No newline at end of file diff --git a/components/spi_flash/spi_flash_os_func_app.c b/components/spi_flash/spi_flash_os_func_app.c index b2e13c8e44..ad97c433c5 100644 --- a/components/spi_flash/spi_flash_os_func_app.c +++ b/components/spi_flash/spi_flash_os_func_app.c @@ -17,6 +17,8 @@ #include "esp_attr.h" #include "esp_spi_flash.h" //for ``g_flash_guard_default_ops`` #include "esp_flash.h" +#include "esp_flash_partitions.h" + /* * OS functions providing delay service and arbitration among chips, and with the cache. @@ -29,6 +31,11 @@ typedef struct { int host_id; } app_func_arg_t; +typedef struct { + int host_id; + bool no_protect; //to decide whether to check protected region (for the main chip) or not. +} spi1_app_func_arg_t; + // in the future we will have arbitration among devices, including flash on the same flash bus static IRAM_ATTR esp_err_t spi_bus_acquire(int host_id) { @@ -45,7 +52,7 @@ static IRAM_ATTR esp_err_t spi1_start(void *arg) { g_flash_guard_default_ops.start(); - spi_bus_acquire(((app_func_arg_t *)arg)->host_id); + spi_bus_acquire(((spi1_app_func_arg_t *)arg)->host_id); return ESP_OK; } @@ -53,7 +60,7 @@ static IRAM_ATTR esp_err_t spi1_end(void *arg) { g_flash_guard_default_ops.end(); - spi_bus_release(((app_func_arg_t *)arg)->host_id); + spi_bus_release(((spi1_app_func_arg_t *)arg)->host_id); return ESP_OK; } @@ -76,8 +83,24 @@ static IRAM_ATTR esp_err_t delay_ms(void *arg, unsigned ms) return ESP_OK; } -static DRAM_ATTR app_func_arg_t spi1_arg = { +static IRAM_ATTR esp_err_t main_flash_region_protected(void* arg, size_t start_addr, size_t size) +{ + if (((spi1_app_func_arg_t*)arg)->no_protect || esp_partition_main_flash_region_safe(start_addr, size)) { + //ESP_OK = 0, also means protected==0 + return ESP_OK; + } else { + return ESP_ERR_NOT_SUPPORTED; + } +} + +static DRAM_ATTR spi1_app_func_arg_t spi1_arg = { .host_id = 0, //for SPI1, + .no_protect = true, +}; + +static DRAM_ATTR spi1_app_func_arg_t main_flash_arg = { + .host_id = 0, //for SPI1, + .no_protect = false, }; static app_func_arg_t spi2_arg = { @@ -93,6 +116,7 @@ const DRAM_ATTR esp_flash_os_functions_t esp_flash_spi1_default_os_functions = { .start = spi1_start, .end = spi1_end, .delay_ms = delay_ms, + .region_protected = main_flash_region_protected, }; const esp_flash_os_functions_t esp_flash_spi23_default_os_functions = { @@ -117,4 +141,11 @@ esp_err_t esp_flash_init_os_functions(esp_flash_t *chip, int host_id) return ESP_OK; } +esp_err_t esp_flash_app_init_os_functions(esp_flash_t* chip) +{ + chip->os_func = &esp_flash_spi1_default_os_functions; + chip->os_func_data = &main_flash_arg; + return ESP_OK; +} + diff --git a/components/spi_flash/spi_flash_os_func_noos.c b/components/spi_flash/spi_flash_os_func_noos.c index 4b494279b0..910633f9b5 100644 --- a/components/spi_flash/spi_flash_os_func_noos.c +++ b/components/spi_flash/spi_flash_os_func_noos.c @@ -20,13 +20,15 @@ #include "esp_attr.h" -static esp_err_t start(void *arg) + +static IRAM_ATTR esp_err_t start(void *arg) { Cache_Read_Disable(0); Cache_Read_Disable(1); return ESP_OK; } -static esp_err_t end(void *arg) + +static IRAM_ATTR esp_err_t end(void *arg) { Cache_Flush(0); Cache_Flush(1); @@ -35,14 +37,21 @@ static esp_err_t end(void *arg) return ESP_OK; } -static esp_err_t delay_ms(void *arg, unsigned ms) +static IRAM_ATTR esp_err_t delay_ms(void *arg, unsigned ms) { ets_delay_us(1000 * ms); return ESP_OK; } -const esp_flash_os_functions_t esp_flash_noos_functions = { +const DRAM_ATTR esp_flash_os_functions_t esp_flash_noos_functions = { .start = start, .end = end, .delay_ms = delay_ms, + .region_protected = NULL, }; + +esp_err_t IRAM_ATTR esp_flash_app_disable_os_functions(esp_flash_t* chip) +{ + chip->os_func = &esp_flash_noos_functions; + return ESP_OK; +} From 399477cd10aa7effde2c3f6bffe5ebc80860a114 Mon Sep 17 00:00:00 2001 From: "Michael (XIAO Xufeng)" Date: Thu, 12 Sep 2019 02:23:44 +0800 Subject: [PATCH 3/4] coredump: use esp_flash api in coredump Also put esp_flash functions into noflash region, when ESP32_PANIC_HANDLER_IRAM and coredump are enabled. The option disables the re-enabling of the CPU-cache when it's disabled during coredump. This requires all the coredump functions including the flash API to be in the D/IRAM. --- components/espcoredump/linker.lf | 13 ++++++++++-- components/espcoredump/src/core_dump_flash.c | 22 ++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/components/espcoredump/linker.lf b/components/espcoredump/linker.lf index 02dd9cfe78..2b7b2ca998 100644 --- a/components/espcoredump/linker.lf +++ b/components/espcoredump/linker.lf @@ -1,7 +1,16 @@ [mapping:espcoredump] archive: libespcoredump.a -entries: +entries: core_dump_uart (noflash_text) core_dump_flash (noflash_text) core_dump_common (noflash_text) - core_dump_port (noflash_text) \ No newline at end of file + core_dump_port (noflash_text) + +[mapping:spi_flash_override] +archive: libspi_flash.a +entries: + if ESP32_ENABLE_COREDUMP_TO_FLASH = y: + esp_flash_api (noflash_text) + esp_flash_spi_init (noflash_text) + else: + * (default) \ No newline at end of file diff --git a/components/espcoredump/src/core_dump_flash.c b/components/espcoredump/src/core_dump_flash.c index ce7ebef4b9..70ba76d6f4 100644 --- a/components/espcoredump/src/core_dump_flash.c +++ b/components/espcoredump/src/core_dump_flash.c @@ -17,6 +17,8 @@ #include "esp_core_dump_priv.h" #include "esp_flash_internal.h" +#include "sdkconfig.h" + const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_flash"; #if CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH @@ -83,7 +85,11 @@ static uint32_t esp_core_dump_write_flash_padded(size_t off, uint8_t *data, uint assert((off + data_len + (data_size % sizeof(uint32_t) ? sizeof(uint32_t) : 0)) <= s_core_flash_config.partition.start + s_core_flash_config.partition.size); +#ifdef CONFIG_SPI_FLASH_USE_LEGACY_IMPL err = spi_flash_write(off, data, data_len); +#else + err = esp_flash_write(esp_flash_default_chip, data, off, data_len); +#endif if (err != ESP_OK) { ESP_COREDUMP_LOGE("Failed to write data to flash (%d)!", err); return 0; @@ -96,7 +102,11 @@ static uint32_t esp_core_dump_write_flash_padded(size_t off, uint8_t *data, uint for (k = 0; k < len; k++) { rom_data.data8[k] = *(data + data_len + k); } +#ifdef CONFIG_SPI_FLASH_USE_LEGACY_IMPL err = spi_flash_write(off + data_len, &rom_data, sizeof(uint32_t)); +#else + err = esp_flash_write(esp_flash_default_chip, &rom_data, off + data_len, sizeof(uint32_t)); +#endif if (err != ESP_OK) { ESP_COREDUMP_LOGE("Failed to finish write data to flash (%d)!", err); return 0; @@ -128,7 +138,11 @@ static esp_err_t esp_core_dump_flash_write_prepare(void *priv, uint32_t *data_le sec_num++; } assert(sec_num * SPI_FLASH_SEC_SIZE <= s_core_flash_config.partition.size); +#ifdef CONFIG_SPI_FLASH_USE_LEGACY_IMPL err = spi_flash_erase_range(s_core_flash_config.partition.start + 0, sec_num * SPI_FLASH_SEC_SIZE); +#else + err = esp_flash_erase_region(esp_flash_default_chip, s_core_flash_config.partition.start + 0, sec_num * SPI_FLASH_SEC_SIZE); +#endif if (err != ESP_OK) { ESP_COREDUMP_LOGE("Failed to erase flash (%d)!", err); return err; @@ -142,7 +156,11 @@ static esp_err_t esp_core_dump_flash_write_word(core_dump_write_flash_data_t *wr uint32_t data32 = word; assert(wr_data->off + sizeof(uint32_t) <= s_core_flash_config.partition.size); +#ifdef CONFIG_SPI_FLASH_USE_LEGACY_IMPL err = spi_flash_write(s_core_flash_config.partition.start + wr_data->off, &data32, sizeof(uint32_t)); +#else + err = esp_flash_write(esp_flash_default_chip, &data32, s_core_flash_config.partition.start + wr_data->off, sizeof(uint32_t)); +#endif if (err != ESP_OK) { ESP_COREDUMP_LOGE("Failed to write to flash (%d)!", err); return err; @@ -167,7 +185,11 @@ static esp_err_t esp_core_dump_flash_write_end(void *priv) uint32_t data32[4]; } rom_data; +#ifdef CONFIG_SPI_FLASH_USE_LEGACY_IMPL esp_err_t err = spi_flash_read(s_core_flash_config.partition.start + 0, &rom_data, sizeof(rom_data)); +#else + esp_err_t err = esp_flash_read(esp_flash_default_chip, &rom_data, s_core_flash_config.partition.start + 0, sizeof(rom_data)); +#endif if (err != ESP_OK) { ESP_COREDUMP_LOGE("Failed to read flash (%d)!", err); return err; From 0bba92b2a0321a09a244f69d9408b02ccda7e56a Mon Sep 17 00:00:00 2001 From: michael Date: Wed, 18 Sep 2019 15:07:47 +0800 Subject: [PATCH 4/4] esp_flash: put adapter to legacy functions into IRAM to be back-compatible --- components/spi_flash/esp_flash_api.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/spi_flash/esp_flash_api.c b/components/spi_flash/esp_flash_api.c index ae907b4fb8..d00d0a9a3e 100644 --- a/components/spi_flash/esp_flash_api.c +++ b/components/spi_flash/esp_flash_api.c @@ -618,7 +618,7 @@ esp_err_t esp_flash_app_disable_protect(bool disable) #ifndef CONFIG_SPI_FLASH_USE_LEGACY_IMPL -static esp_err_t spi_flash_translate_rc(esp_err_t err) +static IRAM_ATTR esp_err_t spi_flash_translate_rc(esp_err_t err) { switch (err) { case ESP_OK: @@ -641,19 +641,19 @@ static esp_err_t spi_flash_translate_rc(esp_err_t err) return ESP_OK; } -esp_err_t spi_flash_erase_range(uint32_t start_addr, uint32_t size) +esp_err_t IRAM_ATTR spi_flash_erase_range(uint32_t start_addr, uint32_t size) { esp_err_t err = esp_flash_erase_region(NULL, start_addr, size); return spi_flash_translate_rc(err); } -esp_err_t spi_flash_write(size_t dst, const void *srcv, size_t size) +esp_err_t IRAM_ATTR spi_flash_write(size_t dst, const void *srcv, size_t size) { esp_err_t err = esp_flash_write(NULL, srcv, dst, size); return spi_flash_translate_rc(err); } -esp_err_t spi_flash_read(size_t src, void *dstv, size_t size) +esp_err_t IRAM_ATTR spi_flash_read(size_t src, void *dstv, size_t size) { esp_err_t err = esp_flash_read(NULL, dstv, src, size); return spi_flash_translate_rc(err);