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

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)