Skip to content

Commit cdb3704

Browse files
committed
esp_xtensa: Clears OCDDCR_ENABLEOCD on exit
Also removes ESP-specific workaround with exit callbacks and re-uses native target deinit API
1 parent 554180e commit cdb3704

File tree

8 files changed

+110
-88
lines changed

8 files changed

+110
-88
lines changed

src/target/esp32.c

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,7 @@ static int esp32_handle_target_event(struct target *target, enum target_event ev
530530
{
531531
struct xtensa_mcore_common *xtensa_mcore = target_to_xtensa_mcore(target);
532532
enum target_state old_state = target->state;
533+
int ret;
533534

534535
if (target != priv)
535536
return ERROR_OK;
@@ -544,18 +545,44 @@ static int esp32_handle_target_event(struct target *target, enum target_event ev
544545
xtensa_mcore->cores_num = 1;
545546
LOG_DEBUG("Detected %d cores", xtensa_mcore->cores_num);
546547
break;
548+
case TARGET_EVENT_GDB_DETACH:
549+
{
550+
if (target->state != TARGET_HALTED) {
551+
ret = target_halt(target);
552+
if (ret != ERROR_OK) {
553+
LOG_ERROR(
554+
"%s: Failed to halt target to remove flash BPs (%d)!",
555+
target_name(target),
556+
ret);
557+
return ret;
558+
}
559+
ret = target_wait_state(target, TARGET_HALTED, 3000);
560+
if (ret != ERROR_OK) {
561+
LOG_ERROR(
562+
"%s: Failed to wait halted target to remove flash BPs (%d)!",
563+
target_name(target),
564+
ret);
565+
return ret;
566+
}
567+
}
568+
for (size_t i = 0; i < xtensa_mcore->configured_cores_num; i++) {
569+
ret = esp_xtensa_special_breakpoints_clear(
570+
&xtensa_mcore->cores_targets[i]);
571+
if (ret != ERROR_OK)
572+
return ret;
573+
}
574+
break;
575+
}
547576
default:
548577
break;
549578
}
550579

551-
for (size_t i = 0; i < xtensa_mcore->configured_cores_num; i++)
552-
target_call_event_callbacks(&xtensa_mcore->cores_targets[i], event);
553-
554-
if (event == TARGET_EVENT_GDB_DETACH && old_state == TARGET_RUNNING) {
555-
/* the target was stopped by esp_xtensa_handle_target_event(), but not resumed because
556-
esp32_xtensa_core_resume() does nothing
557-
TODO: remove this hack when normal OpenOCD SMP mechanism is supported */
558-
int ret = target_resume(target, 1, 0, 1, 0);
580+
if (event != TARGET_EVENT_GDB_DETACH) {
581+
for (size_t i = 0; i < xtensa_mcore->configured_cores_num; i++)
582+
target_call_event_callbacks(&xtensa_mcore->cores_targets[i], event);
583+
} else if (old_state == TARGET_RUNNING) {
584+
/* TODO: remove this hack when normal OpenOCD SMP mechanism is supported */
585+
ret = target_resume(target, 1, 0, 1, 0);
559586
if (ret != ERROR_OK) {
560587
LOG_ERROR(
561588
"%s: Failed to resume target after flash BPs removal (%d)!",
@@ -564,7 +591,6 @@ static int esp32_handle_target_event(struct target *target, enum target_event ev
564591
return ret;
565592
}
566593
}
567-
568594
return ERROR_OK;
569595
}
570596

@@ -582,6 +608,14 @@ static int esp32_target_init(struct command_context *cmd_ctx, struct target *tar
582608
return ERROR_OK;
583609
}
584610

611+
static void esp32_target_deinit(struct target *target)
612+
{
613+
struct xtensa_mcore_common *xtensa_mcore = target_to_xtensa_mcore(target);
614+
615+
for (size_t i = 0; i < xtensa_mcore->configured_cores_num; i++)
616+
xtensa_mcore->cores_targets[i].type->deinit_target(&xtensa_mcore->cores_targets[i]);
617+
}
618+
585619
static int esp32_xtensa_core_resume(struct target *target,
586620
int current,
587621
target_addr_t address,
@@ -639,6 +673,7 @@ static struct target_type esp32_xtensa_core_target_type = {
639673

640674
.init_target = esp_xtensa_target_init,
641675
.examine = xtensa_examine,
676+
.deinit_target = esp_xtensa_target_deinit,
642677
};
643678

644679
static struct xtensa_debug_ops esp32_dbg_ops = {
@@ -930,6 +965,7 @@ struct target_type esp32_target = {
930965
.target_create = esp32_target_create,
931966
.init_target = esp32_target_init,
932967
.examine = xtensa_mcore_examine,
968+
.deinit_target = esp32_target_deinit,
933969

934970
.commands = esp32_all_command_handlers,
935971

src/target/esp32s2.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,7 @@ struct target_type esp32_s2_target = {
549549
.target_create = esp32_s2_target_create,
550550
.init_target = esp32_s2_target_init,
551551
.examine = xtensa_examine,
552+
.deinit_target = esp_xtensa_target_deinit,
552553

553554
.commands = esp32_s2_command_handlers,
554555
};

src/target/esp_xtensa.c

Lines changed: 43 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -91,21 +91,41 @@ static int esp_xtensa_dbgstubs_restore(struct target *target)
9191
return ERROR_OK;
9292
}
9393

94-
static int esp_xtensa_on_exit(struct target *target, void *priv)
94+
int esp_xtensa_special_breakpoints_clear(struct target *target)
9595
{
96-
if (target != priv)
97-
return ERROR_OK;
96+
struct esp_xtensa_common *esp_xtensa = target_to_esp_xtensa(target);
9897

99-
LOG_DEBUG("start");
100-
int ret = esp_xtensa_dbgstubs_restore(target);
101-
if (ret != ERROR_OK)
102-
return ret;
98+
for (size_t slot = 0; slot < ESP_XTENSA_SPECIAL_BREAKPOINTS_MAX_NUM;
99+
slot++) {
100+
struct esp_xtensa_special_breakpoint *spec_bp =
101+
&esp_xtensa->spec_brps[slot];
102+
if (spec_bp->data.oocd_bp != NULL) {
103+
int ret = esp_xtensa->spec_brps_ops.breakpoint_remove(
104+
target,
105+
spec_bp);
106+
if (ret != ERROR_OK) {
107+
LOG_ERROR(
108+
"%s: Failed to remove SW flash BP @ "
109+
TARGET_ADDR_FMT " (%d)!",
110+
target_name(target),
111+
spec_bp->data.oocd_bp->address,
112+
ret);
113+
return ret;
114+
}
115+
}
116+
}
117+
memset(esp_xtensa->spec_brps,
118+
0,
119+
ESP_XTENSA_SPECIAL_BREAKPOINTS_MAX_NUM*
120+
sizeof(struct esp_xtensa_special_breakpoint));
103121
return ERROR_OK;
104122
}
105123

106124
static int esp_xtensa_handle_target_event(struct target *target, enum target_event event,
107125
void *priv)
108126
{
127+
int ret;
128+
109129
if (target != priv)
110130
return ERROR_OK;
111131

@@ -120,7 +140,7 @@ static int esp_xtensa_handle_target_event(struct target *target, enum target_eve
120140
{
121141
enum target_state old_state = target->state;
122142
if (target->state != TARGET_HALTED) {
123-
int ret = target_halt(target);
143+
ret = target_halt(target);
124144
if (ret != ERROR_OK) {
125145
LOG_ERROR(
126146
"%s: Failed to halt target to remove flash BPs (%d)!",
@@ -137,32 +157,11 @@ static int esp_xtensa_handle_target_event(struct target *target, enum target_eve
137157
return ret;
138158
}
139159
}
140-
struct esp_xtensa_common *esp_xtensa = target_to_esp_xtensa(target);
141-
for (size_t slot = 0; slot < ESP_XTENSA_SPECIAL_BREAKPOINTS_MAX_NUM;
142-
slot++) {
143-
struct esp_xtensa_special_breakpoint *spec_bp =
144-
&esp_xtensa->spec_brps[slot];
145-
if (spec_bp->data.oocd_bp != NULL) {
146-
int ret = esp_xtensa->spec_brps_ops.breakpoint_remove(
147-
target,
148-
spec_bp);
149-
if (ret != ERROR_OK) {
150-
LOG_ERROR(
151-
"%s: Failed to remove SW flash BP @ "
152-
TARGET_ADDR_FMT " (%d)!",
153-
target_name(target),
154-
spec_bp->data.oocd_bp->address,
155-
ret);
156-
return ret;
157-
}
158-
}
159-
}
160-
memset(esp_xtensa->spec_brps,
161-
0,
162-
ESP_XTENSA_SPECIAL_BREAKPOINTS_MAX_NUM*
163-
sizeof(struct esp_xtensa_special_breakpoint));
160+
ret = esp_xtensa_special_breakpoints_clear(target);
161+
if (ret != ERROR_OK)
162+
return ret;
164163
if (old_state == TARGET_RUNNING) {
165-
int ret = target_resume(target, 1, 0, 1, 0);
164+
ret = target_resume(target, 1, 0, 1, 0);
166165
if (ret != ERROR_OK) {
167166
LOG_ERROR(
168167
"%s: Failed to resume target after flash BPs removal (%d)!",
@@ -188,10 +187,7 @@ int esp_xtensa_init_arch_info(struct target *target, struct target *chip_target,
188187
{
189188
struct esp_xtensa_common *esp_xtensa;
190189

191-
int ret = target_register_exit_callback(esp_xtensa_on_exit, NULL);
192-
if (ret != ERROR_OK)
193-
return ret;
194-
ret = target_register_event_callback(esp_xtensa_handle_target_event, target);
190+
int ret = target_register_event_callback(esp_xtensa_handle_target_event, target);
195191
if (ret != ERROR_OK)
196192
return ret;
197193
if (target != chip_target) {
@@ -234,6 +230,16 @@ int esp_xtensa_target_init(struct command_context *cmd_ctx, struct target *targe
234230
return ERROR_OK;
235231
}
236232

233+
void esp_xtensa_target_deinit(struct target *target)
234+
{
235+
LOG_DEBUG("start");
236+
237+
int ret = esp_xtensa_dbgstubs_restore(target);
238+
if (ret != ERROR_OK)
239+
return;
240+
xtensa_deinit(target);
241+
}
242+
237243
int esp_xtensa_arch_state(struct target *target)
238244
{
239245
return ERROR_OK;

src/target/esp_xtensa.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,13 @@ int esp_xtensa_init_arch_info(struct target *target,
134134
const struct xtensa_chip_ops *chip_ops,
135135
const struct esp_xtensa_special_breakpoint_ops *spec_brps_ops);
136136
int esp_xtensa_target_init(struct command_context *cmd_ctx, struct target *target);
137+
void esp_xtensa_target_deinit(struct target *target);
137138
int esp_xtensa_arch_state(struct target *target);
138139
void esp_xtensa_queue_tdi_idle(struct target *target);
139140
int esp_xtensa_breakpoint_add(struct target *target, struct breakpoint *breakpoint);
140141
int esp_xtensa_breakpoint_remove(struct target *target, struct breakpoint *breakpoint);
141142
bool esp_xtensa_is_special_breakpoint(struct target *target, struct breakpoint *breakpoint);
143+
int esp_xtensa_special_breakpoints_clear(struct target *target);
142144
void esp_xtensa_on_reset(struct target *target);
143145
bool esp_xtensa_on_halt(struct target *target);
144146
void esp_xtensa_on_poll(struct target *target);

src/target/target.c

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,6 @@ static struct target_event_callback *target_event_callbacks;
164164
static struct target_timer_callback *target_timer_callbacks;
165165
LIST_HEAD(target_reset_callback_list);
166166
LIST_HEAD(target_trace_callback_list);
167-
LIST_HEAD(target_exit_callback_list);
168167
static const int polling_interval = 100;
169168

170169
static const Jim_Nvp nvp_assert[] = {
@@ -1571,27 +1570,6 @@ int target_register_timer_callback(int (*callback)(void *priv),
15711570
return ERROR_OK;
15721571
}
15731572

1574-
int target_register_exit_callback(int (*callback)(struct target *target, void *priv), void *priv)
1575-
{
1576-
struct target_exit_callback *entry;
1577-
1578-
if (callback == NULL)
1579-
return ERROR_COMMAND_SYNTAX_ERROR;
1580-
1581-
entry = malloc(sizeof(struct target_exit_callback));
1582-
if (entry == NULL) {
1583-
LOG_ERROR("error allocating buffer for exit callback entry");
1584-
return ERROR_COMMAND_SYNTAX_ERROR;
1585-
}
1586-
1587-
entry->callback = callback;
1588-
entry->priv = priv;
1589-
list_add(&entry->list, &target_exit_callback_list);
1590-
1591-
1592-
return ERROR_OK;
1593-
}
1594-
15951573
int target_unregister_event_callback(int (*callback)(struct target *target,
15961574
enum target_event event, void *priv), void *priv)
15971575
{
@@ -1717,19 +1695,6 @@ int target_call_trace_callbacks(struct target *target, size_t len, uint8_t *data
17171695
return ERROR_OK;
17181696
}
17191697

1720-
int target_call_exit_callbacks()
1721-
{
1722-
struct target_exit_callback *callback;
1723-
1724-
struct target *target;
1725-
for (target = all_targets; target; target = target->next) {
1726-
list_for_each_entry(callback, &target_exit_callback_list, list)
1727-
callback->callback(target, callback->priv);
1728-
}
1729-
1730-
return ERROR_OK;
1731-
}
1732-
17331698
static int target_timer_callback_periodic_restart(
17341699
struct target_timer_callback *cb, struct timeval *now)
17351700
{
@@ -2181,8 +2146,6 @@ static void target_destroy(struct target *target)
21812146

21822147
void target_quit(void)
21832148
{
2184-
target_call_exit_callbacks();
2185-
21862149
struct target_event_callback *pe = target_event_callbacks;
21872150
while (pe) {
21882151
struct target_event_callback *t = pe->next;

src/target/target.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -377,10 +377,6 @@ int target_unregister_trace_callback(
377377
size_t len, uint8_t *data, void *priv),
378378
void *priv);
379379

380-
int target_register_exit_callback(
381-
int (*callback)(struct target *target, void *priv),
382-
void *priv);
383-
384380
/* Poll the status of the target, detect any error conditions and report them.
385381
*
386382
* Also note that this fn will clear such error conditions, so a subsequent
@@ -400,7 +396,6 @@ int target_halt(struct target *target);
400396
int target_call_event_callbacks(struct target *target, enum target_event event);
401397
int target_call_reset_callbacks(struct target *target, enum target_reset_mode reset_mode);
402398
int target_call_trace_callbacks(struct target *target, size_t len, uint8_t *data);
403-
int target_call_exit_callbacks(void);
404399

405400
/**
406401
* The period is very approximate, the callback can happen much more often

src/target/xtensa.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2136,6 +2136,24 @@ int xtensa_init_arch_info(struct target *target, struct xtensa *xtensa,
21362136
return ERROR_OK;
21372137
}
21382138

2139+
void xtensa_deinit(struct target *target)
2140+
{
2141+
struct xtensa *xtensa = target_to_xtensa(target);
2142+
2143+
LOG_DEBUG("start");
2144+
int ret = xtensa_queue_dbg_reg_write(xtensa, NARADR_DCRCLR, OCDDCR_ENABLEOCD);
2145+
if (ret != ERROR_OK) {
2146+
LOG_ERROR("Failed to queue OCDDCR_ENABLEOCD clear operation!");
2147+
return;
2148+
}
2149+
xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
2150+
ret = jtag_execute_queue();
2151+
if (ret != ERROR_OK) {
2152+
LOG_ERROR("Failed to clear OCDDCR_ENABLEOCD!");
2153+
return;
2154+
}
2155+
}
2156+
21392157
COMMAND_HELPER(xtensa_cmd_permissive_mode_do, struct xtensa *xtensa)
21402158
{
21412159
if (CMD_ARGC != 1)

src/target/xtensa.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ int xtensa_init_arch_info(struct target *target,
348348
const struct xtensa_debug_module_config *dm_cfg,
349349
const struct xtensa_chip_ops *chip_ops);
350350
void xtensa_build_reg_cache(struct target *target);
351+
void xtensa_deinit(struct target *target);
351352

352353
static inline void xtensa_stepping_isr_mode_set(struct target *target,
353354
enum xtensa_stepping_isr_mode mode)

0 commit comments

Comments
 (0)