b5487407f3e706ddd09231df43a8d62104ac8937
[openocd.git] / src / target / espressif / esp32s3.c
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 /***************************************************************************
4 * ESP32-S3 target API for OpenOCD *
5 * Copyright (C) 2020 Espressif Systems Ltd. *
6 ***************************************************************************/
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 #include <helper/time_support.h>
13 #include <target/target.h>
14 #include <target/target_type.h>
15 #include <target/smp.h>
16 #include "assert.h"
17 #include "esp32s3.h"
18 #include "esp_xtensa_smp.h"
19
20 /*
21 This is a JTAG driver for the ESP32_S3, the are two Tensilica cores inside
22 the ESP32_S3 chip. For more information please have a look into ESP32_S3 target
23 implementation.
24 */
25
26 /* ESP32_S3 memory map */
27 #define ESP32_S3_IRAM_LOW 0x40370000
28 #define ESP32_S3_IRAM_HIGH 0x403E0000
29 #define ESP32_S3_IROM_MASK_LOW 0x40000000
30 #define ESP32_S3_IROM_MASK_HIGH 0x40060000
31 #define ESP32_S3_DRAM_LOW 0x3FC88000
32 #define ESP32_S3_DRAM_HIGH 0x3FD00000
33 #define ESP32_S3_RTC_IRAM_LOW 0x600FE000
34 #define ESP32_S3_RTC_IRAM_HIGH 0x60100000
35 #define ESP32_S3_RTC_DRAM_LOW 0x600FE000
36 #define ESP32_S3_RTC_DRAM_HIGH 0x60100000
37 #define ESP32_S3_RTC_DATA_LOW 0x50000000
38 #define ESP32_S3_RTC_DATA_HIGH 0x50002000
39 #define ESP32_S3_EXTRAM_DATA_LOW 0x3D000000
40 #define ESP32_S3_EXTRAM_DATA_HIGH 0x3E000000
41 #define ESP32_S3_SYS_RAM_LOW 0x60000000UL
42 #define ESP32_S3_SYS_RAM_HIGH (ESP32_S3_SYS_RAM_LOW + 0x10000000UL)
43 #define ESP32_S3_RTC_SLOW_MEM_BASE ESP32_S3_RTC_DATA_LOW
44
45 /* ESP32_S3 WDT */
46 #define ESP32_S3_WDT_WKEY_VALUE 0x50D83AA1
47 #define ESP32_S3_TIMG0_BASE 0x6001F000
48 #define ESP32_S3_TIMG1_BASE 0x60020000
49 #define ESP32_S3_TIMGWDT_CFG0_OFF 0x48
50 #define ESP32_S3_TIMGWDT_PROTECT_OFF 0x64
51 #define ESP32_S3_TIMG0WDT_CFG0 (ESP32_S3_TIMG0_BASE + ESP32_S3_TIMGWDT_CFG0_OFF)
52 #define ESP32_S3_TIMG1WDT_CFG0 (ESP32_S3_TIMG1_BASE + ESP32_S3_TIMGWDT_CFG0_OFF)
53 #define ESP32_S3_TIMG0WDT_PROTECT (ESP32_S3_TIMG0_BASE + ESP32_S3_TIMGWDT_PROTECT_OFF)
54 #define ESP32_S3_TIMG1WDT_PROTECT (ESP32_S3_TIMG1_BASE + ESP32_S3_TIMGWDT_PROTECT_OFF)
55 #define ESP32_S3_RTCCNTL_BASE 0x60008000
56 #define ESP32_S3_RTCWDT_CFG_OFF 0x98
57 #define ESP32_S3_RTCWDT_PROTECT_OFF 0xB0
58 #define ESP32_S3_SWD_CONF_OFF 0xB0
59 #define ESP32_S3_SWD_WPROTECT_OFF 0xB4
60 #define ESP32_S3_RTCWDT_CFG (ESP32_S3_RTCCNTL_BASE + ESP32_S3_RTCWDT_CFG_OFF)
61 #define ESP32_S3_RTCWDT_PROTECT (ESP32_S3_RTCCNTL_BASE + ESP32_S3_RTCWDT_PROTECT_OFF)
62 #define ESP32_S3_SWD_CONF_REG (ESP32_S3_RTCCNTL_BASE + ESP32_S3_SWD_CONF_OFF)
63 #define ESP32_S3_SWD_WPROTECT_REG (ESP32_S3_RTCCNTL_BASE + ESP32_S3_SWD_WPROTECT_OFF)
64 #define ESP32_S3_SWD_AUTO_FEED_EN_M BIT(31)
65 #define ESP32_S3_SWD_WKEY_VALUE 0x8F1D312AU
66
67 #define ESP32_S3_TRACEMEM_BLOCK_SZ 0x4000
68
69 /* ESP32_S3 dport regs */
70 #define ESP32_S3_DR_REG_SYSTEM_BASE 0x600c0000
71 #define ESP32_S3_SYSTEM_CORE_1_CONTROL_0_REG (ESP32_S3_DR_REG_SYSTEM_BASE + 0x014)
72 #define ESP32_S3_SYSTEM_CONTROL_CORE_1_CLKGATE_EN BIT(1)
73
74 /* ESP32_S3 RTC regs */
75 #define ESP32_S3_RTC_CNTL_SW_CPU_STALL_REG (ESP32_S3_RTCCNTL_BASE + 0xBC)
76 #define ESP32_S3_RTC_CNTL_SW_CPU_STALL_DEF 0x0
77
78 /* this should map local reg IDs to GDB reg mapping as defined in xtensa-config.c 'rmap' in
79 *xtensa-overlay */
80 static const unsigned int esp32s3_gdb_regs_mapping[ESP32_S3_NUM_REGS] = {
81 XT_REG_IDX_PC,
82 XT_REG_IDX_AR0, XT_REG_IDX_AR1, XT_REG_IDX_AR2, XT_REG_IDX_AR3,
83 XT_REG_IDX_AR4, XT_REG_IDX_AR5, XT_REG_IDX_AR6, XT_REG_IDX_AR7,
84 XT_REG_IDX_AR8, XT_REG_IDX_AR9, XT_REG_IDX_AR10, XT_REG_IDX_AR11,
85 XT_REG_IDX_AR12, XT_REG_IDX_AR13, XT_REG_IDX_AR14, XT_REG_IDX_AR15,
86 XT_REG_IDX_AR16, XT_REG_IDX_AR17, XT_REG_IDX_AR18, XT_REG_IDX_AR19,
87 XT_REG_IDX_AR20, XT_REG_IDX_AR21, XT_REG_IDX_AR22, XT_REG_IDX_AR23,
88 XT_REG_IDX_AR24, XT_REG_IDX_AR25, XT_REG_IDX_AR26, XT_REG_IDX_AR27,
89 XT_REG_IDX_AR28, XT_REG_IDX_AR29, XT_REG_IDX_AR30, XT_REG_IDX_AR31,
90 XT_REG_IDX_AR32, XT_REG_IDX_AR33, XT_REG_IDX_AR34, XT_REG_IDX_AR35,
91 XT_REG_IDX_AR36, XT_REG_IDX_AR37, XT_REG_IDX_AR38, XT_REG_IDX_AR39,
92 XT_REG_IDX_AR40, XT_REG_IDX_AR41, XT_REG_IDX_AR42, XT_REG_IDX_AR43,
93 XT_REG_IDX_AR44, XT_REG_IDX_AR45, XT_REG_IDX_AR46, XT_REG_IDX_AR47,
94 XT_REG_IDX_AR48, XT_REG_IDX_AR49, XT_REG_IDX_AR50, XT_REG_IDX_AR51,
95 XT_REG_IDX_AR52, XT_REG_IDX_AR53, XT_REG_IDX_AR54, XT_REG_IDX_AR55,
96 XT_REG_IDX_AR56, XT_REG_IDX_AR57, XT_REG_IDX_AR58, XT_REG_IDX_AR59,
97 XT_REG_IDX_AR60, XT_REG_IDX_AR61, XT_REG_IDX_AR62, XT_REG_IDX_AR63,
98 XT_REG_IDX_LBEG, XT_REG_IDX_LEND, XT_REG_IDX_LCOUNT, XT_REG_IDX_SAR,
99 XT_REG_IDX_WINDOWBASE, XT_REG_IDX_WINDOWSTART, XT_REG_IDX_CONFIGID0, XT_REG_IDX_CONFIGID1,
100 XT_REG_IDX_PS, XT_REG_IDX_THREADPTR, XT_REG_IDX_BR, XT_REG_IDX_SCOMPARE1,
101 XT_REG_IDX_ACCLO, XT_REG_IDX_ACCHI,
102 XT_REG_IDX_M0, XT_REG_IDX_M1, XT_REG_IDX_M2, XT_REG_IDX_M3,
103 ESP32_S3_REG_IDX_GPIOOUT,
104 XT_REG_IDX_F0, XT_REG_IDX_F1, XT_REG_IDX_F2, XT_REG_IDX_F3,
105 XT_REG_IDX_F4, XT_REG_IDX_F5, XT_REG_IDX_F6, XT_REG_IDX_F7,
106 XT_REG_IDX_F8, XT_REG_IDX_F9, XT_REG_IDX_F10, XT_REG_IDX_F11,
107 XT_REG_IDX_F12, XT_REG_IDX_F13, XT_REG_IDX_F14, XT_REG_IDX_F15,
108 XT_REG_IDX_FCR, XT_REG_IDX_FSR,
109 ESP32_S3_REG_IDX_ACCX_0, ESP32_S3_REG_IDX_ACCX_1,
110 ESP32_S3_REG_IDX_QACC_H_0, ESP32_S3_REG_IDX_QACC_H_1, ESP32_S3_REG_IDX_QACC_H_2,
111 ESP32_S3_REG_IDX_QACC_H_3, ESP32_S3_REG_IDX_QACC_H_4,
112 ESP32_S3_REG_IDX_QACC_L_0, ESP32_S3_REG_IDX_QACC_L_1, ESP32_S3_REG_IDX_QACC_L_2,
113 ESP32_S3_REG_IDX_QACC_L_3, ESP32_S3_REG_IDX_QACC_L_4,
114 ESP32_S3_REG_IDX_SAR_BYTE, ESP32_S3_REG_IDX_FFT_BIT_WIDTH,
115 ESP32_S3_REG_IDX_UA_STATE_0, ESP32_S3_REG_IDX_UA_STATE_1, ESP32_S3_REG_IDX_UA_STATE_2,
116 ESP32_S3_REG_IDX_UA_STATE_3,
117 ESP32_S3_REG_IDX_Q0, ESP32_S3_REG_IDX_Q1, ESP32_S3_REG_IDX_Q2, ESP32_S3_REG_IDX_Q3,
118 ESP32_S3_REG_IDX_Q4, ESP32_S3_REG_IDX_Q5, ESP32_S3_REG_IDX_Q6, ESP32_S3_REG_IDX_Q7,
119
120 XT_REG_IDX_MMID, XT_REG_IDX_IBREAKENABLE,
121 XT_REG_IDX_MEMCTL, XT_REG_IDX_ATOMCTL, XT_REG_IDX_OCD_DDR,
122 XT_REG_IDX_IBREAKA0, XT_REG_IDX_IBREAKA1, XT_REG_IDX_DBREAKA0, XT_REG_IDX_DBREAKA1,
123 XT_REG_IDX_DBREAKC0, XT_REG_IDX_DBREAKC1,
124 XT_REG_IDX_EPC1, XT_REG_IDX_EPC2, XT_REG_IDX_EPC3, XT_REG_IDX_EPC4,
125 XT_REG_IDX_EPC5, XT_REG_IDX_EPC6, XT_REG_IDX_EPC7, XT_REG_IDX_DEPC,
126 XT_REG_IDX_EPS2, XT_REG_IDX_EPS3, XT_REG_IDX_EPS4, XT_REG_IDX_EPS5,
127 XT_REG_IDX_EPS6, XT_REG_IDX_EPS7,
128 XT_REG_IDX_EXCSAVE1, XT_REG_IDX_EXCSAVE2, XT_REG_IDX_EXCSAVE3, XT_REG_IDX_EXCSAVE4,
129 XT_REG_IDX_EXCSAVE5, XT_REG_IDX_EXCSAVE6, XT_REG_IDX_EXCSAVE7, XT_REG_IDX_CPENABLE,
130 XT_REG_IDX_INTERRUPT, XT_REG_IDX_INTSET, XT_REG_IDX_INTCLEAR, XT_REG_IDX_INTENABLE,
131 XT_REG_IDX_VECBASE, XT_REG_IDX_EXCCAUSE, XT_REG_IDX_DEBUGCAUSE, XT_REG_IDX_CCOUNT,
132 XT_REG_IDX_PRID, XT_REG_IDX_ICOUNT, XT_REG_IDX_ICOUNTLEVEL, XT_REG_IDX_EXCVADDR,
133 XT_REG_IDX_CCOMPARE0, XT_REG_IDX_CCOMPARE1, XT_REG_IDX_CCOMPARE2,
134 XT_REG_IDX_MISC0, XT_REG_IDX_MISC1, XT_REG_IDX_MISC2, XT_REG_IDX_MISC3,
135
136 XT_REG_IDX_PWRCTL, XT_REG_IDX_PWRSTAT, XT_REG_IDX_ERISTAT,
137 XT_REG_IDX_CS_ITCTRL, XT_REG_IDX_CS_CLAIMSET, XT_REG_IDX_CS_CLAIMCLR,
138 XT_REG_IDX_CS_LOCKACCESS, XT_REG_IDX_CS_LOCKSTATUS, XT_REG_IDX_CS_AUTHSTATUS,
139 XT_REG_IDX_FAULT_INFO,
140 XT_REG_IDX_TRAX_ID, XT_REG_IDX_TRAX_CTRL, XT_REG_IDX_TRAX_STAT,
141 XT_REG_IDX_TRAX_DATA, XT_REG_IDX_TRAX_ADDR, XT_REG_IDX_TRAX_PCTRIGGER,
142 XT_REG_IDX_TRAX_PCMATCH, XT_REG_IDX_TRAX_DELAY, XT_REG_IDX_TRAX_MEMSTART,
143 XT_REG_IDX_TRAX_MEMEND,
144 XT_REG_IDX_PMG, XT_REG_IDX_PMPC, XT_REG_IDX_PM0, XT_REG_IDX_PM1,
145 XT_REG_IDX_PMCTRL0, XT_REG_IDX_PMCTRL1, XT_REG_IDX_PMSTAT0, XT_REG_IDX_PMSTAT1,
146 XT_REG_IDX_OCD_ID, XT_REG_IDX_OCD_DCRCLR, XT_REG_IDX_OCD_DCRSET, XT_REG_IDX_OCD_DSR,
147 XT_REG_IDX_A0, XT_REG_IDX_A1, XT_REG_IDX_A2, XT_REG_IDX_A3,
148 XT_REG_IDX_A4, XT_REG_IDX_A5, XT_REG_IDX_A6, XT_REG_IDX_A7,
149 XT_REG_IDX_A8, XT_REG_IDX_A9, XT_REG_IDX_A10, XT_REG_IDX_A11,
150 XT_REG_IDX_A12, XT_REG_IDX_A13, XT_REG_IDX_A14, XT_REG_IDX_A15,
151 };
152
153 /* actually this table contains user + TIE registers
154 * TODO: for TIE registers we need to specify custom access functions instead of `xtensa_user_reg_xxx_type`*/
155 static const struct xtensa_user_reg_desc esp32s3_user_regs[ESP32_S3_NUM_REGS - XT_NUM_REGS] = {
156 { "gpio_out", 0x00, 0, 32, &xtensa_user_reg_u32_type },
157 { "accx_0", 0x01, 0, 32, &xtensa_user_reg_u32_type },
158 { "accx_1", 0x02, 0, 32, &xtensa_user_reg_u32_type },
159 { "qacc_h_0", 0x03, 0, 32, &xtensa_user_reg_u32_type },
160 { "qacc_h_1", 0x04, 0, 32, &xtensa_user_reg_u32_type },
161 { "qacc_h_2", 0x05, 0, 32, &xtensa_user_reg_u32_type },
162 { "qacc_h_3", 0x06, 0, 32, &xtensa_user_reg_u32_type },
163 { "qacc_h_4", 0x07, 0, 32, &xtensa_user_reg_u32_type },
164 { "qacc_l_0", 0x08, 0, 32, &xtensa_user_reg_u32_type },
165 { "qacc_l_1", 0x09, 0, 32, &xtensa_user_reg_u32_type },
166 { "qacc_l_2", 0x0A, 0, 32, &xtensa_user_reg_u32_type },
167 { "qacc_l_3", 0x0B, 0, 32, &xtensa_user_reg_u32_type },
168 { "qacc_l_4", 0x0C, 0, 32, &xtensa_user_reg_u32_type },
169 { "sar_byte", 0x0D, 0, 32, &xtensa_user_reg_u32_type },
170 { "fft_bit_width", 0x0E, 0, 32, &xtensa_user_reg_u32_type },
171 { "ua_state_0", 0x0F, 0, 32, &xtensa_user_reg_u32_type },
172 { "ua_state_1", 0x10, 0, 32, &xtensa_user_reg_u32_type },
173 { "ua_state_2", 0x11, 0, 32, &xtensa_user_reg_u32_type },
174 { "ua_state_3", 0x12, 0, 32, &xtensa_user_reg_u32_type },
175 { "q0", 0x13, 0, 128, &xtensa_user_reg_u128_type },
176 { "q1", 0x14, 0, 128, &xtensa_user_reg_u128_type },
177 { "q2", 0x15, 0, 128, &xtensa_user_reg_u128_type },
178 { "q3", 0x16, 0, 128, &xtensa_user_reg_u128_type },
179 { "q4", 0x17, 0, 128, &xtensa_user_reg_u128_type },
180 { "q5", 0x18, 0, 128, &xtensa_user_reg_u128_type },
181 { "q6", 0x19, 0, 128, &xtensa_user_reg_u128_type },
182 { "q7", 0x20, 0, 128, &xtensa_user_reg_u128_type },
183 };
184
185 struct esp32s3_common {
186 struct esp_xtensa_smp_common esp_xtensa_smp;
187 };
188
189 static int esp32s3_fetch_user_regs(struct target *target);
190 static int esp32s3_queue_write_dirty_user_regs(struct target *target);
191
192 static const struct xtensa_config esp32s3_xtensa_cfg = {
193 .density = true,
194 .aregs_num = XT_AREGS_NUM_MAX,
195 .windowed = true,
196 .coproc = true,
197 .fp_coproc = true,
198 .loop = true,
199 .miscregs_num = 4,
200 .threadptr = true,
201 .boolean = true,
202 .reloc_vec = true,
203 .proc_id = true,
204 .cond_store = true,
205 .mac16 = true,
206 .user_regs_num = ARRAY_SIZE(esp32s3_user_regs),
207 .user_regs = esp32s3_user_regs,
208 .fetch_user_regs = esp32s3_fetch_user_regs,
209 .queue_write_dirty_user_regs = esp32s3_queue_write_dirty_user_regs,
210 .gdb_general_regs_num = ESP32_S3_NUM_REGS_G_COMMAND,
211 .gdb_regs_mapping = esp32s3_gdb_regs_mapping,
212 .irom = {
213 .count = 2,
214 .regions = {
215 {
216 .base = ESP32_S3_IROM_LOW,
217 .size = ESP32_S3_IROM_HIGH - ESP32_S3_IROM_LOW,
218 .access = XT_MEM_ACCESS_READ,
219 },
220 {
221 .base = ESP32_S3_IROM_MASK_LOW,
222 .size = ESP32_S3_IROM_MASK_HIGH - ESP32_S3_IROM_MASK_LOW,
223 .access = XT_MEM_ACCESS_READ,
224 }
225 }
226 },
227 .iram = {
228 .count = 2,
229 .regions = {
230 {
231 .base = ESP32_S3_IRAM_LOW,
232 .size = ESP32_S3_IRAM_HIGH - ESP32_S3_IRAM_LOW,
233 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
234 },
235 {
236 .base = ESP32_S3_RTC_IRAM_LOW,
237 .size = ESP32_S3_RTC_IRAM_HIGH - ESP32_S3_RTC_IRAM_LOW,
238 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
239 },
240 }
241 },
242 .drom = {
243 .count = 1,
244 .regions = {
245 {
246 .base = ESP32_S3_DROM_LOW,
247 .size = ESP32_S3_DROM_HIGH - ESP32_S3_DROM_LOW,
248 .access = XT_MEM_ACCESS_READ,
249 },
250 }
251 },
252 .dram = {
253 .count = 4,
254 .regions = {
255 {
256 .base = ESP32_S3_DRAM_LOW,
257 .size = ESP32_S3_DRAM_HIGH - ESP32_S3_DRAM_LOW,
258 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
259 },
260 {
261 .base = ESP32_S3_RTC_DRAM_LOW,
262 .size = ESP32_S3_RTC_DRAM_HIGH - ESP32_S3_RTC_DRAM_LOW,
263 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
264 },
265 {
266 .base = ESP32_S3_RTC_DATA_LOW,
267 .size = ESP32_S3_RTC_DATA_HIGH - ESP32_S3_RTC_DATA_LOW,
268 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
269 },
270 {
271 .base = ESP32_S3_SYS_RAM_LOW,
272 .size = ESP32_S3_SYS_RAM_HIGH - ESP32_S3_SYS_RAM_LOW,
273 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
274 },
275 }
276 },
277 .exc = {
278 .enabled = true,
279 },
280 .irq = {
281 .enabled = true,
282 .irq_num = 32,
283 },
284 .high_irq = {
285 .enabled = true,
286 .excm_level = 3,
287 .nmi_num = 1,
288 },
289 .tim_irq = {
290 .enabled = true,
291 .comp_num = 3,
292 },
293 .debug = {
294 .enabled = true,
295 .irq_level = 6,
296 .ibreaks_num = 2,
297 .dbreaks_num = 2,
298 .icount_sz = 32,
299 },
300 .trace = {
301 .enabled = true,
302 .mem_sz = ESP32_S3_TRACEMEM_BLOCK_SZ,
303 },
304 };
305
306 static int esp32s3_fetch_user_regs(struct target *target)
307 {
308 LOG_DEBUG("%s: user regs fetching is not implemented!", target_name(target));
309 return ERROR_OK;
310 }
311
312 static int esp32s3_queue_write_dirty_user_regs(struct target *target)
313 {
314 LOG_DEBUG("%s: user regs writing is not implemented!", target_name(target));
315 return ERROR_OK;
316 }
317
318 /* Reset ESP32-S3's peripherals.
319 * 1. OpenOCD makes sure the target is halted; if not, tries to halt it.
320 * If that fails, tries to reset it (via OCD) and then halt.
321 * 2. OpenOCD loads the stub code into RTC_SLOW_MEM.
322 * 3. Executes the stub code from address 0x50000004.
323 * 4. The stub code changes the reset vector to 0x50000000, and triggers
324 * a system reset using RTC_CNTL_SW_SYS_RST bit.
325 * 5. Once the PRO CPU is out of reset, it executes the stub code from address 0x50000000.
326 * The stub code disables the watchdog, re-enables JTAG and the APP CPU,
327 * restores the reset vector, and enters an infinite loop.
328 * 6. OpenOCD waits until it can talk to the OCD module again, then halts the target.
329 * 7. OpenOCD restores the contents of RTC_SLOW_MEM.
330 *
331 * End result: all the peripherals except RTC_CNTL are reset, CPU's PC is undefined,
332 * PRO CPU is halted, APP CPU is in reset.
333 */
334
335 const uint8_t esp32s3_reset_stub_code[] = {
336 #include "../../../contrib/loaders/reset/espressif/esp32s3/cpu_reset_handler_code.inc"
337 };
338
339 static int esp32s3_soc_reset(struct target *target)
340 {
341 int res;
342 struct target_list *head;
343 struct xtensa *xtensa;
344
345 LOG_DEBUG("start");
346 /* In order to write to peripheral registers, target must be halted first */
347 if (target->state != TARGET_HALTED) {
348 LOG_DEBUG("Target not halted before SoC reset, trying to halt it first");
349 xtensa_halt(target);
350 res = target_wait_state(target, TARGET_HALTED, 1000);
351 if (res != ERROR_OK) {
352 LOG_DEBUG("Couldn't halt target before SoC reset, trying to do reset-halt");
353 res = xtensa_assert_reset(target);
354 if (res != ERROR_OK) {
355 LOG_ERROR(
356 "Couldn't halt target before SoC reset! (xtensa_assert_reset returned %d)",
357 res);
358 return res;
359 }
360 alive_sleep(10);
361 xtensa_poll(target);
362 bool reset_halt_save = target->reset_halt;
363 target->reset_halt = true;
364 res = xtensa_deassert_reset(target);
365 target->reset_halt = reset_halt_save;
366 if (res != ERROR_OK) {
367 LOG_ERROR(
368 "Couldn't halt target before SoC reset! (xtensa_deassert_reset returned %d)",
369 res);
370 return res;
371 }
372 alive_sleep(10);
373 xtensa_poll(target);
374 xtensa_halt(target);
375 res = target_wait_state(target, TARGET_HALTED, 1000);
376 if (res != ERROR_OK) {
377 LOG_ERROR("Couldn't halt target before SoC reset");
378 return res;
379 }
380 }
381 }
382
383 if (target->smp) {
384 foreach_smp_target(head, target->smp_targets) {
385 xtensa = target_to_xtensa(head->target);
386 /* if any of the cores is stalled unstall them */
387 if (xtensa_dm_core_is_stalled(&xtensa->dbg_mod)) {
388 LOG_TARGET_DEBUG(head->target, "Unstall CPUs before SW reset!");
389 res = target_write_u32(target,
390 ESP32_S3_RTC_CNTL_SW_CPU_STALL_REG,
391 ESP32_S3_RTC_CNTL_SW_CPU_STALL_DEF);
392 if (res != ERROR_OK) {
393 LOG_TARGET_ERROR(head->target, "Failed to unstall CPUs before SW reset!");
394 return res;
395 }
396 break; /* both cores are unstalled now, so exit the loop */
397 }
398 }
399 }
400
401 LOG_DEBUG("Loading stub code into RTC RAM");
402 uint8_t slow_mem_save[sizeof(esp32s3_reset_stub_code)];
403
404 /* Save contents of RTC_SLOW_MEM which we are about to overwrite */
405 res = target_read_buffer(target, ESP32_S3_RTC_SLOW_MEM_BASE, sizeof(slow_mem_save), slow_mem_save);
406 if (res != ERROR_OK) {
407 LOG_ERROR("Failed to save contents of RTC_SLOW_MEM (%d)!", res);
408 return res;
409 }
410
411 /* Write stub code into RTC_SLOW_MEM */
412 res = target_write_buffer(target,
413 ESP32_S3_RTC_SLOW_MEM_BASE,
414 sizeof(esp32s3_reset_stub_code),
415 esp32s3_reset_stub_code);
416 if (res != ERROR_OK) {
417 LOG_ERROR("Failed to write stub (%d)!", res);
418 return res;
419 }
420
421 LOG_DEBUG("Resuming the target");
422 xtensa = target_to_xtensa(target);
423 xtensa->suppress_dsr_errors = true;
424 res = xtensa_resume(target, 0, ESP32_S3_RTC_SLOW_MEM_BASE + 4, 0, 0);
425 xtensa->suppress_dsr_errors = false;
426 if (res != ERROR_OK) {
427 LOG_ERROR("Failed to run stub (%d)!", res);
428 return res;
429 }
430 LOG_DEBUG("resume done, waiting for the target to come alive");
431
432 /* Wait for SoC to reset */
433 alive_sleep(100);
434 int64_t timeout = timeval_ms() + 100;
435 bool get_timeout = false;
436 while (target->state != TARGET_RESET && target->state != TARGET_RUNNING) {
437 alive_sleep(10);
438 xtensa_poll(target);
439 if (timeval_ms() >= timeout) {
440 LOG_TARGET_ERROR(target,
441 "Timed out waiting for CPU to be reset, target state=%d",
442 target->state);
443 get_timeout = true;
444 break;
445 }
446 }
447
448 /* Halt the CPU again */
449 LOG_DEBUG("halting the target");
450 xtensa_halt(target);
451 res = target_wait_state(target, TARGET_HALTED, 1000);
452 if (res == ERROR_OK) {
453 LOG_DEBUG("restoring RTC_SLOW_MEM");
454 res = target_write_buffer(target, ESP32_S3_RTC_SLOW_MEM_BASE, sizeof(slow_mem_save), slow_mem_save);
455 if (res != ERROR_OK)
456 LOG_TARGET_ERROR(target, "Failed to restore contents of RTC_SLOW_MEM (%d)!", res);
457 } else {
458 LOG_TARGET_ERROR(target, "Timed out waiting for CPU to be halted after SoC reset");
459 }
460
461 return get_timeout ? ERROR_TARGET_TIMEOUT : res;
462 }
463
464 static int esp32s3_disable_wdts(struct target *target)
465 {
466 /* TIMG1 WDT */
467 int res = target_write_u32(target, ESP32_S3_TIMG0WDT_PROTECT, ESP32_S3_WDT_WKEY_VALUE);
468 if (res != ERROR_OK) {
469 LOG_ERROR("Failed to write ESP32_S3_TIMG0WDT_PROTECT (%d)!", res);
470 return res;
471 }
472 res = target_write_u32(target, ESP32_S3_TIMG0WDT_CFG0, 0);
473 if (res != ERROR_OK) {
474 LOG_ERROR("Failed to write ESP32_S3_TIMG0WDT_CFG0 (%d)!", res);
475 return res;
476 }
477 /* TIMG2 WDT */
478 res = target_write_u32(target, ESP32_S3_TIMG1WDT_PROTECT, ESP32_S3_WDT_WKEY_VALUE);
479 if (res != ERROR_OK) {
480 LOG_ERROR("Failed to write ESP32_S3_TIMG1WDT_PROTECT (%d)!", res);
481 return res;
482 }
483 res = target_write_u32(target, ESP32_S3_TIMG1WDT_CFG0, 0);
484 if (res != ERROR_OK) {
485 LOG_ERROR("Failed to write ESP32_S3_TIMG1WDT_CFG0 (%d)!", res);
486 return res;
487 }
488 /* RTC WDT */
489 res = target_write_u32(target, ESP32_S3_RTCWDT_PROTECT, ESP32_S3_WDT_WKEY_VALUE);
490 if (res != ERROR_OK) {
491 LOG_ERROR("Failed to write ESP32_S3_RTCWDT_PROTECT (%d)!", res);
492 return res;
493 }
494 res = target_write_u32(target, ESP32_S3_RTCWDT_CFG, 0);
495 if (res != ERROR_OK) {
496 LOG_ERROR("Failed to write ESP32_S3_RTCWDT_CFG (%d)!", res);
497 return res;
498 }
499 /* Enable SWD auto-feed */
500 res = target_write_u32(target, ESP32_S3_SWD_WPROTECT_REG, ESP32_S3_SWD_WKEY_VALUE);
501 if (res != ERROR_OK) {
502 LOG_ERROR("Failed to write ESP32_S3_SWD_WPROTECT_REG (%d)!", res);
503 return res;
504 }
505 uint32_t swd_conf_reg = 0;
506 res = target_read_u32(target, ESP32_S3_SWD_CONF_REG, &swd_conf_reg);
507 if (res != ERROR_OK) {
508 LOG_ERROR("Failed to read ESP32_S3_SWD_CONF_REG (%d)!", res);
509 return res;
510 }
511 swd_conf_reg |= ESP32_S3_SWD_AUTO_FEED_EN_M;
512 res = target_write_u32(target, ESP32_S3_SWD_CONF_REG, swd_conf_reg);
513 if (res != ERROR_OK) {
514 LOG_ERROR("Failed to write ESP32_S3_SWD_CONF_REG (%d)!", res);
515 return res;
516 }
517 return ERROR_OK;
518 }
519
520 static int esp32s3_on_halt(struct target *target)
521 {
522 return esp32s3_disable_wdts(target);
523 }
524
525 static int esp32s3_arch_state(struct target *target)
526 {
527 return ERROR_OK;
528 }
529
530 static int esp32s3_virt2phys(struct target *target,
531 target_addr_t virtual, target_addr_t *physical)
532 {
533 if (physical) {
534 *physical = virtual;
535 return ERROR_OK;
536 }
537 return ERROR_FAIL;
538 }
539
540
541 static int esp32s3_target_init(struct command_context *cmd_ctx, struct target *target)
542 {
543 return esp_xtensa_target_init(cmd_ctx, target);
544 }
545
546 static const struct xtensa_debug_ops esp32s3_dbg_ops = {
547 .queue_enable = xtensa_dm_queue_enable,
548 .queue_reg_read = xtensa_dm_queue_reg_read,
549 .queue_reg_write = xtensa_dm_queue_reg_write
550 };
551
552 static const struct xtensa_power_ops esp32s3_pwr_ops = {
553 .queue_reg_read = xtensa_dm_queue_pwr_reg_read,
554 .queue_reg_write = xtensa_dm_queue_pwr_reg_write
555 };
556
557 static const struct esp_xtensa_smp_chip_ops esp32s3_chip_ops = {
558 .reset = esp32s3_soc_reset,
559 .on_halt = esp32s3_on_halt
560 };
561
562 static int esp32s3_target_create(struct target *target, Jim_Interp *interp)
563 {
564 struct xtensa_debug_module_config esp32s3_dm_cfg = {
565 .dbg_ops = &esp32s3_dbg_ops,
566 .pwr_ops = &esp32s3_pwr_ops,
567 .tap = target->tap,
568 .queue_tdi_idle = NULL,
569 .queue_tdi_idle_arg = NULL
570 };
571
572 struct esp32s3_common *esp32s3 = calloc(1, sizeof(struct esp32s3_common));
573 if (!esp32s3) {
574 LOG_ERROR("Failed to alloc memory for arch info!");
575 return ERROR_FAIL;
576 }
577
578 int ret = esp_xtensa_smp_init_arch_info(target,
579 &esp32s3->esp_xtensa_smp,
580 &esp32s3_xtensa_cfg,
581 &esp32s3_dm_cfg,
582 &esp32s3_chip_ops);
583 if (ret != ERROR_OK) {
584 LOG_ERROR("Failed to init arch info!");
585 free(esp32s3);
586 return ret;
587 }
588
589 /* Assume running target. If different, the first poll will fix this. */
590 target->state = TARGET_RUNNING;
591 target->debug_reason = DBG_REASON_NOTHALTED;
592 return ERROR_OK;
593 }
594
595 static const struct command_registration esp32s3_command_handlers[] = {
596 {
597 .usage = "",
598 .chain = esp_xtensa_smp_command_handlers,
599 },
600 {
601 .name = "esp32",
602 .usage = "",
603 .chain = smp_command_handlers,
604 },
605 COMMAND_REGISTRATION_DONE
606 };
607
608 /** Holds methods for Xtensa targets. */
609 struct target_type esp32s3_target = {
610 .name = "esp32s3",
611
612 .poll = esp_xtensa_smp_poll,
613 .arch_state = esp32s3_arch_state,
614
615 .halt = xtensa_halt,
616 .resume = esp_xtensa_smp_resume,
617 .step = esp_xtensa_smp_step,
618
619 .assert_reset = esp_xtensa_smp_assert_reset,
620 .deassert_reset = esp_xtensa_smp_deassert_reset,
621 .soft_reset_halt = esp_xtensa_smp_soft_reset_halt,
622
623 .virt2phys = esp32s3_virt2phys,
624 .mmu = xtensa_mmu_is_enabled,
625 .read_memory = xtensa_read_memory,
626 .write_memory = xtensa_write_memory,
627
628 .read_buffer = xtensa_read_buffer,
629 .write_buffer = xtensa_write_buffer,
630
631 .checksum_memory = xtensa_checksum_memory,
632
633 .get_gdb_arch = xtensa_get_gdb_arch,
634 .get_gdb_reg_list = xtensa_get_gdb_reg_list,
635
636 .add_breakpoint = esp_xtensa_breakpoint_add,
637 .remove_breakpoint = esp_xtensa_breakpoint_remove,
638
639 .add_watchpoint = esp_xtensa_smp_watchpoint_add,
640 .remove_watchpoint = esp_xtensa_smp_watchpoint_remove,
641
642 .target_create = esp32s3_target_create,
643 .init_target = esp32s3_target_init,
644 .examine = xtensa_examine,
645 .deinit_target = esp_xtensa_target_deinit,
646
647 .commands = esp32s3_command_handlers,
648 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)