From 0ee46b6321887f62fbc07c6146a587222f7da472 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 1 Nov 2018 11:30:48 +0800 Subject: [PATCH] bootloader, esp32: add workaround for Tensilica erratum 572 If zero-overhead loop buffer is enabled, under certain rare conditions when executing a zero-overhead loop, the CPU may attempt to execute an invalid instruction. Work around by disabling the buffer. --- .../bootloader/subproject/main/bootloader_start.c | 1 + components/esp32/cpu_start.c | 2 ++ components/esp32/include/xtensa/config/core.h | 11 +++++++++++ components/soc/esp32/include/soc/cpu.h | 9 +++++++++ 4 files changed, 23 insertions(+) diff --git a/components/bootloader/subproject/main/bootloader_start.c b/components/bootloader/subproject/main/bootloader_start.c index 7c70ac964d..62b236cfc9 100644 --- a/components/bootloader/subproject/main/bootloader_start.c +++ b/components/bootloader/subproject/main/bootloader_start.c @@ -87,6 +87,7 @@ static void wdt_reset_check(void); void call_start_cpu0() { cpu_configure_region_protection(); + cpu_init_memctl(); /* Sanity check that static RAM is after the stack */ #ifndef NDEBUG diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 671bbd525b..c702cde82f 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -115,6 +115,7 @@ void IRAM_ATTR call_start_cpu0() RESET_REASON rst_reas[2]; #endif cpu_configure_region_protection(); + cpu_init_memctl(); //Move exception vectors to IRAM asm volatile (\ @@ -219,6 +220,7 @@ void IRAM_ATTR call_start_cpu1() ets_set_appcpu_boot_addr(0); cpu_configure_region_protection(); + cpu_init_memctl(); #if CONFIG_CONSOLE_UART_NONE ets_install_putc1(NULL); diff --git a/components/esp32/include/xtensa/config/core.h b/components/esp32/include/xtensa/config/core.h index 98f1b1961a..0204757b05 100644 --- a/components/esp32/include/xtensa/config/core.h +++ b/components/esp32/include/xtensa/config/core.h @@ -1401,5 +1401,16 @@ extern const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP7_IDENT); #define XCHAL_ERRATUM_497 0 #endif +/* + * Erratum 572 (releases TBD, but present in ESP32) + * Disable zero-overhead loop buffer to prevent rare illegal instruction + * exceptions while executing zero-overhead loops. + */ +#if ( XCHAL_HAVE_LOOPS && XCHAL_LOOP_BUFFER_SIZE != 0 ) +#define XCHAL_ERRATUM_572 1 +#else +#define XCHAL_ERRATUM_572 0 +#endif + #endif /*XTENSA_CONFIG_CORE_H*/ diff --git a/components/soc/esp32/include/soc/cpu.h b/components/soc/esp32/include/soc/cpu.h index 05ec91776b..f28feb59fa 100644 --- a/components/soc/esp32/include/soc/cpu.h +++ b/components/soc/esp32/include/soc/cpu.h @@ -19,6 +19,7 @@ #include #include #include "xtensa/corebits.h" +#include "xtensa/config/core.h" /* C macros for xtensa special register read/write/exchange */ @@ -51,6 +52,14 @@ static inline void cpu_write_itlb(unsigned vpn, unsigned attr) asm volatile ("witlb %1, %0; isync\n" :: "r" (vpn), "r" (attr)); } +static inline void cpu_init_memctl() +{ +#if XCHAL_ERRATUM_572 + uint32_t memctl = XCHAL_CACHE_MEMCTL_DEFAULT; + WSR(MEMCTL, memctl); +#endif // XCHAL_ERRATUM_572 +} + /** * @brief Configure memory region protection *