2016-08-23 05:09:44 -04:00
|
|
|
// Copyright 2010-2016 Espressif Systems (Shanghai) PTE LTD
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
#ifndef _SOC_CPU_H
|
|
|
|
#define _SOC_CPU_H
|
|
|
|
|
2016-10-25 10:12:07 -04:00
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stddef.h>
|
2020-11-05 23:00:07 -05:00
|
|
|
|
|
|
|
#if __XTENSA__
|
|
|
|
#include "xt_instr_macros.h"
|
|
|
|
// [refactor-todo] not actually needed in this header now,
|
|
|
|
// but kept for compatibility
|
2016-08-23 05:09:44 -04:00
|
|
|
#include "xtensa/corebits.h"
|
2018-10-31 23:30:48 -04:00
|
|
|
#include "xtensa/config/core.h"
|
2016-08-23 05:09:44 -04:00
|
|
|
|
2020-01-18 21:02:21 -05:00
|
|
|
#include "xtensa/config/specreg.h"
|
2020-11-05 23:00:07 -05:00
|
|
|
#endif
|
2020-01-18 21:02:21 -05:00
|
|
|
|
2020-01-18 21:47:20 -05:00
|
|
|
#include "hal/cpu_hal.h"
|
|
|
|
|
2020-01-26 22:43:08 -05:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2016-12-20 00:04:15 -05:00
|
|
|
/** @brief Read current stack pointer address
|
|
|
|
*
|
|
|
|
*/
|
2019-07-16 05:33:30 -04:00
|
|
|
static inline void *get_sp(void)
|
2016-12-20 00:04:15 -05:00
|
|
|
{
|
2020-01-18 21:47:20 -05:00
|
|
|
return cpu_hal_get_sp();
|
2016-12-20 00:04:15 -05:00
|
|
|
}
|
|
|
|
|
2016-11-21 04:15:37 -05:00
|
|
|
/**
|
|
|
|
* @brief Stall CPU using RTC controller
|
|
|
|
* @param cpu_id ID of the CPU to stall (0 = PRO, 1 = APP)
|
|
|
|
*/
|
|
|
|
void esp_cpu_stall(int cpu_id);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Un-stall CPU using RTC controller
|
|
|
|
* @param cpu_id ID of the CPU to un-stall (0 = PRO, 1 = APP)
|
|
|
|
*/
|
|
|
|
void esp_cpu_unstall(int cpu_id);
|
|
|
|
|
esp_restart: fix possible race while stalling other CPU, enable WDT early
Previously esp_restart would stall the other CPU before enabling RTC_WDT.
If the other CPU was executing an s32c1i instruction, the lock signal
from CPU to the arbiter would still be held after CPU was stalled. If
the CPU running esp_restart would then try to access the same locked
memory pool, it would be stuck, because lock signal would never be
released.
With this change, esp_restart resets the other CPU before stalling it.
Ideally, we would want to reset the CPU and keep it in reset, but the
hardware doesn't have such feature for PRO_CPU (it is possible to hold
APP_CPU in reset using DPORT register). Given that ROM code will not use
s32c1i in the first few hundred cycles, doing reset and then stall seems
to be safe.
In addition to than, RTC_WDT initialization is moved to the beginning of
the function, to prevent possible lock-up if CPU stalling still has any
issue.
2017-10-26 07:11:47 -04:00
|
|
|
/**
|
|
|
|
* @brief Reset CPU using RTC controller
|
|
|
|
* @param cpu_id ID of the CPU to reset (0 = PRO, 1 = APP)
|
|
|
|
*/
|
|
|
|
void esp_cpu_reset(int cpu_id);
|
|
|
|
|
|
|
|
|
2016-12-06 19:33:24 -05:00
|
|
|
/**
|
|
|
|
* @brief Returns true if a JTAG debugger is attached to CPU
|
|
|
|
* OCD (on chip debug) port.
|
|
|
|
*
|
|
|
|
* @note If "Make exception and panic handlers JTAG/OCD aware"
|
|
|
|
* is disabled, this function always returns false.
|
|
|
|
*/
|
2019-07-16 05:33:30 -04:00
|
|
|
bool esp_cpu_in_ocd_debug_mode(void);
|
2016-12-06 19:33:24 -05:00
|
|
|
|
2018-11-29 04:06:21 -05:00
|
|
|
/**
|
|
|
|
* @brief Convert the PC register value to its true address
|
|
|
|
*
|
|
|
|
* The address of the current instruction is not stored as an exact uint32_t
|
|
|
|
* representation in PC register. This function will convert the value stored in
|
|
|
|
* the PC register to a uint32_t address.
|
|
|
|
*
|
|
|
|
* @param pc_raw The PC as stored in register format.
|
|
|
|
*
|
|
|
|
* @return Address in uint32_t format
|
|
|
|
*/
|
|
|
|
static inline uint32_t esp_cpu_process_stack_pc(uint32_t pc)
|
|
|
|
{
|
|
|
|
if (pc & 0x80000000) {
|
|
|
|
//Top two bits of a0 (return address) specify window increment. Overwrite to map to address space.
|
|
|
|
pc = (pc & 0x3fffffff) | 0x40000000;
|
|
|
|
}
|
|
|
|
//Minus 3 to get PC of previous instruction (i.e. instruction executed before return address)
|
|
|
|
return pc - 3;
|
|
|
|
}
|
|
|
|
|
2019-11-21 12:42:46 -05:00
|
|
|
typedef uint32_t esp_cpu_ccount_t;
|
|
|
|
|
|
|
|
static inline esp_cpu_ccount_t esp_cpu_get_ccount(void)
|
|
|
|
{
|
2020-11-05 23:00:07 -05:00
|
|
|
return cpu_hal_get_cycle_count();
|
2019-11-21 12:42:46 -05:00
|
|
|
}
|
|
|
|
|
2020-11-05 23:00:07 -05:00
|
|
|
/**
|
|
|
|
* @brief Configure CPU to disable access to invalid memory regions
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
void esp_cpu_configure_region_protection(void);
|
|
|
|
|
2020-01-26 22:43:08 -05:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-08-23 05:09:44 -04:00
|
|
|
#endif
|