mirror of
https://github.com/espressif/esp-idf.git
synced 2025-09-02 14:49:04 +00:00
Merge branch 'refactor/esp_hw_support_cpu' into 'master'
esp_hw_support: Add new esp_cpu.h abstraction Closes IDF-4769 See merge request espressif/esp-idf!17091
This commit is contained in:
@@ -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
|
@@ -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
|
@@ -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
|
Reference in New Issue
Block a user