diff --git a/components/app_trace/app_trace.c b/components/app_trace/app_trace.c index 152746f893..2f3f99623f 100644 --- a/components/app_trace/app_trace.c +++ b/components/app_trace/app_trace.c @@ -159,14 +159,15 @@ #include "sdkconfig.h" #include "soc/soc.h" #include "soc/dport_access.h" -#if CONFIG_IDF_TARGET_ESP32 +#if !CONFIG_IDF_TARGET_ESP32C3 #include "soc/dport_reg.h" -#elif CONFIG_IDF_TARGET_ESP32S2 +#endif +#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 #include "soc/sensitive_reg.h" #endif #if __XTENSA__ +#include "xtensa-debug-module.h" #include "eri.h" -#include "trax.h" #endif #include "soc/timer_periph.h" #include "freertos/FreeRTOS.h" @@ -210,18 +211,6 @@ const static char *TAG = "esp_apptrace"; #define ESP_APPTRACE_LOGV( format, ... ) ESP_APPTRACE_LOG_LEV(V, ESP_LOG_VERBOSE, format, ##__VA_ARGS__) #define ESP_APPTRACE_LOGO( format, ... ) ESP_APPTRACE_LOG_LEV(E, ESP_LOG_NONE, format, ##__VA_ARGS__) -// TODO: move these (and same definitions in trax.c to dport_reg.h) -#if CONFIG_IDF_TARGET_ESP32 -#define TRACEMEM_MUX_PROBLK0_APPBLK1 0 -#define TRACEMEM_MUX_BLK0_ONLY 1 -#define TRACEMEM_MUX_BLK1_ONLY 2 -#define TRACEMEM_MUX_PROBLK1_APPBLK0 3 -#elif CONFIG_IDF_TARGET_ESP32S2 -#define TRACEMEM_MUX_BLK0_NUM 19 -#define TRACEMEM_MUX_BLK1_NUM 20 -#define TRACEMEM_BLK_NUM2ADDR(_n_) (0x3FFB8000UL + 0x4000UL*((_n_)-4)) -#endif - // TRAX is disabled, so we use its registers for our own purposes // | 31..XXXXXX..24 | 23 .(host_connect). 23 | 22 .(host_data). 22| 21..(block_id)..15 | 14..(block_len)..0 | #define ESP_APPTRACE_TRAX_CTRL_REG ERI_TRAX_DELAYCNT diff --git a/components/bootloader_support/src/esp32/bootloader_esp32.c b/components/bootloader_support/src/esp32/bootloader_esp32.c index 4bd3d04680..4bc9e37bf7 100644 --- a/components/bootloader_support/src/esp32/bootloader_esp32.c +++ b/components/bootloader_support/src/esp32/bootloader_esp32.c @@ -364,7 +364,7 @@ esp_err_t bootloader_init(void) { assert(&_bss_start <= &_bss_end); assert(&_data_start <= &_data_end); - int *sp = get_sp(); + int *sp = esp_cpu_get_sp(); assert(sp < &_bss_start); assert(sp < &_data_start); } diff --git a/components/bootloader_support/src/esp_image_format.c b/components/bootloader_support/src/esp_image_format.c index 592ff6f550..d4b04e4fb9 100644 --- a/components/bootloader_support/src/esp_image_format.c +++ b/components/bootloader_support/src/esp_image_format.c @@ -402,7 +402,7 @@ static bool verify_load_addresses(int segment_index, intptr_t load_addr, intptr_ if (esp_ptr_in_dram(load_addr_p) && esp_ptr_in_dram(load_end_p)) { /* Writing to DRAM */ /* Check if we're clobbering the stack */ - intptr_t sp = (intptr_t)get_sp(); + intptr_t sp = (intptr_t)esp_cpu_get_sp(); if (bootloader_util_regions_overlap(sp - STACK_LOAD_HEADROOM, SOC_ROM_STACK_START, load_addr, load_end)) { reason = "overlaps bootloader stack"; diff --git a/components/esp32/system_api_esp32.c b/components/esp32/system_api_esp32.c index 2ed2e9b7a1..f8ce88ffb4 100644 --- a/components/esp32/system_api_esp32.c +++ b/components/esp32/system_api_esp32.c @@ -84,7 +84,7 @@ void IRAM_ATTR esp_restart_noos(void) esp_rom_uart_tx_wait_idle(2); #ifdef CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY - if (esp_ptr_external_ram(get_sp())) { + if (esp_ptr_external_ram(esp_cpu_get_sp())) { // If stack_addr is from External Memory (CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY is used) // then need to switch SP to Internal Memory otherwise // we will get the "Cache disabled but cached memory region accessed" error after Cache_Read_Disable. diff --git a/components/xtensa/include/esp_attr.h b/components/esp_common/include/esp_attr.h similarity index 98% rename from components/xtensa/include/esp_attr.h rename to components/esp_common/include/esp_attr.h index 27db5cbf00..21e52bd67b 100644 --- a/components/xtensa/include/esp_attr.h +++ b/components/esp_common/include/esp_attr.h @@ -1,3 +1,4 @@ + // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +15,10 @@ #ifndef __ESP_ATTR_H__ #define __ESP_ATTR_H__ -#include +#ifdef __cplusplus +extern "C" { +#endif + #include "sdkconfig.h" #define ROMFN_ATTR @@ -147,4 +151,8 @@ FORCE_INLINE_ATTR TYPE& operator<<=(TYPE& a, int b) { a <<= b; return a; } #define IDF_DEPRECATED(REASON) #endif +#ifdef __cplusplus +} +#endif #endif /* __ESP_ATTR_H__ */ + diff --git a/components/esp_hw_support/cpu_util.c b/components/esp_hw_support/cpu_util.c index 2840b17db1..847695d368 100644 --- a/components/esp_hw_support/cpu_util.c +++ b/components/esp_hw_support/cpu_util.c @@ -19,10 +19,11 @@ #include "sdkconfig.h" #include "hal/cpu_hal.h" -#include "esp_debug_helpers.h" #include "hal/cpu_types.h" #include "hal/mpu_hal.h" +#include "esp_cpu.h" + #include "hal/soc_hal.h" #include "soc/soc_caps.h" @@ -47,7 +48,7 @@ void IRAM_ATTR esp_cpu_reset(int cpu_id) soc_hal_reset_core(cpu_id); } -esp_err_t IRAM_ATTR esp_set_watchpoint(int no, void *adr, int size, int flags) +esp_err_t IRAM_ATTR esp_cpu_set_watchpoint(int no, void *adr, int size, int flags) { watchpoint_trigger_t trigger; @@ -70,7 +71,7 @@ esp_err_t IRAM_ATTR esp_set_watchpoint(int no, void *adr, int size, int flags) return ESP_OK; } -void IRAM_ATTR esp_clear_watchpoint(int no) +void IRAM_ATTR esp_cpu_clear_watchpoint(int no) { cpu_hal_clear_watchpoint(no); } @@ -87,13 +88,6 @@ bool IRAM_ATTR esp_cpu_in_ocd_debug_mode(void) #endif } -void IRAM_ATTR esp_set_breakpoint_if_jtag(void *fn) -{ - if (esp_cpu_in_ocd_debug_mode()) { - cpu_hal_set_breakpoint(0, fn); - } -} - #if __XTENSA__ void esp_cpu_configure_region_protection(void) diff --git a/components/esp_hw_support/include/esp_cpu.h b/components/esp_hw_support/include/esp_cpu.h new file mode 100644 index 0000000000..e1536e979b --- /dev/null +++ b/components/esp_hw_support/include/esp_cpu.h @@ -0,0 +1,109 @@ +// Copyright 2010-2016 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. + +#ifndef _ESP_CPU_H +#define _ESP_CPU_H + +#include +#include +#include + +#include "hal/cpu_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ESP_WATCHPOINT_LOAD 0x40000000 +#define ESP_WATCHPOINT_STORE 0x80000000 +#define ESP_WATCHPOINT_ACCESS 0xC0000000 + +typedef uint32_t esp_cpu_ccount_t; + +/** @brief Read current stack pointer address + * + */ +static inline void *esp_cpu_get_sp(void) +{ + return cpu_hal_get_sp(); +} + +/** + * @brief Stall CPU using RTC controller + * @param cpu_id ID of the CPU to stall (0 = PRO, 1 = APP) + */ +void esp_cpu_stall(int cpu_id); + +/** + * @brief Un-stall CPU using RTC controller + * @param cpu_id ID of the CPU to un-stall (0 = PRO, 1 = APP) + */ +void esp_cpu_unstall(int cpu_id); + +/** + * @brief Reset CPU using RTC controller + * @param cpu_id ID of the CPU to reset (0 = PRO, 1 = APP) + */ +void esp_cpu_reset(int cpu_id); + +/** + * @brief Returns true if a JTAG debugger is attached to CPU + * OCD (on chip debug) port. + * + * @note If "Make exception and panic handlers JTAG/OCD aware" + * is disabled, this function always returns false. + */ +bool esp_cpu_in_ocd_debug_mode(void); + +static inline esp_cpu_ccount_t esp_cpu_get_ccount(void) +{ + return cpu_hal_get_cycle_count(); +} + +static inline void esp_cpu_set_ccount(esp_cpu_ccount_t val) +{ + cpu_hal_set_cycle_count(val); +} + +/** + * @brief Set a watchpoint to break/panic when a certain memory range is accessed. + * + * @param no Watchpoint number. On the ESP32, this can be 0 or 1. + * @param adr Base address to watch + * @param size Size of the region, starting at the base address, to watch. Must + * be one of 2^n, with n in [0..6]. + * @param flags One of ESP_WATCHPOINT_* flags + * + * @return ESP_ERR_INVALID_ARG on invalid arg, ESP_OK otherwise + * + * @warning The ESP32 watchpoint hardware watches a region of bytes by effectively + * masking away the lower n bits for a region with size 2^n. If adr does + * not have zero for these lower n bits, you may not be watching the + * region you intended. + */ +esp_err_t esp_cpu_set_watchpoint(int no, void *adr, int size, int flags); + +/** + * @brief Clear a watchpoint + * + * @param no Watchpoint to clear + * + */ +void esp_cpu_clear_watchpoint(int no); + +#ifdef __cplusplus +} +#endif + +#endif // _ESP_CPU_H diff --git a/components/esp_hw_support/include/soc/cpu.h b/components/esp_hw_support/include/soc/cpu.h index 3e787ae4a6..0e4d1688ca 100644 --- a/components/esp_hw_support/include/soc/cpu.h +++ b/components/esp_hw_support/include/soc/cpu.h @@ -19,6 +19,8 @@ #include #include +#include "esp_cpu.h" + #if __XTENSA__ #include "xt_instr_macros.h" // [refactor-todo] not actually needed in this header now, @@ -29,59 +31,18 @@ #include "xtensa/config/specreg.h" #endif -#include "hal/cpu_hal.h" - #ifdef __cplusplus extern "C" { #endif -/** @brief Read current stack pointer address - * +/** @brief Read current stack pointer address. + * Superseded by esp_cpu_get_sp in esp_cpu.h. */ -static inline void *get_sp(void) +static inline __attribute__((deprecated)) void *get_sp(void) { - return cpu_hal_get_sp(); + return esp_cpu_get_sp(); } -/** - * @brief Stall CPU using RTC controller - * @param cpu_id ID of the CPU to stall (0 = PRO, 1 = APP) - */ -void esp_cpu_stall(int cpu_id); - -/** - * @brief Un-stall CPU using RTC controller - * @param cpu_id ID of the CPU to un-stall (0 = PRO, 1 = APP) - */ -void esp_cpu_unstall(int cpu_id); - -/** - * @brief Reset CPU using RTC controller - * @param cpu_id ID of the CPU to reset (0 = PRO, 1 = APP) - */ -void esp_cpu_reset(int cpu_id); - - -/** - * @brief Returns true if a JTAG debugger is attached to CPU - * OCD (on chip debug) port. - * - * @note If "Make exception and panic handlers JTAG/OCD aware" - * is disabled, this function always returns false. - */ -bool esp_cpu_in_ocd_debug_mode(void); - -/** - * @brief Convert the PC register value to its true address - * - * The address of the current instruction is not stored as an exact uint32_t - * representation in PC register. This function will convert the value stored in - * the PC register to a uint32_t address. - * - * @param pc_raw The PC as stored in register format. - * - * @return Address in uint32_t format - */ static inline uint32_t esp_cpu_process_stack_pc(uint32_t pc) { if (pc & 0x80000000) { @@ -92,18 +53,6 @@ static inline uint32_t esp_cpu_process_stack_pc(uint32_t pc) return pc - 3; } -typedef uint32_t esp_cpu_ccount_t; - -static inline esp_cpu_ccount_t esp_cpu_get_ccount(void) -{ - return cpu_hal_get_cycle_count(); -} - -static inline void esp_cpu_set_ccount(esp_cpu_ccount_t val) -{ - cpu_hal_set_cycle_count(val); -} - /** * @brief Configure CPU to disable access to invalid memory regions * diff --git a/components/xtensa/include/esp_debug_helpers.h b/components/esp_system/include/esp_debug_helpers.h similarity index 80% rename from components/xtensa/include/esp_debug_helpers.h rename to components/esp_system/include/esp_debug_helpers.h index 5bdc028c61..a802cb4023 100644 --- a/components/xtensa/include/esp_debug_helpers.h +++ b/components/esp_system/include/esp_debug_helpers.h @@ -23,10 +23,7 @@ extern "C" { #include #include "esp_err.h" #include "soc/soc.h" // [refactor-todo] IDF-2297 - -#define ESP_WATCHPOINT_LOAD 0x40000000 -#define ESP_WATCHPOINT_STORE 0x80000000 -#define ESP_WATCHPOINT_ACCESS 0xC0000000 +#include "esp_cpu.h" /* * @brief Structure used for backtracing @@ -53,32 +50,6 @@ typedef struct { */ void esp_set_breakpoint_if_jtag(void *fn); -/** - * @brief Set a watchpoint to break/panic when a certain memory range is accessed. - * - * @param no Watchpoint number. On the ESP32, this can be 0 or 1. - * @param adr Base address to watch - * @param size Size of the region, starting at the base address, to watch. Must - * be one of 2^n, with n in [0..6]. - * @param flags One of ESP_WATCHPOINT_* flags - * - * @return ESP_ERR_INVALID_ARG on invalid arg, ESP_OK otherwise - * - * @warning The ESP32 watchpoint hardware watches a region of bytes by effectively - * masking away the lower n bits for a region with size 2^n. If adr does - * not have zero for these lower n bits, you may not be watching the - * region you intended. - */ -esp_err_t esp_set_watchpoint(int no, void *adr, int size, int flags); - -/** - * @brief Clear a watchpoint - * - * @param no Watchpoint to clear - * - */ -void esp_clear_watchpoint(int no); - /** * Get the first frame of the current stack's backtrace * @@ -127,6 +98,24 @@ bool esp_backtrace_get_next_frame(esp_backtrace_frame_t *frame); */ esp_err_t esp_backtrace_print(int depth); +/** + * @brief Set a watchpoint to break/panic when a certain memory range is accessed. + * Superseded by esp_cpu_set_watchpoint in esp_cpu.h. + */ +static inline __attribute__((deprecated)) esp_err_t esp_set_watchpoint(int no, void *adr, int size, int flags) +{ + return esp_cpu_set_watchpoint(no, adr, size, flags); +} + +/** + * @brief Set a watchpoint to break/panic when a certain memory range is accessed. + * Superseded by esp_cpu_clear_watchpoint in esp_cpu.h. + */ +static inline __attribute__((deprecated)) void esp_clear_watchpoint(int no) +{ + esp_cpu_clear_watchpoint(no); +} + #endif #ifdef __cplusplus } diff --git a/components/riscv/expression_with_stack_riscv.c b/components/esp_system/port/arch/riscv/expression_with_stack.c similarity index 100% rename from components/riscv/expression_with_stack_riscv.c rename to components/esp_system/port/arch/riscv/expression_with_stack.c diff --git a/components/riscv/expression_with_stack_riscv_asm.S b/components/esp_system/port/arch/riscv/expression_with_stack_asm.S similarity index 100% rename from components/riscv/expression_with_stack_riscv_asm.S rename to components/esp_system/port/arch/riscv/expression_with_stack_asm.S diff --git a/components/xtensa/debug_helpers.c b/components/esp_system/port/arch/xtensa/debug_helpers.c similarity index 100% rename from components/xtensa/debug_helpers.c rename to components/esp_system/port/arch/xtensa/debug_helpers.c diff --git a/components/xtensa/debug_helpers_asm.S b/components/esp_system/port/arch/xtensa/debug_helpers_asm.S similarity index 100% rename from components/xtensa/debug_helpers_asm.S rename to components/esp_system/port/arch/xtensa/debug_helpers_asm.S diff --git a/components/xtensa/expression_with_stack_xtensa.c b/components/esp_system/port/arch/xtensa/expression_with_stack.c similarity index 97% rename from components/xtensa/expression_with_stack_xtensa.c rename to components/esp_system/port/arch/xtensa/expression_with_stack.c index 6002c86821..22ba16268b 100644 --- a/components/xtensa/expression_with_stack_xtensa.c +++ b/components/esp_system/port/arch/xtensa/expression_with_stack.c @@ -13,8 +13,6 @@ // limitations under the License. #include -#include -#include #include #include #include "freertos/FreeRTOS.h" diff --git a/components/xtensa/expression_with_stack_xtensa_asm.S b/components/esp_system/port/arch/xtensa/expression_with_stack_asm.S similarity index 100% rename from components/xtensa/expression_with_stack_xtensa_asm.S rename to components/esp_system/port/arch/xtensa/expression_with_stack_asm.S diff --git a/components/esp_system/port/arch/xtensa/trax.c b/components/esp_system/port/arch/xtensa/trax.c new file mode 100644 index 0000000000..ef5a9ecb45 --- /dev/null +++ b/components/esp_system/port/arch/xtensa/trax.c @@ -0,0 +1,88 @@ + +// 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. + +#include +#include "esp_err.h" +#include "esp_log.h" +#include "xt_trax.h" +#include "trax.h" +#include "hal/trace_ll.h" +#include "soc/dport_reg.h" +#include "sdkconfig.h" + +// Utility functions for enabling TRAX in early startup (hence the use +// of ESP_EARLY_LOGX) in Xtensa targets. + +#if defined(CONFIG_ESP32_TRAX) || defined(CONFIG_ESP32S2_TRAX) +#define WITH_TRAX 1 +#endif + +static const char* __attribute__((unused)) TAG = "trax"; + +int trax_enable(trax_ena_select_t which) +{ +#if !WITH_TRAX + ESP_EARLY_LOGE(TAG, "trax_enable called, but trax is disabled in menuconfig!"); + return ESP_ERR_NO_MEM; +#endif +#if CONFIG_IDF_TARGET_ESP32 +#ifndef CONFIG_ESP32_TRAX_TWOBANKS + if (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP) return ESP_ERR_NO_MEM; +#endif + if (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP) { + trace_ll_set_mode((which == TRAX_ENA_PRO_APP_SWAP)?TRACEMEM_MUX_PROBLK1_APPBLK0:TRACEMEM_MUX_PROBLK0_APPBLK1); + } else { + trace_ll_set_mode(TRACEMEM_MUX_BLK0_ONLY); + } + trace_ll_mem_enable(0, (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP || which == TRAX_ENA_PRO)); + trace_ll_mem_enable(1, (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP || which == TRAX_ENA_APP)); + return ESP_OK; +#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 + if (which != TRAX_ENA_PRO) { + return ESP_ERR_INVALID_ARG; + } + trace_ll_set_mem_block(TRACEMEM_MUX_BLK1_NUM); + return ESP_OK; +#endif +} + +int trax_start_trace(trax_downcount_unit_t units_until_stop) +{ +#if !WITH_TRAX + ESP_EARLY_LOGE(TAG, "trax_start_trace called, but trax is disabled in menuconfig!"); + return ESP_ERR_NO_MEM; +#endif + if (xt_trax_trace_is_active()) { + ESP_EARLY_LOGI(TAG, "Stopping active trace first."); + //Trace is active. Stop trace. + xt_trax_trigger_traceend_after_delay(0); + } + if (units_until_stop == TRAX_DOWNCOUNT_INSTRUCTIONS) { + xt_trax_start_trace_instructions(); + } else { + xt_trax_start_trace_words(); + } + return ESP_OK; +} + +int trax_trigger_traceend_after_delay(int delay) +{ +#if !WITH_TRAX + ESP_EARLY_LOGE(TAG, "trax_trigger_traceend_after_delay called, but trax is disabled in menuconfig!"); + return ESP_ERR_NO_MEM; +#endif + xt_trax_trigger_traceend_after_delay(delay); + return ESP_OK; +} diff --git a/components/esp_system/port/include/intr.h b/components/esp_system/port/include/intr.h deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/components/xtensa/include/trax.h b/components/esp_system/port/include/trax.h similarity index 75% rename from components/xtensa/include/trax.h rename to components/esp_system/port/include/trax.h index 543deb2e39..7d1f52ec2d 100644 --- a/components/xtensa/include/trax.h +++ b/components/esp_system/port/include/trax.h @@ -1,8 +1,22 @@ +// Copyright 2015-2016 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. + #include "sdkconfig.h" #include "esp_err.h" #include "eri.h" #include "xtensa-debug-module.h" - +#include "xt_trax.h" typedef enum { TRAX_DOWNCOUNT_WORDS, @@ -17,7 +31,6 @@ typedef enum { TRAX_ENA_PRO_APP_SWAP } trax_ena_select_t; - /** * @brief Enable the trax memory blocks to be used as Trax memory. * diff --git a/components/esp_system/port/soc/esp32/CMakeLists.txt b/components/esp_system/port/soc/esp32/CMakeLists.txt index 388edd5a6e..81c53f44e9 100644 --- a/components/esp_system/port/soc/esp32/CMakeLists.txt +++ b/components/esp_system/port/soc/esp32/CMakeLists.txt @@ -3,6 +3,11 @@ set(srcs "dport_panic_highint_hdl.S" "reset_reason.c" "../../arch/xtensa/panic_arch.c" "../../arch/xtensa/panic_handler_asm.S" + "../../arch/xtensa/expression_with_stack.c" + "../../arch/xtensa/expression_with_stack_asm.S" + "../../arch/xtensa/debug_helpers.c" + "../../arch/xtensa/debug_helpers_asm.S" + "../../arch/xtensa/trax.c" ) add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" ${srcs}) diff --git a/components/esp_system/port/soc/esp32c3/CMakeLists.txt b/components/esp_system/port/soc/esp32c3/CMakeLists.txt index 7a0a56c9ee..a5792ab4cd 100644 --- a/components/esp_system/port/soc/esp32c3/CMakeLists.txt +++ b/components/esp_system/port/soc/esp32c3/CMakeLists.txt @@ -2,6 +2,8 @@ set(srcs "clk.c" "reset_reason.c" "../../async_memcpy_impl_gdma.c" "apb_backup_dma.c" + "../../arch/riscv/expression_with_stack.c" + "../../arch/riscv/expression_with_stack_asm.S" "../../arch/riscv/panic_arch.c") add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" ${srcs}) diff --git a/components/esp_system/port/soc/esp32s2/CMakeLists.txt b/components/esp_system/port/soc/esp32s2/CMakeLists.txt index 443c34c8c0..e30c0bf4c1 100644 --- a/components/esp_system/port/soc/esp32s2/CMakeLists.txt +++ b/components/esp_system/port/soc/esp32s2/CMakeLists.txt @@ -4,6 +4,11 @@ set(srcs "async_memcpy_impl_cp_dma.c" "reset_reason.c" "../../arch/xtensa/panic_arch.c" "../../arch/xtensa/panic_handler_asm.S" + "../../arch/xtensa/expression_with_stack.c" + "../../arch/xtensa/expression_with_stack_asm.S" + "../../arch/xtensa/debug_helpers.c" + "../../arch/xtensa/debug_helpers_asm.S" + "../../arch/xtensa/trax.c" ) add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" ${srcs}) diff --git a/components/esp_system/port/soc/esp32s3/CMakeLists.txt b/components/esp_system/port/soc/esp32s3/CMakeLists.txt index d35152b1d3..68b9a6c829 100644 --- a/components/esp_system/port/soc/esp32s3/CMakeLists.txt +++ b/components/esp_system/port/soc/esp32s3/CMakeLists.txt @@ -4,6 +4,11 @@ set(srcs "dport_panic_highint_hdl.S" "../../async_memcpy_impl_gdma.c" "../../arch/xtensa/panic_arch.c" "../../arch/xtensa/panic_handler_asm.S" + "../../arch/xtensa/expression_with_stack.c" + "../../arch/xtensa/expression_with_stack_asm.S" + "../../arch/xtensa/debug_helpers.c" + "../../arch/xtensa/debug_helpers_asm.S" + "../../arch/xtensa/trax.c" ) add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" ${srcs}) diff --git a/components/esp_system/test/test_reset_reason.c b/components/esp_system/test/test_reset_reason.c index 4a0521c887..6f874590ba 100644 --- a/components/esp_system/test/test_reset_reason.c +++ b/components/esp_system/test/test_reset_reason.c @@ -306,7 +306,7 @@ static int fibonacci(int n, void* func(void)) RSR(WINDOWSTART, start); printf("WINDOWBASE = %-2d WINDOWSTART = 0x%x\n", base, start); if (n <= 1) { - StackType_t *last_addr_stack = get_sp(); + StackType_t *last_addr_stack = esp_cpu_get_sp(); StackType_t *used_stack = (StackType_t *) (start_addr_stack - last_addr_stack); printf("addr_stack = %p, used[%p]/all[0x%x] space in stack\n", last_addr_stack, used_stack, size_stack); func(); @@ -319,7 +319,7 @@ static int fibonacci(int n, void* func(void)) static void test_task(void *func) { - start_addr_stack = get_sp(); + start_addr_stack = esp_cpu_get_sp(); if (esp_ptr_external_ram(start_addr_stack)) { printf("restart_task: uses external stack, addr_stack = %p\n", start_addr_stack); } else { @@ -336,7 +336,7 @@ static void func_do_exception(void) static void init_restart_task(void) { StackType_t *stack_for_task = (StackType_t *) heap_caps_calloc(1, size_stack, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); - printf("init_task: current addr_stack = %p, stack_for_task = %p\n", get_sp(), stack_for_task); + printf("init_task: current addr_stack = %p, stack_for_task = %p\n", esp_cpu_get_sp(), stack_for_task); static StaticTask_t task_buf; xTaskCreateStaticPinnedToCore(test_task, "test_task", size_stack, esp_restart, 5, stack_for_task, &task_buf, 1); while (1) { }; @@ -345,7 +345,7 @@ static void init_restart_task(void) static void init_task_do_exception(void) { StackType_t *stack_for_task = (StackType_t *) heap_caps_calloc(1, size_stack, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); - printf("init_task: current addr_stack = %p, stack_for_task = %p\n", get_sp(), stack_for_task); + printf("init_task: current addr_stack = %p, stack_for_task = %p\n", esp_cpu_get_sp(), stack_for_task); static StaticTask_t task_buf; xTaskCreateStaticPinnedToCore(test_task, "test_task", size_stack, func_do_exception, 5, stack_for_task, &task_buf, 1); while (1) { }; diff --git a/components/espcoredump/src/core_dump_common.c b/components/espcoredump/src/core_dump_common.c index d67eda41e4..b5cf5bdd34 100644 --- a/components/espcoredump/src/core_dump_common.c +++ b/components/espcoredump/src/core_dump_common.c @@ -77,15 +77,15 @@ FORCE_INLINE_ATTR void esp_core_dump_setup_stack(void) memset(s_coredump_stack, COREDUMP_STACK_FILL_BYTE, ESP_COREDUMP_STACK_SIZE); /* watchpoint 1 can be used for task stack overflow detection, re-use it, it is no more necessary */ - //esp_clear_watchpoint(1); - //esp_set_watchpoint(1, s_coredump_stack, 1, ESP_WATCHPOINT_STORE); + //esp_cpu_clear_watchpoint(1); + //esp_cpu_set_watchpoint(1, s_coredump_stack, 1, ESP_WATCHPOINT_STORE); /* Replace the stack pointer depending on the architecture, but save the * current stack pointer, in order to be able too restore it later. * This function must be inlined. */ s_core_dump_backup = esp_core_dump_replace_sp(s_core_dump_sp); ESP_COREDUMP_LOGI("Backing up stack @ %p and use core dump stack @ %p", - s_core_dump_backup, get_sp()); + s_core_dump_backup, esp_cpu_get_sp()); } /** @@ -127,8 +127,8 @@ FORCE_INLINE_ATTR void esp_core_dump_setup_stack(void) /* If we are in ISR set watchpoint to the end of ISR stack */ if (esp_core_dump_in_isr_context()) { uint8_t* topStack = esp_core_dump_get_isr_stack_top(); - esp_clear_watchpoint(1); - esp_set_watchpoint(1, topStack+xPortGetCoreID()*configISR_STACK_SIZE, 1, ESP_WATCHPOINT_STORE); + esp_cpu_clear_watchpoint(1); + esp_cpu_set_watchpoint(1, topStack+xPortGetCoreID()*configISR_STACK_SIZE, 1, ESP_WATCHPOINT_STORE); } else { /* for tasks user should enable stack overflow detection in menuconfig TODO: if not enabled in menuconfig enable it ourselves */ diff --git a/components/freertos/port/riscv/port.c b/components/freertos/port/riscv/port.c index bd6b584adb..f464b37811 100644 --- a/components/freertos/port/riscv/port.c +++ b/components/freertos/port/riscv/port.c @@ -337,7 +337,7 @@ void vPortSetStackWatchpoint(void *pxStackStart) { uint32_t addr = (uint32_t)pxStackStart; addr = (addr + (STACK_WATCH_AREA_SIZE - 1)) & (~(STACK_WATCH_AREA_SIZE - 1)); - esp_set_watchpoint(STACK_WATCH_POINT_NUMBER, (char *)addr, STACK_WATCH_AREA_SIZE, ESP_WATCHPOINT_STORE); + esp_cpu_set_watchpoint(STACK_WATCH_POINT_NUMBER, (char *)addr, STACK_WATCH_AREA_SIZE, ESP_WATCHPOINT_STORE); } uint32_t xPortGetTickRateHz(void) { diff --git a/components/freertos/port/xtensa/port.c b/components/freertos/port/xtensa/port.c index 438d9dcfe5..4061223364 100644 --- a/components/freertos/port/xtensa/port.c +++ b/components/freertos/port/xtensa/port.c @@ -428,7 +428,7 @@ void vPortSetStackWatchpoint( void* pxStackStart ) { //This way, we make sure we trigger before/when the stack canary is corrupted, not after. int addr=(int)pxStackStart; addr=(addr+31)&(~31); - esp_set_watchpoint(STACK_WATCH_POINT_NUMBER, (char*)addr, 32, ESP_WATCHPOINT_STORE); + esp_cpu_set_watchpoint(STACK_WATCH_POINT_NUMBER, (char*)addr, 32, ESP_WATCHPOINT_STORE); } uint32_t xPortGetTickRateHz(void) { diff --git a/components/hal/esp32/include/hal/trace_ll.h b/components/hal/esp32/include/hal/trace_ll.h new file mode 100644 index 0000000000..da1130c193 --- /dev/null +++ b/components/hal/esp32/include/hal/trace_ll.h @@ -0,0 +1,28 @@ +// 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 "soc/dport_reg.h" + +static inline void trace_ll_mem_enable(int cpu, bool enable) +{ + int reg[] = {DPORT_PRO_TRACEMEM_ENA_REG, DPORT_APP_TRACEMEM_ENA_REG}; + DPORT_WRITE_PERI_REG(reg[cpu], enable); +} + +static inline void trace_ll_set_mode(int mode) +{ + DPORT_WRITE_PERI_REG(DPORT_TRACEMEM_MUX_MODE_REG, mode); +} diff --git a/components/hal/esp32s2/include/hal/trace_ll.h b/components/hal/esp32s2/include/hal/trace_ll.h new file mode 100644 index 0000000000..a9befdf87d --- /dev/null +++ b/components/hal/esp32s2/include/hal/trace_ll.h @@ -0,0 +1,23 @@ +// 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_bit_defs.h" +#include "soc/dport_reg.h" + +static inline void trace_ll_set_mem_block(int block) +{ + DPORT_WRITE_PERI_REG(DPORT_PMS_OCCUPY_3_REG, BIT(block-4)); +} diff --git a/components/hal/esp32s3/include/hal/trace_ll.h b/components/hal/esp32s3/include/hal/trace_ll.h new file mode 100644 index 0000000000..b271409b0a --- /dev/null +++ b/components/hal/esp32s3/include/hal/trace_ll.h @@ -0,0 +1,24 @@ +// 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 + +#include "soc/dport_reg.h" + +static inline void trace_ll_set_mem_block(int block) +{ + // IDF-1785 + abort(); +} diff --git a/components/lwip/port/esp32/hooks/tcp_isn_default.c b/components/lwip/port/esp32/hooks/tcp_isn_default.c index 858bee7de1..2646ab93b5 100644 --- a/components/lwip/port/esp32/hooks/tcp_isn_default.c +++ b/components/lwip/port/esp32/hooks/tcp_isn_default.c @@ -167,7 +167,7 @@ lwip_hook_tcp_isn(const ip_addr_t *local_ip, u16_t local_port, * APIs should not create any issues. */ #if CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY - assert(!esp_ptr_external_ram(get_sp())); + assert(!esp_ptr_external_ram(esp_cpu_get_sp())); #endif struct MD5Context ctx; diff --git a/components/newlib/CMakeLists.txt b/components/newlib/CMakeLists.txt index 924a27212b..4a9f680220 100644 --- a/components/newlib/CMakeLists.txt +++ b/components/newlib/CMakeLists.txt @@ -15,6 +15,7 @@ set(srcs "newlib_init.c" "syscalls.c" "termios.c" + "stdatomic.c" "time.c") set(include_dirs platform_include) diff --git a/components/newlib/newlib.lf b/components/newlib/newlib.lf index 63a93164a2..3d9a0ed14d 100644 --- a/components/newlib/newlib.lf +++ b/components/newlib/newlib.lf @@ -3,3 +3,4 @@ archive: libnewlib.a entries: heap (noflash) abort (noflash) + stdatomic (noflash) diff --git a/components/xtensa/stdatomic.c b/components/newlib/stdatomic.c similarity index 83% rename from components/xtensa/stdatomic.c rename to components/newlib/stdatomic.c index dad6170fb3..26f0810641 100644 --- a/components/xtensa/stdatomic.c +++ b/components/newlib/stdatomic.c @@ -16,13 +16,13 @@ #include "sdkconfig.h" #include +#include + +#ifdef __XTENSA__ + #include "xtensa/config/core-isa.h" #include "xtensa/xtruntime.h" -//reserved to measure atomic operation time -#define atomic_benchmark_intr_disable() -#define atomic_benchmark_intr_restore(STATE) - // This allows nested interrupts disabling and restoring via local registers or stack. // They can be called from interrupts too. // WARNING: Only applies to current CPU. @@ -37,6 +37,38 @@ XTOS_RESTORE_JUST_INTLEVEL(state); \ } while (0) +#ifndef XCHAL_HAVE_S32C1I +#error "XCHAL_HAVE_S32C1I not defined, include correct header!" +#endif + +#define NO_ATOMICS_SUPPORT (XCHAL_HAVE_S32C1I == 0) +#else // RISCV + +#include "freertos/portmacro.h" + +// This allows nested interrupts disabling and restoring via local registers or stack. +// They can be called from interrupts too. +// WARNING: Only applies to current CPU. +#define _ATOMIC_ENTER_CRITICAL(void) ({ \ + unsigned state = portENTER_CRITICAL_NESTED(); \ + atomic_benchmark_intr_disable(); \ + state; \ +}) + +#define _ATOMIC_EXIT_CRITICAL(state) do { \ + atomic_benchmark_intr_restore(state); \ + portEXIT_CRITICAL_NESTED(state); \ + } while (0) + +#define NO_ATOMICS_SUPPORT 1 // [todo] Get the equivalent XCHAL_HAVE_S32C1I check for RISCV + +#endif + + +//reserved to measure atomic operation time +#define atomic_benchmark_intr_disable() +#define atomic_benchmark_intr_restore(STATE) + #define CMP_EXCHANGE(n, type) bool __atomic_compare_exchange_ ## n (type* mem, type* expect, type desired, int success, int failure) \ { \ bool ret = false; \ @@ -96,15 +128,10 @@ return ret; \ } -#ifndef XCHAL_HAVE_S32C1I -#error "XCHAL_HAVE_S32C1I not defined, include correct header!" -#endif - -//this piece of code should only be compiled if the cpu doesn't support atomic compare and swap (s32c1i) -#if XCHAL_HAVE_S32C1I == 0 - #pragma GCC diagnostic ignored "-Wbuiltin-declaration-mismatch" +#if NO_ATOMICS_SUPPORT + CMP_EXCHANGE(1, uint8_t) CMP_EXCHANGE(2, uint16_t) CMP_EXCHANGE(4, uint32_t) diff --git a/components/newlib/test/test_shared_stack_printf.c b/components/newlib/test/test_shared_stack_printf.c index a2d94dfe3a..d22ee49ccd 100644 --- a/components/newlib/test/test_shared_stack_printf.c +++ b/components/newlib/test/test_shared_stack_printf.c @@ -14,9 +14,9 @@ static StackType_t *shared_stack_sp = NULL; void external_stack_function(void) { - printf("Executing this printf from external stack! sp=%p\n", get_sp()); + printf("Executing this printf from external stack! sp=%p\n", esp_cpu_get_sp()); - shared_stack_sp = (StackType_t *)get_sp(); + shared_stack_sp = (StackType_t *)esp_cpu_get_sp(); char *res = NULL; /* Test return value from asprintf, this could potentially help catch a misaligned @@ -30,9 +30,9 @@ void external_stack_function(void) void another_external_stack_function(void) { //We can even use Freertos resources inside of this context. - printf("We can even use FreeRTOS resources... yielding, sp=%p\n", get_sp()); + printf("We can even use FreeRTOS resources... yielding, sp=%p\n", esp_cpu_get_sp()); taskYIELD(); - shared_stack_sp = (StackType_t *)get_sp(); + shared_stack_sp = (StackType_t *)esp_cpu_get_sp(); } TEST_CASE("test printf using shared buffer stack", "[newlib]") @@ -43,7 +43,7 @@ TEST_CASE("test printf using shared buffer stack", "[newlib]") SemaphoreHandle_t printf_lock = xSemaphoreCreateMutex(); TEST_ASSERT_NOT_NULL(printf_lock); - printf("current task sp: %p\n", get_sp()); + printf("current task sp: %p\n", esp_cpu_get_sp()); printf("shared_stack: %p\n", (void *)shared_stack); printf("shared_stack expected top: %p\n", (void *)(shared_stack + SHARED_STACK_SIZE)); diff --git a/components/riscv/CMakeLists.txt b/components/riscv/CMakeLists.txt index 0290ca9937..dc71ead66e 100644 --- a/components/riscv/CMakeLists.txt +++ b/components/riscv/CMakeLists.txt @@ -1,17 +1,16 @@ idf_build_get_property(target IDF_TARGET) + if(NOT "${target}" STREQUAL "esp32c3") return() endif() + if(BOOTLOADER_BUILD) set(priv_requires soc) else() set(priv_requires soc freertos) set(srcs - "expression_with_stack_riscv.c" - "expression_with_stack_riscv_asm.S" "instruction_decode.c" "interrupt.c" - "stdatomic.c" "vectors.S") endif() diff --git a/components/riscv/include/esp_attr.h b/components/riscv/include/esp_attr.h deleted file mode 100644 index 38a8fbe4ee..0000000000 --- a/components/riscv/include/esp_attr.h +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2015-2016 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. -#ifndef __ESP_ATTR_H__ -#define __ESP_ATTR_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "sdkconfig.h" - -#define ROMFN_ATTR - -//Normally, the linker script will put all code and rodata in flash, -//and all variables in shared RAM. These macros can be used to redirect -//particular functions/variables to other memory regions. - -// Forces code into IRAM instead of flash -#define IRAM_ATTR _SECTION_ATTR_IMPL(".iram1", __COUNTER__) - -// Forces data into DRAM instead of flash -#define DRAM_ATTR _SECTION_ATTR_IMPL(".dram1", __COUNTER__) - -// Forces data to be 4 bytes aligned -#define WORD_ALIGNED_ATTR __attribute__((aligned(4))) - -// Forces data to be placed to DMA-capable places -#define DMA_ATTR WORD_ALIGNED_ATTR DRAM_ATTR - -// Forces a function to be inlined -#define FORCE_INLINE_ATTR static inline __attribute__((always_inline)) - -// Forces a string into DRAM instead of flash -// Use as ets_printf(DRAM_STR("Hello world!\n")); -#define DRAM_STR(str) (__extension__({static const DRAM_ATTR char __c[] = (str); (const char *)&__c;})) - -// Forces code into RTC fast memory. See "docs/deep-sleep-stub.rst" -#define RTC_IRAM_ATTR _SECTION_ATTR_IMPL(".rtc.text", __COUNTER__) - -#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY -// Forces bss variable into external memory. " -#define EXT_RAM_ATTR _SECTION_ATTR_IMPL(".ext_ram.bss", __COUNTER__) -#else -#define EXT_RAM_ATTR -#endif - -// Forces data into RTC slow memory. See "docs/deep-sleep-stub.rst" -// Any variable marked with this attribute will keep its value -// during a deep sleep / wake cycle. -#define RTC_DATA_ATTR _SECTION_ATTR_IMPL(".rtc.data", __COUNTER__) - -// Forces read-only data into RTC memory. See "docs/deep-sleep-stub.rst" -#define RTC_RODATA_ATTR _SECTION_ATTR_IMPL(".rtc.rodata", __COUNTER__) - -// Allows to place data into RTC_SLOW memory. -#define RTC_SLOW_ATTR _SECTION_ATTR_IMPL(".rtc.force_slow", __COUNTER__) - -// Allows to place data into RTC_FAST memory. -#define RTC_FAST_ATTR _SECTION_ATTR_IMPL(".rtc.force_fast", __COUNTER__) - -// Forces data into noinit section to avoid initialization after restart. -#define __NOINIT_ATTR _SECTION_ATTR_IMPL(".noinit", __COUNTER__) - -// Forces data into RTC slow memory of .noinit section. -// Any variable marked with this attribute will keep its value -// after restart or during a deep sleep / wake cycle. -#define RTC_NOINIT_ATTR _SECTION_ATTR_IMPL(".rtc_noinit", __COUNTER__) - -// Forces to not inline function -#define NOINLINE_ATTR __attribute__((noinline)) - -// This allows using enum as flags in C++ -// Format: FLAG_ATTR(flag_enum_t) -#ifdef __cplusplus - -// Inline is required here to avoid multiple definition error in linker -#define FLAG_ATTR_IMPL(TYPE, INT_TYPE) \ -FORCE_INLINE_ATTR constexpr TYPE operator~ (TYPE a) { return (TYPE)~(INT_TYPE)a; } \ -FORCE_INLINE_ATTR constexpr TYPE operator| (TYPE a, TYPE b) { return (TYPE)((INT_TYPE)a | (INT_TYPE)b); } \ -FORCE_INLINE_ATTR constexpr TYPE operator& (TYPE a, TYPE b) { return (TYPE)((INT_TYPE)a & (INT_TYPE)b); } \ -FORCE_INLINE_ATTR constexpr TYPE operator^ (TYPE a, TYPE b) { return (TYPE)((INT_TYPE)a ^ (INT_TYPE)b); } \ -FORCE_INLINE_ATTR constexpr TYPE operator>> (TYPE a, int b) { return (TYPE)((INT_TYPE)a >> b); } \ -FORCE_INLINE_ATTR constexpr TYPE operator<< (TYPE a, int b) { return (TYPE)((INT_TYPE)a << b); } \ -FORCE_INLINE_ATTR TYPE& operator|=(TYPE& a, TYPE b) { a = a | b; return a; } \ -FORCE_INLINE_ATTR TYPE& operator&=(TYPE& a, TYPE b) { a = a & b; return a; } \ -FORCE_INLINE_ATTR TYPE& operator^=(TYPE& a, TYPE b) { a = a ^ b; return a; } \ -FORCE_INLINE_ATTR TYPE& operator>>=(TYPE& a, int b) { a >>= b; return a; } \ -FORCE_INLINE_ATTR TYPE& operator<<=(TYPE& a, int b) { a <<= b; return a; } - -#define FLAG_ATTR_U32(TYPE) FLAG_ATTR_IMPL(TYPE, uint32_t) -#define FLAG_ATTR FLAG_ATTR_U32 - -#else -#define FLAG_ATTR(TYPE) -#endif - -// Implementation for a unique custom section -// -// This prevents gcc producing "x causes a section type conflict with y" -// errors if two variables in the same source file have different linkage (maybe const & non-const) but are placed in the same custom section -// -// Using unique sections also means --gc-sections can remove unused -// data with a custom section type set -#define _SECTION_ATTR_IMPL(SECTION, COUNTER) __attribute__((section(SECTION "." _COUNTER_STRINGIFY(COUNTER)))) - -#define _COUNTER_STRINGIFY(COUNTER) #COUNTER - -/* Use IDF_DEPRECATED attribute to mark anything deprecated from use in - ESP-IDF's own source code, but not deprecated for external users. -*/ -#ifdef IDF_CI_BUILD -#define IDF_DEPRECATED(REASON) __attribute__((deprecated(REASON))) -#else -#define IDF_DEPRECATED(REASON) -#endif - -#ifdef __cplusplus -} -#endif -#endif /* __ESP_ATTR_H__ */ diff --git a/components/riscv/include/esp_debug_helpers.h b/components/riscv/include/esp_debug_helpers.h deleted file mode 100644 index d088ddeef1..0000000000 --- a/components/riscv/include/esp_debug_helpers.h +++ /dev/null @@ -1,133 +0,0 @@ -// 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 - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __ASSEMBLER__ - -#include -#include "esp_err.h" -#include "soc/soc.h" - -#define ESP_WATCHPOINT_LOAD 0x40000000 -#define ESP_WATCHPOINT_STORE 0x80000000 -#define ESP_WATCHPOINT_ACCESS 0xC0000000 - -/* - * @brief Structure used for backtracing - * - * This structure stores the backtrace information of a particular stack frame - * (i.e. the PC and SP). This structure is used iteratively with the - * esp_cpu_get_next_backtrace_frame() function to traverse each frame within a - * single stack. The next_pc represents the PC of the current frame's caller, thus - * a next_pc of 0 indicates that the current frame is the last frame on the stack. - * - * @note Call esp_backtrace_get_start() to obtain initialization values for - * this structure - */ -typedef struct { - uint32_t pc; /* PC of the current frame */ - uint32_t sp; /* SP of the current frame */ - uint32_t next_pc; /* PC of the current frame's caller */ -} esp_backtrace_frame_t; - -/** - * @brief If an OCD is connected over JTAG. set breakpoint 0 to the given function - * address. Do nothing otherwise. - * @param fn Pointer to the target breakpoint position - */ -void esp_set_breakpoint_if_jtag(void *fn); - -/** - * @brief Set a watchpoint to break/panic when a certain memory range is accessed. - * - * @param no Watchpoint number. On the ESP32, this can be 0 or 1. - * @param adr Base address to watch - * @param size Size of the region, starting at the base address, to watch. Must - * be one of 2^n, with n in [0..6]. - * @param flags One of ESP_WATCHPOINT_* flags - * - * @return ESP_ERR_INVALID_ARG on invalid arg, ESP_OK otherwise - * - * @warning The ESP32 watchpoint hardware watches a region of bytes by effectively - * masking away the lower n bits for a region with size 2^n. If adr does - * not have zero for these lower n bits, you may not be watching the - * region you intended. - */ -esp_err_t esp_set_watchpoint(int no, void *adr, int size, int flags); - -/** - * @brief Clear a watchpoint - * - * @param no Watchpoint to clear - * - */ -void esp_clear_watchpoint(int no); - -/** - * Get the first frame of the current stack's backtrace - * - * Given the following function call flow (B -> A -> X -> esp_backtrace_get_start), - * this function will do the following. - * - Flush CPU registers and window frames onto the current stack - * - Return PC and SP of function A (i.e. start of the stack's backtrace) - * - Return PC of function B (i.e. next_pc) - * - * @note This function is implemented in assembly - * - * @param[out] pc PC of the first frame in the backtrace - * @param[out] sp SP of the first frame in the backtrace - * @param[out] next_pc PC of the first frame's caller - */ -extern void esp_backtrace_get_start(uint32_t *pc, uint32_t *sp, uint32_t *next_pc); - -/** - * Get the next frame on a stack for backtracing - * - * Given a stack frame(i), this function will obtain the next stack frame(i-1) - * on the same call stack (i.e. the caller of frame(i)). This function is meant to be - * called iteratively when doing a backtrace. - * - * Entry Conditions: Frame structure containing valid SP and next_pc - * Exit Conditions: - * - Frame structure updated with SP and PC of frame(i-1). next_pc now points to frame(i-2). - * - If a next_pc of 0 is returned, it indicates that frame(i-1) is last frame on the stack - * - * @param[inout] frame Pointer to frame structure - * - * @return - * - True if the SP and PC of the next frame(i-1) are sane - * - False otherwise - */ -bool esp_backtrace_get_next_frame(esp_backtrace_frame_t *frame); - -/** - * @brief Print the backtrace of the current stack - * - * @param depth The maximum number of stack frames to print (should be > 0) - * - * @return - * - ESP_OK Backtrace successfully printed to completion or to depth limit - * - ESP_FAIL Backtrace is corrupted - */ -esp_err_t esp_backtrace_print(int depth); - -#endif -#ifdef __cplusplus -} -#endif diff --git a/components/riscv/linker.lf b/components/riscv/linker.lf index 2e5681238c..cfcb303cf0 100644 --- a/components/riscv/linker.lf +++ b/components/riscv/linker.lf @@ -3,4 +3,3 @@ archive: libriscv.a entries: interrupt (noflash_text) vectors (noflash_text) - stdatomic (noflash_text) diff --git a/components/riscv/stdatomic.c b/components/riscv/stdatomic.c deleted file mode 100644 index 7c0c395db5..0000000000 --- a/components/riscv/stdatomic.c +++ /dev/null @@ -1,129 +0,0 @@ -// 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. - -//replacement for gcc built-in functions - -#include "sdkconfig.h" -#include -#include -#include "freertos/portmacro.h" - -//reserved to measure atomic operation time -#define atomic_benchmark_intr_disable() -#define atomic_benchmark_intr_restore(STATE) - -// This allows nested interrupts disabling and restoring via local registers or stack. -// They can be called from interrupts too. -// WARNING: Only applies to current CPU. -#define _ATOMIC_ENTER_CRITICAL(void) ({ \ - unsigned state = portENTER_CRITICAL_NESTED(); \ - atomic_benchmark_intr_disable(); \ - state; \ -}) - -#define _ATOMIC_EXIT_CRITICAL(state) do { \ - atomic_benchmark_intr_restore(state); \ - portEXIT_CRITICAL_NESTED(state); \ - } while (0) - -#define CMP_EXCHANGE(n, type) bool __atomic_compare_exchange_ ## n (type* mem, type* expect, type desired, int success, int failure) \ -{ \ - bool ret = false; \ - unsigned state = _ATOMIC_ENTER_CRITICAL(); \ - if (*mem == *expect) { \ - ret = true; \ - *mem = desired; \ - } else { \ - *expect = *mem; \ - } \ - _ATOMIC_EXIT_CRITICAL(state); \ - return ret; \ -} - -#define FETCH_ADD(n, type) type __atomic_fetch_add_ ## n (type* ptr, type value, int memorder) \ -{ \ - unsigned state = _ATOMIC_ENTER_CRITICAL(); \ - type ret = *ptr; \ - *ptr = *ptr + value; \ - _ATOMIC_EXIT_CRITICAL(state); \ - return ret; \ -} - -#define FETCH_SUB(n, type) type __atomic_fetch_sub_ ## n (type* ptr, type value, int memorder) \ -{ \ - unsigned state = _ATOMIC_ENTER_CRITICAL(); \ - type ret = *ptr; \ - *ptr = *ptr - value; \ - _ATOMIC_EXIT_CRITICAL(state); \ - return ret; \ -} - -#define FETCH_AND(n, type) type __atomic_fetch_and_ ## n (type* ptr, type value, int memorder) \ -{ \ - unsigned state = _ATOMIC_ENTER_CRITICAL(); \ - type ret = *ptr; \ - *ptr = *ptr & value; \ - _ATOMIC_EXIT_CRITICAL(state); \ - return ret; \ -} - -#define FETCH_OR(n, type) type __atomic_fetch_or_ ## n (type* ptr, type value, int memorder) \ -{ \ - unsigned state = _ATOMIC_ENTER_CRITICAL(); \ - type ret = *ptr; \ - *ptr = *ptr | value; \ - _ATOMIC_EXIT_CRITICAL(state); \ - return ret; \ -} - -#define FETCH_XOR(n, type) type __atomic_fetch_xor_ ## n (type* ptr, type value, int memorder) \ -{ \ - unsigned state = _ATOMIC_ENTER_CRITICAL(); \ - type ret = *ptr; \ - *ptr = *ptr ^ value; \ - _ATOMIC_EXIT_CRITICAL(state); \ - return ret; \ -} - -#pragma GCC diagnostic ignored "-Wbuiltin-declaration-mismatch" - -CMP_EXCHANGE(1, uint8_t) -CMP_EXCHANGE(2, uint16_t) -CMP_EXCHANGE(4, uint32_t) -CMP_EXCHANGE(8, uint64_t) - -FETCH_ADD(1, uint8_t) -FETCH_ADD(2, uint16_t) -FETCH_ADD(4, uint32_t) -FETCH_ADD(8, uint64_t) - -FETCH_SUB(1, uint8_t) -FETCH_SUB(2, uint16_t) -FETCH_SUB(4, uint32_t) -FETCH_SUB(8, uint64_t) - -FETCH_AND(1, uint8_t) -FETCH_AND(2, uint16_t) -FETCH_AND(4, uint32_t) -FETCH_AND(8, uint64_t) - -FETCH_OR(1, uint8_t) -FETCH_OR(2, uint16_t) -FETCH_OR(4, uint32_t) -FETCH_OR(8, uint64_t) - -FETCH_XOR(1, uint8_t) -FETCH_XOR(2, uint16_t) -FETCH_XOR(4, uint32_t) -FETCH_XOR(8, uint64_t) diff --git a/components/soc/esp32/include/soc/dport_reg.h b/components/soc/esp32/include/soc/dport_reg.h index ee92bcd5bd..727d181e1a 100644 --- a/components/soc/esp32/include/soc/dport_reg.h +++ b/components/soc/esp32/include/soc/dport_reg.h @@ -4281,4 +4281,9 @@ #define DPORT_MMU_ADDRESS_MASK 0xff +#define TRACEMEM_MUX_PROBLK0_APPBLK1 0 +#define TRACEMEM_MUX_BLK0_ONLY 1 +#define TRACEMEM_MUX_BLK1_ONLY 2 +#define TRACEMEM_MUX_PROBLK1_APPBLK0 3 + #endif /*_SOC_DPORT_REG_H_ */ diff --git a/components/soc/esp32s2/include/soc/dport_reg.h b/components/soc/esp32s2/include/soc/dport_reg.h index ff5b616314..d38723706f 100644 --- a/components/soc/esp32s2/include/soc/dport_reg.h +++ b/components/soc/esp32s2/include/soc/dport_reg.h @@ -25,6 +25,10 @@ extern "C" { #define DPORT_DATE_REG SYSTEM_DATE_REG +#define TRACEMEM_MUX_BLK0_NUM 19 +#define TRACEMEM_MUX_BLK1_NUM 20 +#define TRACEMEM_BLK_NUM2ADDR(_n_) (0x3FFB8000UL + 0x4000UL*((_n_)-4)) + #ifndef __ASSEMBLER__ #include "dport_access.h" #endif diff --git a/components/soc/esp32s2/include/soc/sensitive_reg.h b/components/soc/esp32s2/include/soc/sensitive_reg.h index 8eb4ee6e9d..5652628a6a 100644 --- a/components/soc/esp32s2/include/soc/sensitive_reg.h +++ b/components/soc/esp32s2/include/soc/sensitive_reg.h @@ -1291,6 +1291,4 @@ extern "C" { } #endif - - #endif /*_SOC_SENSITIVE_REG_H_ */ diff --git a/components/soc/esp32s3/include/soc/dport_reg.h b/components/soc/esp32s3/include/soc/dport_reg.h index 1a3f69f462..7ce26583b4 100644 --- a/components/soc/esp32s3/include/soc/dport_reg.h +++ b/components/soc/esp32s3/include/soc/dport_reg.h @@ -24,6 +24,10 @@ extern "C" { #define DPORT_DATE_REG SYSTEM_DATE_REG +#define TRACEMEM_MUX_BLK0_NUM 19 +#define TRACEMEM_MUX_BLK1_NUM 20 +#define TRACEMEM_BLK_NUM2ADDR(_n_) (0x3FFB8000UL + 0x4000UL*((_n_)-4)) + #ifndef __ASSEMBLER__ #include "dport_access.h" #endif diff --git a/components/spi_flash/cache_utils.c b/components/spi_flash/cache_utils.c index a71dd0acac..e811724b25 100644 --- a/components/spi_flash/cache_utils.c +++ b/components/spi_flash/cache_utils.c @@ -125,7 +125,7 @@ void IRAM_ATTR spi_flash_op_block_func(void *arg) void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu(void) { - assert(esp_ptr_in_dram((const void *)get_sp())); + assert(esp_ptr_in_dram((const void *)esp_cpu_get_sp())); spi_flash_op_lock(); diff --git a/components/xtensa/CMakeLists.txt b/components/xtensa/CMakeLists.txt index 3fa959a936..3a8e20ad05 100644 --- a/components/xtensa/CMakeLists.txt +++ b/components/xtensa/CMakeLists.txt @@ -1,33 +1,17 @@ idf_build_get_property(target IDF_TARGET) -if(${target} STREQUAL "esp32c3") + +if("${target}" STREQUAL "esp32c3") return() endif() -if(BOOTLOADER_BUILD) - # bootloader only needs headers from this component - set(priv_requires soc) -else() - set(priv_requires soc freertos) - set(srcs "debug_helpers.c" - "debug_helpers_asm.S" - "expression_with_stack_xtensa.c" - "expression_with_stack_xtensa_asm.S" - "eri.c" - "trax.c" - "xtensa_intr.c" - "xtensa_intr_asm.S" - "${target}/trax_init.c" - ) - if(IDF_TARGET STREQUAL "esp32s2") - list(APPEND srcs "stdatomic.c") - endif() +set(srcs "eri.c" "xt_trax.c") + +if(NOT BOOTLOADER_BUILD) + list(APPEND srcs "xtensa_intr.c" "xtensa_intr_asm.S") endif() idf_component_register(SRCS ${srcs} INCLUDE_DIRS include ${target}/include - LDFRAGMENTS linker.lf - PRIV_REQUIRES ${priv_requires}) + LDFRAGMENTS linker.lf) -if(NOT BOOTLOADER_BUILD) - target_link_libraries(${COMPONENT_LIB} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/${target}/libxt_hal.a") -endif() +target_link_libraries(${COMPONENT_LIB} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/${target}/libxt_hal.a") \ No newline at end of file diff --git a/components/xtensa/esp32/trax_init.c b/components/xtensa/esp32/trax_init.c deleted file mode 100644 index 7341039a6c..0000000000 --- a/components/xtensa/esp32/trax_init.c +++ /dev/null @@ -1,46 +0,0 @@ -// 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. - -#include -#include "esp_err.h" -#include "esp_log.h" -#include "trax.h" -#include "soc/dport_reg.h" -#include "sdkconfig.h" - -#define TRACEMEM_MUX_PROBLK0_APPBLK1 0 -#define TRACEMEM_MUX_BLK0_ONLY 1 -#define TRACEMEM_MUX_BLK1_ONLY 2 -#define TRACEMEM_MUX_PROBLK1_APPBLK0 3 - -static const char* __attribute__((unused)) TAG = "trax"; - -int trax_enable(trax_ena_select_t which) -{ -#ifndef CONFIG_ESP32_TRAX - ESP_LOGE(TAG, "Trax_enable called, but trax is disabled in menuconfig!"); - return ESP_ERR_NO_MEM; -#endif -#ifndef CONFIG_ESP32_TRAX_TWOBANKS - if (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP) return ESP_ERR_NO_MEM; -#endif - if (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP) { - DPORT_WRITE_PERI_REG(DPORT_TRACEMEM_MUX_MODE_REG, (which == TRAX_ENA_PRO_APP_SWAP)?TRACEMEM_MUX_PROBLK1_APPBLK0:TRACEMEM_MUX_PROBLK0_APPBLK1); - } else { - DPORT_WRITE_PERI_REG(DPORT_TRACEMEM_MUX_MODE_REG, TRACEMEM_MUX_BLK0_ONLY); - } - DPORT_WRITE_PERI_REG(DPORT_PRO_TRACEMEM_ENA_REG, (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP || which == TRAX_ENA_PRO)); - DPORT_WRITE_PERI_REG(DPORT_APP_TRACEMEM_ENA_REG, (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP || which == TRAX_ENA_APP)); - return ESP_OK; -} diff --git a/components/xtensa/esp32s2/trax_init.c b/components/xtensa/esp32s2/trax_init.c deleted file mode 100644 index dfb5771dba..0000000000 --- a/components/xtensa/esp32s2/trax_init.c +++ /dev/null @@ -1,38 +0,0 @@ -// 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. - -#include -#include "esp_err.h" -#include "esp_log.h" -#include "trax.h" -#include "soc/sensitive_reg.h" -#include "sdkconfig.h" - -#define TRACEMEM_MUX_BLK0_NUM 19 -#define TRACEMEM_MUX_BLK1_NUM 20 - -static const char* __attribute__((unused)) TAG = "trax"; - -int trax_enable(trax_ena_select_t which) -{ -#ifndef CONFIG_ESP32S2_TRAX - ESP_LOGE(TAG, "Trax_enable called, but trax is disabled in menuconfig!"); - return ESP_ERR_NO_MEM; -#endif - if (which != TRAX_ENA_PRO) { - return ESP_ERR_INVALID_ARG; - } - REG_WRITE(DPORT_PMS_OCCUPY_3_REG, BIT(TRACEMEM_MUX_BLK1_NUM-4)); - return ESP_OK; -} diff --git a/components/xtensa/esp32s3/trax_init.c b/components/xtensa/esp32s3/trax_init.c deleted file mode 100644 index a2ff55e13d..0000000000 --- a/components/xtensa/esp32s3/trax_init.c +++ /dev/null @@ -1,40 +0,0 @@ -// 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. - -#include -#include "esp_attr.h" -#include "esp_err.h" -#include "esp_log.h" -#include "trax.h" -#include "soc/sensitive_reg.h" -#include "sdkconfig.h" - -#define TRACEMEM_MUX_BLK0_NUM 19 -#define TRACEMEM_MUX_BLK1_NUM 20 - -static const char *__attribute__((unused)) TAG = "trax"; - -// IDF-1785 -int trax_enable(trax_ena_select_t which) -{ -#ifndef CONFIG_ESP32S3_TRAX - ESP_LOGE(TAG, "Trax_enable called, but trax is disabled in menuconfig!"); - return ESP_ERR_NO_MEM; -#endif - if (which != TRAX_ENA_PRO) { - return ESP_ERR_INVALID_ARG; - } - // REG_WRITE(DPORT_PMS_OCCUPY_3_REG, BIT(TRACEMEM_MUX_BLK1_NUM-4)); - return ESP_OK; -} diff --git a/components/xtensa/include/xt_trax.h b/components/xtensa/include/xt_trax.h new file mode 100644 index 0000000000..763d638c8b --- /dev/null +++ b/components/xtensa/include/xt_trax.h @@ -0,0 +1,54 @@ +// Copyright 2015-2016 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 + +#include "eri.h" +#include "xtensa-debug-module.h" + +// Low-level Xtensa TRAX utils + +/** + * @brief Start a Trax trace on the current CPU with instructions as unit of delay. + * Memory blocks to be used as Trax memory must be enabled before + * calling this function, if needed. + */ +void xt_trax_start_trace_instructions(void); + +/** + * @brief Start a Trax trace on the current CPU with words as unit of delay. + * Memory blocks to be used as Trax memory must be enabled before + * calling this function, if needed. + */ +void xt_trax_start_trace_words(void); + +/** + * @brief Check if Trax trace is active on current CPU. + * + * @return bool. Return true if trace is active. + */ +bool xt_trax_trace_is_active(void); + +/** + * @brief Trigger a Trax trace stop after the indicated delay. If this is called + * before and the previous delay hasn't ended yet, this will overwrite + * that delay with the new value. The delay will always start at the time + * the function is called. + * + * @param delay : The delay to stop the trace in, in the unit indicated to + * trax_start_trace. Note: the trace memory has 4K words available. + */ +void xt_trax_trigger_traceend_after_delay(int delay); diff --git a/components/xtensa/linker.lf b/components/xtensa/linker.lf index 157857b722..2d9d446097 100644 --- a/components/xtensa/linker.lf +++ b/components/xtensa/linker.lf @@ -2,8 +2,6 @@ archive: libxtensa.a entries: eri (noflash_text) - if IDF_TARGET_ESP32S2 = y: - stdatomic (noflash) [mapping:xt_hal] archive: libxt_hal.a diff --git a/components/xtensa/trax.c b/components/xtensa/xt_trax.c similarity index 50% rename from components/xtensa/trax.c rename to components/xtensa/xt_trax.c index 5a46ad749a..cc7bab0991 100644 --- a/components/xtensa/trax.c +++ b/components/xtensa/xt_trax.c @@ -13,51 +13,44 @@ // limitations under the License. #include -#include "esp_log.h" +#include + #include "esp_err.h" + #include "xtensa-debug-module.h" #include "eri.h" -#include "trax.h" -#include "sdkconfig.h" -#if defined(CONFIG_ESP32_TRAX) || defined(CONFIG_ESP32S2_TRAX) -#define WITH_TRAX 1 -#endif - -static const char* TAG = "trax"; - - -int trax_start_trace(trax_downcount_unit_t units_until_stop) +bool xt_trax_trace_is_active(void) +{ + return eri_read(ERI_TRAX_TRAXSTAT)&TRAXSTAT_TRACT; +} + +static void _xt_trax_start_trace(bool instructions) { -#if !WITH_TRAX - ESP_EARLY_LOGE(TAG, "Trax_start_trace called, but trax is disabled in menuconfig!"); - return ESP_ERR_NO_MEM; -#endif uint32_t v; - if (eri_read(ERI_TRAX_TRAXSTAT)&TRAXSTAT_TRACT) { - ESP_EARLY_LOGI(TAG, "Stopping active trace first."); - //Trace is active. Stop trace. - eri_write(ERI_TRAX_DELAYCNT, 0); - eri_write(ERI_TRAX_TRAXCTRL, eri_read(ERI_TRAX_TRAXCTRL)|TRAXCTRL_TRSTP); - //ToDo: This will probably trigger a trace done interrupt. ToDo: Fix, but how? -JD - eri_write(ERI_TRAX_TRAXCTRL, 0); - } eri_write(ERI_TRAX_PCMATCHCTRL, 31); //do not stop at any pc match v=TRAXCTRL_TREN | TRAXCTRL_TMEN | TRAXCTRL_PTOWS | (1<` to set a watchpoint on this address and have the CPU halt when it is written to. -- If you don't have JTAG, but you do know roughly when the corruption happens, then you can set a watchpoint in software just beforehand via :cpp:func:`esp_set_watchpoint`. A fatal exception will occur when the watchpoint triggers. For example ``esp_set_watchpoint(0, (void *)addr, 4, ESP_WATCHPOINT_STORE``. Note that watchpoints are per-CPU and are set on the current running CPU only, so if you don't know which CPU is corrupting memory then you will need to call this function on both CPUs. +- If you don't have JTAG, but you do know roughly when the corruption happens, then you can set a watchpoint in software just beforehand via :cpp:func:`esp_cpu_set_watchpoint`. A fatal exception will occur when the watchpoint triggers. For example ``esp_cpu_set_watchpoint(0, (void *)addr, 4, ESP_WATCHPOINT_STORE``. Note that watchpoints are per-CPU and are set on the current running CPU only, so if you don't know which CPU is corrupting memory then you will need to call this function on both CPUs. - For buffer overflows, `heap tracing`_ in ``HEAP_TRACE_ALL`` mode lets you see which callers are allocating which addresses from the heap. See `Heap Tracing To Find Heap Corruption`_ for more details. If you can find the function which allocates memory with an address immediately before the address which is corrupted, this will probably be the function which overflows the buffer. - Calling :cpp:func:`heap_caps_dump` or :cpp:func:`heap_caps_dump_all` can give an indication of what heap blocks are surrounding the corrupted region and may have overflowed/underflowed/etc.