1
6
7
17
18
19
20
24
25
26
29
30
37
38
45
46
51
52
65
66
69
70
71
72
73
74
75
79
80
81
82
99
100
101
102
103
104
108
109
110
111
122
123
124
125
126
127
128
129
133
136
137
138
141
142
143
146
147
148
149
150
151
164
165
166
167
168
169
173
174
175
176
187
188
189
190
191
194
195
196
197
198
199
200
201
202
203
204
205
206
208
209
210
211
216
217
218
221
222
223
224
225
226
227
228
229
234
235
236
237
238
239
/* ... */
#include "sdkconfig.h"
#include <stdint.h>
#include <assert.h>
#include "soc/soc.h"
#include "soc/soc_caps.h"
#include "hal/cpu_utility_ll.h"
#include "esp_bit_defs.h"
#include "esp_attr.h"
#include "esp_err.h"
#include "esp_cpu.h"10 includes
#if __XTENSA__
#include "xtensa/config/core-isa.h"
#else
#include "riscv/semihosting.h"
#if SOC_CPU_HAS_FLEXIBLE_INTC
#include "riscv/instruction_decode.h"
#endif/* ... */
#endif
/* ... */
void esp_cpu_stall(int core_id)
{
#if SOC_CPU_CORES_NUM > 1
assert(core_id >= 0 && core_id < SOC_CPU_CORES_NUM);
cpu_utility_ll_stall_cpu(core_id);/* ... */
#endif
}{ ... }
void esp_cpu_unstall(int core_id)
{
#if SOC_CPU_CORES_NUM > 1
assert(core_id >= 0 && core_id < SOC_CPU_CORES_NUM);
cpu_utility_ll_unstall_cpu(core_id);/* ... */
#endif
}{ ... }
void esp_cpu_reset(int core_id)
{
assert(core_id >= 0 && core_id < SOC_CPU_CORES_NUM);
cpu_utility_ll_reset_cpu(core_id);
}{ ... }
void esp_cpu_wait_for_intr(void)
{
#if __XTENSA__
xt_utils_wait_for_intr();
#else
if (esp_cpu_dbgr_is_attached() && cpu_utility_ll_wait_mode() == 0) {
/* ... */
return;
}{...}
rv_utils_wait_for_intr();/* ... */
#endif
}{ ... }
/* ... */
#if SOC_CPU_BREAKPOINTS_NUM > 0
esp_err_t esp_cpu_set_breakpoint(int bp_num, const void *bp_addr)
{
/* ... */
#if __XTENSA__
xt_utils_set_breakpoint(bp_num, (uint32_t)bp_addr);
#else
if (esp_cpu_dbgr_is_attached()) {
/* ... */
long args[] = {true, bp_num, (long)bp_addr};
int ret = semihosting_call_noerrno(ESP_SEMIHOSTING_SYS_BREAKPOINT_SET, args);
if (ret == 0) {
return ESP_ERR_INVALID_RESPONSE;
}{...}
}{...} else {
rv_utils_set_breakpoint(bp_num, (uint32_t)bp_addr);
}{...}
#endif/* ... */
return ESP_OK;
}{ ... }
esp_err_t esp_cpu_clear_breakpoint(int bp_num)
{
/* ... */
#if __XTENSA__
xt_utils_clear_breakpoint(bp_num);
#else
if (esp_cpu_dbgr_is_attached()) {
long args[] = {false, bp_num};
int ret = semihosting_call_noerrno(ESP_SEMIHOSTING_SYS_BREAKPOINT_SET, args);
if (ret == 0) {
return ESP_ERR_INVALID_RESPONSE;
}{...}
}{...} else {
rv_utils_clear_breakpoint(bp_num);
}{...}
#endif/* ... */
return ESP_OK;
}{ ... }
#endif/* ... */
#if SOC_CPU_WATCHPOINTS_NUM > 0
esp_err_t esp_cpu_set_watchpoint(int wp_num, const void *wp_addr, size_t size, esp_cpu_watchpoint_trigger_t trigger)
{
/* ... */
if (wp_num < 0 || wp_num >= SOC_CPU_WATCHPOINTS_NUM) {
return ESP_ERR_INVALID_ARG;
}{...}
if ((uint32_t)wp_addr % size) {
return ESP_ERR_INVALID_ARG;
}{...}
if (size < 1 || size > SOC_CPU_WATCHPOINT_MAX_REGION_SIZE || (size & (size - 1)) != 0) {
return ESP_ERR_INVALID_ARG;
}{...}
bool on_read = (trigger == ESP_CPU_WATCHPOINT_LOAD || trigger == ESP_CPU_WATCHPOINT_ACCESS);
bool on_write = (trigger == ESP_CPU_WATCHPOINT_STORE || trigger == ESP_CPU_WATCHPOINT_ACCESS);
#if __XTENSA__
xt_utils_set_watchpoint(wp_num, (uint32_t)wp_addr, size, on_read, on_write);
#else
if (esp_cpu_dbgr_is_attached()) {
long args[] = {true, wp_num, (long)wp_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 ESP_ERR_INVALID_RESPONSE;
}{...}
}{...} else {
rv_utils_set_watchpoint(wp_num, (uint32_t)wp_addr, size, on_read, on_write);
}{...}
#endif/* ... */
return ESP_OK;
}{ ... }
esp_err_t esp_cpu_clear_watchpoint(int wp_num)
{
/* ... */
#if __XTENSA__
xt_utils_clear_watchpoint(wp_num);
#else
if (esp_cpu_dbgr_is_attached()) {
long args[] = {false, wp_num};
int ret = semihosting_call_noerrno(ESP_SEMIHOSTING_SYS_WATCHPOINT_SET, args);
if (ret == 0) {
return ESP_ERR_INVALID_RESPONSE;
}{...}
}{...} else {
rv_utils_clear_watchpoint(wp_num);
}{...}
#endif/* ... */
return ESP_OK;
}{ ... }
#endif/* ... */
/* ... */
#if __XTENSA__ && XCHAL_HAVE_S32C1I && CONFIG_SPIRAM
static DRAM_ATTR uint32_t external_ram_cas_lock = 0;
#endif
bool esp_cpu_compare_and_set(volatile uint32_t *addr, uint32_t compare_value, uint32_t new_value)
{
#if __XTENSA__
bool ret;
#if XCHAL_HAVE_S32C1I && CONFIG_SPIRAM
if ((uint32_t)addr >= SOC_EXTRAM_DATA_LOW && (uint32_t)addr < SOC_EXTRAM_DATA_HIGH) {
/* ... */
uint32_t intr_level;
__asm__ __volatile__ ("rsil %0, " XTSTR(XCHAL_EXCM_LEVEL) "\n"
: "=r"(intr_level));
if (!xt_utils_compare_and_set(&external_ram_cas_lock, 0, 1)) {
ret = false;
goto exit;
}{...}
ret = (*addr == compare_value);
if (ret) {
*addr = new_value;
}{...}
external_ram_cas_lock = 0;
exit:
__asm__ __volatile__ ("memw \n"
"wsr %0, ps\n"
:: "r"(intr_level));
}{...} else
#endif
{
ret = xt_utils_compare_and_set(addr, compare_value, new_value);
}{...}
return ret;
/* ... */
#else
return rv_utils_compare_and_set(addr, compare_value, new_value);
#endif
}{ ... }