diff --git a/components/esp32/panic.c b/components/esp32/panic.c index a9dafe197..cbf7090a3 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 1209974f8..5c38f1b04 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 853b1ba08..a0da9e8cc 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 7116f7261..eb67fa974 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 000000000..a9845ab8a --- /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 000000000..aee44f6ac --- /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 000000000..25699893b --- /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 000000000..14675a726 --- /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 000000000..d8554daf7 --- /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 82e710bfa..450cd8c8a 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 9d05e7710..df2191e32 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 000000000..fbfd780bd --- /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 000000000..8e12a2b13 --- /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 283c7ae0c..b6a052da0 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 000000000..fbfd780bd --- /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 000000000..8e12a2b13 --- /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 85a465e89..f01159785 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 ed2c6361e..8bfed6205 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 be5ed8b4f..e4c31149f 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 000000000..362de7399 --- /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 000000000..1735f46d7 --- /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 000000000..b83a0756b --- /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 4fc1eb04c..765ef7776 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 000000000..a81775965 --- /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 000000000..1735f46d7 --- /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 000000000..13d0aabb0 --- /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 000000000..87b7c959c --- /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 000000000..0a0bc6dae --- /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 000000000..ea17fc6bb --- /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 000000000..12ab76618 --- /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 0135d4c7f..d35988556 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 000000000..95a6a69b6 --- /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 30e95592a..b63d82b96 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 000000000..9df78f5f2 --- /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