@@ -235,34 +235,22 @@ static int esp32_assert_reset(struct target *target)
235235 return xtensa_mcore_assert_reset (target );
236236}
237237
238- static int esp32_write_uint32_list (struct target * target ,
239- const target_addr_t * addrs ,
240- const uint32_t * values ,
241- size_t count )
242- {
243- int res ;
244- for (size_t i = 0 ; i < count ; ++ i ) {
245- res = target_write_u32 (target , addrs [i ], values [i ]);
246- if (res != ERROR_OK ) {
247- LOG_ERROR ("%s: error writing to " TARGET_ADDR_FMT , __func__ , addrs [i ]);
248- return res ;
249- }
250- }
251- return ERROR_OK ;
252- }
253-
254238/* Reset ESP32's peripherals.
255- Postconditions: all peripherals except RTC_CNTL are reset, CPU's PC is undefined, PRO CPU is halted, APP CPU is in reset
256- How this works:
257- 0. make sure target is halted; if not, try to halt it; if that fails, try to reset it (via OCD) and then halt
258- 1. set CPU initial PC to 0x50000000 (RTC_SLOW_MEM) by clearing RTC_CNTL_{PRO,APP}CPU_STAT_VECTOR_SEL
259- 2. load stub code into RTC_SLOW_MEM; once executed, stub code will disable watchdogs and make CPU spin in an idle loop.
260- 3. trigger SoC reset using RTC_CNTL_SW_SYS_RST bit
261- 4. wait for the OCD to be reset
262- 5. halt the target and wait for it to be halted (at this point CPU is in the idle loop)
263- 6. restore initial PC and the contents of RTC_SLOW_MEM
264- TODO: some state of RTC_CNTL is not reset during SW_SYS_RST. Need to reset that manually.
265- */
239+ * 1. OpenOCD makes sure the target is halted; if not, tries to halt it.
240+ * If that fails, tries to reset it (via OCD) and then halt.
241+ * 2. OpenOCD loads the stub code into RTC_SLOW_MEM.
242+ * 3. Executes the stub code from address 0x50000004.
243+ * 4. The stub code changes the reset vector to 0x50000000, and triggers
244+ * a system reset using RTC_CNTL_SW_SYS_RST bit.
245+ * 5. Once the PRO CPU is out of reset, it executes the stub code from address 0x50000000.
246+ * The stub code disables the watchdog, re-enables JTAG and the APP CPU,
247+ * restores the reset vector, and enters an infinite loop.
248+ * 6. OpenOCD waits until it can talk to the OCD module again, then halts the target.
249+ * 7. OpenOCD restores the contents of RTC_SLOW_MEM.
250+ *
251+ * End result: all the peripherals except RTC_CNTL are reset, CPU's PC is undefined,
252+ * PRO CPU is halted, APP CPU is in reset.
253+ */
266254static int esp32_soc_reset (struct target * active_core_target )
267255{
268256 int res ;
@@ -314,25 +302,37 @@ static int esp32_soc_reset(struct target *active_core_target)
314302
315303 /* This this the stub code compiled from esp32_cpu_reset_handler.S.
316304 To compile it, run:
317- xtensa-esp32-elf-as -o stub.o esp32_cpu_reset_handler.S
305+ xtensa-esp32-elf-gcc -c -mtext-section-literals -o stub.o esp32_cpu_reset_handler.S
318306 xtensa-esp32-elf-objcopy -j .text -O binary stub.o stub.bin
319307 These steps are not included into OpenOCD build process so that a
320308 dependency on xtensa-esp32-elf toolchain is not introduced.
321309 */
322- const uint32_t esp32_post_reset_code [] = {
323- 0x00000806 , 0x50d83aa1 , 0x00000000 , 0x3ff480a4 , 0x3ff4808c , 0x3ff5f064 , 0x3ff5f048 ,
324- 0x3ff60064 ,
325- 0x3ff60048 , 0x41fff831 , 0x0439fff9 , 0x39fffa41 , 0xfffa4104 , 0xf4310439 , 0xfff541ff ,
326- 0xf6410439 ,
327- 0x410439ff , 0x0439fff7 , 0x46007000 ,
310+ const uint32_t esp32_reset_stub_code [] = {
311+ 0x00001e06 , 0x00001406 , 0x3ff48034 , 0x3ff480b0 ,
312+ 0x3ff480b4 , 0x3ff48070 , 0x00002210 , 0x9c492000 ,
313+ 0x3ff48000 , 0x50d83aa1 , 0x3ff480a4 , 0x3ff5f064 ,
314+ 0x3ff60064 , 0x3ff4808c , 0x3ff5f048 , 0x3ff60048 ,
315+ 0x3ff5a1fc , 0x3ff00038 , 0x3ff00030 , 0x3ff0002c ,
316+ 0x3ff48034 , 0x00003000 , 0x41305550 , 0x0459ffeb ,
317+ 0x59ffeb41 , 0xffea4104 , 0xea410459 , 0xffea31ff ,
318+ 0xea310439 , 0xffea41ff , 0x00000439 , 0x6003eb60 ,
319+ 0x66560461 , 0x30555004 , 0x41ffe731 , 0x0439ffe7 ,
320+ 0x39ffe741 , 0xffe64104 , 0xe6410439 , 0x410459ff ,
321+ 0x0459ffe6 , 0x59ffe641 , 0xffe54104 , 0xe5410459 ,
322+ 0x410459ff , 0x130cffe5 , 0xe4410439 , 0x39130cff ,
323+ 0x41045904 , 0xe331ffe3 , 0x006432ff , 0x46007000 ,
324+ 0x0000fffe ,
328325 };
329326
330- uint32_t slow_mem_save [sizeof (esp32_post_reset_code ) / sizeof (uint32_t )];
327+ LOG_DEBUG ("loading stub code into RTC RAM" );
328+ uint32_t slow_mem_save [sizeof (esp32_reset_stub_code ) / sizeof (uint32_t )];
331329
332330 const int RTC_SLOW_MEM_BASE = 0x50000000 ;
333331 /* Save contents of RTC_SLOW_MEM which we are about to overwrite */
334332 res =
335- target_read_buffer (active_core_target , RTC_SLOW_MEM_BASE , sizeof (slow_mem_save ),
333+ target_read_buffer (active_core_target ,
334+ RTC_SLOW_MEM_BASE ,
335+ sizeof (slow_mem_save ),
336336 (uint8_t * )slow_mem_save );
337337 if (res != ERROR_OK ) {
338338 LOG_ERROR ("%s %d err=%d" , __func__ , __LINE__ , res );
@@ -341,66 +341,30 @@ static int esp32_soc_reset(struct target *active_core_target)
341341
342342 /* Write stub code into RTC_SLOW_MEM */
343343 res =
344- target_write_buffer (active_core_target ,
345- RTC_SLOW_MEM_BASE ,
346- sizeof (esp32_post_reset_code ),
347- (const uint8_t * )esp32_post_reset_code );
344+ target_write_buffer (active_core_target , RTC_SLOW_MEM_BASE ,
345+ sizeof (esp32_reset_stub_code ),
346+ (const uint8_t * )esp32_reset_stub_code );
348347 if (res != ERROR_OK ) {
349348 LOG_ERROR ("%s %d err=%d" , __func__ , __LINE__ , res );
350349 return res ;
351350 }
352- /* TODO: add addreses to chip config */
353- const int RTC_CNTL_RESET_STATE_REG = 0x3ff48034 ;
354- const int RTC_CNTL_RESET_STATE_DEF = 0x3000 ;
355- const int RTC_CNTL_CLK_CONF_REG = 0x3ff48070 ;
356- const int RTC_CNTL_CLK_CONF_DEF = 0x2210 ;
357- const int RTC_CNTL_STORE4_REG = 0x3ff480b0 ;
358- const int RTC_CNTL_STORE5_REG = 0x3ff480b4 ;
359- const int RTC_CNTL_OPTIONS0_REG = 0x3ff48000 ;
360- const int RTC_CNTL_OPTIONS0_DEF = 0x1c492000 ;
361- const int RTC_CNTL_SW_SYS_RST = 0x80000000 ;
362- const int DPORT_APPCPU_CTRL_A_REG = 0x3ff0002c ;
363- const int DPORT_APPCPU_CTRL_B_REG = 0x3ff00030 ;
364- const int DPORT_APPCPU_CLKGATE_EN = 0x1 ;
365- const int DPORT_APPCPU_CTRL_D_REG = 0x3ff00038 ;
366-
367- /* Set a list of registers to these values */
368- const target_addr_t addrs_pre [] = {
369- /* Set entry point to RTC_SLOW_MEM */
370- RTC_CNTL_RESET_STATE_REG ,
371- /* Reset SoC clock to XTAL, in case it was running from PLL */
372- RTC_CNTL_CLK_CONF_REG ,
373- /* Reset RTC_CNTL_STORE{4,5}_REG, which are related to clock state */
374- RTC_CNTL_STORE4_REG ,
375- RTC_CNTL_STORE5_REG ,
376- /* Perform reset */
377- RTC_CNTL_OPTIONS0_REG
378- };
379- const uint32_t values_pre [] = {
380- /* Set entry point to RTC_SLOW_MEM */
381- 0 ,
382- /* Reset SoC clock to XTAL, in case it was running from PLL */
383- RTC_CNTL_CLK_CONF_DEF ,
384- /* Reset RTC_CNTL_STORE{4,5}_REG, which are related to clock state */
385- 0 ,
386- 0 ,
387- /* Perform reset */
388- RTC_CNTL_OPTIONS0_DEF | RTC_CNTL_SW_SYS_RST
389- };
390- res = esp32_write_uint32_list (active_core_target ,
391- addrs_pre ,
392- values_pre ,
393- sizeof (addrs_pre ) / sizeof (target_addr_t ));
351+
352+ LOG_DEBUG ("resuming the target" );
353+ struct xtensa * xtensa = target_to_xtensa (active_core_target );
354+ xtensa -> suppress_dsr_errors = true;
355+ res = xtensa_resume (active_core_target , 0 , RTC_SLOW_MEM_BASE + 4 , 0 , 0 );
394356 if (res != ERROR_OK ) {
395- LOG_WARNING ("%s esp32_write_uint32_list (reg_value_pairs_pre) err=%d" , __func__ ,
396- res );
357+ LOG_WARNING ("%s xtensa_resume err=%d" , __func__ , res );
397358 return res ;
398359 }
360+ xtensa -> suppress_dsr_errors = false;
361+ LOG_DEBUG ("resume done, waiting for the target to come alive" );
399362
400363 /* Wait for SoC to reset */
364+ alive_sleep (100 );
401365 int timeout = 100 ;
402- while (active_core_target -> state != TARGET_RESET &&
403- active_core_target -> state != TARGET_RUNNING && -- timeout > 0 ) {
366+ while (active_core_target -> state != TARGET_RESET && active_core_target -> state !=
367+ TARGET_RUNNING && -- timeout > 0 ) {
404368 alive_sleep (10 );
405369 xtensa_poll (active_core_target );
406370 }
@@ -412,45 +376,16 @@ static int esp32_soc_reset(struct target *active_core_target)
412376 }
413377
414378 /* Halt the CPU again */
379+ LOG_DEBUG ("halting the target" );
415380 xtensa_halt (active_core_target );
416381 res = target_wait_state (active_core_target , TARGET_HALTED , 1000 );
417382 if (res != ERROR_OK ) {
418383 LOG_ERROR ("%s: Timed out waiting for CPU to be halted after SoC reset" , __func__ );
419384 return res ;
420385 }
421386
422- const target_addr_t addrs_post [] = {
423- /* Reset entry point back to the reset vector */
424- RTC_CNTL_RESET_STATE_REG ,
425- /* Clear APP CPU boot address */
426- DPORT_APPCPU_CTRL_D_REG ,
427- /* Enable clock to APP CPU */
428- DPORT_APPCPU_CTRL_B_REG ,
429- /* Take APP CPU out of reset */
430- DPORT_APPCPU_CTRL_A_REG ,
431- };
432- const uint32_t values_post [] = {
433- /* Reset entry point back to the reset vector */
434- RTC_CNTL_RESET_STATE_DEF ,
435- /* Clear APP CPU boot address */
436- 0 ,
437- /* Enable clock to APP CPU */
438- DPORT_APPCPU_CLKGATE_EN ,
439- /* Take APP CPU out of reset */
440- 0 ,
441- };
442- res = esp32_write_uint32_list (active_core_target ,
443- addrs_post ,
444- values_post ,
445- sizeof (addrs_post ) / sizeof (target_addr_t ));
446- if (res != ERROR_OK ) {
447- LOG_WARNING ("%s esp32_write_uint32_list (reg_value_pairs_post) err=%d" ,
448- __func__ ,
449- res );
450- return res ;
451- }
452-
453387 /* Restore the original contents of RTC_SLOW_MEM */
388+ LOG_DEBUG ("restoring RTC_SLOW_MEM" );
454389 res =
455390 target_write_buffer (active_core_target , RTC_SLOW_MEM_BASE , sizeof (slow_mem_save ),
456391 (const uint8_t * )slow_mem_save );
@@ -459,8 +394,6 @@ static int esp32_soc_reset(struct target *active_core_target)
459394 return res ;
460395 }
461396
462- LOG_DEBUG ("end" );
463-
464397 /* Clear memory which is used by RTOS layer to get the task count */
465398 if (active_core_target -> rtos && active_core_target -> rtos -> type -> post_reset_cleanup ) {
466399 res = (* active_core_target -> rtos -> type -> post_reset_cleanup )(active_core_target );
0 commit comments