From 6139864a4c9b5cd4b8c2c0d7da12886516d06316 Mon Sep 17 00:00:00 2001 From: "Michael (XIAO Xufeng)" Date: Tue, 10 Sep 2019 14:34:06 +0800 Subject: [PATCH 1/3] 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 | 4 +- components/espcoredump/Kconfig | 1 - 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 +++++++++++++++++++ components/spi_flash/partition.c | 9 +-- 8 files changed, 107 insertions(+), 65 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 c5f2528818..18a8e97f7c 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" @@ -395,11 +395,9 @@ void start_cpu0_default(void) /* init default OS-aware flash access critical section */ spi_flash_guard_set(&g_flash_guard_default_ops); -#ifndef CONFIG_SPI_FLASH_USE_LEGACY_IMPL esp_flash_app_init(); esp_err_t flash_ret = esp_flash_init_default_chip(); assert(flash_ret == ESP_OK); -#endif uint8_t revision = esp_efuse_get_chip_ver(); ESP_LOGI(TAG, "Chip Revision: %d", revision); diff --git a/components/espcoredump/Kconfig b/components/espcoredump/Kconfig index fe8b6e4553..991bf18f7b 100644 --- a/components/espcoredump/Kconfig +++ b/components/espcoredump/Kconfig @@ -13,7 +13,6 @@ menu "Core dump" config ESP32_ENABLE_COREDUMP_TO_FLASH bool "Flash" select ESP32_ENABLE_COREDUMP - select SPI_FLASH_USE_LEGACY_IMPL config ESP32_ENABLE_COREDUMP_TO_UART bool "UART" select ESP32_ENABLE_COREDUMP 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 e45f906abc..7f29d86fc4 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 c554f4a292..ba0d26b567 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(void) { memspi_host_config_t cfg = ESP_FLASH_HOST_CONFIG_DEFAULT(); @@ -204,3 +209,5 @@ esp_err_t esp_flash_app_init(void) { 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 0de03e1218..77ffe31f58 100644 --- a/components/spi_flash/include/esp_flash.h +++ b/components/spi_flash/include/esp_flash.h @@ -282,33 +282,6 @@ esp_err_t esp_flash_read_encrypted(esp_flash_t *chip, uint32_t address, void *ou */ 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(void); - -/** - * 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(void); - -/** - * 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 diff --git a/components/spi_flash/partition.c b/components/spi_flash/partition.c index a6b33a1382..14de32c9f5 100644 --- a/components/spi_flash/partition.c +++ b/components/spi_flash/partition.c @@ -172,9 +172,7 @@ static esp_err_t load_partitions(void) err = ESP_ERR_NO_MEM; break; } -#ifndef CONFIG_SPI_FLASH_USE_LEGACY_IMPL item->info.flash_chip = esp_flash_default_chip; -#endif item->info.address = it->pos.offset; item->info.size = it->pos.size; item->info.type = it->type; @@ -336,11 +334,10 @@ esp_err_t esp_partition_read(const esp_partition_t* partition, #endif // CONFIG_SPI_FLASH_USE_LEGACY_IMPL } else { #if CONFIG_SECURE_FLASH_ENC_ENABLED -#ifndef CONFIG_SPI_FLASH_USE_LEGACY_IMPL if (partition->flash_chip != esp_flash_default_chip) { return ESP_ERR_NOT_SUPPORTED; } -#endif + /* Encrypted partitions need to be read via a cache mapping */ const void *buf; spi_flash_mmap_handle_t handle; @@ -379,11 +376,9 @@ esp_err_t esp_partition_write(const esp_partition_t* partition, #endif // CONFIG_SPI_FLASH_USE_LEGACY_IMPL } else { #if CONFIG_SECURE_FLASH_ENC_ENABLED -#ifndef CONFIG_SPI_FLASH_USE_LEGACY_IMPL if (partition->flash_chip != esp_flash_default_chip) { return ESP_ERR_NOT_SUPPORTED; } -#endif return spi_flash_write_encrypted(dst_offset, src, size); #else return ESP_ERR_NOT_SUPPORTED; @@ -433,11 +428,9 @@ esp_err_t esp_partition_mmap(const esp_partition_t* partition, size_t offset, si if (offset + size > partition->size) { return ESP_ERR_INVALID_SIZE; } -#ifndef CONFIG_SPI_FLASH_USE_LEGACY_IMPL if (partition->flash_chip != esp_flash_default_chip) { return ESP_ERR_NOT_SUPPORTED; } -#endif size_t phys_addr = partition->address + offset; // offset within 64kB block size_t region_offset = phys_addr & 0xffff; From 511820820e0aafbbfcb780589dbe06614d73ac15 Mon Sep 17 00:00:00 2001 From: "Michael (XIAO Xufeng)" Date: Thu, 12 Sep 2019 02:41:00 +0800 Subject: [PATCH 2/3] 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 | 6 +-- 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(+), 41 deletions(-) diff --git a/components/espcoredump/src/core_dump_flash.c b/components/espcoredump/src/core_dump_flash.c index 21e85731e0..5705e94bb8 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) +void esp_core_dump_flash_init(void) { const esp_partition_t *core_part; @@ -214,10 +215,9 @@ void esp_core_dump_to_flash(XtExcFrame *frame) return; } -#if CONFIG_SPI_FLASH_USE_LEGACY_IMPL // init non-OS flash access critical section spi_flash_guard_set(&g_flash_guard_no_os_ops); -#endif + 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 7f29d86fc4..b062619dcd 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) @@ -616,6 +617,17 @@ esp_err_t IRAM_ATTR esp_flash_read_encrypted(esp_flash_t *chip, uint32_t address return spi_flash_read_encrypted(address, out_buffer, length); } +#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 ba0d26b567..9938ab3fbe 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(void) esp_err_t esp_flash_app_init(void) { - 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 77ffe31f58..caca075960 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 9d30b04f6804eae6e73838e33f5b6a3f91ae59ad Mon Sep 17 00:00:00 2001 From: "Michael (XIAO Xufeng)" Date: Thu, 12 Sep 2019 02:23:44 +0800 Subject: [PATCH 3/3] 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 | 11 +++++++++- components/espcoredump/src/core_dump_flash.c | 22 ++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/components/espcoredump/linker.lf b/components/espcoredump/linker.lf index 131e10c30b..17470b53a1 100644 --- a/components/espcoredump/linker.lf +++ b/components/espcoredump/linker.lf @@ -1,6 +1,6 @@ [mapping:espcoredump] archive: libespcoredump.a -entries: +entries: if ESP32_PANIC_HANDLER_IRAM = y: core_dump_uart (noflash_text) core_dump_flash (noflash_text) @@ -8,3 +8,12 @@ entries: core_dump_port (noflash_text) else: * (default) + +[mapping:spi_flash_override] +archive: libspi_flash.a +entries: + if ESP32_PANIC_HANDLER_IRAM = y && ESP32_ENABLE_COREDUMP_TO_FLASH = y: + esp_flash_api (noflash_text) + esp_flash_spi_init (noflash_text) + else: + * (default) diff --git a/components/espcoredump/src/core_dump_flash.c b/components/espcoredump/src/core_dump_flash.c index 5705e94bb8..5698525365 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;