Skip to content

Commit 72cc59b

Browse files
committed
esp32: go directly into halted state in xtensa_step
Previous behaviour of stepping in Xtensa target was different from most other OpenOCD targets. The target was kept in running state, and xtensa_poll function would handle the fact that CPU is halted and return control to the debugger. This caused stepping to be slow in many cases, since xtensa_poll is only called once every 100ms. This changes xtensa_step to indicate that target is halted. This allows gdb to do the next step immediately instead of waiting for the next polling period. Related to #29
1 parent ec6d2c8 commit 72cc59b

File tree

1 file changed

+28
-27
lines changed

1 file changed

+28
-27
lines changed

src/target/esp32.c

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -978,7 +978,7 @@ static int xtensa_step(struct target *target,
978978
uint8_t dsr[4];
979979
static const uint32_t icount_val = -2; /* ICOUNT value to load for 1 step */
980980
uint32_t icountlvl;
981-
uint32_t oldps, newps, oldpc;
981+
uint32_t oldps, newps, oldpc, cur_pc;
982982

983983
LOG_DEBUG("%s: %s(current=%d, address=0x%04x, handle_breakpoints=%i)", target->cmd_name, __func__, current, address, handle_breakpoints);
984984

@@ -1024,24 +1024,18 @@ static int xtensa_step(struct target *target,
10241024
current = 0; // The PC was modified.
10251025
}
10261026

1027-
1027+
struct reg *cpu_reg_list = esp32->core_caches[esp32->active_cpu]->reg_list;
1028+
10281029

10291030
do {
1030-
{
1031-
struct reg *cpu_reg_list = esp32->core_caches[esp32->active_cpu]->reg_list;
1032-
esp108_reg_set(&cpu_reg_list[XT_REG_IDX_ICOUNTLEVEL], icountlvl);
1033-
esp108_reg_set(&cpu_reg_list[XT_REG_IDX_ICOUNT], icount_val);
1034-
}
1031+
esp108_reg_set(&cpu_reg_list[XT_REG_IDX_ICOUNTLEVEL], icountlvl);
1032+
esp108_reg_set(&cpu_reg_list[XT_REG_IDX_ICOUNT], icount_val);
10351033

10361034
/* Now ICOUNT is set, we can resume as if we were going to run */
1037-
int cause_local = esp108_reg_get(&reg_list[XT_REG_IDX_DEBUGCAUSE]);
1038-
if ((cause_local&(DEBUGCAUSE_BI | DEBUGCAUSE_DB)) == 0)
1039-
{
1040-
res = xtensa_resume_cpu(target, current, address, 0, 0);
1041-
if (res != ERROR_OK) {
1042-
LOG_ERROR("%s: %s: Failed to resume after setting up single step", target->cmd_name, __func__);
1043-
return res;
1044-
}
1035+
res = xtensa_resume_cpu(target, current, address, 0, 0);
1036+
if (res != ERROR_OK) {
1037+
LOG_ERROR("%s: %s: Failed to resume after setting up single step", target->cmd_name, __func__);
1038+
return res;
10451039
}
10461040

10471041
/* Wait for stepping to complete */
@@ -1060,19 +1054,28 @@ static int xtensa_step(struct target *target,
10601054
}
10611055
}
10621056
if(!(intfromchars(dsr)&OCDDSR_STOPPED)) {
1063-
LOG_ERROR("%s: %s: Timed out waiting for target to finish stepping. dsr=0x%08x", target->cmd_name, __func__, intfromchars(dsr));
1064-
return ERROR_TARGET_TIMEOUT;
1057+
LOG_WARNING("%s: %s: Timed out waiting for target to finish stepping. dsr=0x%08x", target->cmd_name, __func__, intfromchars(dsr));
1058+
target->debug_reason = DBG_REASON_NOTHALTED;
1059+
target->state = TARGET_RUNNING;
1060+
return ERROR_OK;
10651061
}
1062+
target->debug_reason = DBG_REASON_SINGLESTEP;
1063+
target->state = TARGET_HALTED;
1064+
10661065
esp32_fetch_all_regs(target, 1 << esp32->active_cpu);
1067-
} while (0);
10681066

1069-
uint32_t cur_pc = esp108_reg_get(&reg_list[XT_REG_IDX_PC]);
1070-
if (oldpc == cur_pc) {
1071-
LOG_WARNING("%s: %s: Stepping doesn't seem to change PC! dsr=0x%08x", target->cmd_name, __func__, intfromchars(dsr));
1072-
}
1073-
else {
1074-
LOG_DEBUG("Stepped from %X to %X", oldpc, cur_pc);
1067+
cur_pc = esp108_reg_get(&reg_list[XT_REG_IDX_PC]);
1068+
if (oldpc == cur_pc) {
1069+
LOG_WARNING("%s: %s: Stepping doesn't seem to change PC! dsr=0x%08x", target->cmd_name, __func__, intfromchars(dsr));
1070+
}
1071+
else {
1072+
LOG_DEBUG("Stepped from %X to %X", oldpc, cur_pc);
1073+
}
1074+
break;
10751075
}
1076+
while(true);
1077+
LOG_DEBUG("Done stepping, PC=%X", cur_pc);
1078+
10761079
// This operation required to clear state
10771080
for (size_t cp = 0; cp < ESP32_CPU_COUNT; cp++)
10781081
{
@@ -1103,9 +1106,7 @@ static int xtensa_step(struct target *target,
11031106
esp108_reg_set(&reg_list[XT_REG_IDX_ICOUNTLEVEL], 0);
11041107
res = esp32_write_dirty_registers(esp32->esp32_targets[esp32->active_cpu], reg_list);
11051108

1106-
//Make sure the poll routine will pick up that something has changed by artificially
1107-
//triggering a running->halted state change
1108-
target->state = TARGET_RUNNING;
1109+
target_call_event_callbacks(target, TARGET_EVENT_HALTED);
11091110
return res;
11101111
}
11111112

0 commit comments

Comments
 (0)