From c9a51bfbb26e4c6133a0aced0f2db3b75a875e30 Mon Sep 17 00:00:00 2001 From: Renz Christian Bagaporo Date: Sun, 19 Jan 2020 10:02:21 +0800 Subject: [PATCH 1/9] soc: create abstraction for cpu related operations --- components/esp32/panic.c | 53 ------ components/esp32s2/panic.c | 53 ------ .../esp_gdbstub/xtensa/gdbstub_xtensa.c | 1 + components/soc/CMakeLists.txt | 6 +- components/soc/include/hal/cpu_hal.h | 121 +++++++++++++ components/soc/include/hal/cpu_types.h | 21 +++ components/soc/include/hal/mpu_hal.h | 32 ++++ components/soc/include/hal/mpu_types.h | 33 ++++ components/soc/include/hal/soc_hal.h | 56 ++++++ .../soc/{soc/esp32 => }/include/soc/cpu.h | 9 +- components/soc/linker.lf | 2 + .../soc/soc/esp32/include/soc/cpu_caps.h | 20 ++ .../soc/soc/esp32/include/soc/mpu_caps.h | 21 +++ .../soc/soc/esp32/include/soc/soc_caps.h | 2 + .../soc/soc/esp32s2/include/soc/cpu_caps.h | 20 ++ .../soc/soc/esp32s2/include/soc/mpu_caps.h | 21 +++ .../soc/soc/esp32s2/include/soc/soc_caps.h | 2 + components/soc/src/{esp32 => }/cpu_util.c | 59 +++++- components/soc/src/esp32/CMakeLists.txt | 1 - components/soc/src/esp32/include/hal/cpu_ll.h | 171 ++++++++++++++++++ components/soc/src/esp32/include/hal/mpu_ll.h | 60 ++++++ components/soc/src/esp32/include/hal/soc_ll.h | 53 ++++++ components/soc/src/esp32s2/CMakeLists.txt | 1 - .../soc/src/esp32s2/include/hal/cpu_ll.h | 167 +++++++++++++++++ .../soc/src/esp32s2/include/hal/mpu_ll.h | 60 ++++++ .../soc/src/esp32s2/include/hal/soc_ll.h | 45 +++++ components/soc/src/hal/cpu_hal.c | 96 ++++++++++ components/soc/src/hal/mpu_hal.c | 54 ++++++ components/soc/src/hal/soc_hal.c | 70 +++++++ .../esp32/include/xtensa/config/extreg.h | 21 +++ .../esp32/include/xtensa/config/specreg.h | 2 + .../esp32s2/include/xtensa/config/extreg.h | 21 +++ .../esp32s2/include/xtensa/config/specreg.h | 2 + components/xtensa/include/xt_instr_macros.h | 24 +++ 34 files changed, 1263 insertions(+), 117 deletions(-) create mode 100644 components/soc/include/hal/cpu_hal.h create mode 100644 components/soc/include/hal/cpu_types.h create mode 100644 components/soc/include/hal/mpu_hal.h create mode 100644 components/soc/include/hal/mpu_types.h create mode 100644 components/soc/include/hal/soc_hal.h rename components/soc/{soc/esp32 => }/include/soc/cpu.h (93%) create mode 100644 components/soc/soc/esp32/include/soc/cpu_caps.h create mode 100644 components/soc/soc/esp32/include/soc/mpu_caps.h create mode 100644 components/soc/soc/esp32s2/include/soc/cpu_caps.h create mode 100644 components/soc/soc/esp32s2/include/soc/mpu_caps.h rename components/soc/src/{esp32 => }/cpu_util.c (62%) create mode 100644 components/soc/src/esp32/include/hal/cpu_ll.h create mode 100644 components/soc/src/esp32/include/hal/mpu_ll.h create mode 100644 components/soc/src/esp32/include/hal/soc_ll.h create mode 100644 components/soc/src/esp32s2/include/hal/cpu_ll.h create mode 100644 components/soc/src/esp32s2/include/hal/mpu_ll.h create mode 100644 components/soc/src/esp32s2/include/hal/soc_ll.h create mode 100644 components/soc/src/hal/cpu_hal.c create mode 100644 components/soc/src/hal/mpu_hal.c create mode 100644 components/soc/src/hal/soc_hal.c create mode 100644 components/xtensa/esp32/include/xtensa/config/extreg.h create mode 100644 components/xtensa/esp32s2/include/xtensa/config/extreg.h create mode 100644 components/xtensa/include/xt_instr_macros.h diff --git a/components/esp32/panic.c b/components/esp32/panic.c index a9dafe197c..cbf7090a30 100644 --- a/components/esp32/panic.c +++ b/components/esp32/panic.c @@ -664,59 +664,6 @@ void esp_set_breakpoint_if_jtag(void *fn) } } - -esp_err_t esp_set_watchpoint(int no, void *adr, int size, int flags) -{ - int x; - if (no < 0 || no > 1) { - return ESP_ERR_INVALID_ARG; - } - if (flags & (~0xC0000000)) { - return ESP_ERR_INVALID_ARG; - } - int dbreakc = 0x3F; - //We support watching 2^n byte values, from 1 to 64. Calculate the mask for that. - for (x = 0; x < 7; x++) { - if (size == (1 << x)) { - break; - } - dbreakc <<= 1; - } - if (x == 7) { - return ESP_ERR_INVALID_ARG; - } - //Mask mask and add in flags. - dbreakc = (dbreakc & 0x3f) | flags; - - if (no == 0) { - asm volatile( - "wsr.dbreaka0 %0\n" \ - "wsr.dbreakc0 %1\n" \ - ::"r"(adr), "r"(dbreakc)); - } else { - asm volatile( - "wsr.dbreaka1 %0\n" \ - "wsr.dbreakc1 %1\n" \ - ::"r"(adr), "r"(dbreakc)); - } - return ESP_OK; -} - -void esp_clear_watchpoint(int no) -{ - //Setting a dbreakc register to 0 makes it trigger on neither load nor store, effectively disabling it. - int dbreakc = 0; - if (no == 0) { - asm volatile( - "wsr.dbreakc0 %0\n" \ - ::"r"(dbreakc)); - } else { - asm volatile( - "wsr.dbreakc1 %0\n" \ - ::"r"(dbreakc)); - } -} - static void esp_error_check_failed_print(const char *msg, esp_err_t rc, const char *file, int line, const char *function, const char *expression) { ets_printf("%s failed: esp_err_t 0x%x", msg, rc); diff --git a/components/esp32s2/panic.c b/components/esp32s2/panic.c index 1209974f89..5c38f1b04c 100644 --- a/components/esp32s2/panic.c +++ b/components/esp32s2/panic.c @@ -672,59 +672,6 @@ void esp_set_breakpoint_if_jtag(void *fn) } } - -esp_err_t esp_set_watchpoint(int no, void *adr, int size, int flags) -{ - int x; - if (no < 0 || no > 1) { - return ESP_ERR_INVALID_ARG; - } - if (flags & (~0xC0000000)) { - return ESP_ERR_INVALID_ARG; - } - int dbreakc = 0x3F; - //We support watching 2^n byte values, from 1 to 64. Calculate the mask for that. - for (x = 0; x < 7; x++) { - if (size == (1 << x)) { - break; - } - dbreakc <<= 1; - } - if (x == 7) { - return ESP_ERR_INVALID_ARG; - } - //Mask mask and add in flags. - dbreakc = (dbreakc & 0x3f) | flags; - - if (no == 0) { - asm volatile( - "wsr.dbreaka0 %0\n" \ - "wsr.dbreakc0 %1\n" \ - ::"r"(adr), "r"(dbreakc)); - } else { - asm volatile( - "wsr.dbreaka1 %0\n" \ - "wsr.dbreakc1 %1\n" \ - ::"r"(adr), "r"(dbreakc)); - } - return ESP_OK; -} - -void esp_clear_watchpoint(int no) -{ - //Setting a dbreakc register to 0 makes it trigger on neither load nor store, effectively disabling it. - int dbreakc = 0; - if (no == 0) { - asm volatile( - "wsr.dbreakc0 %0\n" \ - ::"r"(dbreakc)); - } else { - asm volatile( - "wsr.dbreakc1 %0\n" \ - ::"r"(dbreakc)); - } -} - void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression) { ets_printf("ESP_ERROR_CHECK failed: esp_err_t 0x%x", rc); diff --git a/components/esp_gdbstub/xtensa/gdbstub_xtensa.c b/components/esp_gdbstub/xtensa/gdbstub_xtensa.c index 853b1ba085..a0da9e8cc7 100644 --- a/components/esp_gdbstub/xtensa/gdbstub_xtensa.c +++ b/components/esp_gdbstub/xtensa/gdbstub_xtensa.c @@ -17,6 +17,7 @@ #include "esp_gdbstub_common.h" #include "soc/cpu.h" #include "soc/soc_memory_layout.h" +#include "xtensa/config/specreg.h" #include "sdkconfig.h" #if !XCHAL_HAVE_WINDOWED diff --git a/components/soc/CMakeLists.txt b/components/soc/CMakeLists.txt index 7116f72614..eb67fa9747 100644 --- a/components/soc/CMakeLists.txt +++ b/components/soc/CMakeLists.txt @@ -1,7 +1,9 @@ idf_build_get_property(target IDF_TARGET) -idf_component_register(SRCS "src/memory_layout_utils.c" +idf_component_register(SRCS "src/cpu_util.c" + "src/memory_layout_utils.c" "src/lldesc.c" + "src/hal/cpu_hal.c" "src/hal/rmt_hal.c" "src/hal/rtc_io_hal.c" "src/hal/dac_hal.c" @@ -25,6 +27,8 @@ idf_component_register(SRCS "src/memory_layout_utils.c" "src/hal/uart_hal_iram.c" "src/hal/spi_flash_hal.c" "src/hal/spi_flash_hal_iram.c" + "src/hal/mpu_hal.c" + "src/hal/soc_hal.c" "src/compare_set.c" PRIV_REQUIRES ${target} LDFRAGMENTS linker.lf) diff --git a/components/soc/include/hal/cpu_hal.h b/components/soc/include/hal/cpu_hal.h new file mode 100644 index 0000000000..a9845ab8ad --- /dev/null +++ b/components/soc/include/hal/cpu_hal.h @@ -0,0 +1,121 @@ +// 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 + +#include "esp_err.h" + +#include "hal/cpu_types.h" +#include "hal/cpu_ll.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Return the ID of the core currently executing this code. + * + * @return core id [0..SOC_CPU_CORES_NUM - 1] + */ +#define cpu_hal_get_core_id() cpu_ll_get_core_id() + +/** + * Get the current value of the stack pointer. + * + * @return the current stack pointer + */ +#define cpu_hal_get_sp() cpu_ll_get_sp() + +/** + * Get the current value of the internal counter that increments + * every processor-clock cycle. + * + * @return cycle count; returns 0 if not supported + */ +#define cpu_hal_get_cycle_count() cpu_ll_get_cycle_count() + +/** + * Check if some form of debugger is attached to CPU. + * + * @return true debugger is attached + * @return false no debugger is attached/ no support for debuggers + */ +#define cpu_hal_is_debugger_attached() cpu_ll_is_debugger_attached() + +/** + * Init HW loop status. + */ +#define cpu_hal_init_hwloop() cpu_ll_init_hwloop() + +/** + * Trigger a call to debugger. + */ +#define cpu_hal_break() cpu_ll_break() + +/** + * Set and enable breakpoint at an instruction address. + * + * @note Overwrites previously set breakpoint with same breakpoint ID. + * + * @param id breakpoint to set [0..SOC_CPU_BREAKPOINT_NUM - 1] + * @param addr address to set a breakpoint on + * + * @return ESP_ERR_INVALID_ARG invalid breakpoint id or addr + * @return ESP_ERR_NOT_SUPPORTED processor does not support breakpoints + * @return ESP_OK success + */ +esp_err_t cpu_hal_set_breakpoint(int id, const void* addr); + +/** + * Clear and disable breakpoint. + * + * @param id breakpoint to clear [0..SOC_CPU_BREAKPOINT_NUM - 1] + * + * @return ESP_ERR_INVALID_ARG invalid breakpoint id + * @return ESP_ERR_NOT_SUPPORTED processor does not support breakpoints + * @return ESP_OK success + */ +esp_err_t cpu_hal_clear_breakpoint(int id); + +/** + * Set and enable a watchpoint, specifying the memory range and trigger operation. + * + * @param id watchpoint to set [0..SOC_CPU_WATCHPOINT_NUM - 1] + * @param addr starting address + * @param size number of bytes from starting address to watch + * @param trigger operation on specified memory range that triggers the watchpoint (read, write, read/write) + * + * @return ESP_ERR_INVALID_ARG invalid watchpoint id + * @return ESP_ERR_NOT_SUPPORTED processor does not support watchpoints + * @return ESP_OK success + */ +esp_err_t cpu_hal_set_watchpoint(int id, const void* addr, size_t size, watchpoint_trigger_t trigger); + +/** + * Clear and disable watchpoint. + * + * @param id watchpoint to clear [0..SOC_CPU_WATCHPOINT_NUM - 1] + * + * @return ESP_ERR_INVALID_ARG invalid watchpoint id + * @return ESP_ERR_NOT_SUPPORTED processor does not support watchpoints + * @return ESP_OK success + */ +esp_err_t cpu_hal_clear_watchpoint(int id); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/components/soc/include/hal/cpu_types.h b/components/soc/include/hal/cpu_types.h new file mode 100644 index 0000000000..aee44f6ac9 --- /dev/null +++ b/components/soc/include/hal/cpu_types.h @@ -0,0 +1,21 @@ +// 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 + +typedef enum { + WATCHPOINT_TRIGGER_ON_RO, // on read + WATCHPOINT_TRIGGER_ON_WO, // on write + WATCHPOINT_TRIGGER_ON_RW // on either read or write +} watchpoint_trigger_t; \ No newline at end of file diff --git a/components/soc/include/hal/mpu_hal.h b/components/soc/include/hal/mpu_hal.h new file mode 100644 index 0000000000..25699893b9 --- /dev/null +++ b/components/soc/include/hal/mpu_hal.h @@ -0,0 +1,32 @@ +// 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 "hal/mpu_types.h" +#include "soc/mpu_caps.h" + +/** + * Specify the type of access allowed on a memory region. + * + * @param id index to the region table; on targets not SOC_MPU_CONFIGURABLE_REGIONS_SUPPORTED, + * the region divisions is predefined in hardware which is likely reflected in LL implementation. + * @param access type of access allowed + * + * @return ESP_ERR_INVALID_ARG invalid id or access + * @return ESP_OK success + */ +esp_err_t mpu_hal_set_region_access(int id, mpu_access_t access); \ No newline at end of file diff --git a/components/soc/include/hal/mpu_types.h b/components/soc/include/hal/mpu_types.h new file mode 100644 index 0000000000..14675a7268 --- /dev/null +++ b/components/soc/include/hal/mpu_types.h @@ -0,0 +1,33 @@ +// 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 + +#if SOC_MPU_CONFIGURABLE_REGIONS_SUPPORTED +typedef void** mpu_region_table_t; +#endif + +typedef enum { + MPU_REGION_ILLEGAL, +#if SOC_MPU_REGION_RO_SUPPORTED + MPU_REGION_RO, // read-only +#endif +#if SOC_MPU_REGION_WO_SUPPORTED + MPU_REGION_WO, // write-only +#endif + MPU_REGION_RW, // read-write + MPU_REGION_X, // executable + MPU_REGION_RWX // read-write-executable +} mpu_access_t; \ No newline at end of file diff --git a/components/soc/include/hal/soc_hal.h b/components/soc/include/hal/soc_hal.h new file mode 100644 index 0000000000..d8554daf7b --- /dev/null +++ b/components/soc/include/hal/soc_hal.h @@ -0,0 +1,56 @@ +// 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 + +#include "esp_err.h" + +/** + * Stall the specified CPU core. + * + * @note Has no effect if the core is already stalled - does not return an + * ESP_ERR_INVALID_STATE. + * + * @param core core to stall [0..SOC_CPU_CORES_NUM - 1]; if core < 0 is specified, all other cores are stalled + * + * @return ESP_ERR_INVALID_ARG core argument invalid + * @return ESP_OK success + */ +esp_err_t soc_hal_stall_core(int core); + +/** + * Unstall the specified CPU core. + * + * @note Has no effect if the core is already unstalled - does not return an + * ESP_ERR_INVALID_STATE. + * + * @param core core to unstall [0..SOC_CPU_CORES_NUM - 1]; if core < 0 is specified, all other cores are unstalled + * + * @return ESP_ERR_INVALID_ARG core argument invalid + * @return ESP_OK success + */ +esp_err_t soc_hal_unstall_core(int core); + +/** + * Reset the specified core. + * + * @param core core to reset [0..SOC_CPU_CORES_NUM - 1]; if core < 0 is specified, all other cores are reset + * + * @return ESP_ERR_INVALID_ARG core argument invalid + * @return ESP_OK success + */ +esp_err_t soc_hal_reset_core(int core); \ No newline at end of file diff --git a/components/soc/soc/esp32/include/soc/cpu.h b/components/soc/include/soc/cpu.h similarity index 93% rename from components/soc/soc/esp32/include/soc/cpu.h rename to components/soc/include/soc/cpu.h index 82e710bfa6..450cd8c8a0 100644 --- a/components/soc/soc/esp32/include/soc/cpu.h +++ b/components/soc/include/soc/cpu.h @@ -21,16 +21,13 @@ #include "xtensa/corebits.h" #include "xtensa/config/core.h" +#include "xtensa/config/specreg.h" +#include "xt_instr_macros.h" + #ifdef __cplusplus extern "C" { #endif -/* C macros for xtensa special register read/write/exchange */ - -#define RSR(reg, curval) asm volatile ("rsr %0, " #reg : "=r" (curval)); -#define WSR(reg, newval) asm volatile ("wsr %0, " #reg : : "r" (newval)); -#define XSR(reg, swapval) asm volatile ("xsr %0, " #reg : "+r" (swapval)); - /** @brief Read current stack pointer address * */ diff --git a/components/soc/linker.lf b/components/soc/linker.lf index 9d05e77103..df2191e324 100644 --- a/components/soc/linker.lf +++ b/components/soc/linker.lf @@ -21,3 +21,5 @@ entries: i2c_hal_iram (noflash) spi_flash_hal_gpspi (noflash) lldesc (noflash_text) + cpu_hal (noflash) + soc_hal (noflash) diff --git a/components/soc/soc/esp32/include/soc/cpu_caps.h b/components/soc/soc/esp32/include/soc/cpu_caps.h new file mode 100644 index 0000000000..fbfd780bd4 --- /dev/null +++ b/components/soc/soc/esp32/include/soc/cpu_caps.h @@ -0,0 +1,20 @@ +// 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 + +#define SOC_CPU_BREAKPOINTS_NUM 2 +#define SOC_CPU_WATCHPOINTS_NUM 2 + +#define SOC_CPU_WATCHPOINT_SIZE 64 // bytes \ No newline at end of file diff --git a/components/soc/soc/esp32/include/soc/mpu_caps.h b/components/soc/soc/esp32/include/soc/mpu_caps.h new file mode 100644 index 0000000000..8e12a2b133 --- /dev/null +++ b/components/soc/soc/esp32/include/soc/mpu_caps.h @@ -0,0 +1,21 @@ +// 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 + +#define SOC_MPU_CONFIGURABLE_REGIONS_SUPPORTED 0 +#define SOC_MPU_MIN_REGION_SIZE 0x20000000 +#define SOC_MPU_REGIONS_MAX_NUM 8 +#define SOC_MPU_REGION_RO_SUPPORTED 0 +#define SOC_MPU_REGION_WO_SUPPORTED 0 \ No newline at end of file diff --git a/components/soc/soc/esp32/include/soc/soc_caps.h b/components/soc/soc/esp32/include/soc/soc_caps.h index 283c7ae0c7..b6a052da0b 100644 --- a/components/soc/soc/esp32/include/soc/soc_caps.h +++ b/components/soc/soc/esp32/include/soc/soc_caps.h @@ -11,3 +11,5 @@ #define SOC_SDIO_SLAVE_SUPPORTED 1 #define SOC_CAN_SUPPORTED 1 #define SOC_EMAC_SUPPORTED 1 + +#define SOC_CPU_CORES_NUM 2 diff --git a/components/soc/soc/esp32s2/include/soc/cpu_caps.h b/components/soc/soc/esp32s2/include/soc/cpu_caps.h new file mode 100644 index 0000000000..fbfd780bd4 --- /dev/null +++ b/components/soc/soc/esp32s2/include/soc/cpu_caps.h @@ -0,0 +1,20 @@ +// 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 + +#define SOC_CPU_BREAKPOINTS_NUM 2 +#define SOC_CPU_WATCHPOINTS_NUM 2 + +#define SOC_CPU_WATCHPOINT_SIZE 64 // bytes \ No newline at end of file diff --git a/components/soc/soc/esp32s2/include/soc/mpu_caps.h b/components/soc/soc/esp32s2/include/soc/mpu_caps.h new file mode 100644 index 0000000000..8e12a2b133 --- /dev/null +++ b/components/soc/soc/esp32s2/include/soc/mpu_caps.h @@ -0,0 +1,21 @@ +// 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 + +#define SOC_MPU_CONFIGURABLE_REGIONS_SUPPORTED 0 +#define SOC_MPU_MIN_REGION_SIZE 0x20000000 +#define SOC_MPU_REGIONS_MAX_NUM 8 +#define SOC_MPU_REGION_RO_SUPPORTED 0 +#define SOC_MPU_REGION_WO_SUPPORTED 0 \ No newline at end of file diff --git a/components/soc/soc/esp32s2/include/soc/soc_caps.h b/components/soc/soc/esp32s2/include/soc/soc_caps.h index 85a465e89f..f011597850 100644 --- a/components/soc/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/soc/esp32s2/include/soc/soc_caps.h @@ -4,3 +4,5 @@ // include them here. #pragma once + +#define SOC_CPU_CORES_NUM 1 \ No newline at end of file diff --git a/components/soc/src/esp32/cpu_util.c b/components/soc/src/cpu_util.c similarity index 62% rename from components/soc/src/esp32/cpu_util.c rename to components/soc/src/cpu_util.c index ed2c6361ef..8bfed62058 100644 --- a/components/soc/src/esp32/cpu_util.c +++ b/components/soc/src/cpu_util.c @@ -15,7 +15,9 @@ #include "esp_attr.h" #include "soc/cpu.h" #include "soc/soc.h" -#include "soc/rtc_periph.h" +#include "soc/rtc_cntl_reg.h" +#include "esp_err.h" + #include "sdkconfig.h" void IRAM_ATTR esp_cpu_stall(int cpu_id) @@ -52,7 +54,7 @@ void IRAM_ATTR esp_cpu_reset(int cpu_id) bool IRAM_ATTR esp_cpu_in_ocd_debug_mode(void) { -#if CONFIG_ESP32_DEBUG_OCDAWARE +#if CONFIG_ESP32S2_DEBUG_OCDAWARE int dcr; int reg=0x10200C; //DSRSET register asm("rer %0,%1":"=r"(dcr):"r"(reg)); @@ -61,3 +63,56 @@ bool IRAM_ATTR esp_cpu_in_ocd_debug_mode(void) return false; // Always return false if "OCD aware" is disabled #endif } + +esp_err_t esp_set_watchpoint(int no, void *adr, int size, int flags) +{ + int x; + if (no < 0 || no > 1) { + return ESP_ERR_INVALID_ARG; + } + if (flags & (~0xC0000000)) { + return ESP_ERR_INVALID_ARG; + } + int dbreakc = 0x3F; + //We support watching 2^n byte values, from 1 to 64. Calculate the mask for that. + for (x = 0; x < 7; x++) { + if (size == (1 << x)) { + break; + } + dbreakc <<= 1; + } + if (x == 7) { + return ESP_ERR_INVALID_ARG; + } + //Mask mask and add in flags. + dbreakc = (dbreakc & 0x3f) | flags; + + if (no == 0) { + asm volatile( + "wsr.dbreaka0 %0\n" \ + "wsr.dbreakc0 %1\n" \ + ::"r"(adr), "r"(dbreakc)); + } else { + asm volatile( + "wsr.dbreaka1 %0\n" \ + "wsr.dbreakc1 %1\n" \ + ::"r"(adr), "r"(dbreakc)); + } + return ESP_OK; +} + +void esp_clear_watchpoint(int no) +{ + //Setting a dbreakc register to 0 makes it trigger on neither load nor store, effectively disabling it. + int dbreakc = 0; + if (no == 0) { + asm volatile( + "wsr.dbreakc0 %0\n" \ + ::"r"(dbreakc)); + } else { + asm volatile( + "wsr.dbreakc1 %0\n" \ + ::"r"(dbreakc)); + } +} + diff --git a/components/soc/src/esp32/CMakeLists.txt b/components/soc/src/esp32/CMakeLists.txt index be5ed8b4f9..e4c31149fc 100644 --- a/components/soc/src/esp32/CMakeLists.txt +++ b/components/soc/src/esp32/CMakeLists.txt @@ -1,5 +1,4 @@ set(srcs "brownout_hal.c" - "cpu_util.c" "rtc_clk.c" "rtc_clk_init.c" "rtc_init.c" diff --git a/components/soc/src/esp32/include/hal/cpu_ll.h b/components/soc/src/esp32/include/hal/cpu_ll.h new file mode 100644 index 0000000000..362de73997 --- /dev/null +++ b/components/soc/src/esp32/include/hal/cpu_ll.h @@ -0,0 +1,171 @@ +// 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/cpu_caps.h" + +#include "xt_instr_macros.h" +#include "xtensa/config/specreg.h" +#include "xtensa/config/extreg.h" +#include "esp_bit_defs.h" +#include "xtensa/config/core.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static inline int cpu_ll_get_core_id(void) +{ + uint32_t id; + asm volatile ( + "rsr.prid %0\n" + "extui %0,%0,13,1" + :"=r"(id)); + return (int) id; +} + +static inline uint32_t cpu_ll_get_cycle_count(void) +{ + uint32_t result; + RSR(CCOUNT, result); + return result; +} + +static inline void* cpu_ll_get_sp(void) +{ + void *sp; + asm volatile ("mov %0, sp;" : "=r" (sp)); + return sp; +} + +static inline void cpu_ll_init_hwloop(void) +{ +#if XCHAL_ERRATUM_572 + uint32_t memctl = XCHAL_CACHE_MEMCTL_DEFAULT; + WSR(MEMCTL, memctl); +#endif // XCHAL_ERRATUM_572 +} + +static inline void cpu_ll_set_breakpoint(int id, uint32_t pc) +{ + uint32_t en; + + // Set the break address register to the appropriate PC + if (id) { + WSR(IBREAKA_1, pc); + } else { + WSR(IBREAKA_0, pc); + } + + // Enable the breakpoint using the break enable register + RSR(IBREAKENABLE, en); + en |= BIT(id); + WSR(IBREAKENABLE, en); +} + +static inline void cpu_ll_clear_breakpoint(int id) +{ + uint32_t en = 0; + uint32_t pc = 0; + + // Set the break address register to the appropriate PC + if (id) { + WSR(IBREAKA_1, pc); + } else { + WSR(IBREAKA_0, pc); + } + + // Enable the breakpoint using the break enable register + RSR(IBREAKENABLE, en); + en &= ~BIT(id); + WSR(IBREAKENABLE, en); +} + +static inline uint32_t cpu_ll_ptr_to_pc(const void* addr) +{ + return ((uint32_t) addr); +} + +static inline void* cpu_ll_pc_to_ptr(uint32_t pc) +{ + return (void*) ((pc & 0x3fffffff) | 0x40000000); +} + +static inline void cpu_ll_set_watchpoint(int id, + const void* addr, + size_t size, + bool on_read, + bool on_write) +{ + uint32_t dbreakc = 0x3F; + + //We support watching 2^n byte values, from 1 to 64. Calculate the mask for that. + for (int x = 0; x < 7; x++) { + if (size == (1 << x)) { + break; + } + dbreakc <<= 1; + } + + dbreakc = (dbreakc & 0x3F); + + if (on_read) { + dbreakc |= BIT(30); + } + + if (on_write) { + dbreakc |= BIT(31); + } + + // Write the break address register and the size to control + // register. + if (id) { + WSR(DBREAKA_1, (uint32_t) addr); + WSR(DBREAKC_1, dbreakc); + } else { + WSR(DBREAKA_0, (uint32_t) addr); + WSR(DBREAKC_0, dbreakc); + } +} + +static inline void cpu_ll_clear_watchpoint(int id) +{ + // Clear both break address register and control register + if (id) { + WSR(DBREAKA_1, 0); + WSR(DBREAKC_1, 0); + } else { + WSR(DBREAKA_0, 0); + WSR(DBREAKC_0, 0); + } +} + +static inline bool cpu_ll_is_debugger_attached(void) +{ + uint32_t dcr = 0; + uint32_t reg = DSRSET; + RER(reg, dcr); + return (dcr&0x1); +} + +static inline void cpu_ll_break(void) +{ + __asm__ ("break 0,0"); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/src/esp32/include/hal/mpu_ll.h b/components/soc/src/esp32/include/hal/mpu_ll.h new file mode 100644 index 0000000000..1735f46d7a --- /dev/null +++ b/components/soc/src/esp32/include/hal/mpu_ll.h @@ -0,0 +1,60 @@ +// 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 "xt_instr_macros.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static inline uint32_t cpu_ll_id_to_addr(int id) +{ + // vpn - id + // 0x00000000 = 0 + // 0x20000000 = 1 + // 0x40000000 = 2 + // 0x60000000 = 3 + // 0x80000000 = 4 + // 0xa0000000 = 5 + // 0xc0000000 = 6 + // 0xe0000000 = 7 + return id * SOC_MPU_MIN_REGION_SIZE; +} + +static inline void mpu_ll_set_region_rw(uint32_t addr) +{ + WDTLB(0x0, addr); // cached, no allocate +} + +static inline void mpu_ll_set_region_rwx(uint32_t addr) +{ + WDTLB(0x2, addr); // bypass cache +} + +static inline void mpu_ll_set_region_x(uint32_t addr) +{ + WITLB(0x3, addr); // cached +} + +static inline void mpu_ll_set_region_illegal(uint32_t addr) +{ + WITLB(0xF, addr); + WDTLB(0xF, addr); +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/components/soc/src/esp32/include/hal/soc_ll.h b/components/soc/src/esp32/include/hal/soc_ll.h new file mode 100644 index 0000000000..b83a0756bc --- /dev/null +++ b/components/soc/src/esp32/include/hal/soc_ll.h @@ -0,0 +1,53 @@ +// 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/soc.h" +#include "soc/rtc_cntl_reg.h" +#include "soc/soc_caps.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static inline void soc_ll_stall_core(int core) +{ + const int rtc_cntl_c1_m[SOC_CPU_CORES_NUM] = {RTC_CNTL_SW_STALL_PROCPU_C1_M, RTC_CNTL_SW_STALL_APPCPU_C1_M}; + const int rtc_cntl_c1_s[SOC_CPU_CORES_NUM] = {RTC_CNTL_SW_STALL_PROCPU_C1_S, RTC_CNTL_SW_STALL_APPCPU_C1_S}; + const int rtc_cntl_c0_m[SOC_CPU_CORES_NUM] = {RTC_CNTL_SW_STALL_PROCPU_C0_M, RTC_CNTL_SW_STALL_APPCPU_C0_M}; + const int rtc_cntl_c0_s[SOC_CPU_CORES_NUM] = {RTC_CNTL_SW_STALL_PROCPU_C0_S, RTC_CNTL_SW_STALL_APPCPU_C0_S}; + + CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, rtc_cntl_c1_m[core]); + SET_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, 0x21 << rtc_cntl_c1_s[core]); + CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, rtc_cntl_c0_m[core]); + SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, 2 << rtc_cntl_c0_s[core]); +} + +static inline void soc_ll_unstall_core(int core) +{ + const int rtc_cntl_c1_m[SOC_CPU_CORES_NUM] = {RTC_CNTL_SW_STALL_PROCPU_C1_M, RTC_CNTL_SW_STALL_APPCPU_C1_M}; + const int rtc_cntl_c0_m[SOC_CPU_CORES_NUM] = {RTC_CNTL_SW_STALL_PROCPU_C0_M, RTC_CNTL_SW_STALL_APPCPU_C0_M}; + CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, rtc_cntl_c1_m[core]); + CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, rtc_cntl_c0_m[core]); +} + +static inline void soc_ll_reset_core(int core) +{ + SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, + core == 0 ? RTC_CNTL_SW_PROCPU_RST_M : RTC_CNTL_SW_APPCPU_RST_M); +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/components/soc/src/esp32s2/CMakeLists.txt b/components/soc/src/esp32s2/CMakeLists.txt index 4fc1eb04c4..765ef77769 100644 --- a/components/soc/src/esp32s2/CMakeLists.txt +++ b/components/soc/src/esp32s2/CMakeLists.txt @@ -1,5 +1,4 @@ set(srcs "brownout_hal.c" - "cpu_util.c" "rtc_clk.c" "rtc_clk_init.c" "rtc_init.c" diff --git a/components/soc/src/esp32s2/include/hal/cpu_ll.h b/components/soc/src/esp32s2/include/hal/cpu_ll.h new file mode 100644 index 0000000000..a817759656 --- /dev/null +++ b/components/soc/src/esp32s2/include/hal/cpu_ll.h @@ -0,0 +1,167 @@ +// 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/cpu_caps.h" + +#include "xt_instr_macros.h" +#include "xtensa/config/specreg.h" +#include "xtensa/config/extreg.h" +#include "esp_bit_defs.h" +#include "xtensa/config/core.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static inline int cpu_ll_get_core_id(void) +{ + return 0; +} + +static inline uint32_t cpu_ll_get_cycle_count(void) +{ + uint32_t result; + RSR(CCOUNT, result); + return result; +} + +static inline void* cpu_ll_get_sp(void) +{ + void *sp; + asm volatile ("mov %0, sp;" : "=r" (sp)); + return sp; +} + +static inline void cpu_ll_init_hwloop(void) +{ +#if XCHAL_ERRATUM_572 + uint32_t memctl = XCHAL_CACHE_MEMCTL_DEFAULT; + WSR(MEMCTL, memctl); +#endif // XCHAL_ERRATUM_572 +} + +static inline void cpu_ll_set_breakpoint(int id, uint32_t pc) +{ + uint32_t en; + + // Set the break address register to the appropriate PC + if (id) { + WSR(IBREAKA_1, pc); + } else { + WSR(IBREAKA_0, pc); + } + + // Enable the breakpoint using the break enable register + RSR(IBREAKENABLE, en); + en |= BIT(id); + WSR(IBREAKENABLE, en); +} + +static inline void cpu_ll_clear_breakpoint(int id) +{ + uint32_t en = 0; + uint32_t pc = 0; + + // Set the break address register to the appropriate PC + if (id) { + WSR(IBREAKA_1, pc); + } else { + WSR(IBREAKA_0, pc); + } + + // Enable the breakpoint using the break enable register + RSR(IBREAKENABLE, en); + en &= ~BIT(id); + WSR(IBREAKENABLE, en); +} + +static inline uint32_t cpu_ll_ptr_to_pc(const void* addr) +{ + return ((uint32_t) addr); +} + +static inline void* cpu_ll_pc_to_ptr(uint32_t pc) +{ + return (void*) ((pc & 0x3fffffff) | 0x40000000); +} + +static inline void cpu_ll_set_watchpoint(int id, + const void* addr, + size_t size, + bool on_read, + bool on_write) +{ + uint32_t dbreakc = 0x3F; + + //We support watching 2^n byte values, from 1 to 64. Calculate the mask for that. + for (int x = 0; x < 7; x++) { + if (size == (1 << x)) { + break; + } + dbreakc <<= 1; + } + + dbreakc = (dbreakc & 0x3F); + + if (on_read) { + dbreakc |= BIT(30); + } + + if (on_write) { + dbreakc |= BIT(31); + } + + // Write the break address register and the size to control + // register. + if (id) { + WSR(DBREAKA_1, (uint32_t) addr); + WSR(DBREAKC_1, dbreakc); + } else { + WSR(DBREAKA_0, (uint32_t) addr); + WSR(DBREAKC_0, dbreakc); + } +} + +static inline void cpu_ll_clear_watchpoint(int id) +{ + // Clear both break address register and control register + if (id) { + WSR(DBREAKA_1, 0); + WSR(DBREAKC_1, 0); + } else { + WSR(DBREAKA_0, 0); + WSR(DBREAKC_0, 0); + } +} + +static inline bool cpu_ll_is_debugger_attached(void) +{ + uint32_t dcr = 0; + uint32_t reg = DSRSET; + RER(reg, dcr); + return (dcr&0x1); +} + + +static inline void cpu_ll_break(void) +{ + __asm__ ("break 0,0"); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/src/esp32s2/include/hal/mpu_ll.h b/components/soc/src/esp32s2/include/hal/mpu_ll.h new file mode 100644 index 0000000000..1735f46d7a --- /dev/null +++ b/components/soc/src/esp32s2/include/hal/mpu_ll.h @@ -0,0 +1,60 @@ +// 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 "xt_instr_macros.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static inline uint32_t cpu_ll_id_to_addr(int id) +{ + // vpn - id + // 0x00000000 = 0 + // 0x20000000 = 1 + // 0x40000000 = 2 + // 0x60000000 = 3 + // 0x80000000 = 4 + // 0xa0000000 = 5 + // 0xc0000000 = 6 + // 0xe0000000 = 7 + return id * SOC_MPU_MIN_REGION_SIZE; +} + +static inline void mpu_ll_set_region_rw(uint32_t addr) +{ + WDTLB(0x0, addr); // cached, no allocate +} + +static inline void mpu_ll_set_region_rwx(uint32_t addr) +{ + WDTLB(0x2, addr); // bypass cache +} + +static inline void mpu_ll_set_region_x(uint32_t addr) +{ + WITLB(0x3, addr); // cached +} + +static inline void mpu_ll_set_region_illegal(uint32_t addr) +{ + WITLB(0xF, addr); + WDTLB(0xF, addr); +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/components/soc/src/esp32s2/include/hal/soc_ll.h b/components/soc/src/esp32s2/include/hal/soc_ll.h new file mode 100644 index 0000000000..13d0aabb05 --- /dev/null +++ b/components/soc/src/esp32s2/include/hal/soc_ll.h @@ -0,0 +1,45 @@ +// 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/soc.h" +#include "soc/rtc_cntl_reg.h" +#include "soc/soc_caps.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static inline void soc_ll_stall_core(int core) +{ + CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, RTC_CNTL_SW_STALL_PROCPU_C1_M); + SET_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, 0x21 << RTC_CNTL_SW_STALL_PROCPU_C1_S); + CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_STALL_PROCPU_C0_M); + SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, 2 << RTC_CNTL_SW_STALL_PROCPU_C0_S); +} + +static inline void soc_ll_unstall_core(int core) +{ + CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, RTC_CNTL_SW_STALL_PROCPU_C1_M); + CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_STALL_PROCPU_C0_M); +} + +static inline void soc_ll_reset_core(int core) +{ + SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_PROCPU_RST_M); +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/components/soc/src/hal/cpu_hal.c b/components/soc/src/hal/cpu_hal.c new file mode 100644 index 0000000000..87b7c959c7 --- /dev/null +++ b/components/soc/src/hal/cpu_hal.c @@ -0,0 +1,96 @@ +// 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 "hal/cpu_hal.h" +#include "hal/cpu_types.h" + +#include "soc/cpu_caps.h" + +esp_err_t cpu_hal_set_breakpoint(int id, const void* addr) +{ +#if SOC_CPU_BREAKPOINTS_NUM != 0 + if (id >= SOC_CPU_BREAKPOINTS_NUM || id < 0) { + return ESP_ERR_INVALID_ARG; + } + + cpu_ll_set_breakpoint(id, cpu_ll_ptr_to_pc(addr)); + + return ESP_OK; +#else + return ESP_ERR_NOT_SUPPORTED; +#endif +} + +esp_err_t cpu_hal_clear_breakpoint(int id) +{ +#if SOC_CPU_BREAKPOINTS_NUM > 0 + if (id >= SOC_CPU_BREAKPOINTS_NUM || id < 0) { + return ESP_ERR_INVALID_ARG; + } + + cpu_ll_clear_breakpoint(id); + + return ESP_OK; +#else + return ESP_ERR_NOT_SUPPORTED; +#endif +} + +esp_err_t cpu_hal_set_watchpoint(int id, const void* addr, size_t size, watchpoint_trigger_t trigger) +{ +#if SOC_CPU_WATCHPOINTS_NUM > 0 + if (id >= SOC_CPU_WATCHPOINTS_NUM || id < 0) { + return ESP_ERR_INVALID_ARG; + } + + if (size > SOC_CPU_WATCHPOINT_SIZE) { + return ESP_ERR_INVALID_ARG; + } + + bool on_read = false, on_write = false; + + if (trigger == WATCHPOINT_TRIGGER_ON_RO) { + on_read = true; + } else if (trigger == WATCHPOINT_TRIGGER_ON_WO) { + on_write = true; + } else { + on_read = on_write = true; + } + + cpu_ll_set_watchpoint(id, addr, size, on_read, on_write); + + return ESP_OK; +#else + return ESP_ERR_NOT_SUPPORTED; +#endif +} + +esp_err_t cpu_hal_clear_watchpoint(int id) +{ +#if SOC_CPU_WATCHPOINTS_NUM > 0 + if (id >= SOC_CPU_WATCHPOINTS_NUM || id < 0) { + return ESP_ERR_INVALID_ARG; + } + + cpu_ll_clear_watchpoint(id); + + return ESP_OK; +#else + return ESP_ERR_NOT_SUPPORTED; +#endif +} \ No newline at end of file diff --git a/components/soc/src/hal/mpu_hal.c b/components/soc/src/hal/mpu_hal.c new file mode 100644 index 0000000000..0a0bc6dae1 --- /dev/null +++ b/components/soc/src/hal/mpu_hal.c @@ -0,0 +1,54 @@ +// 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 "hal/mpu_hal.h" +#include "hal/mpu_ll.h" +#include "hal/mpu_types.h" + +esp_err_t mpu_hal_set_region_access(int id, mpu_access_t access) +{ + if (id > SOC_MPU_REGIONS_MAX_NUM || id < 0) { + return ESP_ERR_INVALID_ARG; + } + + uint32_t addr = cpu_ll_id_to_addr(id); + + switch (access) + { +#if SOC_MPU_REGION_RO_SUPPORTED + case MPU_REGION_RO: + mpu_ll_set_region_ro(addr); + break; +#endif +#if SOC_MPU_REGION_WO_SUPPORTED + case MPU_REGION_WO: + mpu_ll_set_region_wo(addr); + break; +#endif + case MPU_REGION_RW: + mpu_ll_set_region_rw(addr); + break; + case MPU_REGION_X: + mpu_ll_set_region_x(addr); + break; + case MPU_REGION_RWX: + mpu_ll_set_region_rwx(addr); + break; + default: + return ESP_ERR_INVALID_ARG; + break; + } + + return ESP_OK; +} \ No newline at end of file diff --git a/components/soc/src/hal/soc_hal.c b/components/soc/src/hal/soc_hal.c new file mode 100644 index 0000000000..ea17fc6bbe --- /dev/null +++ b/components/soc/src/hal/soc_hal.c @@ -0,0 +1,70 @@ +// 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 "hal/cpu_hal.h" +#include "hal/soc_hal.h" +#include "hal/soc_ll.h" +#include "soc/soc_caps.h" + +#define CHECK_CORE(core) { if ((core) > SOC_CPU_CORES_NUM) return ESP_ERR_INVALID_ARG; } +#define PERFORM_ON_OTHER_CORES(action) { \ + for (int i = 0, cur = cpu_hal_get_core_id(); i < SOC_CPU_CORES_NUM; i++) { \ + if (i != cur) { \ + action(i); \ + } \ + } \ + } + +esp_err_t soc_hal_stall_core(int core) +{ + CHECK_CORE(core); + + if (core < 0) { + PERFORM_ON_OTHER_CORES(soc_hal_stall_core); + } else { + soc_ll_stall_core(core); + } + + return ESP_OK; +} + +esp_err_t soc_hal_unstall_core(int core) +{ + CHECK_CORE(core); + + if (core < 0) { + PERFORM_ON_OTHER_CORES(soc_hal_unstall_core); + } else { + soc_ll_unstall_core(core); + } + + return ESP_OK; +} + +esp_err_t soc_hal_reset_core(int core) +{ + CHECK_CORE(core); + + if (core < 0) { + PERFORM_ON_OTHER_CORES(soc_hal_reset_core); + } else { + soc_ll_reset_core(core); + } + + return ESP_OK; +} \ No newline at end of file diff --git a/components/xtensa/esp32/include/xtensa/config/extreg.h b/components/xtensa/esp32/include/xtensa/config/extreg.h new file mode 100644 index 0000000000..12ab76618a --- /dev/null +++ b/components/xtensa/esp32/include/xtensa/config/extreg.h @@ -0,0 +1,21 @@ +/* + * ESP32 External Register symbolic names + */ + +// 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 + +#define DSRSET 0x10200C \ No newline at end of file diff --git a/components/xtensa/esp32/include/xtensa/config/specreg.h b/components/xtensa/esp32/include/xtensa/config/specreg.h index 0135d4c7f5..d35988556d 100644 --- a/components/xtensa/esp32/include/xtensa/config/specreg.h +++ b/components/xtensa/esp32/include/xtensa/config/specreg.h @@ -57,6 +57,7 @@ #define DBREAKA_1 145 #define DBREAKC_0 160 #define DBREAKC_1 161 +#define CONFIGID0 176 #define EPC_1 177 #define EPC_2 178 #define EPC_3 179 @@ -71,6 +72,7 @@ #define EPS_5 197 #define EPS_6 198 #define EPS_7 199 +#define CONFIGID1 208 #define EXCSAVE_1 209 #define EXCSAVE_2 210 #define EXCSAVE_3 211 diff --git a/components/xtensa/esp32s2/include/xtensa/config/extreg.h b/components/xtensa/esp32s2/include/xtensa/config/extreg.h new file mode 100644 index 0000000000..95a6a69b62 --- /dev/null +++ b/components/xtensa/esp32s2/include/xtensa/config/extreg.h @@ -0,0 +1,21 @@ +/* + * ESP32-S2 External Register symbolic names + */ + +// 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 + +#define DSRSET 0x10200C \ No newline at end of file diff --git a/components/xtensa/esp32s2/include/xtensa/config/specreg.h b/components/xtensa/esp32s2/include/xtensa/config/specreg.h index 30e95592ab..b63d82b964 100644 --- a/components/xtensa/esp32s2/include/xtensa/config/specreg.h +++ b/components/xtensa/esp32s2/include/xtensa/config/specreg.h @@ -44,6 +44,7 @@ #define DBREAKA_1 145 #define DBREAKC_0 160 #define DBREAKC_1 161 +#define CONFIGID0 176 #define EPC_1 177 #define EPC_2 178 #define EPC_3 179 @@ -58,6 +59,7 @@ #define EPS_5 197 #define EPS_6 198 #define EPS_7 199 +#define CONFIGID1 208 #define EXCSAVE_1 209 #define EXCSAVE_2 210 #define EXCSAVE_3 211 diff --git a/components/xtensa/include/xt_instr_macros.h b/components/xtensa/include/xt_instr_macros.h new file mode 100644 index 0000000000..9df78f5f25 --- /dev/null +++ b/components/xtensa/include/xt_instr_macros.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 + +#define RSR(reg, at) asm volatile ("rsr %0, %1" : "=r" (at) : "i" (reg)) +#define WSR(reg, at) asm volatile ("wsr %0, %1" : : "r" (at), "i" (reg)) +#define XSR(reg, at) asm volatile ("xsr %0, %1" : "+r" (at) : "i" (reg)) + +#define RER(reg, at) asm volatile ("rer %0, %1" : "=r" (at) : "r" (reg)) + +#define WITLB(at, as) asm volatile ("witlb %0, %1; \n isync \n " : : "r" (at), "r" (as)) +#define WDTLB(at, as) asm volatile ("wdtlb %0, %1; \n dsync \n " : : "r" (at), "r" (as)) \ No newline at end of file From f3c6320ff626ac631f61164e2e9fc18103b59e1a Mon Sep 17 00:00:00 2001 From: Renz Christian Bagaporo Date: Sun, 19 Jan 2020 10:47:20 +0800 Subject: [PATCH 2/9] soc: implement cpu utils in terms of cpu abstractions --- components/soc/include/soc/cpu.h | 6 +- components/soc/src/cpu_util.c | 122 +++++++++----------------- components/soc/src/esp32s2/cpu_util.c | 63 ------------- components/soc/src/hal/mpu_hal.c | 5 ++ 4 files changed, 50 insertions(+), 146 deletions(-) delete mode 100644 components/soc/src/esp32s2/cpu_util.c diff --git a/components/soc/include/soc/cpu.h b/components/soc/include/soc/cpu.h index 450cd8c8a0..f680b8ff7a 100644 --- a/components/soc/include/soc/cpu.h +++ b/components/soc/include/soc/cpu.h @@ -24,6 +24,8 @@ #include "xtensa/config/specreg.h" #include "xt_instr_macros.h" +#include "hal/cpu_hal.h" + #ifdef __cplusplus extern "C" { #endif @@ -33,9 +35,7 @@ extern "C" { */ static inline void *get_sp(void) { - void *sp; - asm volatile ("mov %0, sp;" : "=r" (sp)); - return sp; + return cpu_hal_get_sp(); } /* Functions to set page attributes for Region Protection option in the CPU. diff --git a/components/soc/src/cpu_util.c b/components/soc/src/cpu_util.c index 8bfed62058..61d7034186 100644 --- a/components/soc/src/cpu_util.c +++ b/components/soc/src/cpu_util.c @@ -1,4 +1,4 @@ -// Copyright 2013-2016 Espressif Systems (Shanghai) PTE LTD +// 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. @@ -15,104 +15,66 @@ #include "esp_attr.h" #include "soc/cpu.h" #include "soc/soc.h" -#include "soc/rtc_cntl_reg.h" -#include "esp_err.h" +#include "soc/rtc_periph.h" +#include "sdkconfig.h" + +#include "hal/cpu_hal.h" +#include "esp_debug_helpers.h" +#include "hal/cpu_types.h" + +#include "hal/soc_hal.h" #include "sdkconfig.h" void IRAM_ATTR esp_cpu_stall(int cpu_id) { - if (cpu_id == 1) { - CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, RTC_CNTL_SW_STALL_APPCPU_C1_M); - SET_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, 0x21< 1) { - return ESP_ERR_INVALID_ARG; - } - if (flags & (~0xC0000000)) { - return ESP_ERR_INVALID_ARG; - } - int dbreakc = 0x3F; - //We support watching 2^n byte values, from 1 to 64. Calculate the mask for that. - for (x = 0; x < 7; x++) { - if (size == (1 << x)) { - break; - } - dbreakc <<= 1; - } - if (x == 7) { - return ESP_ERR_INVALID_ARG; - } - //Mask mask and add in flags. - dbreakc = (dbreakc & 0x3f) | flags; - - if (no == 0) { - asm volatile( - "wsr.dbreaka0 %0\n" \ - "wsr.dbreakc0 %1\n" \ - ::"r"(adr), "r"(dbreakc)); - } else { - asm volatile( - "wsr.dbreaka1 %0\n" \ - "wsr.dbreakc1 %1\n" \ - ::"r"(adr), "r"(dbreakc)); - } - return ESP_OK; -} - -void esp_clear_watchpoint(int no) -{ - //Setting a dbreakc register to 0 makes it trigger on neither load nor store, effectively disabling it. - int dbreakc = 0; - if (no == 0) { - asm volatile( - "wsr.dbreakc0 %0\n" \ - ::"r"(dbreakc)); - } else { - asm volatile( - "wsr.dbreakc1 %0\n" \ - ::"r"(dbreakc)); - } -} - diff --git a/components/soc/src/esp32s2/cpu_util.c b/components/soc/src/esp32s2/cpu_util.c deleted file mode 100644 index ab45ab3b26..0000000000 --- a/components/soc/src/esp32s2/cpu_util.c +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2013-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 "esp_attr.h" -#include "soc/cpu.h" -#include "soc/soc.h" -#include "soc/rtc_cntl_reg.h" -#include "sdkconfig.h" - -void IRAM_ATTR esp_cpu_stall(int cpu_id) -{ - if (cpu_id == 1) { - CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, RTC_CNTL_SW_STALL_APPCPU_C1_M); - SET_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, 0x21< +#include + +#include "esp_err.h" + #include "hal/mpu_hal.h" #include "hal/mpu_ll.h" #include "hal/mpu_types.h" From db608736fb187dbe68de706a7d6bf59ca7eb7fa7 Mon Sep 17 00:00:00 2001 From: Renz Christian Bagaporo Date: Sun, 19 Jan 2020 10:30:06 +0800 Subject: [PATCH 3/9] freertos: implement get core id with cpu abstraction --- components/freertos/include/freertos/portable.h | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/components/freertos/include/freertos/portable.h b/components/freertos/include/freertos/portable.h index d07ac2f73f..cd99a975f4 100644 --- a/components/freertos/include/freertos/portable.h +++ b/components/freertos/include/freertos/portable.h @@ -86,7 +86,6 @@ specific constants has been moved into the deprecated_definitions.h header file. */ #include "deprecated_definitions.h" -#include "soc/cpu.h" /* If portENTER_CRITICAL is not defined then including deprecated_definitions.h did not result in a portmacro.h header file being included - and it should be @@ -127,6 +126,9 @@ extern "C" { #include "mpu_wrappers.h" #include "esp_system.h" +#include "hal/cpu_hal.h" +#include "xt_instr_macros.h" + /* * Setup the stack of a new task so it is ready to be placed under the * scheduler control. The registers have to be placed on the stack in @@ -200,12 +202,7 @@ BaseType_t xPortInterruptedFromISRContext(void); /* Multi-core: get current core ID */ static inline uint32_t IRAM_ATTR xPortGetCoreID(void) { - uint32_t id; - __asm__ __volatile__ ( - "rsr.prid %0\n" - " extui %0,%0,13,1" - :"=r"(id)); - return id; + return cpu_hal_get_core_id(); } /* Get tick rate per second */ From cefc71cdcd9a0665f66da3693d588dfdbbd9c668 Mon Sep 17 00:00:00 2001 From: Renz Christian Bagaporo Date: Mon, 3 Feb 2020 18:12:32 +0800 Subject: [PATCH 4/9] bootloader_support: mem-related initializations using cpu abstractions --- components/bootloader_support/CMakeLists.txt | 1 + .../include/bootloader_mem.h | 24 ++++++++++ .../bootloader_support/src/bootloader_mem.c | 48 +++++++++++++++++++ .../src/esp32/bootloader_esp32.c | 8 ++-- .../src/esp32s2/bootloader_esp32s2.c | 5 +- components/esp32/cpu_start.c | 9 ++-- components/esp32s2/cpu_start.c | 3 +- components/soc/include/soc/cpu.h | 45 ----------------- 8 files changed, 88 insertions(+), 55 deletions(-) create mode 100644 components/bootloader_support/include/bootloader_mem.h create mode 100644 components/bootloader_support/src/bootloader_mem.c diff --git a/components/bootloader_support/CMakeLists.txt b/components/bootloader_support/CMakeLists.txt index a207084d00..9d208c8627 100644 --- a/components/bootloader_support/CMakeLists.txt +++ b/components/bootloader_support/CMakeLists.txt @@ -2,6 +2,7 @@ set(srcs "src/bootloader_clock.c" "src/bootloader_common.c" "src/bootloader_flash.c" + "src/bootloader_mem.c" "src/bootloader_random.c" "src/bootloader_utility.c" "src/esp_image_format.c" diff --git a/components/bootloader_support/include/bootloader_mem.h b/components/bootloader_support/include/bootloader_mem.h new file mode 100644 index 0000000000..81c1b4ce79 --- /dev/null +++ b/components/bootloader_support/include/bootloader_mem.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 + +#ifdef __cplusplus +extern "C" { +#endif + +void bootloader_init_mem(void); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/components/bootloader_support/src/bootloader_mem.c b/components/bootloader_support/src/bootloader_mem.c new file mode 100644 index 0000000000..e5a2218cc9 --- /dev/null +++ b/components/bootloader_support/src/bootloader_mem.c @@ -0,0 +1,48 @@ +// 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 "xtensa/config/core.h" +#include "hal/cpu_hal.h" +#include "hal/mpu_hal.h" +#include "hal/mpu_types.h" +#include "soc/mpu_caps.h" +#include "bootloader_mem.h" +#include "xt_instr_macros.h" +#include "xtensa/config/specreg.h" + +static inline void cpu_configure_region_protection(void) +{ + /* Currently, the only supported chips esp32 and esp32s2 + * have the same configuration. Move this to the port layer once + * more chips with different configurations are supported. + * + * Both chips have the address space divided into 8 regions, 512MB each. + */ + const int illegal_regions[] = {0, 4, 5, 6, 7}; // 0x00000000, 0x80000000, 0xa0000000, 0xc0000000, 0xe0000000 + for (int i = 0; i < sizeof(illegal_regions) / sizeof(illegal_regions[0]); ++i) { + mpu_hal_set_region_access(illegal_regions[i], MPU_REGION_ILLEGAL); + } + + mpu_hal_set_region_access(1, MPU_REGION_RW); // 0x20000000 +} + +void bootloader_init_mem(void) +{ + cpu_hal_init_hwloop(); + + // protect memory region + cpu_configure_region_protection(); +} \ No newline at end of file diff --git a/components/bootloader_support/src/esp32/bootloader_esp32.c b/components/bootloader_support/src/esp32/bootloader_esp32.c index cf0572f407..6a06d8cd14 100644 --- a/components/bootloader_support/src/esp32/bootloader_esp32.c +++ b/components/bootloader_support/src/esp32/bootloader_esp32.c @@ -22,6 +22,7 @@ #include "bootloader_clock.h" #include "bootloader_common.h" #include "bootloader_flash_config.h" +#include "bootloader_mem.h" #include "soc/cpu.h" #include "soc/dport_reg.h" @@ -426,10 +427,9 @@ void abort(void) esp_err_t bootloader_init(void) { esp_err_t ret = ESP_OK; - // workaround for tensilica erratum572 - cpu_init_memctl(); - // protect memory region - cpu_configure_region_protection(); + + bootloader_init_mem(); + // check that static RAM is after the stack #ifndef NDEBUG { diff --git a/components/bootloader_support/src/esp32s2/bootloader_esp32s2.c b/components/bootloader_support/src/esp32s2/bootloader_esp32s2.c index 0c16ff1294..2a26524375 100644 --- a/components/bootloader_support/src/esp32s2/bootloader_esp32s2.c +++ b/components/bootloader_support/src/esp32s2/bootloader_esp32s2.c @@ -25,6 +25,7 @@ #include "bootloader_init.h" #include "bootloader_clock.h" #include "bootloader_flash_config.h" +#include "bootloader_mem.h" #include "esp32s2/rom/cache.h" #include "esp32s2/rom/ets_sys.h" @@ -349,7 +350,9 @@ esp_err_t bootloader_init(void) esp_err_t ret = ESP_OK; bootloader_super_wdt_auto_feed(); // protect memory region - cpu_configure_region_protection(); + + bootloader_init_mem(); + /* 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 6ecd1eeb17..61060c5f38 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -69,6 +69,7 @@ #include "esp_ota_ops.h" #include "esp_efuse.h" #include "bootloader_flash_config.h" +#include "bootloader_mem.h" #ifdef CONFIG_APP_BUILD_TYPE_ELF_RAM #include "esp32/rom/efuse.h" @@ -126,8 +127,8 @@ void IRAM_ATTR call_start_cpu0(void) #else RESET_REASON rst_reas[2]; #endif - cpu_configure_region_protection(); - cpu_init_memctl(); + + bootloader_init_mem(); //Move exception vectors to IRAM asm volatile (\ @@ -277,8 +278,8 @@ void IRAM_ATTR call_start_cpu1(void) ::"r"(&_init_start)); ets_set_appcpu_boot_addr(0); - cpu_configure_region_protection(); - cpu_init_memctl(); + + bootloader_init_mem(); #if CONFIG_ESP_CONSOLE_UART_NONE ets_install_putc1(NULL); diff --git a/components/esp32s2/cpu_start.c b/components/esp32s2/cpu_start.c index f25cb3b075..ae18101fc3 100644 --- a/components/esp32s2/cpu_start.c +++ b/components/esp32s2/cpu_start.c @@ -69,6 +69,7 @@ #include "esp_private/pm_impl.h" #include "trax.h" #include "esp_efuse.h" +#include "bootloader_mem.h" #define STRINGIFY(s) STRINGIFY2(s) #define STRINGIFY2(s) #s @@ -110,7 +111,7 @@ void IRAM_ATTR call_start_cpu0(void) { RESET_REASON rst_reas; - cpu_configure_region_protection(); + bootloader_init_mem(); //Move exception vectors to IRAM asm volatile (\ diff --git a/components/soc/include/soc/cpu.h b/components/soc/include/soc/cpu.h index f680b8ff7a..d019706101 100644 --- a/components/soc/include/soc/cpu.h +++ b/components/soc/include/soc/cpu.h @@ -38,51 +38,6 @@ static inline void *get_sp(void) return cpu_hal_get_sp(); } -/* Functions to set page attributes for Region Protection option in the CPU. - * See Xtensa ISA Reference manual for explanation of arguments (section 4.6.3.2). - */ - -static inline void cpu_write_dtlb(uint32_t vpn, unsigned attr) -{ - asm volatile ("wdtlb %1, %0; dsync\n" :: "r" (vpn), "r" (attr)); -} - - -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(void) -{ -#if XCHAL_ERRATUM_572 - uint32_t memctl = XCHAL_CACHE_MEMCTL_DEFAULT; - WSR(MEMCTL, memctl); -#endif // XCHAL_ERRATUM_572 -} - -/** - * @brief Configure memory region protection - * - * Make page 0 access raise an exception. - * Also protect some other unused pages so we can catch weirdness. - * Useful attribute values: - * 0 — cached, RW - * 2 — bypass cache, RWX (default value after CPU reset) - * 15 — no access, raise exception - */ - -static inline void cpu_configure_region_protection(void) -{ - const uint32_t pages_to_protect[] = {0x00000000, 0x80000000, 0xa0000000, 0xc0000000, 0xe0000000}; - for (int i = 0; i < sizeof(pages_to_protect)/sizeof(pages_to_protect[0]); ++i) { - cpu_write_dtlb(pages_to_protect[i], 0xf); - cpu_write_itlb(pages_to_protect[i], 0xf); - } - cpu_write_dtlb(0x20000000, 0); - cpu_write_itlb(0x20000000, 0); -} - /** * @brief Stall CPU using RTC controller * @param cpu_id ID of the CPU to stall (0 = PRO, 1 = APP) From 7f864d24adff2d25058d3074b3f02e1e4cfa4a0f Mon Sep 17 00:00:00 2001 From: Renz Christian Bagaporo Date: Mon, 3 Feb 2020 14:58:19 +0800 Subject: [PATCH 5/9] soc: prefer assertions, disabling functions for cpu abstractions Prefer assertions, making available functions only when caps support it for cpu-related abstractions. Changes cpu hal functions to stall, unstall, reset to not accept -1; instead prefering macros that provide the same functionality. --- components/soc/include/hal/cpu_hal.h | 35 +++++++------ components/soc/include/hal/mpu_hal.h | 13 +++-- components/soc/include/hal/soc_hal.h | 36 +++++++++++-- .../soc/soc/esp32/include/soc/soc_caps.h | 2 +- .../soc/soc/esp32s2/include/soc/soc_caps.h | 2 +- components/soc/src/cpu_util.c | 5 ++ components/soc/src/esp32/include/hal/mpu_ll.h | 2 + .../soc/src/esp32s2/include/hal/mpu_ll.h | 2 + .../soc/src/esp32s2/include/hal/soc_ll.h | 14 ----- components/soc/src/hal/cpu_hal.c | 52 +++++-------------- components/soc/src/hal/mpu_hal.c | 18 +++++-- components/soc/src/hal/soc_hal.c | 42 ++++----------- 12 files changed, 109 insertions(+), 114 deletions(-) diff --git a/components/soc/include/hal/cpu_hal.h b/components/soc/include/hal/cpu_hal.h index a9845ab8ad..34e2a7a1e3 100644 --- a/components/soc/include/hal/cpu_hal.h +++ b/components/soc/include/hal/cpu_hal.h @@ -21,6 +21,7 @@ #include "hal/cpu_types.h" #include "hal/cpu_ll.h" +#include "soc/cpu_caps.h" #ifdef __cplusplus extern "C" { @@ -66,56 +67,60 @@ extern "C" { */ #define cpu_hal_break() cpu_ll_break() +#if SOC_CPU_BREAKPOINTS_NUM > 0 + /** * Set and enable breakpoint at an instruction address. * * @note Overwrites previously set breakpoint with same breakpoint ID. * - * @param id breakpoint to set [0..SOC_CPU_BREAKPOINT_NUM - 1] + * @param id breakpoint to set [0..SOC_CPU_BREAKPOINTS_NUM - 1] * @param addr address to set a breakpoint on - * - * @return ESP_ERR_INVALID_ARG invalid breakpoint id or addr - * @return ESP_ERR_NOT_SUPPORTED processor does not support breakpoints + * * @return ESP_OK success + * @return others fail */ esp_err_t cpu_hal_set_breakpoint(int id, const void* addr); /** * Clear and disable breakpoint. * - * @param id breakpoint to clear [0..SOC_CPU_BREAKPOINT_NUM - 1] + * @param id breakpoint to clear [0..SOC_CPU_BREAKPOINTS_NUM - 1] * - * @return ESP_ERR_INVALID_ARG invalid breakpoint id - * @return ESP_ERR_NOT_SUPPORTED processor does not support breakpoints * @return ESP_OK success + * @return others fail */ esp_err_t cpu_hal_clear_breakpoint(int id); +#endif // SOC_CPU_BREAKPOINTS_NUM > 0 + +#if SOC_CPU_WATCHPOINTS_NUM > 0 + /** * Set and enable a watchpoint, specifying the memory range and trigger operation. * - * @param id watchpoint to set [0..SOC_CPU_WATCHPOINT_NUM - 1] + * @param id watchpoint to set [0..SOC_CPU_WATCHPOINTS_NUM - 1] * @param addr starting address * @param size number of bytes from starting address to watch * @param trigger operation on specified memory range that triggers the watchpoint (read, write, read/write) - * - * @return ESP_ERR_INVALID_ARG invalid watchpoint id - * @return ESP_ERR_NOT_SUPPORTED processor does not support watchpoints + * * @return ESP_OK success + * @return others fail */ esp_err_t cpu_hal_set_watchpoint(int id, const void* addr, size_t size, watchpoint_trigger_t trigger); /** * Clear and disable watchpoint. * - * @param id watchpoint to clear [0..SOC_CPU_WATCHPOINT_NUM - 1] - * - * @return ESP_ERR_INVALID_ARG invalid watchpoint id - * @return ESP_ERR_NOT_SUPPORTED processor does not support watchpoints + * @param id watchpoint to clear [0..SOC_CPU_WATCHPOINTS_NUM - 1] + * * @return ESP_OK success + * @return others fail */ esp_err_t cpu_hal_clear_watchpoint(int id); +#endif // SOC_CPU_WATCHPOINTS_NUM > 0 + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/components/soc/include/hal/mpu_hal.h b/components/soc/include/hal/mpu_hal.h index 25699893b9..4f96a43628 100644 --- a/components/soc/include/hal/mpu_hal.h +++ b/components/soc/include/hal/mpu_hal.h @@ -17,7 +17,10 @@ #include "esp_err.h" #include "hal/mpu_types.h" -#include "soc/mpu_caps.h" + +#ifdef __cplusplus +extern "C" { +#endif /** * Specify the type of access allowed on a memory region. @@ -26,7 +29,11 @@ * the region divisions is predefined in hardware which is likely reflected in LL implementation. * @param access type of access allowed * - * @return ESP_ERR_INVALID_ARG invalid id or access * @return ESP_OK success + * @return others fail */ -esp_err_t mpu_hal_set_region_access(int id, mpu_access_t access); \ No newline at end of file +esp_err_t mpu_hal_set_region_access(int id, mpu_access_t access); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/components/soc/include/hal/soc_hal.h b/components/soc/include/hal/soc_hal.h index d8554daf7b..2680f8da31 100644 --- a/components/soc/include/hal/soc_hal.h +++ b/components/soc/include/hal/soc_hal.h @@ -17,15 +17,37 @@ #include #include +#include "hal/cpu_hal.h" +#include "soc/soc_caps.h" + #include "esp_err.h" +#ifdef __cplusplus +extern "C" { +#endif + +#if SOC_CPU_CORES_NUM > 1 + +// Utility functions for multicore targets +#define __SOC_HAL_PERFORM_ON_OTHER_CORES(action) { \ + for (int i = 0, cur = cpu_hal_get_core_id(); i < SOC_CPU_CORES_NUM; i++) { \ + if (i != cur) { \ + action(i); \ + } \ + } \ + } + +#define SOC_HAL_STALL_OTHER_CORES() __SOC_HAL_PERFORM_ON_OTHER_CORES(soc_hal_stall_core); +#define SOC_HAL_UNSTALL_OTHER_CORES() __SOC_HAL_PERFORM_ON_OTHER_CORES(soc_hal_unstall_core); +#define SOC_HAL_RESET_OTHER_CORES() __SOC_HAL_PERFORM_ON_OTHER_CORES(soc_hal_reset_core); + /** * Stall the specified CPU core. * * @note Has no effect if the core is already stalled - does not return an * ESP_ERR_INVALID_STATE. * - * @param core core to stall [0..SOC_CPU_CORES_NUM - 1]; if core < 0 is specified, all other cores are stalled + * @param core core to stall [0..SOC_CPU_CORES_NUM - 1] * * @return ESP_ERR_INVALID_ARG core argument invalid * @return ESP_OK success @@ -38,19 +60,25 @@ esp_err_t soc_hal_stall_core(int core); * @note Has no effect if the core is already unstalled - does not return an * ESP_ERR_INVALID_STATE. * - * @param core core to unstall [0..SOC_CPU_CORES_NUM - 1]; if core < 0 is specified, all other cores are unstalled + * @param core core to unstall [0..SOC_CPU_CORES_NUM - 1] * * @return ESP_ERR_INVALID_ARG core argument invalid * @return ESP_OK success */ esp_err_t soc_hal_unstall_core(int core); +#endif // SOC_CPU_CORES_NUM > 1 + /** * Reset the specified core. * - * @param core core to reset [0..SOC_CPU_CORES_NUM - 1]; if core < 0 is specified, all other cores are reset + * @param core core to reset [0..SOC_CPU_CORES_NUM - 1] * * @return ESP_ERR_INVALID_ARG core argument invalid * @return ESP_OK success */ -esp_err_t soc_hal_reset_core(int core); \ No newline at end of file +esp_err_t soc_hal_reset_core(int core); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/components/soc/soc/esp32/include/soc/soc_caps.h b/components/soc/soc/esp32/include/soc/soc_caps.h index b6a052da0b..bb01067af8 100644 --- a/components/soc/soc/esp32/include/soc/soc_caps.h +++ b/components/soc/soc/esp32/include/soc/soc_caps.h @@ -12,4 +12,4 @@ #define SOC_CAN_SUPPORTED 1 #define SOC_EMAC_SUPPORTED 1 -#define SOC_CPU_CORES_NUM 2 +#define SOC_CPU_CORES_NUM 2 diff --git a/components/soc/soc/esp32s2/include/soc/soc_caps.h b/components/soc/soc/esp32s2/include/soc/soc_caps.h index f011597850..0b24ddbb14 100644 --- a/components/soc/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/soc/esp32s2/include/soc/soc_caps.h @@ -5,4 +5,4 @@ #pragma once -#define SOC_CPU_CORES_NUM 1 \ No newline at end of file +#define SOC_CPU_CORES_NUM 1 \ No newline at end of file diff --git a/components/soc/src/cpu_util.c b/components/soc/src/cpu_util.c index 61d7034186..8e947d15c8 100644 --- a/components/soc/src/cpu_util.c +++ b/components/soc/src/cpu_util.c @@ -23,17 +23,22 @@ #include "hal/cpu_types.h" #include "hal/soc_hal.h" +#include "soc/soc_caps.h" #include "sdkconfig.h" void IRAM_ATTR esp_cpu_stall(int cpu_id) { +#if SOC_CPU_CORES_NUM > 1 soc_hal_stall_core(cpu_id); +#endif } void IRAM_ATTR esp_cpu_unstall(int cpu_id) { +#if SOC_CPU_CORES_NUM > 1 soc_hal_unstall_core(cpu_id); +#endif } void IRAM_ATTR esp_cpu_reset(int cpu_id) diff --git a/components/soc/src/esp32/include/hal/mpu_ll.h b/components/soc/src/esp32/include/hal/mpu_ll.h index 1735f46d7a..b11e11a7d8 100644 --- a/components/soc/src/esp32/include/hal/mpu_ll.h +++ b/components/soc/src/esp32/include/hal/mpu_ll.h @@ -14,6 +14,8 @@ #include +#include "soc/mpu_caps.h" + #include "xt_instr_macros.h" #ifdef __cplusplus diff --git a/components/soc/src/esp32s2/include/hal/mpu_ll.h b/components/soc/src/esp32s2/include/hal/mpu_ll.h index 1735f46d7a..b11e11a7d8 100644 --- a/components/soc/src/esp32s2/include/hal/mpu_ll.h +++ b/components/soc/src/esp32s2/include/hal/mpu_ll.h @@ -14,6 +14,8 @@ #include +#include "soc/mpu_caps.h" + #include "xt_instr_macros.h" #ifdef __cplusplus diff --git a/components/soc/src/esp32s2/include/hal/soc_ll.h b/components/soc/src/esp32s2/include/hal/soc_ll.h index 13d0aabb05..e61651581e 100644 --- a/components/soc/src/esp32s2/include/hal/soc_ll.h +++ b/components/soc/src/esp32s2/include/hal/soc_ll.h @@ -21,20 +21,6 @@ extern "C" { #endif -static inline void soc_ll_stall_core(int core) -{ - CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, RTC_CNTL_SW_STALL_PROCPU_C1_M); - SET_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, 0x21 << RTC_CNTL_SW_STALL_PROCPU_C1_S); - CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_STALL_PROCPU_C0_M); - SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, 2 << RTC_CNTL_SW_STALL_PROCPU_C0_S); -} - -static inline void soc_ll_unstall_core(int core) -{ - CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, RTC_CNTL_SW_STALL_PROCPU_C1_M); - CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_STALL_PROCPU_C0_M); -} - static inline void soc_ll_reset_core(int core) { SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_PROCPU_RST_M); diff --git a/components/soc/src/hal/cpu_hal.c b/components/soc/src/hal/cpu_hal.c index 87b7c959c7..ac56b4c268 100644 --- a/components/soc/src/hal/cpu_hal.c +++ b/components/soc/src/hal/cpu_hal.c @@ -21,46 +21,30 @@ #include "soc/cpu_caps.h" +#if SOC_CPU_BREAKPOINTS_NUM > 0 esp_err_t cpu_hal_set_breakpoint(int id, const void* addr) { -#if SOC_CPU_BREAKPOINTS_NUM != 0 - if (id >= SOC_CPU_BREAKPOINTS_NUM || id < 0) { - return ESP_ERR_INVALID_ARG; - } - + assert(id < SOC_CPU_BREAKPOINTS_NUM && id >= 0); cpu_ll_set_breakpoint(id, cpu_ll_ptr_to_pc(addr)); - return ESP_OK; -#else - return ESP_ERR_NOT_SUPPORTED; -#endif } esp_err_t cpu_hal_clear_breakpoint(int id) { -#if SOC_CPU_BREAKPOINTS_NUM > 0 - if (id >= SOC_CPU_BREAKPOINTS_NUM || id < 0) { - return ESP_ERR_INVALID_ARG; - } - + assert(id < SOC_CPU_BREAKPOINTS_NUM && id >= 0); cpu_ll_clear_breakpoint(id); - return ESP_OK; -#else - return ESP_ERR_NOT_SUPPORTED; -#endif } +#endif // SOC_CPU_BREAKPOINTS_NUM > 0 +#if SOC_CPU_WATCHPOINTS_NUM > 0 esp_err_t cpu_hal_set_watchpoint(int id, const void* addr, size_t size, watchpoint_trigger_t trigger) { -#if SOC_CPU_WATCHPOINTS_NUM > 0 - if (id >= SOC_CPU_WATCHPOINTS_NUM || id < 0) { - return ESP_ERR_INVALID_ARG; - } - - if (size > SOC_CPU_WATCHPOINT_SIZE) { - return ESP_ERR_INVALID_ARG; - } + assert(id < SOC_CPU_WATCHPOINTS_NUM && id >= 0); + assert(size <= SOC_CPU_WATCHPOINT_SIZE); + assert(trigger == WATCHPOINT_TRIGGER_ON_RO || + trigger == WATCHPOINT_TRIGGER_ON_WO || + trigger == WATCHPOINT_TRIGGER_ON_RW); bool on_read = false, on_write = false; @@ -75,22 +59,12 @@ esp_err_t cpu_hal_set_watchpoint(int id, const void* addr, size_t size, watchpoi cpu_ll_set_watchpoint(id, addr, size, on_read, on_write); return ESP_OK; -#else - return ESP_ERR_NOT_SUPPORTED; -#endif } esp_err_t cpu_hal_clear_watchpoint(int id) { -#if SOC_CPU_WATCHPOINTS_NUM > 0 - if (id >= SOC_CPU_WATCHPOINTS_NUM || id < 0) { - return ESP_ERR_INVALID_ARG; - } - + assert(id < SOC_CPU_WATCHPOINTS_NUM && id >= 0); cpu_ll_clear_watchpoint(id); - return ESP_OK; -#else - return ESP_ERR_NOT_SUPPORTED; -#endif -} \ No newline at end of file +} +#endif // SOC_CPU_WATCHPOINTS_NUM > 0 \ No newline at end of file diff --git a/components/soc/src/hal/mpu_hal.c b/components/soc/src/hal/mpu_hal.c index 01bc9db124..b075a85986 100644 --- a/components/soc/src/hal/mpu_hal.c +++ b/components/soc/src/hal/mpu_hal.c @@ -21,11 +21,22 @@ #include "hal/mpu_ll.h" #include "hal/mpu_types.h" +#include "soc/mpu_caps.h" + esp_err_t mpu_hal_set_region_access(int id, mpu_access_t access) { - if (id > SOC_MPU_REGIONS_MAX_NUM || id < 0) { - return ESP_ERR_INVALID_ARG; - } + assert(id < SOC_MPU_REGIONS_MAX_NUM && id >= 0); + assert( +#if SOC_MPU_REGION_RO_SUPPORTED + access == MPU_REGION_RO || +#endif +#if SOC_MPU_REGION_WO_SUPPORTED + access == MPU_REGION_WO || +#endif + access == MPU_REGION_RW || + access == MPU_REGION_X || + access == MPU_REGION_RWX || + access == MPU_REGION_ILLEGAL); uint32_t addr = cpu_ll_id_to_addr(id); @@ -51,7 +62,6 @@ esp_err_t mpu_hal_set_region_access(int id, mpu_access_t access) mpu_ll_set_region_rwx(addr); break; default: - return ESP_ERR_INVALID_ARG; break; } diff --git a/components/soc/src/hal/soc_hal.c b/components/soc/src/hal/soc_hal.c index ea17fc6bbe..a923f45eff 100644 --- a/components/soc/src/hal/soc_hal.c +++ b/components/soc/src/hal/soc_hal.c @@ -16,55 +16,31 @@ #include "esp_err.h" -#include "hal/cpu_hal.h" #include "hal/soc_hal.h" #include "hal/soc_ll.h" #include "soc/soc_caps.h" -#define CHECK_CORE(core) { if ((core) > SOC_CPU_CORES_NUM) return ESP_ERR_INVALID_ARG; } -#define PERFORM_ON_OTHER_CORES(action) { \ - for (int i = 0, cur = cpu_hal_get_core_id(); i < SOC_CPU_CORES_NUM; i++) { \ - if (i != cur) { \ - action(i); \ - } \ - } \ - } +#if SOC_CPU_CORES_NUM > 1 esp_err_t soc_hal_stall_core(int core) { - CHECK_CORE(core); - - if (core < 0) { - PERFORM_ON_OTHER_CORES(soc_hal_stall_core); - } else { - soc_ll_stall_core(core); - } - + assert(core < SOC_CPU_CORES_NUM && core >= 0); + soc_ll_stall_core(core); return ESP_OK; } esp_err_t soc_hal_unstall_core(int core) { - CHECK_CORE(core); - - if (core < 0) { - PERFORM_ON_OTHER_CORES(soc_hal_unstall_core); - } else { - soc_ll_unstall_core(core); - } - + assert(core < SOC_CPU_CORES_NUM && core >= 0); + soc_ll_unstall_core(core); return ESP_OK; } +#endif // SOC_CPU_CORES_NUM > 1 + esp_err_t soc_hal_reset_core(int core) { - CHECK_CORE(core); - - if (core < 0) { - PERFORM_ON_OTHER_CORES(soc_hal_reset_core); - } else { - soc_ll_reset_core(core); - } - + assert(core < SOC_CPU_CORES_NUM && core >= 0); + soc_ll_reset_core(core); return ESP_OK; } \ No newline at end of file From 7386ac6d1562891786a12a5137d2545c11fd52fe Mon Sep 17 00:00:00 2001 From: Renz Christian Bagaporo Date: Mon, 3 Feb 2020 17:57:10 +0800 Subject: [PATCH 6/9] esp32s2: remove calls to stall/unstall other core --- components/esp32s2/panic.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/components/esp32s2/panic.c b/components/esp32s2/panic.c index 5c38f1b04c..b4436397d4 100644 --- a/components/esp32s2/panic.c +++ b/components/esp32s2/panic.c @@ -195,10 +195,6 @@ static inline void disableAllWdts(void); //The fact that we've panic'ed probably means the other CPU is now running wild, possibly //messing up the serial output, so we stall it here. -static void haltOtherCore(void) -{ - esp_cpu_stall( xPortGetCoreID() == 0 ? 1 : 0 ); -} static void setFirstBreakpoint(uint32_t pc) @@ -324,7 +320,6 @@ void panicHandler(XtExcFrame *frame) esp_reset_reason_set_hint(ESP_RST_INT_WDT); } - haltOtherCore(); panicPutStr("Guru Meditation Error: Core "); panicPutDec(core_id); panicPutStr(" panic'ed ("); @@ -394,7 +389,6 @@ void panicHandler(XtExcFrame *frame) void xt_unhandled_exception(XtExcFrame *frame) { - haltOtherCore(); if (!abort_called) { panicPutStr("Guru Meditation Error: Core "); panicPutDec(xPortGetCoreID()); @@ -477,8 +471,6 @@ static void esp_panic_dig_reset(void) uart_tx_wait_idle(CONFIG_ESP_CONSOLE_UART_NUM); // switch to XTAL (otherwise we will keep running from the PLL) rtc_clk_cpu_freq_set_xtal(); - // reset the digital part - esp_cpu_unstall(PRO_CPU_NUM); SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_SYS_RST); while (true) { ; From d5c123c1f5ce5723ef0fdab28b5ebe92725e73eb Mon Sep 17 00:00:00 2001 From: Renz Christian Bagaporo Date: Mon, 3 Feb 2020 19:14:48 +0800 Subject: [PATCH 7/9] soc: use own macro to assert proper args for cpu abstractions --- components/soc/src/hal/cpu_hal.c | 15 +++++++++------ components/soc/src/hal/mpu_hal.c | 6 ++++-- components/soc/src/hal/soc_hal.c | 9 ++++++--- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/components/soc/src/hal/cpu_hal.c b/components/soc/src/hal/cpu_hal.c index ac56b4c268..b44270704f 100644 --- a/components/soc/src/hal/cpu_hal.c +++ b/components/soc/src/hal/cpu_hal.c @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include "esp_err.h" @@ -21,17 +22,19 @@ #include "soc/cpu_caps.h" +#define CHECK(cond) { if (!(cond)) abort(); } + #if SOC_CPU_BREAKPOINTS_NUM > 0 esp_err_t cpu_hal_set_breakpoint(int id, const void* addr) { - assert(id < SOC_CPU_BREAKPOINTS_NUM && id >= 0); + CHECK(id < SOC_CPU_BREAKPOINTS_NUM && id >= 0); cpu_ll_set_breakpoint(id, cpu_ll_ptr_to_pc(addr)); return ESP_OK; } esp_err_t cpu_hal_clear_breakpoint(int id) { - assert(id < SOC_CPU_BREAKPOINTS_NUM && id >= 0); + CHECK(id < SOC_CPU_BREAKPOINTS_NUM && id >= 0); cpu_ll_clear_breakpoint(id); return ESP_OK; } @@ -40,9 +43,9 @@ esp_err_t cpu_hal_clear_breakpoint(int id) #if SOC_CPU_WATCHPOINTS_NUM > 0 esp_err_t cpu_hal_set_watchpoint(int id, const void* addr, size_t size, watchpoint_trigger_t trigger) { - assert(id < SOC_CPU_WATCHPOINTS_NUM && id >= 0); - assert(size <= SOC_CPU_WATCHPOINT_SIZE); - assert(trigger == WATCHPOINT_TRIGGER_ON_RO || + CHECK(id < SOC_CPU_WATCHPOINTS_NUM && id >= 0); + CHECK(size <= SOC_CPU_WATCHPOINT_SIZE); + CHECK(trigger == WATCHPOINT_TRIGGER_ON_RO || trigger == WATCHPOINT_TRIGGER_ON_WO || trigger == WATCHPOINT_TRIGGER_ON_RW); @@ -63,7 +66,7 @@ esp_err_t cpu_hal_set_watchpoint(int id, const void* addr, size_t size, watchpoi esp_err_t cpu_hal_clear_watchpoint(int id) { - assert(id < SOC_CPU_WATCHPOINTS_NUM && id >= 0); + CHECK(id < SOC_CPU_WATCHPOINTS_NUM && id >= 0); cpu_ll_clear_watchpoint(id); return ESP_OK; } diff --git a/components/soc/src/hal/mpu_hal.c b/components/soc/src/hal/mpu_hal.c index b075a85986..c721aeb136 100644 --- a/components/soc/src/hal/mpu_hal.c +++ b/components/soc/src/hal/mpu_hal.c @@ -23,10 +23,12 @@ #include "soc/mpu_caps.h" +#define CHECK(cond) { if (!(cond)) abort(); } + esp_err_t mpu_hal_set_region_access(int id, mpu_access_t access) { - assert(id < SOC_MPU_REGIONS_MAX_NUM && id >= 0); - assert( + CHECK(id < SOC_MPU_REGIONS_MAX_NUM && id >= 0); + CHECK( #if SOC_MPU_REGION_RO_SUPPORTED access == MPU_REGION_RO || #endif diff --git a/components/soc/src/hal/soc_hal.c b/components/soc/src/hal/soc_hal.c index a923f45eff..69c29389de 100644 --- a/components/soc/src/hal/soc_hal.c +++ b/components/soc/src/hal/soc_hal.c @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include "esp_err.h" @@ -20,18 +21,20 @@ #include "hal/soc_ll.h" #include "soc/soc_caps.h" +#define CHECK(cond) { if (!(cond)) abort(); } + #if SOC_CPU_CORES_NUM > 1 esp_err_t soc_hal_stall_core(int core) { - assert(core < SOC_CPU_CORES_NUM && core >= 0); + CHECK(core < SOC_CPU_CORES_NUM && core >= 0); soc_ll_stall_core(core); return ESP_OK; } esp_err_t soc_hal_unstall_core(int core) { - assert(core < SOC_CPU_CORES_NUM && core >= 0); + CHECK(core < SOC_CPU_CORES_NUM && core >= 0); soc_ll_unstall_core(core); return ESP_OK; } @@ -40,7 +43,7 @@ esp_err_t soc_hal_unstall_core(int core) esp_err_t soc_hal_reset_core(int core) { - assert(core < SOC_CPU_CORES_NUM && core >= 0); + CHECK(core < SOC_CPU_CORES_NUM && core >= 0); soc_ll_reset_core(core); return ESP_OK; } \ No newline at end of file From f75cb2ef0020f250952ef7d7c79747fc1faf0b13 Mon Sep 17 00:00:00 2001 From: Renz Christian Bagaporo Date: Tue, 18 Feb 2020 15:39:04 +0500 Subject: [PATCH 8/9] soc: change cpu stall, unstall, and reset core to not return values --- components/soc/include/hal/soc_hal.h | 15 +++------------ components/soc/src/hal/soc_hal.c | 9 +++------ 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/components/soc/include/hal/soc_hal.h b/components/soc/include/hal/soc_hal.h index 2680f8da31..bc2d99bf66 100644 --- a/components/soc/include/hal/soc_hal.h +++ b/components/soc/include/hal/soc_hal.h @@ -48,11 +48,8 @@ extern "C" { * ESP_ERR_INVALID_STATE. * * @param core core to stall [0..SOC_CPU_CORES_NUM - 1] - * - * @return ESP_ERR_INVALID_ARG core argument invalid - * @return ESP_OK success */ -esp_err_t soc_hal_stall_core(int core); +void soc_hal_stall_core(int core); /** * Unstall the specified CPU core. @@ -61,11 +58,8 @@ esp_err_t soc_hal_stall_core(int core); * ESP_ERR_INVALID_STATE. * * @param core core to unstall [0..SOC_CPU_CORES_NUM - 1] - * - * @return ESP_ERR_INVALID_ARG core argument invalid - * @return ESP_OK success */ -esp_err_t soc_hal_unstall_core(int core); +void soc_hal_unstall_core(int core); #endif // SOC_CPU_CORES_NUM > 1 @@ -73,11 +67,8 @@ esp_err_t soc_hal_unstall_core(int core); * Reset the specified core. * * @param core core to reset [0..SOC_CPU_CORES_NUM - 1] - * - * @return ESP_ERR_INVALID_ARG core argument invalid - * @return ESP_OK success */ -esp_err_t soc_hal_reset_core(int core); +void soc_hal_reset_core(int core); #ifdef __cplusplus } diff --git a/components/soc/src/hal/soc_hal.c b/components/soc/src/hal/soc_hal.c index 69c29389de..d2e032daf9 100644 --- a/components/soc/src/hal/soc_hal.c +++ b/components/soc/src/hal/soc_hal.c @@ -25,25 +25,22 @@ #if SOC_CPU_CORES_NUM > 1 -esp_err_t soc_hal_stall_core(int core) +void soc_hal_stall_core(int core) { CHECK(core < SOC_CPU_CORES_NUM && core >= 0); soc_ll_stall_core(core); - return ESP_OK; } -esp_err_t soc_hal_unstall_core(int core) +void soc_hal_unstall_core(int core) { CHECK(core < SOC_CPU_CORES_NUM && core >= 0); soc_ll_unstall_core(core); - return ESP_OK; } #endif // SOC_CPU_CORES_NUM > 1 -esp_err_t soc_hal_reset_core(int core) +void soc_hal_reset_core(int core) { CHECK(core < SOC_CPU_CORES_NUM && core >= 0); soc_ll_reset_core(core); - return ESP_OK; } \ No newline at end of file From d46989efa3fc7f856285298bcd1463aaf1baf39f Mon Sep 17 00:00:00 2001 From: Renz Christian Bagaporo Date: Fri, 21 Feb 2020 08:27:14 +0500 Subject: [PATCH 9/9] soc: remove param checking in cpu related abstractions --- components/soc/include/hal/cpu_hal.h | 20 ++++---------------- components/soc/include/hal/mpu_hal.h | 5 +---- components/soc/include/hal/soc_hal.h | 6 +++--- components/soc/src/cpu_util.c | 3 ++- components/soc/src/hal/cpu_hal.c | 24 ++++-------------------- components/soc/src/hal/mpu_hal.c | 19 +------------------ components/soc/src/hal/soc_hal.c | 14 +------------- 7 files changed, 16 insertions(+), 75 deletions(-) diff --git a/components/soc/include/hal/cpu_hal.h b/components/soc/include/hal/cpu_hal.h index 34e2a7a1e3..adda25de05 100644 --- a/components/soc/include/hal/cpu_hal.h +++ b/components/soc/include/hal/cpu_hal.h @@ -76,21 +76,15 @@ extern "C" { * * @param id breakpoint to set [0..SOC_CPU_BREAKPOINTS_NUM - 1] * @param addr address to set a breakpoint on - * - * @return ESP_OK success - * @return others fail */ -esp_err_t cpu_hal_set_breakpoint(int id, const void* addr); +void cpu_hal_set_breakpoint(int id, const void* addr); /** * Clear and disable breakpoint. * * @param id breakpoint to clear [0..SOC_CPU_BREAKPOINTS_NUM - 1] - * - * @return ESP_OK success - * @return others fail */ -esp_err_t cpu_hal_clear_breakpoint(int id); +void cpu_hal_clear_breakpoint(int id); #endif // SOC_CPU_BREAKPOINTS_NUM > 0 @@ -103,21 +97,15 @@ esp_err_t cpu_hal_clear_breakpoint(int id); * @param addr starting address * @param size number of bytes from starting address to watch * @param trigger operation on specified memory range that triggers the watchpoint (read, write, read/write) - * - * @return ESP_OK success - * @return others fail */ -esp_err_t cpu_hal_set_watchpoint(int id, const void* addr, size_t size, watchpoint_trigger_t trigger); +void cpu_hal_set_watchpoint(int id, const void* addr, size_t size, watchpoint_trigger_t trigger); /** * Clear and disable watchpoint. * * @param id watchpoint to clear [0..SOC_CPU_WATCHPOINTS_NUM - 1] - * - * @return ESP_OK success - * @return others fail */ -esp_err_t cpu_hal_clear_watchpoint(int id); +void cpu_hal_clear_watchpoint(int id); #endif // SOC_CPU_WATCHPOINTS_NUM > 0 diff --git a/components/soc/include/hal/mpu_hal.h b/components/soc/include/hal/mpu_hal.h index 4f96a43628..0614de9eb8 100644 --- a/components/soc/include/hal/mpu_hal.h +++ b/components/soc/include/hal/mpu_hal.h @@ -28,11 +28,8 @@ extern "C" { * @param id index to the region table; on targets not SOC_MPU_CONFIGURABLE_REGIONS_SUPPORTED, * the region divisions is predefined in hardware which is likely reflected in LL implementation. * @param access type of access allowed - * - * @return ESP_OK success - * @return others fail */ -esp_err_t mpu_hal_set_region_access(int id, mpu_access_t access); +void mpu_hal_set_region_access(int id, mpu_access_t access); #ifdef __cplusplus } diff --git a/components/soc/include/hal/soc_hal.h b/components/soc/include/hal/soc_hal.h index bc2d99bf66..6a4ab30c0a 100644 --- a/components/soc/include/hal/soc_hal.h +++ b/components/soc/include/hal/soc_hal.h @@ -17,8 +17,9 @@ #include #include -#include "hal/cpu_hal.h" #include "soc/soc_caps.h" +#include "hal/cpu_hal.h" +#include "hal/soc_ll.h" #include "esp_err.h" @@ -27,7 +28,6 @@ extern "C" { #endif #if SOC_CPU_CORES_NUM > 1 - // Utility functions for multicore targets #define __SOC_HAL_PERFORM_ON_OTHER_CORES(action) { \ for (int i = 0, cur = cpu_hal_get_core_id(); i < SOC_CPU_CORES_NUM; i++) { \ @@ -68,7 +68,7 @@ void soc_hal_unstall_core(int core); * * @param core core to reset [0..SOC_CPU_CORES_NUM - 1] */ -void soc_hal_reset_core(int core); +#define soc_hal_reset_core(core) soc_ll_reset_core((core)) #ifdef __cplusplus } diff --git a/components/soc/src/cpu_util.c b/components/soc/src/cpu_util.c index 8e947d15c8..eadeb2f526 100644 --- a/components/soc/src/cpu_util.c +++ b/components/soc/src/cpu_util.c @@ -65,7 +65,8 @@ esp_err_t IRAM_ATTR esp_set_watchpoint(int no, void *adr, int size, int flags) return ESP_ERR_INVALID_ARG; } - return cpu_hal_set_watchpoint(no, adr, size, trigger); + cpu_hal_set_watchpoint(no, adr, size, trigger); + return ESP_OK; } void IRAM_ATTR esp_clear_watchpoint(int no) diff --git a/components/soc/src/hal/cpu_hal.c b/components/soc/src/hal/cpu_hal.c index b44270704f..4b2ca22c9e 100644 --- a/components/soc/src/hal/cpu_hal.c +++ b/components/soc/src/hal/cpu_hal.c @@ -22,33 +22,21 @@ #include "soc/cpu_caps.h" -#define CHECK(cond) { if (!(cond)) abort(); } - #if SOC_CPU_BREAKPOINTS_NUM > 0 -esp_err_t cpu_hal_set_breakpoint(int id, const void* addr) +void cpu_hal_set_breakpoint(int id, const void* addr) { - CHECK(id < SOC_CPU_BREAKPOINTS_NUM && id >= 0); cpu_ll_set_breakpoint(id, cpu_ll_ptr_to_pc(addr)); - return ESP_OK; } -esp_err_t cpu_hal_clear_breakpoint(int id) +void cpu_hal_clear_breakpoint(int id) { - CHECK(id < SOC_CPU_BREAKPOINTS_NUM && id >= 0); cpu_ll_clear_breakpoint(id); - return ESP_OK; } #endif // SOC_CPU_BREAKPOINTS_NUM > 0 #if SOC_CPU_WATCHPOINTS_NUM > 0 -esp_err_t cpu_hal_set_watchpoint(int id, const void* addr, size_t size, watchpoint_trigger_t trigger) +void cpu_hal_set_watchpoint(int id, const void* addr, size_t size, watchpoint_trigger_t trigger) { - CHECK(id < SOC_CPU_WATCHPOINTS_NUM && id >= 0); - CHECK(size <= SOC_CPU_WATCHPOINT_SIZE); - CHECK(trigger == WATCHPOINT_TRIGGER_ON_RO || - trigger == WATCHPOINT_TRIGGER_ON_WO || - trigger == WATCHPOINT_TRIGGER_ON_RW); - bool on_read = false, on_write = false; if (trigger == WATCHPOINT_TRIGGER_ON_RO) { @@ -60,14 +48,10 @@ esp_err_t cpu_hal_set_watchpoint(int id, const void* addr, size_t size, watchpoi } cpu_ll_set_watchpoint(id, addr, size, on_read, on_write); - - return ESP_OK; } -esp_err_t cpu_hal_clear_watchpoint(int id) +void cpu_hal_clear_watchpoint(int id) { - CHECK(id < SOC_CPU_WATCHPOINTS_NUM && id >= 0); cpu_ll_clear_watchpoint(id); - return ESP_OK; } #endif // SOC_CPU_WATCHPOINTS_NUM > 0 \ No newline at end of file diff --git a/components/soc/src/hal/mpu_hal.c b/components/soc/src/hal/mpu_hal.c index c721aeb136..b2cae6b76c 100644 --- a/components/soc/src/hal/mpu_hal.c +++ b/components/soc/src/hal/mpu_hal.c @@ -23,23 +23,8 @@ #include "soc/mpu_caps.h" -#define CHECK(cond) { if (!(cond)) abort(); } - -esp_err_t mpu_hal_set_region_access(int id, mpu_access_t access) +void mpu_hal_set_region_access(int id, mpu_access_t access) { - CHECK(id < SOC_MPU_REGIONS_MAX_NUM && id >= 0); - CHECK( -#if SOC_MPU_REGION_RO_SUPPORTED - access == MPU_REGION_RO || -#endif -#if SOC_MPU_REGION_WO_SUPPORTED - access == MPU_REGION_WO || -#endif - access == MPU_REGION_RW || - access == MPU_REGION_X || - access == MPU_REGION_RWX || - access == MPU_REGION_ILLEGAL); - uint32_t addr = cpu_ll_id_to_addr(id); switch (access) @@ -66,6 +51,4 @@ esp_err_t mpu_hal_set_region_access(int id, mpu_access_t access) default: break; } - - return ESP_OK; } \ No newline at end of file diff --git a/components/soc/src/hal/soc_hal.c b/components/soc/src/hal/soc_hal.c index d2e032daf9..c01ab3e628 100644 --- a/components/soc/src/hal/soc_hal.c +++ b/components/soc/src/hal/soc_hal.c @@ -21,26 +21,14 @@ #include "hal/soc_ll.h" #include "soc/soc_caps.h" -#define CHECK(cond) { if (!(cond)) abort(); } - #if SOC_CPU_CORES_NUM > 1 - void soc_hal_stall_core(int core) { - CHECK(core < SOC_CPU_CORES_NUM && core >= 0); soc_ll_stall_core(core); } void soc_hal_unstall_core(int core) { - CHECK(core < SOC_CPU_CORES_NUM && core >= 0); soc_ll_unstall_core(core); } - -#endif // SOC_CPU_CORES_NUM > 1 - -void soc_hal_reset_core(int core) -{ - CHECK(core < SOC_CPU_CORES_NUM && core >= 0); - soc_ll_reset_core(core); -} \ No newline at end of file +#endif // SOC_CPU_CORES_NUM > 1 \ No newline at end of file