soc: create abstraction for cpu related operations

This commit is contained in:
Renz Christian Bagaporo 2020-01-19 10:02:21 +08:00
parent ac55328efd
commit c9a51bfbb2
34 changed files with 1263 additions and 117 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -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)

View file

@ -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 <stdint.h>
#include <stdbool.h>
#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

View file

@ -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;

View file

@ -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 <stdint.h>
#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);

View file

@ -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 <stdint.h>
#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;

View file

@ -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 <stdint.h>
#include <stdbool.h>
#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);

View file

@ -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
*
*/

View file

@ -21,3 +21,5 @@ entries:
i2c_hal_iram (noflash)
spi_flash_hal_gpspi (noflash)
lldesc (noflash_text)
cpu_hal (noflash)
soc_hal (noflash)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -4,3 +4,5 @@
// include them here.
#pragma once
#define SOC_CPU_CORES_NUM 1

View file

@ -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));
}
}

View file

@ -1,5 +1,4 @@
set(srcs "brownout_hal.c"
"cpu_util.c"
"rtc_clk.c"
"rtc_clk_init.c"
"rtc_init.c"

View file

@ -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 <stdint.h>
#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

View file

@ -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 <stdint.h>
#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

View file

@ -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

View file

@ -1,5 +1,4 @@
set(srcs "brownout_hal.c"
"cpu_util.c"
"rtc_clk.c"
"rtc_clk_init.c"
"rtc_init.c"

View file

@ -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 <stdint.h>
#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

View file

@ -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 <stdint.h>
#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

View file

@ -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

View file

@ -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 <stdint.h>
#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
}

View file

@ -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;
}

View file

@ -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 <stdint.h>
#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;
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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))