hal: Route CPU and Interrupt Controller HAL/LL to esp_cpu calls

This commit makes changes to cpu_ll.h, cpu_hal.h, and interrupt_controller_hal.h:

- Moved to esp_hw_support in order to be deprecated in the future
- HAL/LL API now route their calls to esp_cpu.h functions instead

Also updated soc_hal.h as follows:

- Removed __SOC_HAL_..._OTHER_CORES() macros as they dependend on cpu_hal.h
- Made soc_hal.h and soc_ll.h interfaces always inline, and removed soc_hal.c.

This commit also updates the XCHAL_ERRATUM_572 workaround by

- Removing it's HAL function and invoking the workaround it directly the bootloader
- Added missing workaround for the ESP32-S3
This commit is contained in:
Darian Leung 2022-06-07 15:01:05 +08:00
parent 149872131a
commit a8a3756b38
52 changed files with 575 additions and 3011 deletions

View File

@ -15,8 +15,6 @@
void bootloader_init_mem(void)
{
cpu_hal_init_hwloop();
#ifdef CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE
// protect memory region
esp_cpu_configure_region_protection();

View File

@ -27,6 +27,8 @@
#include "soc/rtc.h"
#include "soc/spi_periph.h"
#include "hal/gpio_hal.h"
#include "xtensa/config/core.h"
#include "xt_instr_macros.h"
#include "esp32/rom/cache.h"
#include "esp_rom_gpio.h"
@ -350,6 +352,11 @@ esp_err_t bootloader_init(void)
{
esp_err_t ret = ESP_OK;
#if XCHAL_ERRATUM_572
uint32_t memctl = XCHAL_CACHE_MEMCTL_DEFAULT;
WSR(MEMCTL, memctl);
#endif // XCHAL_ERRATUM_572
bootloader_init_mem();
// check that static RAM is after the stack

View File

@ -37,6 +37,8 @@
#include "esp_efuse.h"
#include "hal/mmu_hal.h"
#include "hal/cache_hal.h"
#include "xtensa/config/core.h"
#include "xt_instr_macros.h"
static const char *TAG = "boot.esp32s3";
@ -316,6 +318,12 @@ static inline void bootloader_ana_reset_config(void)
esp_err_t bootloader_init(void)
{
esp_err_t ret = ESP_OK;
#if XCHAL_ERRATUM_572
uint32_t memctl = XCHAL_CACHE_MEMCTL_DEFAULT;
WSR(MEMCTL, memctl);
#endif // XCHAL_ERRATUM_572
bootloader_ana_reset_config();
bootloader_super_wdt_auto_feed();
// protect memory region

View File

@ -6,7 +6,7 @@
#include <string.h>
#include "esp_gdbstub_common.h"
#include "esp_cpu.h"
#include "hal/cpu_hal.h"
#include "soc/soc_memory_layout.h"
#include "xtensa/config/specreg.h"
#include "sdkconfig.h"

View File

@ -17,18 +17,18 @@ void compare_and_set_extram(volatile uint32_t *addr, uint32_t compare, uint32_t
__asm__ __volatile__ ("rsil %0, " XTSTR(XCHAL_EXCM_LEVEL) "\n"
: "=r"(intlevel));
spinlock_acquire(&global_extram_lock, SPINLOCK_WAIT_FOREVER);
spinlock_acquire(&global_extram_lock, SPINLOCK_WAIT_FOREVER);
old_value = *addr;
if (old_value == compare) {
*addr = *set;
}
spinlock_release(&global_extram_lock);
spinlock_release(&global_extram_lock);
__asm__ __volatile__ ("memw \n"
"wsr %0, ps\n"
:: "r"(intlevel));
__asm__ __volatile__ ("memw \n"
"wsr %0, ps\n"
:: "r"(intlevel));
*set = old_value;
}

View File

@ -8,8 +8,10 @@
#include <stdint.h>
#include <stdbool.h>
#include "esp_attr.h"
#include "esp_cpu.h"
#include "esp_memory_utils.h"
#include "hal/cpu_hal.h"
#ifdef __cplusplus
extern "C" {

View File

@ -6,19 +6,27 @@
#pragma once
/*
Note: This is a compatibility header. Call the interfaces in esp_cpu.h instead
[refactor-todo]: Mark all API in this header as deprecated
*/
#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"
#include <stddef.h>
#include "soc/soc_caps.h"
#include "hal/cpu_types.h"
#include "hal/cpu_ll.h"
#include "esp_cpu.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
WATCHPOINT_TRIGGER_ON_RO = ESP_CPU_WATCHPOINT_LOAD, // on read
WATCHPOINT_TRIGGER_ON_WO = ESP_CPU_WATCHPOINT_STORE, // on write
WATCHPOINT_TRIGGER_ON_RW = ESP_CPU_WATCHPOINT_ACCESS, // on either read or write
} watchpoint_trigger_t;
/**
* Return the ID of the core currently executing this code.
*
@ -45,7 +53,7 @@ extern "C" {
* Set the given value into the internal counter that increments
* every processor-clock cycle.
*/
#define cpu_hal_set_cycle_count(val) cpu_ll_set_cycle_count(val)
#define cpu_hal_set_cycle_count(val) cpu_ll_set_cycle_count(val)
/**
* Check if some form of debugger is attached to CPU.
@ -80,14 +88,19 @@ extern "C" {
* @param id breakpoint to set [0..SOC_CPU_BREAKPOINTS_NUM - 1]
* @param addr address to set a breakpoint on
*/
void cpu_hal_set_breakpoint(int id, const void* addr);
static inline void cpu_hal_set_breakpoint(int id, const void *addr)
{
esp_cpu_set_breakpoint(id, addr);
}
/**
* Clear and disable breakpoint.
*
* @param id breakpoint to clear [0..SOC_CPU_BREAKPOINTS_NUM - 1]
*/
void cpu_hal_clear_breakpoint(int id);
static inline void cpu_hal_clear_breakpoint(int id)
{
esp_cpu_clear_breakpoint(id);
}
#endif // SOC_CPU_BREAKPOINTS_NUM > 0
@ -101,14 +114,20 @@ void cpu_hal_clear_breakpoint(int id);
* @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)
*/
void cpu_hal_set_watchpoint(int id, const void* addr, size_t size, watchpoint_trigger_t trigger);
static inline void cpu_hal_set_watchpoint(int id, const void *addr, size_t size, watchpoint_trigger_t trigger)
{
esp_cpu_set_watchpoint(id, addr, size, (esp_cpu_watchpoint_trigger_t)trigger);
}
/**
* Clear and disable watchpoint.
*
* @param id watchpoint to clear [0..SOC_CPU_WATCHPOINTS_NUM - 1]
*/
void cpu_hal_clear_watchpoint(int id);
static inline void cpu_hal_clear_watchpoint(int id)
{
esp_cpu_clear_watchpoint(id);
}
#endif // SOC_CPU_WATCHPOINTS_NUM > 0
@ -117,7 +136,10 @@ void cpu_hal_clear_watchpoint(int id);
*
* @param base address to move the exception vector table to
*/
void cpu_hal_set_vecbase(const void* base);
static inline void cpu_hal_set_vecbase(const void *base)
{
esp_cpu_intr_set_ivt_addr(base);
}
#ifdef __cplusplus
}

View File

@ -0,0 +1,168 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/*
Note: This is a compatibility header. Call the interfaces in esp_cpu.h instead
[refactor-todo]: Mark all API in this header as deprecated
*/
#include <stdint.h>
#include <stdbool.h>
#include "soc/soc_caps.h"
#include "esp_attr.h"
#include "esp_cpu.h"
#ifdef __cplusplus
extern "C" {
#endif
FORCE_INLINE_ATTR __attribute__((pure)) uint32_t cpu_ll_get_core_id(void)
{
return esp_cpu_get_core_id();
}
FORCE_INLINE_ATTR uint32_t cpu_ll_get_cycle_count(void)
{
return (uint32_t)esp_cpu_get_ccount();
}
FORCE_INLINE_ATTR void cpu_ll_set_cycle_count(uint32_t val)
{
esp_cpu_set_cycle_count((esp_cpu_ccount_t)val);
}
FORCE_INLINE_ATTR void *cpu_ll_get_sp(void)
{
return esp_cpu_get_sp();
}
FORCE_INLINE_ATTR void cpu_ll_init_hwloop(void)
{
; // Nothing to do. Contents moved to bootloader directly
}
#if SOC_CPU_BREAKPOINTS_NUM > 0
FORCE_INLINE_ATTR void cpu_ll_set_breakpoint(int id, uint32_t pc)
{
esp_cpu_set_breakpoint(id, (const void *)pc);
}
FORCE_INLINE_ATTR void cpu_ll_clear_breakpoint(int id)
{
esp_cpu_clear_breakpoint(id);
}
#endif // SOC_CPU_BREAKPOINTS_NUM > 0
FORCE_INLINE_ATTR __attribute__((pure)) uint32_t cpu_ll_ptr_to_pc(const void *addr)
{
return ((uint32_t) addr);
}
FORCE_INLINE_ATTR __attribute__((pure)) void *cpu_ll_pc_to_ptr(uint32_t pc)
{
return esp_cpu_pc_to_addr(pc);
}
FORCE_INLINE_ATTR void cpu_ll_set_watchpoint(int id,
const void* addr,
size_t size,
bool on_read,
bool on_write)
{
esp_cpu_watchpoint_trigger_t trigger;
if (on_read && on_write) {
trigger = ESP_CPU_WATCHPOINT_ACCESS;
} else if (on_read) {
trigger = ESP_CPU_WATCHPOINT_LOAD;
} else {
trigger = ESP_CPU_WATCHPOINT_STORE;
}
esp_cpu_set_watchpoint(id, addr, size, trigger);
}
FORCE_INLINE_ATTR void cpu_ll_clear_watchpoint(int id)
{
esp_cpu_clear_watchpoint(id);
}
FORCE_INLINE_ATTR bool cpu_ll_is_debugger_attached(void)
{
return esp_cpu_dbgr_is_attached();
}
FORCE_INLINE_ATTR void cpu_ll_break(void)
{
esp_cpu_dbgr_break();
}
FORCE_INLINE_ATTR void cpu_ll_set_vecbase(const void *base)
{
esp_cpu_intr_set_ivt_addr(base);
}
FORCE_INLINE_ATTR void cpu_ll_waiti(void)
{
esp_cpu_wait_for_intr();
}
FORCE_INLINE_ATTR void cpu_ll_compare_and_set_native(volatile uint32_t *addr, uint32_t compare, uint32_t *set)
{
#ifdef __clang_analyzer__
//Teach clang-tidy that "addr" and "set" cannot be const as they can both be updated by S32C1I instruction
volatile uint32_t temp;
temp = *addr;
*addr = temp;
temp = *set;
*set = temp;
#endif
#ifdef __XTENSA__
#if XCHAL_HAVE_S32C1I
__asm__ __volatile__ (
"WSR %2, SCOMPARE1 \n"
"S32C1I %0, %1, 0 \n"
:"=r"(*set)
:"r"(addr), "r"(compare), "0"(*set)
);
#else // XCHAL_HAVE_S32C1I
uint32_t old_value;
// No S32C1I, so do this by disabling and re-enabling interrupts (slower)
uint32_t intlevel;
__asm__ __volatile__ ("rsil %0, " XTSTR(XCHAL_EXCM_LEVEL) "\n"
: "=r"(intlevel));
old_value = *addr;
if (old_value == compare) {
*addr = *set;
}
__asm__ __volatile__ ("memw \n"
"wsr %0, ps\n"
:: "r"(intlevel));
*set = old_value;
#endif // XCHAL_HAVE_S32C1I
#else
uint32_t old_value;
unsigned old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
old_value = *addr;
if (old_value == compare) {
*addr = *set;
}
RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
*set = old_value;
#endif
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,235 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/*
Note: This is a compatibility header. Call the interfaces in esp_cpu.h instead
[refactor-todo]: Mark all API in this header as deprecated
*/
#include <stdint.h>
#include <stdbool.h>
#include "soc/soc_caps.h"
#include "esp_attr.h"
#include "esp_cpu.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
INTDESC_NORMAL = 0,
INTDESC_RESVD,
INTDESC_SPECIAL,
} int_desc_flag_t;
typedef enum {
INTTP_LEVEL = ESP_CPU_INTR_TYPE_LEVEL,
INTTP_EDGE = ESP_CPU_INTR_TYPE_EDGE,
INTTP_NA = ESP_CPU_INTR_TYPE_NA,
} int_type_t;
typedef struct {
int level;
int_type_t type;
int_desc_flag_t cpuflags[SOC_CPU_CORES_NUM];
} int_desc_t;
typedef void (*interrupt_handler_t)(void *arg);
// ---------------- Interrupt Descriptors ------------------
/**
* @brief Gets the interrupt type given an interrupt number.
*
* @param interrupt_number Interrupt number 0 to 31
* @return interrupt type
*/
FORCE_INLINE_ATTR int_type_t interrupt_controller_hal_desc_type(int interrupt_number)
{
esp_cpu_intr_desc_t intr_desc;
esp_cpu_intr_get_desc(esp_cpu_get_core_id(), interrupt_number, &intr_desc);
return (int_type_t)intr_desc.type;
}
/**
* @brief Gets the interrupt level given an interrupt number.
*
* @param interrupt_number Interrupt number 0 to 31
* @return interrupt level bitmask
*/
FORCE_INLINE_ATTR int interrupt_controller_hal_desc_level(int interrupt_number)
{
esp_cpu_intr_desc_t intr_desc;
esp_cpu_intr_get_desc(esp_cpu_get_core_id(), interrupt_number, &intr_desc);
return intr_desc.priority;
}
/**
* @brief Gets the cpu flags given the interrupt number and target cpu.
*
* @param interrupt_number Interrupt number 0 to 31
* @param cpu_number CPU number between 0 and SOC_CPU_CORES_NUM - 1
* @return flags for that interrupt number
*/
FORCE_INLINE_ATTR int_desc_flag_t interrupt_controller_hal_desc_flags(int interrupt_number, int cpu_number)
{
esp_cpu_intr_desc_t intr_desc;
esp_cpu_intr_get_desc(cpu_number, interrupt_number, &intr_desc);
int_desc_flag_t ret;
if (intr_desc.flags & ESP_CPU_INTR_DESC_FLAG_SPECIAL) {
ret = INTDESC_SPECIAL;
} else if (intr_desc.flags & ESP_CPU_INTR_DESC_FLAG_RESVD) {
ret = INTDESC_RESVD;
} else {
ret = INTDESC_NORMAL;
}
return ret;
}
/**
* @brief Gets the interrupt type given an interrupt number.
*
* @param interrupt_number Interrupt number 0 to 31
* @return interrupt type
*/
FORCE_INLINE_ATTR int_type_t interrupt_controller_hal_get_type(int interrupt_number)
{
return interrupt_controller_hal_desc_type(interrupt_number);
}
/**
* @brief Gets the interrupt level given an interrupt number.
*
* @param interrupt_number Interrupt number 0 to 31
* @return interrupt level bitmask
*/
FORCE_INLINE_ATTR int interrupt_controller_hal_get_level(int interrupt_number)
{
return interrupt_controller_hal_desc_level(interrupt_number);
}
/**
* @brief Gets the cpu flags given the interrupt number and target cpu.
*
* @param interrupt_number Interrupt number 0 to 31
* @param cpu_number CPU number between 0 and SOC_CPU_CORES_NUM - 1
* @return flags for that interrupt number
*/
FORCE_INLINE_ATTR uint32_t interrupt_controller_hal_get_cpu_desc_flags(int interrupt_number, int cpu_number)
{
return (uint32_t)interrupt_controller_hal_desc_flags(interrupt_number, cpu_number);
}
// --------------- Interrupt Configuration -----------------
#if SOC_CPU_HAS_FLEXIBLE_INTC
/**
* @brief Set the type of an interrupt in the controller.
*
* @param interrupt_number Interrupt number 0 to 31
* @param type interrupt type as edge or level triggered
*/
FORCE_INLINE_ATTR void interrupt_controller_hal_set_int_type(int intr, int_type_t type)
{
esp_cpu_intr_set_type(intr, (esp_cpu_intr_type_t)type);
}
/**
* @brief Sets the interrupt level int the interrupt controller.
*
* @param interrupt_number Interrupt number 0 to 31
* @param level priority between 1 (lowest) to 7 (highest)
*/
FORCE_INLINE_ATTR void interrupt_controller_hal_set_int_level(int intr, int level)
{
esp_cpu_intr_set_priority(intr, level);
}
#endif // SOC_CPU_HAS_FLEXIBLE_INTC
/**
* @brief checks if given interrupt number has a valid handler
*
* @param intr interrupt number ranged from 0 to 31
* @param cpu this argument is ignored
* @return true for valid handler, false otherwise
*/
FORCE_INLINE_ATTR bool interrupt_controller_hal_has_handler(int intr, int cpu)
{
(void) cpu;
return esp_cpu_intr_has_handler(intr);
}
/**
* @brief sets interrupt handler and optional argument of a given interrupt number
*
* @param intr interrupt number ranged from 0 to 31
* @param handler handler invoked when an interrupt occurs
* @param arg optional argument to pass to the handler
*/
FORCE_INLINE_ATTR void interrupt_controller_hal_set_int_handler(uint8_t intr, interrupt_handler_t handler, void *arg)
{
esp_cpu_intr_set_handler(intr, (esp_cpu_intr_handler_t)handler, arg);
}
/**
* @brief Gets argument passed to handler of a given interrupt number
*
* @param intr interrupt number ranged from 0 to 31
*
* @return argument used by handler of passed interrupt number
*/
FORCE_INLINE_ATTR void *interrupt_controller_hal_get_int_handler_arg(uint8_t intr)
{
return esp_cpu_intr_get_handler_arg(intr);
}
// ------------------ Interrupt Control --------------------
/**
* @brief enable interrupts specified by the mask
*
* @param mask bitmask of interrupts that needs to be enabled
*/
FORCE_INLINE_ATTR void interrupt_controller_hal_enable_interrupts(uint32_t mask)
{
esp_cpu_intr_enable(mask);
}
/**
* @brief disable interrupts specified by the mask
*
* @param mask bitmask of interrupts that needs to be disabled
*/
FORCE_INLINE_ATTR void interrupt_controller_hal_disable_interrupts(uint32_t mask)
{
esp_cpu_intr_disable(mask);
}
/**
* @brief Read the current interrupt mask.
*
* @return The bitmask of current interrupts
*/
FORCE_INLINE_ATTR uint32_t interrupt_controller_hal_read_interrupt_mask(void)
{
return esp_cpu_intr_get_enabled_mask();
}
/**
* @brief Acknowledge an edge-trigger interrupt by clearing its pending flag
*
* @param intr interrupt number ranged from 0 to 31
*/
FORCE_INLINE_ATTR void interrupt_controller_hal_edge_int_acknowledge(int intr)
{
esp_cpu_intr_edge_ack(intr);
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,52 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/*
Note: This is a compatibility header. Call the interfaces in esp_cpu.h instead
[refactor-todo]: Mark all API in this header as deprecated
*/
#include "soc/soc_caps.h"
#include "hal/soc_ll.h"
#ifdef __cplusplus
extern "C" {
#endif
#if SOC_CPU_CORES_NUM > 1 // We only allow stalling/unstalling of other cores
/**
* 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]
*/
#define soc_hal_stall_core(core) soc_ll_stall_core(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]
*/
#define soc_hal_unstall_core(core) soc_ll_unstall_core(core)
#endif // SOC_CPU_CORES_NUM > 1
/**
* Reset the specified core.
*
* @param core core to reset [0..SOC_CPU_CORES_NUM - 1]
*/
#define soc_hal_reset_core(core) soc_ll_reset_core((core))
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,38 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/*
Note: This is a compatibility header. Call the interfaces in esp_cpu.h instead
[refactor-todo]: Mark all API in this header as deprecated
*/
#include "esp_attr.h"
#include "esp_cpu.h"
#ifdef __cplusplus
extern "C" {
#endif
FORCE_INLINE_ATTR void soc_ll_stall_core(int core)
{
esp_cpu_stall(core);
}
FORCE_INLINE_ATTR void soc_ll_unstall_core(int core)
{
esp_cpu_unstall(core);
}
FORCE_INLINE_ATTR void soc_ll_reset_core(int core)
{
esp_cpu_reset(core);
}
#ifdef __cplusplus
}
#endif

View File

@ -153,8 +153,13 @@ static void panic_handler(void *frame, bool pseudo_excause)
esp_panic_handler_reconfigure_wdts();
esp_rom_delay_us(1);
SOC_HAL_STALL_OTHER_CORES();
#endif
// Stall all other cores
for (uint32_t i = 0; i < SOC_CPU_CORES_NUM; i++) {
if (i != core_id) {
esp_cpu_stall(i);
}
}
#endif // !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
esp_ipc_isr_stall_abort();

View File

@ -23,6 +23,7 @@
#include "soc/syscon_reg.h"
#include "soc/system_reg.h"
#include "hal/wdt_hal.h"
#include "hal/cpu_hal.h"
#include "esp_private/cache_err_int.h"
#include "esp32c2/rom/cache.h"

View File

@ -24,6 +24,7 @@
#include "soc/system_reg.h"
#include "soc/uart_reg.h"
#include "hal/wdt_hal.h"
#include "hal/cpu_hal.h"
#include "esp_private/cache_err_int.h"
#include "esp32c3/rom/cache.h"

View File

@ -23,6 +23,7 @@
#include "soc/syscon_reg.h"
#include "soc/system_reg.h"
#include "hal/wdt_hal.h"
#include "hal/cpu_hal.h"
#include "esp_private/cache_err_int.h"
#include "esp32h2/rom/cache.h"

View File

@ -22,6 +22,7 @@
#include "soc/syscon_reg.h"
#include "soc/rtc_periph.h"
#include "hal/wdt_hal.h"
#include "hal/cpu_hal.h"
#include "freertos/xtensa_api.h"
#include "soc/soc_memory_layout.h"
#include "hal/cpu_hal.h"

View File

@ -21,6 +21,7 @@
#include "soc/syscon_reg.h"
#include "soc/rtc_periph.h"
#include "hal/wdt_hal.h"
#include "hal/cpu_hal.h"
#include "freertos/xtensa_api.h"
#include "soc/soc_memory_layout.h"

View File

@ -17,6 +17,7 @@
#include "portbenchmark.h"
#include "esp_macros.h"
#include "hal/cpu_hal.h"
#include "compare_set.h" /* For compare_and_set_native(). [refactor-todo] Use esp_cpu.h instead */
#include "esp_private/crosscore_int.h"
/*

View File

@ -50,6 +50,7 @@
#include "esp_heap_caps.h"
#include "esp_system.h" /* required by esp_get_...() functions in portable.h. [refactor-todo] Update portable.h */
#include "esp_newlib.h"
#include "compare_set.h" /* For compare_and_set_native(). [refactor-todo] Use esp_cpu.h instead */
/* [refactor-todo] These includes are not directly used in this file. They are kept into to prevent a breaking change. Remove these. */
#include <limits.h>

View File

@ -80,6 +80,7 @@
#include "esp_heap_caps.h"
#include "esp_rom_sys.h"
#include "esp_system.h" /* required by esp_get_...() functions in portable.h. [refactor-todo] Update portable.h */
#include "compare_set.h" /* For compare_and_set_native(). [refactor-todo] Use esp_cpu.h instead */
#include "portbenchmark.h"
/* [refactor-todo] These includes are not directly used in this file. They are kept into to prevent a breaking change. Remove these. */

View File

@ -1,7 +1,6 @@
idf_build_get_property(target IDF_TARGET)
set(srcs "mpu_hal.c"
"cpu_hal.c"
"efuse_hal.c"
"${target}/efuse_hal.c"
"mmu_hal.c")
@ -43,8 +42,6 @@ if(NOT BOOTLOADER_BUILD)
"spi_flash_hal.c"
"spi_flash_hal_iram.c"
"spi_flash_encrypt_hal_iram.c"
"soc_hal.c"
"interrupt_controller_hal.c"
"sha_hal.c"
"adc_hal_common.c"
"adc_hal.c")
@ -97,7 +94,6 @@ if(NOT BOOTLOADER_BUILD)
"aes_hal.c"
"esp32/adc_hal.c"
"esp32/brownout_hal.c"
"esp32/interrupt_descriptor_table.c"
"esp32/touch_sensor_hal.c"
"esp32/gpio_hal_workaround.c")
endif()
@ -116,7 +112,6 @@ if(NOT BOOTLOADER_BUILD)
"esp32s2/cp_dma_hal.c"
"esp32s2/touch_sensor_hal.c"
"esp32s2/dac_hal.c"
"esp32s2/interrupt_descriptor_table.c"
"usbh_hal.c")
endif()
@ -132,7 +127,6 @@ if(NOT BOOTLOADER_BUILD)
"aes_hal.c"
"esp32s3/brownout_hal.c"
"esp32s3/hmac_hal.c"
"esp32s3/interrupt_descriptor_table.c"
"esp32s3/touch_sensor_hal.c"
"esp32s3/rtc_cntl_hal.c"
"usbh_hal.c")

View File

@ -1,64 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdint.h>
#include <stdlib.h>
#include "sdkconfig.h"
#include "esp_err.h"
#include "hal/cpu_hal.h"
#include "hal/cpu_types.h"
#include "soc/soc_caps.h"
#if SOC_CPU_BREAKPOINTS_NUM > 0
void cpu_hal_set_breakpoint(int id, const void* addr)
{
cpu_ll_set_breakpoint(id, cpu_ll_ptr_to_pc(addr));
}
void cpu_hal_clear_breakpoint(int id)
{
cpu_ll_clear_breakpoint(id);
}
#endif // SOC_CPU_BREAKPOINTS_NUM > 0
#if SOC_CPU_WATCHPOINTS_NUM > 0
void cpu_hal_set_watchpoint(int id, const void* addr, size_t size, watchpoint_trigger_t trigger)
{
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);
}
void cpu_hal_clear_watchpoint(int id)
{
cpu_ll_clear_watchpoint(id);
}
#endif // SOC_CPU_WATCHPOINTS_NUM > 0
void cpu_hal_set_vecbase(const void* base)
{
cpu_ll_set_vecbase(base);
}

View File

@ -1,190 +0,0 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "esp_attr.h"
#include "soc/soc_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 uint32_t IRAM_ATTR cpu_ll_get_core_id(void)
{
uint32_t id;
asm volatile (
"rsr.prid %0\n"
"extui %0,%0,13,1"
:"=r"(id));
return id;
}
static inline uint32_t IRAM_ATTR cpu_ll_get_cycle_count(void)
{
uint32_t result;
RSR(CCOUNT, result);
return result;
}
static inline void IRAM_ATTR cpu_ll_set_cycle_count(uint32_t val)
{
WSR(CCOUNT, val);
}
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 & 0x3fffffffU) | 0x40000000U);
}
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 == (size_t)(1U << 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 1,15");
}
static inline void cpu_ll_set_vecbase(const void* vecbase)
{
asm volatile ("wsr %0, vecbase" :: "r" (vecbase));
}
static inline void cpu_ll_waiti(void)
{
asm volatile ("waiti 0\n");
}
static inline void cpu_ll_compare_and_set_native(volatile uint32_t *addr, uint32_t compare, uint32_t *set)
{
__asm__ __volatile__ (
"WSR %2,SCOMPARE1 \n"
"S32C1I %0, %1, 0 \n"
:"=r"(*set)
:"r"(addr), "r"(compare), "0"(*set)
);
}
#ifdef __cplusplus
}
#endif

View File

@ -1,108 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdint.h>
#include "soc/soc_caps.h"
#include "soc/soc.h"
#include "xtensa/xtensa_api.h"
#include "xt_instr_macros.h"
#include "xtensa/config/specreg.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief enable interrupts specified by the mask
*
* @param mask bitmask of interrupts that needs to be enabled
*/
static inline void intr_cntrl_ll_enable_interrupts(uint32_t mask)
{
xt_ints_on(mask);
}
/**
* @brief disable interrupts specified by the mask
*
* @param mask bitmask of interrupts that needs to be disabled
*/
static inline void intr_cntrl_ll_disable_interrupts(uint32_t mask)
{
xt_ints_off(mask);
}
/**
* @brief Read the current interrupt mask of the CPU running this code.
*
* @return The current interrupt bitmask.
*/
static inline uint32_t intr_cntrl_ll_read_interrupt_mask(void)
{
uint32_t int_mask;
RSR(INTENABLE, int_mask);
return int_mask;
}
/**
* @brief checks if given interrupt number has a valid handler
*
* @param intr interrupt number ranged from 0 to 31
* @param cpu cpu number ranged betweeen 0 to SOC_CPU_CORES_NUM - 1
* @return true for valid handler, false otherwise
*/
static inline bool intr_cntrl_ll_has_handler(uint8_t intr, uint8_t cpu)
{
return xt_int_has_handler(intr, cpu);
}
/**
* @brief sets interrupt handler and optional argument of a given interrupt number
*
* @param intr interrupt number ranged from 0 to 31
* @param handler handler invoked when an interrupt occurs
* @param arg optional argument to pass to the handler
*/
static inline void intr_cntrl_ll_set_int_handler(uint8_t intr, interrupt_handler_t handler, void *arg)
{
xt_set_interrupt_handler(intr, (xt_handler)handler, arg);
}
/**
* @brief Gets argument passed to handler of a given interrupt number
*
* @param intr interrupt number ranged from 0 to 31
*
* @return argument used by handler of passed interrupt number
*/
static inline void *intr_cntrl_ll_get_int_handler_arg(uint8_t intr)
{
return xt_get_interrupt_handler_arg(intr);
}
/**
* @brief Acknowledge an edge-trigger interrupt by clearing its pending flag
*
* @param intr interrupt number ranged from 0 to 31
*/
static inline void intr_cntrl_ll_edge_int_acknowledge(int intr)
{
xthal_set_intclear(1 << intr);
}
#ifdef __cplusplus
}
#endif

View File

@ -1,54 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/soc_caps.h"
#include "soc/rtc.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,75 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "sdkconfig.h"
#include "hal/interrupt_controller_hal.h"
#include "hal/interrupt_controller_ll.h"
#include "soc/soc_caps.h"
#include "soc/soc.h"
//We should mark the interrupt for the timer used by FreeRTOS as reserved. The specific timer
//is selectable using menuconfig; we use these cpp bits to convert that into something we can use in
//the table below.
#if CONFIG_FREERTOS_CORETIMER_0
#define INT6RES INTDESC_RESVD
#else
#define INT6RES INTDESC_SPECIAL
#endif
#if CONFIG_FREERTOS_CORETIMER_1
#define INT15RES INTDESC_RESVD
#else
#define INT15RES INTDESC_SPECIAL
#endif
//This is basically a software-readable version of the interrupt usage table in include/soc/soc.h
const static int_desc_t interrupt_descriptor_table [32]={
{ 1, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //0
{ 1, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //1
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //2
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //3
{ 1, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_NORMAL} }, //4
{ 1, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //5
{ 1, INTTP_NA, {INT6RES, INT6RES } }, //6
{ 1, INTTP_NA, {INTDESC_SPECIAL,INTDESC_SPECIAL}}, //7
{ 1, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //8
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //9
{ 1, INTTP_EDGE , {INTDESC_NORMAL, INTDESC_NORMAL} }, //10
{ 3, INTTP_NA, {INTDESC_SPECIAL,INTDESC_SPECIAL}}, //11
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //12
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //13
{ 7, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //14, NMI
{ 3, INTTP_NA, {INT15RES, INT15RES } }, //15
{ 5, INTTP_NA, {INTDESC_SPECIAL,INTDESC_SPECIAL} }, //16
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //17
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //18
{ 2, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //19
{ 2, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //20
{ 2, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //21
{ 3, INTTP_EDGE, {INTDESC_RESVD, INTDESC_NORMAL} }, //22
{ 3, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //23
{ 4, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_NORMAL} }, //24
{ 4, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //25
{ 5, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_RESVD } }, //26
{ 3, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //27
{ 4, INTTP_EDGE, {INTDESC_NORMAL, INTDESC_NORMAL} }, //28
{ 3, INTTP_NA, {INTDESC_SPECIAL,INTDESC_SPECIAL}}, //29
{ 4, INTTP_EDGE, {INTDESC_RESVD, INTDESC_RESVD } }, //30
{ 5, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //31
};
const int_desc_t *interrupt_controller_hal_desc_table(void)
{
return interrupt_descriptor_table;
}

View File

@ -1,219 +0,0 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "soc/soc_caps.h"
#include "soc/dport_access.h"
#include "soc/system_reg.h"
#include "esp_bit_defs.h"
#include "soc/assist_debug_reg.h"
#include "esp_attr.h"
#include "riscv/csr.h"
#include "riscv/semihosting.h"
/*performance counter*/
#define CSR_PCER_MACHINE 0x7e0
#define CSR_PCMR_MACHINE 0x7e1
#define CSR_PCCR_MACHINE 0x7e2
#ifdef __cplusplus
extern "C" {
#endif
static inline int IRAM_ATTR cpu_ll_get_core_id(void)
{
#if SOC_CPU_CORES_NUM == 1
return 0; // No need to check core ID on single core hardware
#else
int cpuid;
cpuid = RV_READ_CSR(mhartid);
return cpuid;
#endif
}
static inline void cpu_ll_enable_cycle_count(void)
{
RV_WRITE_CSR(CSR_PCER_MACHINE,1);
RV_WRITE_CSR(CSR_PCMR_MACHINE,1);
return;
}
static inline uint32_t IRAM_ATTR cpu_ll_get_cycle_count(void)
{
uint32_t result;
result = RV_READ_CSR(CSR_PCCR_MACHINE);
return result;
}
static inline void IRAM_ATTR cpu_ll_set_cycle_count(uint32_t val)
{
RV_WRITE_CSR(CSR_PCCR_MACHINE, val);
}
static inline void* cpu_ll_get_sp(void)
{
void *sp;
asm volatile ("mv %0, sp;" : "=r" (sp));
return sp;
}
static inline void cpu_ll_init_hwloop(void)
{
// Nothing needed here for ESP32-C3
}
FORCE_INLINE_ATTR bool cpu_ll_is_debugger_attached(void)
{
return REG_GET_BIT(ASSIST_DEBUG_CORE_0_DEBUG_MODE_REG, ASSIST_DEBUG_CORE_0_DEBUG_MODULE_ACTIVE);
}
static inline void cpu_ll_set_breakpoint(int id, uint32_t pc)
{
if (cpu_ll_is_debugger_attached()) {
/* If we want to set breakpoint which when hit transfers control to debugger
* we need to set `action` in `mcontrol` to 1 (Enter Debug Mode).
* That `action` value is supported only when `dmode` of `tdata1` is set.
* But `dmode` can be modified by debugger only (from Debug Mode).
*
* So when debugger is connected we use special syscall to ask it to set breakpoint for us.
*/
long args[] = {true, id, (long)pc};
int ret = semihosting_call_noerrno(ESP_SEMIHOSTING_SYS_BREAKPOINT_SET, args);
if (ret == 0) {
return;
}
}
/* The code bellow sets breakpoint which will trigger `Breakpoint` exception
* instead transfering control to debugger. */
RV_WRITE_CSR(tselect,id);
RV_SET_CSR(CSR_TCONTROL,TCONTROL_MTE);
RV_SET_CSR(CSR_TDATA1, TDATA1_USER|TDATA1_MACHINE|TDATA1_EXECUTE);
RV_WRITE_CSR(tdata2,pc);
return;
}
static inline void cpu_ll_clear_breakpoint(int id)
{
if (cpu_ll_is_debugger_attached()) {
/* see description in cpu_ll_set_breakpoint() */
long args[] = {false, id};
int ret = semihosting_call_noerrno(ESP_SEMIHOSTING_SYS_BREAKPOINT_SET, args);
if (ret == 0){
return;
}
}
RV_WRITE_CSR(tselect,id);
RV_CLEAR_CSR(CSR_TCONTROL,TCONTROL_MTE);
RV_CLEAR_CSR(CSR_TDATA1, TDATA1_USER|TDATA1_MACHINE|TDATA1_EXECUTE);
return;
}
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 addr_napot;
if (cpu_ll_is_debugger_attached()) {
/* see description in cpu_ll_set_breakpoint() */
long args[] = {true, id, (long)addr, (long)size,
(long)((on_read ? ESP_SEMIHOSTING_WP_FLG_RD : 0) | (on_write ? ESP_SEMIHOSTING_WP_FLG_WR : 0))};
int ret = semihosting_call_noerrno(ESP_SEMIHOSTING_SYS_WATCHPOINT_SET, args);
if (ret == 0) {
return;
}
}
RV_WRITE_CSR(tselect,id);
RV_SET_CSR(CSR_TCONTROL, TCONTROL_MPTE | TCONTROL_MTE);
RV_SET_CSR(CSR_TDATA1, TDATA1_USER|TDATA1_MACHINE);
RV_SET_CSR_FIELD(CSR_TDATA1, (long unsigned int) TDATA1_MATCH, 1);
// add 0 in napot encoding
addr_napot = ((uint32_t) addr) | ((size >> 1) - 1);
if (on_read) {
RV_SET_CSR(CSR_TDATA1, TDATA1_LOAD);
}
if (on_write) {
RV_SET_CSR(CSR_TDATA1, TDATA1_STORE);
}
RV_WRITE_CSR(tdata2,addr_napot);
return;
}
static inline void cpu_ll_clear_watchpoint(int id)
{
if (cpu_ll_is_debugger_attached()) {
/* see description in cpu_ll_set_breakpoint() */
long args[] = {false, id};
int ret = semihosting_call_noerrno(ESP_SEMIHOSTING_SYS_WATCHPOINT_SET, args);
if (ret == 0){
return;
}
}
RV_WRITE_CSR(tselect,id);
RV_CLEAR_CSR(CSR_TCONTROL,TCONTROL_MTE);
RV_CLEAR_CSR(CSR_TDATA1, TDATA1_USER|TDATA1_MACHINE);
RV_CLEAR_CSR_FIELD(CSR_TDATA1, (long unsigned int) TDATA1_MATCH);
RV_CLEAR_CSR(CSR_TDATA1, TDATA1_MACHINE);
RV_CLEAR_CSR(CSR_TDATA1, TDATA1_LOAD|TDATA1_STORE|TDATA1_EXECUTE);
return;
}
static inline void cpu_ll_break(void)
{
asm volatile("ebreak\n");
return;
}
static inline void cpu_ll_set_vecbase(const void* vecbase)
{
uintptr_t vecbase_int = (uintptr_t)vecbase;
vecbase_int |= 1; // Set MODE field to treat MTVEC as a vector base address
RV_WRITE_CSR(mtvec, vecbase_int);
}
static inline void cpu_ll_waiti(void)
{
if (cpu_ll_is_debugger_attached() && DPORT_REG_GET_BIT(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPU_WAIT_MODE_FORCE_ON) == 0) {
/* when SYSTEM_CPU_WAIT_MODE_FORCE_ON is disabled in WFI mode SBA access to memory does not work for debugger,
so do not enter that mode when debugger is connected */
return;
}
asm volatile ("wfi\n");
}
static inline void cpu_ll_compare_and_set_native(volatile uint32_t *addr, uint32_t compare, uint32_t *set)
{
uint32_t old_value;
unsigned old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
old_value = *addr;
if (old_value == compare) {
*addr = *set;
}
RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
*set = old_value;
}
#ifdef __cplusplus
}
#endif

View File

@ -1,124 +0,0 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "soc/soc_caps.h"
#include "soc/soc.h"
#include "soc/interrupt_core0_reg.h"
#include "riscv/interrupt.h"
#include "riscv/csr.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief enable interrupts specified by the mask
*
* @param mask bitmask of interrupts that needs to be enabled
*/
static inline void intr_cntrl_ll_enable_interrupts(uint32_t mask)
{
unsigned old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
esprv_intc_int_enable(mask);
RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
}
/**
* @brief disable interrupts specified by the mask
*
* @param mask bitmask of interrupts that needs to be disabled
*/
static inline void intr_cntrl_ll_disable_interrupts(uint32_t mask)
{
unsigned old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
esprv_intc_int_disable(mask);
RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
}
/**
* @brief Read the current interrupt mask of the CPU running this code.
*
* @return The current interrupt bitmask.
*/
static inline uint32_t intr_cntrl_ll_read_interrupt_mask(void)
{
return REG_READ(INTERRUPT_CORE0_CPU_INT_ENABLE_REG);
}
/**
* @brief checks if given interrupt number has a valid handler
*
* @param intr interrupt number ranged from 0 to 31
* @param cpu cpu number ranged betweeen 0 to SOC_CPU_CORES_NUM - 1
* @return true for valid handler, false otherwise
*/
static inline bool intr_cntrl_ll_has_handler(uint8_t intr, uint8_t cpu)
{
return intr_handler_get(intr);
}
/**
* @brief sets interrupt handler and optional argument of a given interrupt number
*
* @param intr interrupt number ranged from 0 to 31
* @param handler handler invoked when an interrupt occurs
* @param arg optional argument to pass to the handler
*/
static inline void intr_cntrl_ll_set_int_handler(uint8_t intr, interrupt_handler_t handler, void *arg)
{
intr_handler_set(intr, (void *)handler, arg);
}
/**
* @brief Gets argument passed to handler of a given interrupt number
*
* @param intr interrupt number ranged from 0 to 31
*
* @return argument used by handler of passed interrupt number
*/
static inline void *intr_cntrl_ll_get_int_handler_arg(uint8_t intr)
{
return intr_handler_get_arg(intr);
}
/**
* @brief Acknowledge an edge-trigger interrupt by clearing its pending flag
*
* @param intr interrupt number ranged from 0 to 31
*/
static inline void intr_cntrl_ll_edge_int_acknowledge(int intr)
{
REG_SET_BIT(INTERRUPT_CORE0_CPU_INT_CLEAR_REG, intr);
}
/**
* @brief Sets the interrupt level int the interrupt controller.
*
* @param interrupt_number Interrupt number 0 to 31
* @param level priority between 1 (lowest) to 7 (highest)
*/
static inline void intr_cntrl_ll_set_int_level(int intr, int level)
{
esprv_intc_int_set_priority(intr, level);
}
/**
* @brief Set the type of an interrupt in the controller.
*
* @param interrupt_number Interrupt number 0 to 31
* @param type interrupt type as edge or level triggered
*/
static inline void intr_cntrl_ll_set_int_type(int intr, int_type_t type)
{
esprv_intc_int_set_type(BIT(intr), type);
}
#ifdef __cplusplus
}
#endif

View File

@ -1,44 +0,0 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#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};
const int rtc_cntl_c1_s[SOC_CPU_CORES_NUM] = {RTC_CNTL_SW_STALL_PROCPU_C1_S};
const int rtc_cntl_c0_m[SOC_CPU_CORES_NUM] = {RTC_CNTL_SW_STALL_PROCPU_C0_M};
const int rtc_cntl_c0_s[SOC_CPU_CORES_NUM] = {RTC_CNTL_SW_STALL_PROCPU_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};
const int rtc_cntl_c0_m[SOC_CPU_CORES_NUM] = {RTC_CNTL_SW_STALL_PROCPU_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, RTC_CNTL_SW_PROCPU_RST_M);
}
#ifdef __cplusplus
}
#endif

View File

@ -1,219 +0,0 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "soc/soc_caps.h"
#include "soc/dport_access.h"
#include "soc/system_reg.h"
#include "esp_bit_defs.h"
#include "soc/assist_debug_reg.h"
#include "esp_attr.h"
#include "riscv/csr.h"
#include "riscv/semihosting.h"
/*performance counter*/
#define CSR_PCER_MACHINE 0x7e0
#define CSR_PCMR_MACHINE 0x7e1
#define CSR_PCCR_MACHINE 0x7e2
#ifdef __cplusplus
extern "C" {
#endif
static inline int IRAM_ATTR cpu_ll_get_core_id(void)
{
#if SOC_CPU_CORES_NUM == 1
return 0; // No need to check core ID on single core hardware
#else
int cpuid;
cpuid = RV_READ_CSR(mhartid);
return cpuid;
#endif
}
static inline void cpu_ll_enable_cycle_count(void)
{
RV_WRITE_CSR(CSR_PCER_MACHINE,1);
RV_WRITE_CSR(CSR_PCMR_MACHINE,1);
return;
}
static inline uint32_t IRAM_ATTR cpu_ll_get_cycle_count(void)
{
uint32_t result;
result = RV_READ_CSR(CSR_PCCR_MACHINE);
return result;
}
static inline void IRAM_ATTR cpu_ll_set_cycle_count(uint32_t val)
{
RV_WRITE_CSR(CSR_PCCR_MACHINE, val);
}
static inline void* cpu_ll_get_sp(void)
{
void *sp;
asm volatile ("mv %0, sp;" : "=r" (sp));
return sp;
}
static inline void cpu_ll_init_hwloop(void)
{
// Nothing needed here for ESP32-C3
}
FORCE_INLINE_ATTR bool cpu_ll_is_debugger_attached(void)
{
return REG_GET_BIT(ASSIST_DEBUG_CORE_0_DEBUG_MODE_REG, ASSIST_DEBUG_CORE_0_DEBUG_MODULE_ACTIVE);
}
static inline void cpu_ll_set_breakpoint(int id, uint32_t pc)
{
if (cpu_ll_is_debugger_attached()) {
/* If we want to set breakpoint which when hit transfers control to debugger
* we need to set `action` in `mcontrol` to 1 (Enter Debug Mode).
* That `action` value is supported only when `dmode` of `tdata1` is set.
* But `dmode` can be modified by debugger only (from Debug Mode).
*
* So when debugger is connected we use special syscall to ask it to set breakpoint for us.
*/
long args[] = {true, id, (long)pc};
int ret = semihosting_call_noerrno(ESP_SEMIHOSTING_SYS_BREAKPOINT_SET, args);
if (ret == 0) {
return;
}
}
/* The code bellow sets breakpoint which will trigger `Breakpoint` exception
* instead transfering control to debugger. */
RV_WRITE_CSR(tselect,id);
RV_SET_CSR(CSR_TCONTROL,TCONTROL_MTE);
RV_SET_CSR(CSR_TDATA1, TDATA1_USER|TDATA1_MACHINE|TDATA1_EXECUTE);
RV_WRITE_CSR(tdata2,pc);
return;
}
static inline void cpu_ll_clear_breakpoint(int id)
{
if (cpu_ll_is_debugger_attached()) {
/* see description in cpu_ll_set_breakpoint() */
long args[] = {false, id};
int ret = semihosting_call_noerrno(ESP_SEMIHOSTING_SYS_BREAKPOINT_SET, args);
if (ret == 0){
return;
}
}
RV_WRITE_CSR(tselect,id);
RV_CLEAR_CSR(CSR_TCONTROL,TCONTROL_MTE);
RV_CLEAR_CSR(CSR_TDATA1, TDATA1_USER|TDATA1_MACHINE|TDATA1_EXECUTE);
return;
}
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 addr_napot;
if (cpu_ll_is_debugger_attached()) {
/* see description in cpu_ll_set_breakpoint() */
long args[] = {true, id, (long)addr, (long)size,
(long)((on_read ? ESP_SEMIHOSTING_WP_FLG_RD : 0) | (on_write ? ESP_SEMIHOSTING_WP_FLG_WR : 0))};
int ret = semihosting_call_noerrno(ESP_SEMIHOSTING_SYS_WATCHPOINT_SET, args);
if (ret == 0) {
return;
}
}
RV_WRITE_CSR(tselect,id);
RV_SET_CSR(CSR_TCONTROL, TCONTROL_MPTE | TCONTROL_MTE);
RV_SET_CSR(CSR_TDATA1, TDATA1_USER|TDATA1_MACHINE);
RV_SET_CSR_FIELD(CSR_TDATA1, (long unsigned int) TDATA1_MATCH, 1);
// add 0 in napot encoding
addr_napot = ((uint32_t) addr) | ((size >> 1) - 1);
if (on_read) {
RV_SET_CSR(CSR_TDATA1, TDATA1_LOAD);
}
if (on_write) {
RV_SET_CSR(CSR_TDATA1, TDATA1_STORE);
}
RV_WRITE_CSR(tdata2,addr_napot);
return;
}
static inline void cpu_ll_clear_watchpoint(int id)
{
if (cpu_ll_is_debugger_attached()) {
/* see description in cpu_ll_set_breakpoint() */
long args[] = {false, id};
int ret = semihosting_call_noerrno(ESP_SEMIHOSTING_SYS_WATCHPOINT_SET, args);
if (ret == 0){
return;
}
}
RV_WRITE_CSR(tselect,id);
RV_CLEAR_CSR(CSR_TCONTROL,TCONTROL_MTE);
RV_CLEAR_CSR(CSR_TDATA1, TDATA1_USER|TDATA1_MACHINE);
RV_CLEAR_CSR_FIELD(CSR_TDATA1, (long unsigned int) TDATA1_MATCH);
RV_CLEAR_CSR(CSR_TDATA1, TDATA1_MACHINE);
RV_CLEAR_CSR(CSR_TDATA1, TDATA1_LOAD|TDATA1_STORE|TDATA1_EXECUTE);
return;
}
static inline void cpu_ll_break(void)
{
asm volatile("ebreak\n");
return;
}
static inline void cpu_ll_set_vecbase(const void* vecbase)
{
uintptr_t vecbase_int = (uintptr_t)vecbase;
vecbase_int |= 1; // Set MODE field to treat MTVEC as a vector base address
RV_WRITE_CSR(mtvec, vecbase_int);
}
static inline void cpu_ll_waiti(void)
{
if (cpu_ll_is_debugger_attached() && DPORT_REG_GET_BIT(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPU_WAIT_MODE_FORCE_ON) == 0) {
/* when SYSTEM_CPU_WAIT_MODE_FORCE_ON is disabled in WFI mode SBA access to memory does not work for debugger,
so do not enter that mode when debugger is connected */
return;
}
asm volatile ("wfi\n");
}
static inline void cpu_ll_compare_and_set_native(volatile uint32_t *addr, uint32_t compare, uint32_t *set)
{
uint32_t old_value;
unsigned old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
old_value = *addr;
if (old_value == compare) {
*addr = *set;
}
RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
*set = old_value;
}
#ifdef __cplusplus
}
#endif

View File

@ -1,132 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdint.h>
#include "soc/soc_caps.h"
#include "soc/soc.h"
#include "soc/interrupt_core0_reg.h"
#include "riscv/interrupt.h"
#include "riscv/csr.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief enable interrupts specified by the mask
*
* @param mask bitmask of interrupts that needs to be enabled
*/
static inline void intr_cntrl_ll_enable_interrupts(uint32_t mask)
{
unsigned old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
esprv_intc_int_enable(mask);
RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
}
/**
* @brief disable interrupts specified by the mask
*
* @param mask bitmask of interrupts that needs to be disabled
*/
static inline void intr_cntrl_ll_disable_interrupts(uint32_t mask)
{
unsigned old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
esprv_intc_int_disable(mask);
RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
}
/**
* @brief Read the current interrupt mask of the CPU running this code.
*
* @return The current interrupt bitmask.
*/
static inline uint32_t intr_cntrl_ll_read_interrupt_mask(void)
{
return REG_READ(INTERRUPT_CORE0_CPU_INT_ENABLE_REG);
}
/**
* @brief checks if given interrupt number has a valid handler
*
* @param intr interrupt number ranged from 0 to 31
* @param cpu cpu number ranged betweeen 0 to SOC_CPU_CORES_NUM - 1
* @return true for valid handler, false otherwise
*/
static inline bool intr_cntrl_ll_has_handler(uint8_t intr, uint8_t cpu)
{
return intr_handler_get(intr);
}
/**
* @brief sets interrupt handler and optional argument of a given interrupt number
*
* @param intr interrupt number ranged from 0 to 31
* @param handler handler invoked when an interrupt occurs
* @param arg optional argument to pass to the handler
*/
static inline void intr_cntrl_ll_set_int_handler(uint8_t intr, interrupt_handler_t handler, void *arg)
{
intr_handler_set(intr, (void *)handler, arg);
}
/**
* @brief Gets argument passed to handler of a given interrupt number
*
* @param intr interrupt number ranged from 0 to 31
*
* @return argument used by handler of passed interrupt number
*/
static inline void *intr_cntrl_ll_get_int_handler_arg(uint8_t intr)
{
return intr_handler_get_arg(intr);
}
/**
* @brief Acknowledge an edge-trigger interrupt by clearing its pending flag
*
* @param intr interrupt number ranged from 0 to 31
*/
static inline void intr_cntrl_ll_edge_int_acknowledge(int intr)
{
REG_SET_BIT(INTERRUPT_CORE0_CPU_INT_CLEAR_REG, intr);
}
/**
* @brief Sets the interrupt level int the interrupt controller.
*
* @param interrupt_number Interrupt number 0 to 31
* @param level priority between 1 (lowest) to 7 (highest)
*/
static inline void intr_cntrl_ll_set_int_level(int intr, int level)
{
esprv_intc_int_set_priority(intr, level);
}
/**
* @brief Set the type of an interrupt in the controller.
*
* @param interrupt_number Interrupt number 0 to 31
* @param type interrupt type as edge or level triggered
*/
static inline void intr_cntrl_ll_set_int_type(int intr, int_type_t type)
{
esprv_intc_int_set_type(BIT(intr), type);
}
#ifdef __cplusplus
}
#endif

View File

@ -1,52 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#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};
const int rtc_cntl_c1_s[SOC_CPU_CORES_NUM] = {RTC_CNTL_SW_STALL_PROCPU_C1_S};
const int rtc_cntl_c0_m[SOC_CPU_CORES_NUM] = {RTC_CNTL_SW_STALL_PROCPU_C0_M};
const int rtc_cntl_c0_s[SOC_CPU_CORES_NUM] = {RTC_CNTL_SW_STALL_PROCPU_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};
const int rtc_cntl_c0_m[SOC_CPU_CORES_NUM] = {RTC_CNTL_SW_STALL_PROCPU_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, RTC_CNTL_SW_PROCPU_RST_M);
}
#ifdef __cplusplus
}
#endif

View File

@ -1,212 +0,0 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "soc/soc_caps.h"
#include "esp_bit_defs.h"
#include "soc/assist_debug_reg.h"
#include "esp_attr.h"
#include "riscv/csr.h"
#include "riscv/semihosting.h"
/*performance counter*/
#define CSR_PCER_MACHINE 0x7e0
#define CSR_PCMR_MACHINE 0x7e1
#define CSR_PCCR_MACHINE 0x7e2
#ifdef __cplusplus
extern "C" {
#endif
static inline int IRAM_ATTR cpu_ll_get_core_id(void)
{
#if SOC_CPU_CORES_NUM == 1
return 0; // No need to check core ID on single core hardware
#else
int cpuid;
cpuid = RV_READ_CSR(mhartid);
return cpuid;
#endif
}
static inline void cpu_ll_enable_cycle_count(void)
{
RV_WRITE_CSR(CSR_PCER_MACHINE,1);
RV_WRITE_CSR(CSR_PCMR_MACHINE,1);
return;
}
static inline uint32_t IRAM_ATTR cpu_ll_get_cycle_count(void)
{
uint32_t result;
result = RV_READ_CSR(CSR_PCCR_MACHINE);
return result;
}
static inline void IRAM_ATTR cpu_ll_set_cycle_count(uint32_t val)
{
RV_WRITE_CSR(CSR_PCCR_MACHINE, val);
}
static inline void* cpu_ll_get_sp(void)
{
void *sp;
asm volatile ("mv %0, sp;" : "=r" (sp));
return sp;
}
static inline void cpu_ll_init_hwloop(void)
{
// Nothing needed here for ESP32-H2
}
FORCE_INLINE_ATTR bool cpu_ll_is_debugger_attached(void)
{
return REG_GET_BIT(ASSIST_DEBUG_CORE_0_DEBUG_MODE_REG, ASSIST_DEBUG_CORE_0_DEBUG_MODULE_ACTIVE);
}
static inline void cpu_ll_set_breakpoint(int id, uint32_t pc)
{
if (cpu_ll_is_debugger_attached()) {
/* If we want to set breakpoint which when hit transfers control to debugger
* we need to set `action` in `mcontrol` to 1 (Enter Debug Mode).
* That `action` value is supported only when `dmode` of `tdata1` is set.
* But `dmode` can be modified by debugger only (from Debug Mode).
*
* So when debugger is connected we use special syscall to ask it to set breakpoint for us.
*/
long args[] = {true, id, (long)pc};
int ret = semihosting_call_noerrno(ESP_SEMIHOSTING_SYS_BREAKPOINT_SET, args);
if (ret == 0) {
return;
}
}
/* The code bellow sets breakpoint which will trigger `Breakpoint` exception
* instead transfering control to debugger. */
RV_WRITE_CSR(tselect,id);
RV_SET_CSR(CSR_TCONTROL,TCONTROL_MTE);
RV_SET_CSR(CSR_TDATA1, TDATA1_USER|TDATA1_MACHINE|TDATA1_EXECUTE);
RV_WRITE_CSR(tdata2,pc);
return;
}
static inline void cpu_ll_clear_breakpoint(int id)
{
if (cpu_ll_is_debugger_attached()) {
/* see description in cpu_ll_set_breakpoint() */
long args[] = {false, id};
int ret = semihosting_call_noerrno(ESP_SEMIHOSTING_SYS_BREAKPOINT_SET, args);
if (ret == 0){
return;
}
}
RV_WRITE_CSR(tselect,id);
RV_CLEAR_CSR(CSR_TCONTROL,TCONTROL_MTE);
RV_CLEAR_CSR(CSR_TDATA1, TDATA1_USER|TDATA1_MACHINE|TDATA1_EXECUTE);
return;
}
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 addr_napot;
if (cpu_ll_is_debugger_attached()) {
/* see description in cpu_ll_set_breakpoint() */
long args[] = {true, id, (long)addr, (long)size,
(long)((on_read ? ESP_SEMIHOSTING_WP_FLG_RD : 0) | (on_write ? ESP_SEMIHOSTING_WP_FLG_WR : 0))};
int ret = semihosting_call_noerrno(ESP_SEMIHOSTING_SYS_WATCHPOINT_SET, args);
if (ret == 0) {
return;
}
}
RV_WRITE_CSR(tselect,id);
RV_SET_CSR(CSR_TCONTROL, TCONTROL_MPTE | TCONTROL_MTE);
RV_SET_CSR(CSR_TDATA1, TDATA1_USER|TDATA1_MACHINE);
RV_SET_CSR_FIELD(CSR_TDATA1, (long unsigned int) TDATA1_MATCH, 1);
// add 0 in napot encoding
addr_napot = ((uint32_t) addr) | ((size >> 1) - 1);
if (on_read) {
RV_SET_CSR(CSR_TDATA1, TDATA1_LOAD);
}
if (on_write) {
RV_SET_CSR(CSR_TDATA1, TDATA1_STORE);
}
RV_WRITE_CSR(tdata2,addr_napot);
return;
}
static inline void cpu_ll_clear_watchpoint(int id)
{
if (cpu_ll_is_debugger_attached()) {
/* see description in cpu_ll_set_breakpoint() */
long args[] = {false, id};
int ret = semihosting_call_noerrno(ESP_SEMIHOSTING_SYS_WATCHPOINT_SET, args);
if (ret == 0){
return;
}
}
RV_WRITE_CSR(tselect,id);
RV_CLEAR_CSR(CSR_TCONTROL,TCONTROL_MTE);
RV_CLEAR_CSR(CSR_TDATA1, TDATA1_USER|TDATA1_MACHINE);
RV_CLEAR_CSR_FIELD(CSR_TDATA1, (long unsigned int) TDATA1_MATCH);
RV_CLEAR_CSR(CSR_TDATA1, TDATA1_MACHINE);
RV_CLEAR_CSR(CSR_TDATA1, TDATA1_LOAD|TDATA1_STORE|TDATA1_EXECUTE);
return;
}
static inline void cpu_ll_break(void)
{
asm volatile("ebreak\n");
return;
}
static inline void cpu_ll_set_vecbase(const void* vecbase)
{
uintptr_t vecbase_int = (uintptr_t)vecbase;
vecbase_int |= 1; // Set MODE field to treat MTVEC as a vector base address
RV_WRITE_CSR(mtvec, vecbase_int);
}
static inline void cpu_ll_waiti(void)
{
asm volatile ("wfi\n");
}
static inline void cpu_ll_compare_and_set_native(volatile uint32_t *addr, uint32_t compare, uint32_t *set)
{
uint32_t old_value;
unsigned old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
old_value = *addr;
if (old_value == compare) {
*addr = *set;
}
RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
*set = old_value;
}
#ifdef __cplusplus
}
#endif

View File

@ -1,132 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdint.h>
#include "soc/soc_caps.h"
#include "soc/soc.h"
#include "soc/interrupt_core0_reg.h"
#include "riscv/interrupt.h"
#include "riscv/csr.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief enable interrupts specified by the mask
*
* @param mask bitmask of interrupts that needs to be enabled
*/
static inline void intr_cntrl_ll_enable_interrupts(uint32_t mask)
{
unsigned old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
esprv_intc_int_enable(mask);
RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
}
/**
* @brief disable interrupts specified by the mask
*
* @param mask bitmask of interrupts that needs to be disabled
*/
static inline void intr_cntrl_ll_disable_interrupts(uint32_t mask)
{
unsigned old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
esprv_intc_int_disable(mask);
RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
}
/**
* @brief Read the current interrupt mask of the CPU running this code.
*
* @return The current interrupt bitmask.
*/
static inline uint32_t intr_cntrl_ll_read_interrupt_mask(void)
{
return REG_READ(INTERRUPT_CORE0_CPU_INT_ENABLE_REG);
}
/**
* @brief checks if given interrupt number has a valid handler
*
* @param intr interrupt number ranged from 0 to 31
* @param cpu cpu number ranged betweeen 0 to SOC_CPU_CORES_NUM - 1
* @return true for valid handler, false otherwise
*/
static inline bool intr_cntrl_ll_has_handler(uint8_t intr, uint8_t cpu)
{
return intr_handler_get(intr);
}
/**
* @brief sets interrupt handler and optional argument of a given interrupt number
*
* @param intr interrupt number ranged from 0 to 31
* @param handler handler invoked when an interrupt occurs
* @param arg optional argument to pass to the handler
*/
static inline void intr_cntrl_ll_set_int_handler(uint8_t intr, interrupt_handler_t handler, void *arg)
{
intr_handler_set(intr, (void *)handler, arg);
}
/**
* @brief Gets argument passed to handler of a given interrupt number
*
* @param intr interrupt number ranged from 0 to 31
*
* @return argument used by handler of passed interrupt number
*/
static inline void *intr_cntrl_ll_get_int_handler_arg(uint8_t intr)
{
return intr_handler_get_arg(intr);
}
/**
* @brief Acknowledge an edge-trigger interrupt by clearing its pending flag
*
* @param intr interrupt number ranged from 0 to 31
*/
static inline void intr_cntrl_ll_edge_int_acknowledge(int intr)
{
REG_SET_BIT(INTERRUPT_CORE0_CPU_INT_CLEAR_REG, intr);
}
/**
* @brief Sets the interrupt level int the interrupt controller.
*
* @param interrupt_number Interrupt number 0 to 31
* @param level priority between 1 (lowest) to 7 (highest)
*/
static inline void intr_cntrl_ll_set_int_level(int intr, int level)
{
esprv_intc_int_set_priority(intr, level);
}
/**
* @brief Set the type of an interrupt in the controller.
*
* @param interrupt_number Interrupt number 0 to 31
* @param type interrupt type as edge or level triggered
*/
static inline void intr_cntrl_ll_set_int_type(int intr, int_type_t type)
{
esprv_intc_int_set_type(BIT(intr), type);
}
#ifdef __cplusplus
}
#endif

View File

@ -1,52 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#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};
const int rtc_cntl_c1_s[SOC_CPU_CORES_NUM] = {RTC_CNTL_SW_STALL_PROCPU_C1_S};
const int rtc_cntl_c0_m[SOC_CPU_CORES_NUM] = {RTC_CNTL_SW_STALL_PROCPU_C0_M};
const int rtc_cntl_c0_s[SOC_CPU_CORES_NUM] = {RTC_CNTL_SW_STALL_PROCPU_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};
const int rtc_cntl_c0_m[SOC_CPU_CORES_NUM] = {RTC_CNTL_SW_STALL_PROCPU_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, RTC_CNTL_SW_PROCPU_RST_M);
}
#ifdef __cplusplus
}
#endif

View File

@ -1,197 +0,0 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "esp_attr.h"
#include "soc/soc_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"
#include "xtensa/xtruntime.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline uint32_t IRAM_ATTR cpu_ll_get_core_id(void)
{
return 0;
}
static inline uint32_t IRAM_ATTR cpu_ll_get_cycle_count(void)
{
uint32_t result;
RSR(CCOUNT, result);
return result;
}
static inline void IRAM_ATTR cpu_ll_set_cycle_count(uint32_t val)
{
WSR(CCOUNT, val);
}
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 & 0x3fffffffU) | 0x40000000U);
}
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 == (size_t)(1U << 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 1,15");
}
static inline void cpu_ll_set_vecbase(const void* vecbase)
{
asm volatile ("wsr %0, vecbase" :: "r" (vecbase));
}
static inline void cpu_ll_waiti(void)
{
asm volatile ("waiti 0\n");
}
static inline void cpu_ll_compare_and_set_native(volatile uint32_t *addr, uint32_t compare, uint32_t *set)
{
uint32_t old_value;
// No S32C1I, so do this by disabling and re-enabling interrupts (slower)
uint32_t intlevel;
__asm__ __volatile__ ("rsil %0, " XTSTR(XCHAL_EXCM_LEVEL) "\n"
: "=r"(intlevel));
old_value = *addr;
if (old_value == compare) {
*addr = *set;
}
__asm__ __volatile__ ("memw \n"
"wsr %0, ps\n"
:: "r"(intlevel));
*set = old_value;
}
#ifdef __cplusplus
}
#endif

View File

@ -1,107 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdint.h>
#include "soc/soc_caps.h"
#include "soc/soc.h"
#include "xtensa/xtensa_api.h"
#include "xtensa/config/specreg.h"
#include "xt_instr_macros.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief enable interrupts specified by the mask
*
* @param mask bitmask of interrupts that needs to be enabled
*/
static inline void intr_cntrl_ll_enable_interrupts(uint32_t mask)
{
xt_ints_on(mask);
}
/**
* @brief disable interrupts specified by the mask
*
* @param mask bitmask of interrupts that needs to be disabled
*/
static inline void intr_cntrl_ll_disable_interrupts(uint32_t mask)
{
xt_ints_off(mask);
}
/**
* @brief Read the current interrupt mask of the CPU running this code.
*
* @return The current interrupt bitmask.
*/
static inline uint32_t intr_cntrl_ll_read_interrupt_mask(void)
{
uint32_t int_mask;
RSR(INTENABLE, int_mask);
return int_mask;
}
/**
* @brief checks if given interrupt number has a valid handler
*
* @param intr interrupt number ranged from 0 to 31
* @param cpu cpu number ranged betweeen 0 to SOC_CPU_CORES_NUM - 1
* @return true for valid handler, false otherwise
*/
static inline bool intr_cntrl_ll_has_handler(uint8_t intr, uint8_t cpu)
{
return xt_int_has_handler(intr, cpu);
}
/**
* @brief sets interrupt handler and optional argument of a given interrupt number
*
* @param intr interrupt number ranged from 0 to 31
* @param handler handler invoked when an interrupt occurs
* @param arg optional argument to pass to the handler
*/
static inline void intr_cntrl_ll_set_int_handler(uint8_t intr, interrupt_handler_t handler, void *arg)
{
xt_set_interrupt_handler(intr, (xt_handler)handler, arg);
}
/**
* @brief Gets argument passed to handler of a given interrupt number
*
* @param intr interrupt number ranged from 0 to 31
*
* @return argument used by handler of passed interrupt number
*/
static inline void *intr_cntrl_ll_get_int_handler_arg(uint8_t intr)
{
return xt_get_interrupt_handler_arg(intr);
}
/**
* @brief Acknowledge an edge-trigger interrupt by clearing its pending flag
*
* @param intr interrupt number ranged from 0 to 31
*/
static inline void intr_cntrl_ll_edge_int_acknowledge (int intr)
{
xthal_set_intclear(1 << intr);
}
#ifdef __cplusplus
}
#endif

View File

@ -1,32 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/soc_caps.h"
#include "soc/rtc.h"
#ifdef __cplusplus
extern "C" {
#endif
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

@ -1,75 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "sdkconfig.h"
#include "hal/interrupt_controller_hal.h"
#include "hal/interrupt_controller_ll.h"
#include "soc/soc_caps.h"
#include "soc/soc.h"
//We should mark the interrupt for the timer used by FreeRTOS as reserved. The specific timer
//is selectable using menuconfig; we use these cpp bits to convert that into something we can use in
//the table below.
#if CONFIG_FREERTOS_CORETIMER_0
#define INT6RES INTDESC_RESVD
#else
#define INT6RES INTDESC_SPECIAL
#endif
#if CONFIG_FREERTOS_CORETIMER_1
#define INT15RES INTDESC_RESVD
#else
#define INT15RES INTDESC_SPECIAL
#endif
//This is basically a software-readable version of the interrupt usage table in include/soc/soc.h
const static int_desc_t interrupt_descriptor_table [32]={
{ 1, INTTP_LEVEL, {INTDESC_RESVD} }, //0
{ 1, INTTP_LEVEL, {INTDESC_RESVD} }, //1
{ 1, INTTP_LEVEL, {INTDESC_NORMAL} }, //2
{ 1, INTTP_LEVEL, {INTDESC_NORMAL} }, //3
{ 1, INTTP_LEVEL, {INTDESC_RESVD} }, //4
{ 1, INTTP_LEVEL, {INTDESC_RESVD} }, //5
{ 1, INTTP_NA, {INT6RES} }, //6
{ 1, INTTP_NA, {INTDESC_SPECIAL}}, //7
{ 1, INTTP_LEVEL, {INTDESC_RESVD } }, //8
{ 1, INTTP_LEVEL, {INTDESC_NORMAL } }, //9
{ 1, INTTP_EDGE , {INTDESC_NORMAL } }, //10
{ 3, INTTP_NA, {INTDESC_SPECIAL }}, //11
{ 1, INTTP_LEVEL, {INTDESC_NORMAL } }, //12
{ 1, INTTP_LEVEL, {INTDESC_NORMAL} }, //13
{ 7, INTTP_LEVEL, {INTDESC_RESVD} }, //14, NMI
{ 3, INTTP_NA, {INT15RES} }, //15
{ 5, INTTP_NA, {INTDESC_SPECIAL } }, //16
{ 1, INTTP_LEVEL, {INTDESC_NORMAL } }, //17
{ 1, INTTP_LEVEL, {INTDESC_NORMAL } }, //18
{ 2, INTTP_LEVEL, {INTDESC_NORMAL } }, //19
{ 2, INTTP_LEVEL, {INTDESC_NORMAL } }, //20
{ 2, INTTP_LEVEL, {INTDESC_NORMAL } }, //21
{ 3, INTTP_EDGE, {INTDESC_RESVD } }, //22
{ 3, INTTP_LEVEL, {INTDESC_NORMAL } }, //23
{ 4, INTTP_LEVEL, {INTDESC_RESVD } }, //24
{ 4, INTTP_LEVEL, {INTDESC_RESVD } }, //25
{ 5, INTTP_LEVEL, {INTDESC_NORMAL } }, //26
{ 3, INTTP_LEVEL, {INTDESC_RESVD } }, //27
{ 4, INTTP_EDGE, {INTDESC_NORMAL } }, //28
{ 3, INTTP_NA, {INTDESC_SPECIAL }}, //29
{ 4, INTTP_EDGE, {INTDESC_RESVD } }, //30
{ 5, INTTP_LEVEL, {INTDESC_RESVD } }, //31
};
const int_desc_t *interrupt_controller_hal_desc_table(void)
{
return interrupt_descriptor_table;
}

View File

@ -1,189 +0,0 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "soc/soc_caps.h"
#include "xt_instr_macros.h"
#include "xtensa/config/specreg.h"
#include "xtensa/config/extreg.h"
#include "esp_bit_defs.h"
#include "esp_attr.h"
#include "xtensa/config/core.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline uint32_t IRAM_ATTR cpu_ll_get_core_id(void)
{
uint32_t id;
asm volatile (
"rsr.prid %0\n"
"extui %0,%0,13,1"
:"=r"(id));
return id;
}
static inline uint32_t IRAM_ATTR cpu_ll_get_cycle_count(void)
{
uint32_t result;
RSR(CCOUNT, result);
return result;
}
static inline void IRAM_ATTR cpu_ll_set_cycle_count(uint32_t val)
{
WSR(CCOUNT, val);
}
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 == (size_t)(1U << 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 1,15");
}
static inline void cpu_ll_set_vecbase(const void *vecbase)
{
asm volatile ("wsr %0, vecbase" :: "r" (vecbase));
}
static inline void cpu_ll_waiti(void)
{
asm volatile ("waiti 0\n");
}
static inline void cpu_ll_compare_and_set_native(volatile uint32_t *addr, uint32_t compare, uint32_t *set)
{
__asm__ __volatile__ (
"WSR %2,SCOMPARE1 \n"
"S32C1I %0, %1, 0 \n"
:"=r"(*set)
:"r"(addr), "r"(compare), "0"(*set)
);
}
#ifdef __cplusplus
}
#endif

View File

@ -1,107 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdint.h>
#include "soc/soc_caps.h"
#include "soc/soc.h"
#include "xtensa/xtensa_api.h"
#include "xtensa/config/specreg.h"
#include "xt_instr_macros.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief enable interrupts specified by the mask
*
* @param mask bitmask of interrupts that needs to be enabled
*/
static inline void intr_cntrl_ll_enable_interrupts(uint32_t mask)
{
xt_ints_on(mask);
}
/**
* @brief disable interrupts specified by the mask
*
* @param mask bitmask of interrupts that needs to be disabled
*/
static inline void intr_cntrl_ll_disable_interrupts(uint32_t mask)
{
xt_ints_off(mask);
}
/**
* @brief Read the current interrupt mask of the CPU running this code.
*
* @return The current interrupt bitmask.
*/
static inline uint32_t intr_cntrl_ll_read_interrupt_mask(void)
{
uint32_t int_mask;
RSR(INTENABLE, int_mask);
return int_mask;
}
/**
* @brief checks if given interrupt number has a valid handler
*
* @param intr interrupt number ranged from 0 to 31
* @param cpu cpu number ranged betweeen 0 to SOC_CPU_CORES_NUM - 1
* @return true for valid handler, false otherwise
*/
static inline bool intr_cntrl_ll_has_handler(uint8_t intr, uint8_t cpu)
{
return xt_int_has_handler(intr, cpu);
}
/**
* @brief sets interrupt handler and optional argument of a given interrupt number
*
* @param intr interrupt number ranged from 0 to 31
* @param handler handler invoked when an interrupt occurs
* @param arg optional argument to pass to the handler
*/
static inline void intr_cntrl_ll_set_int_handler(uint8_t intr, interrupt_handler_t handler, void *arg)
{
xt_set_interrupt_handler(intr, (xt_handler)handler, arg);
}
/**
* @brief Gets argument passed to handler of a given interrupt number
*
* @param intr interrupt number ranged from 0 to 31
*
* @return argument used by handler of passed interrupt number
*/
static inline void *intr_cntrl_ll_get_int_handler_arg(uint8_t intr)
{
return xt_get_interrupt_handler_arg(intr);
}
/**
* @brief Acknowledge an edge-trigger interrupt by clearing its pending flag
*
* @param intr interrupt number ranged from 0 to 31
*/
static inline void intr_cntrl_ll_edge_int_acknowledge (int intr)
{
xthal_set_intclear(1 << intr);
}
#ifdef __cplusplus
}
#endif

View File

@ -1,54 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/soc_caps.h"
#include "soc/rtc.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,75 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "sdkconfig.h"
#include "hal/interrupt_controller_hal.h"
#include "hal/interrupt_controller_ll.h"
#include "soc/soc_caps.h"
#include "soc/soc.h"
//We should mark the interrupt for the timer used by FreeRTOS as reserved. The specific timer
//is selectable using menuconfig; we use these cpp bits to convert that into something we can use in
//the table below.
#if CONFIG_FREERTOS_CORETIMER_0
#define INT6RES INTDESC_RESVD
#else
#define INT6RES INTDESC_SPECIAL
#endif
#if CONFIG_FREERTOS_CORETIMER_1
#define INT15RES INTDESC_RESVD
#else
#define INT15RES INTDESC_SPECIAL
#endif
//This is basically a software-readable version of the interrupt usage table in include/soc/soc.h
const static int_desc_t interrupt_descriptor_table [32]={
{ 1, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //0
{ 1, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //1
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //2
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //3
{ 1, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_NORMAL} }, //4
{ 1, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //5
{ 1, INTTP_NA, {INT6RES, INT6RES } }, //6
{ 1, INTTP_NA, {INTDESC_SPECIAL,INTDESC_SPECIAL}}, //7
{ 1, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //8
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //9
{ 1, INTTP_EDGE , {INTDESC_NORMAL, INTDESC_NORMAL} }, //10
{ 3, INTTP_NA, {INTDESC_SPECIAL,INTDESC_SPECIAL}}, //11
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //12
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //13
{ 7, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //14, NMI
{ 3, INTTP_NA, {INT15RES, INT15RES } }, //15
{ 5, INTTP_NA, {INTDESC_SPECIAL,INTDESC_SPECIAL} }, //16
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //17
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //18
{ 2, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //19
{ 2, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //20
{ 2, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //21
{ 3, INTTP_EDGE, {INTDESC_RESVD, INTDESC_NORMAL} }, //22
{ 3, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //23
{ 4, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_NORMAL} }, //24
{ 4, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //25
{ 5, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_RESVD } }, //26
{ 3, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //27
{ 4, INTTP_EDGE, {INTDESC_NORMAL, INTDESC_NORMAL} }, //28
{ 3, INTTP_NA, {INTDESC_SPECIAL,INTDESC_SPECIAL}}, //29
{ 4, INTTP_EDGE, {INTDESC_RESVD, INTDESC_RESVD } }, //30
{ 5, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //31
};
const int_desc_t *interrupt_controller_hal_desc_table(void)
{
return interrupt_descriptor_table;
}

View File

@ -1,21 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#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

@ -1,196 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdbool.h>
#include "hal/interrupt_controller_types.h"
#include "hal/interrupt_controller_ll.h"
#include "soc/soc_caps.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef SOC_CPU_HAS_FLEXIBLE_INTC
/**
* @brief Gets target platform interrupt descriptor table
*
* @return Address of interrupt descriptor table
*/
__attribute__((pure)) const int_desc_t *interrupt_controller_hal_desc_table(void);
#endif
/**
* @brief Gets the interrupt type given an interrupt number.
*
* @param interrupt_number Interrupt number 0 to 31
* @return interrupt type
*/
__attribute__((pure)) int_type_t interrupt_controller_hal_desc_type(int interrupt_number);
/**
* @brief Gets the interrupt level given an interrupt number.
*
* @param interrupt_number Interrupt number 0 to 31
* @return interrupt level bitmask
*/
__attribute__((pure)) int interrupt_controller_hal_desc_level(int interrupt_number);
/**
* @brief Gets the cpu flags given the interrupt number and target cpu.
*
* @param interrupt_number Interrupt number 0 to 31
* @param cpu_number CPU number between 0 and SOC_CPU_CORES_NUM - 1
* @return flags for that interrupt number
*/
__attribute__((pure)) int_desc_flag_t interrupt_controller_hal_desc_flags(int interrupt_number, int cpu_number);
/**
* @brief Gets the interrupt type given an interrupt number.
*
* @param interrupt_number Interrupt number 0 to 31
* @return interrupt type
*/
static inline int_type_t interrupt_controller_hal_get_type(int interrupt_number)
{
return interrupt_controller_hal_desc_type(interrupt_number);
}
/**
* @brief Gets the interrupt level given an interrupt number.
*
* @param interrupt_number Interrupt number 0 to 31
* @return interrupt level bitmask
*/
static inline int interrupt_controller_hal_get_level(int interrupt_number)
{
return interrupt_controller_hal_desc_level(interrupt_number);
}
#ifdef SOC_CPU_HAS_FLEXIBLE_INTC
/**
* @brief Set the type of an interrupt in the controller.
*
* @param interrupt_number Interrupt number 0 to 31
* @param type interrupt type as edge or level triggered
*/
static inline void interrupt_controller_hal_set_int_type(int intr, int_type_t type)
{
intr_cntrl_ll_set_int_type(intr, type);
}
/**
* @brief Sets the interrupt level int the interrupt controller.
*
* @param interrupt_number Interrupt number 0 to 31
* @param level priority between 1 (lowest) to 7 (highest)
*/
static inline void interrupt_controller_hal_set_int_level(int intr, int level)
{
intr_cntrl_ll_set_int_level(intr, level);
}
#endif
/**
* @brief Gets the cpu flags given the interrupt number and target cpu.
*
* @param interrupt_number Interrupt number 0 to 31
* @param cpu_number CPU number between 0 and SOC_CPU_CORES_NUM - 1
* @return flags for that interrupt number
*/
static inline uint32_t interrupt_controller_hal_get_cpu_desc_flags(int interrupt_number, int cpu_number)
{
return interrupt_controller_hal_desc_flags(interrupt_number, cpu_number);
}
/**
* @brief enable interrupts specified by the mask
*
* @param mask bitmask of interrupts that needs to be enabled
*/
static inline void interrupt_controller_hal_enable_interrupts(uint32_t mask)
{
intr_cntrl_ll_enable_interrupts(mask);
}
/**
* @brief disable interrupts specified by the mask
*
* @param mask bitmask of interrupts that needs to be disabled
*/
static inline void interrupt_controller_hal_disable_interrupts(uint32_t mask)
{
intr_cntrl_ll_disable_interrupts(mask);
}
/**
* @brief Read the current interrupt mask.
*
* @return The bitmask of current interrupts
*/
static inline uint32_t interrupt_controller_hal_read_interrupt_mask(void)
{
return intr_cntrl_ll_read_interrupt_mask();
}
/**
* @brief checks if given interrupt number has a valid handler
*
* @param intr interrupt number ranged from 0 to 31
* @param cpu cpu number ranged betweeen 0 to SOC_CPU_CORES_NUM - 1
* @return true for valid handler, false otherwise
*/
static inline bool interrupt_controller_hal_has_handler(int intr, int cpu)
{
return intr_cntrl_ll_has_handler(intr, cpu);
}
/**
* @brief sets interrupt handler and optional argument of a given interrupt number
*
* @param intr interrupt number ranged from 0 to 31
* @param handler handler invoked when an interrupt occurs
* @param arg optional argument to pass to the handler
*/
static inline void interrupt_controller_hal_set_int_handler(uint8_t intr, interrupt_handler_t handler, void *arg)
{
intr_cntrl_ll_set_int_handler(intr, handler, arg);
}
/**
* @brief Gets argument passed to handler of a given interrupt number
*
* @param intr interrupt number ranged from 0 to 31
*
* @return argument used by handler of passed interrupt number
*/
static inline void * interrupt_controller_hal_get_int_handler_arg(uint8_t intr)
{
return intr_cntrl_ll_get_int_handler_arg(intr);
}
/**
* @brief Acknowledge an edge-trigger interrupt by clearing its pending flag
*
* @param intr interrupt number ranged from 0 to 31
*/
static inline void interrupt_controller_hal_edge_int_acknowledge(int intr)
{
intr_cntrl_ll_edge_int_acknowledge(intr);
}
#ifdef __cplusplus
}
#endif

View File

@ -1,46 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "soc/soc_caps.h"
#include "soc/soc.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
INTDESC_NORMAL=0,
INTDESC_RESVD,
INTDESC_SPECIAL,
} int_desc_flag_t;
typedef enum {
INTTP_LEVEL=0,
INTTP_EDGE,
INTTP_NA,
} int_type_t;
typedef struct {
int level;
int_type_t type;
int_desc_flag_t cpuflags[SOC_CPU_CORES_NUM];
} int_desc_t;
typedef void (*interrupt_handler_t)(void *arg);
#ifdef __cplusplus
}
#endif

View File

@ -1,75 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"
#include "soc/soc_caps.h"
#include "hal/cpu_hal.h"
#include "hal/soc_ll.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 (uint32_t 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]
*/
void 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]
*/
void 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]
*/
#define soc_hal_reset_core(core) soc_ll_reset_core((core))
#ifdef __cplusplus
}
#endif

View File

@ -1,73 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "hal/interrupt_controller_hal.h"
#include "soc/soc_caps.h"
#if __riscv
#include "riscv/instruction_decode.h"
static bool is_interrupt_number_reserved(int interrupt_number)
{
// Workaround to reserve interrupt number 1 for Wi-Fi, 5,8 for Bluetooth, 6 for "permanently disabled interrupt"
// [TODO: IDF-2465]
const uint32_t reserved = BIT(1) | BIT(5) | BIT(6) | BIT(8);
if (reserved & BIT(interrupt_number)) {
return true;
}
extern int _vector_table;
extern int _interrupt_handler;
const intptr_t pc = (intptr_t)(&_vector_table + interrupt_number);
/* JAL instructions are relative to the PC there are executed from. */
const intptr_t destination = pc + riscv_decode_offset_from_jal_instruction(pc);
return destination != (intptr_t)&_interrupt_handler;
}
#endif
int_type_t interrupt_controller_hal_desc_type(int interrupt_number)
{
#ifndef SOC_CPU_HAS_FLEXIBLE_INTC
const int_desc_t *int_desc = interrupt_controller_hal_desc_table();
return (int_desc[interrupt_number].type);
#else
return (INTTP_NA);
#endif
}
int interrupt_controller_hal_desc_level(int interrupt_number)
{
#ifndef SOC_CPU_HAS_FLEXIBLE_INTC
const int_desc_t *int_desc = interrupt_controller_hal_desc_table();
return (int_desc[interrupt_number].level);
#else
return 1;
#endif
}
int_desc_flag_t interrupt_controller_hal_desc_flags(int interrupt_number, int cpu_number)
{
#ifndef SOC_CPU_HAS_FLEXIBLE_INTC
const int_desc_t *int_desc = interrupt_controller_hal_desc_table();
return (int_desc[interrupt_number].cpuflags[cpu_number]);
#else
#if __riscv
return is_interrupt_number_reserved(interrupt_number) ? INTDESC_RESVD : INTDESC_NORMAL;
#else
return INTDESC_NORMAL;
#endif
#endif
}

View File

@ -14,8 +14,6 @@ entries:
spi_flash_encrypt_hal_iram (noflash)
ledc_hal_iram (noflash)
i2c_hal_iram (noflash)
cpu_hal (noflash)
soc_hal (noflash)
if HAL_WDT_USE_ROM_IMPL = n:
wdt_hal_iram (noflash)
if SOC_SYSTIMER_SUPPORTED = y && HAL_SYSTIMER_USE_ROM_IMPL = n:

View File

@ -1,36 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdint.h>
#include <stdlib.h>
#include "esp_err.h"
#include "hal/soc_hal.h"
#include "hal/soc_ll.h"
#include "hal/rtc_cntl_ll.h"
#include "soc/soc_caps.h"
#include "soc/rtc.h"
#if SOC_CPU_CORES_NUM > 1
void soc_hal_stall_core(int core)
{
soc_ll_stall_core(core);
}
void soc_hal_unstall_core(int core)
{
soc_ll_unstall_core(core);
}
#endif // SOC_CPU_CORES_NUM > 1

View File

@ -132,6 +132,16 @@
#define XCHAL_ERRATUM_497 0
#endif
/*
* Erratum 572 (releases TBD, but present in ESP32S3)
* Disable zero-overhead loop buffer to prevent rare illegal instruction
* exceptions while executing zero-overhead loops.
*/
#if ( XCHAL_HAVE_LOOPS && XCHAL_LOOP_BUFFER_SIZE != 0 )
#define XCHAL_ERRATUM_572 1
#else
#define XCHAL_ERRATUM_572 0
#endif
/*----------------------------------------------------------------------
ISA

View File

@ -766,35 +766,29 @@ components/freertos/FreeRTOS-Kernel-SMP/stream_buffer.c
components/freertos/FreeRTOS-Kernel-SMP/tasks.c
components/freertos/FreeRTOS-Kernel-SMP/timers.c
components/hal/aes_hal.c
components/hal/cpu_hal.c
components/hal/dac_hal.c
components/hal/ds_hal.c
components/hal/esp32/gpio_hal_workaround.c
components/hal/esp32/include/hal/aes_ll.h
components/hal/esp32/include/hal/can_hal.h
components/hal/esp32/include/hal/can_types.h
components/hal/esp32/include/hal/interrupt_controller_ll.h
components/hal/esp32/include/hal/mpu_ll.h
components/hal/esp32/include/hal/rtc_io_ll.h
components/hal/esp32/include/hal/rwdt_ll.h
components/hal/esp32/include/hal/sigmadelta_ll.h
components/hal/esp32/include/hal/soc_ll.h
components/hal/esp32/include/hal/spi_flash_encrypted_ll.h
components/hal/esp32/include/hal/touch_sensor_hal.h
components/hal/esp32/include/hal/trace_ll.h
components/hal/esp32/include/hal/uart_ll.h
components/hal/esp32/interrupt_descriptor_table.c
components/hal/esp32c3/hmac_hal.c
components/hal/esp32c3/include/hal/aes_ll.h
components/hal/esp32c3/include/hal/ds_ll.h
components/hal/esp32c3/include/hal/hmac_hal.h
components/hal/esp32c3/include/hal/hmac_ll.h
components/hal/esp32c3/include/hal/interrupt_controller_ll.h
components/hal/esp32c3/include/hal/mpu_ll.h
components/hal/esp32c3/include/hal/rtc_cntl_ll.h
components/hal/esp32c3/include/hal/sha_ll.h
components/hal/esp32c3/include/hal/sigmadelta_ll.h
components/hal/esp32c3/include/hal/soc_ll.h
components/hal/esp32c3/include/hal/spi_flash_encrypted_ll.h
components/hal/esp32c3/include/hal/systimer_ll.h
components/hal/esp32c3/include/hal/uhci_ll.h
@ -805,12 +799,10 @@ components/hal/esp32h2/include/hal/aes_ll.h
components/hal/esp32h2/include/hal/ds_ll.h
components/hal/esp32h2/include/hal/hmac_hal.h
components/hal/esp32h2/include/hal/hmac_ll.h
components/hal/esp32h2/include/hal/interrupt_controller_ll.h
components/hal/esp32h2/include/hal/mpu_ll.h
components/hal/esp32h2/include/hal/rtc_cntl_ll.h
components/hal/esp32h2/include/hal/sha_ll.h
components/hal/esp32h2/include/hal/sigmadelta_ll.h
components/hal/esp32h2/include/hal/soc_ll.h
components/hal/esp32h2/include/hal/spi_flash_encrypted_ll.h
components/hal/esp32h2/include/hal/uhci_ll.h
components/hal/esp32h2/include/hal/uhci_types.h
@ -823,42 +815,33 @@ components/hal/esp32s2/include/hal/crypto_dma_ll.h
components/hal/esp32s2/include/hal/dac_hal.h
components/hal/esp32s2/include/hal/dedic_gpio_ll.h
components/hal/esp32s2/include/hal/i2c_ll.h
components/hal/esp32s2/include/hal/interrupt_controller_ll.h
components/hal/esp32s2/include/hal/memprot_peri_ll.h
components/hal/esp32s2/include/hal/mpu_ll.h
components/hal/esp32s2/include/hal/rtc_io_ll.h
components/hal/esp32s2/include/hal/sha_ll.h
components/hal/esp32s2/include/hal/sigmadelta_ll.h
components/hal/esp32s2/include/hal/soc_ll.h
components/hal/esp32s2/include/hal/spi_flash_encrypted_ll.h
components/hal/esp32s2/include/hal/systimer_ll.h
components/hal/esp32s2/include/hal/trace_ll.h
components/hal/esp32s2/include/hal/usb_ll.h
components/hal/esp32s2/interrupt_descriptor_table.c
components/hal/esp32s2/touch_sensor_hal.c
components/hal/esp32s3/include/hal/aes_ll.h
components/hal/esp32s3/include/hal/interrupt_controller_ll.h
components/hal/esp32s3/include/hal/memprot_ll.h
components/hal/esp32s3/include/hal/mpu_ll.h
components/hal/esp32s3/include/hal/rwdt_ll.h
components/hal/esp32s3/include/hal/sha_ll.h
components/hal/esp32s3/include/hal/sigmadelta_ll.h
components/hal/esp32s3/include/hal/soc_ll.h
components/hal/esp32s3/include/hal/spi_flash_encrypted_ll.h
components/hal/esp32s3/include/hal/systimer_ll.h
components/hal/esp32s3/include/hal/uhci_ll.h
components/hal/esp32s3/include/hal/usb_ll.h
components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h
components/hal/esp32s3/interrupt_descriptor_table.c
components/hal/include/hal/aes_hal.h
components/hal/include/hal/aes_types.h
components/hal/include/hal/cpu_types.h
components/hal/include/hal/dac_hal.h
components/hal/include/hal/dac_types.h
components/hal/include/hal/ds_hal.h
components/hal/include/hal/esp_flash_err.h
components/hal/include/hal/interrupt_controller_hal.h
components/hal/include/hal/interrupt_controller_types.h
components/hal/include/hal/mpu_hal.h
components/hal/include/hal/mpu_types.h
components/hal/include/hal/rtc_io_types.h
@ -866,7 +849,6 @@ components/hal/include/hal/sdio_slave_hal.h
components/hal/include/hal/sdio_slave_ll.h
components/hal/include/hal/sha_hal.h
components/hal/include/hal/sigmadelta_hal.h
components/hal/include/hal/soc_hal.h
components/hal/include/hal/spi_flash_encrypt_hal.h
components/hal/include/hal/spi_slave_hal.h
components/hal/include/hal/spi_slave_hd_hal.h
@ -877,7 +859,6 @@ components/hal/include/hal/usb_hal.h
components/hal/include/hal/usb_types_private.h
components/hal/include/hal/wdt_hal.h
components/hal/include/hal/wdt_types.h
components/hal/interrupt_controller_hal.c
components/hal/ledc_hal_iram.c
components/hal/mpu_hal.c
components/hal/platform_port/include/hal/assert.h
@ -886,7 +867,6 @@ components/hal/platform_port/include/hal/misc.h
components/hal/rtc_io_hal.c
components/hal/sha_hal.c
components/hal/sigmadelta_hal.c
components/hal/soc_hal.c
components/hal/spi_flash_encrypt_hal_iram.c
components/hal/spi_flash_hal_gpspi.c
components/hal/spi_slave_hal.c
@ -1406,7 +1386,6 @@ components/soc/esp32s3/include/soc/boot_mode.h
components/soc/esp32s3/include/soc/brownout_caps.h
components/soc/esp32s3/include/soc/clkout_channel.h
components/soc/esp32s3/include/soc/cpu.h
components/soc/esp32s3/include/soc/cpu_caps.h
components/soc/esp32s3/include/soc/extmem_reg.h
components/soc/esp32s3/include/soc/extmem_struct.h
components/soc/esp32s3/include/soc/fe_reg.h