Skip to content

Commit 3ed5c26

Browse files
committed
cortexar: fixed hang-on-run with requested changes
- Added documentation to cortexar_halt_and_wait function. - Reverted cortexar_mem_read to use in-function halt/resume. - Cleared up other requested change items - Added halt_resume in SCTLR MMU check in cortexar_virt_to_phys before returning.
1 parent 7e4fca5 commit 3ed5c26

File tree

1 file changed

+34
-24
lines changed

1 file changed

+34
-24
lines changed

src/target/cortexar.c

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,9 @@ static target_addr_t cortexar_virt_to_phys(target_s *const target, const target_
660660
/* Check if MMU is turned on; if not, return the virt_addr as-is. */
661661
const uint32_t sctlr = cortexar_coproc_read(target, CORTEXAR_SCTLR);
662662
if (!(sctlr & CORTEXAR_SCTLR_MMU_ENABLED)) {
663+
/* Ensure we resume if we halted above, prior to returning. */
664+
if (halted_in_function)
665+
cortexar_halt_resume(target, false);
663666
return virt_addr;
664667
}
665668

@@ -1093,15 +1096,13 @@ static void cortexar_mem_handle_fault(target_s *const target, const char *const
10931096
* This reads memory by jumping from the debug unit bus to the system bus.
10941097
* NB: This requires the core to be halted! Uses instruction launches on
10951098
* the core and requires we're in debug mode to work. Trashes r0.
1096-
* If core is not halted, falls back to adiv5 mem read.
1099+
* If core is not halted, temporarily halts target and resumes at the end
1100+
* of the function.
10971101
*/
10981102
static void cortexar_mem_read(target_s *const target, void *const dest, const target_addr64_t src, const size_t len)
10991103
{
1100-
/* If system is not halted, perform basic adiv5 memory read. */
1101-
if (!(cortex_dbg_read32(target, CORTEXAR_DBG_DSCR) & CORTEXAR_DBG_DSCR_HALTED)) {
1102-
adiv5_mem_read(cortex_ap(target), dest, src, len);
1103-
return;
1104-
}
1104+
/* If system is not halted, halt temporarily within this function. */
1105+
const bool halted_in_function = cortexar_halt_and_wait(target);
11051106

11061107
cortexar_priv_s *const priv = (cortexar_priv_s *)target->priv;
11071108
/* Cache DFSR and DFAR in case we wind up triggering a data fault */
@@ -1136,6 +1137,9 @@ static void cortexar_mem_read(target_s *const target, void *const dest, const ta
11361137
if (len > 16U)
11371138
DEBUG_PROTO(" ...");
11381139
DEBUG_PROTO("\n");
1140+
1141+
if (halted_in_function)
1142+
cortexar_halt_resume(target, false);
11391143
}
11401144

11411145
/* Fast path for cortexar_mem_write(). Assumes the address to read data from is already loaded in r0. */
@@ -1376,7 +1380,6 @@ static void cortexar_reset(target_s *const target)
13761380

13771381
/* 10ms delay to ensure bootroms have had time to run */
13781382
platform_delay(10);
1379-
13801383
/* Ignore any initial errors out of reset */
13811384
target_check_error(target);
13821385
}
@@ -1458,12 +1461,10 @@ static target_halt_reason_e cortexar_halt_poll(target_s *const target, target_ad
14581461
static void cortexar_halt_resume(target_s *const target, const bool step)
14591462
{
14601463
uint32_t dscr = cortex_dbg_read32(target, CORTEXAR_DBG_DSCR);
1461-
cortexar_priv_s *const priv = (cortexar_priv_s *)target->priv;
1462-
14631464
if (!(dscr & CORTEXAR_DBG_DSCR_HALTED))
14641465
return;
14651466

1466-
priv->base.ap->dp->quirks &= ~ADIV5_AP_ACCESS_BANKED;
1467+
cortexar_priv_s *const priv = (cortexar_priv_s *)target->priv;
14671468
/* Restore the core's registers so the running program doesn't know we've been in there */
14681469
cortexar_regs_restore(target);
14691470

@@ -1502,24 +1503,33 @@ static void cortexar_halt_resume(target_s *const target, const bool step)
15021503
}
15031504

15041505
/*
1505-
* Halt the core and await halted status.
1506+
* Halt the core and await halted status. This function should only return true when
1507+
* it is, itself, responsible for having halted the target. This allows storing of the
1508+
* returned value to later determine whether the target should be resumed.
15061509
*/
15071510
static bool cortexar_halt_and_wait(target_s *const target)
15081511
{
1509-
if (!(cortex_dbg_read32(target, CORTEXAR_DBG_DSCR) & CORTEXAR_DBG_DSCR_HALTED)) {
1510-
platform_timeout_s timeout;
1511-
cortexar_halt_request(target);
1512-
platform_timeout_set(&timeout, 250);
1513-
target_halt_reason_e reason = TARGET_HALT_RUNNING;
1514-
while (!platform_timeout_is_expired(&timeout) && reason == TARGET_HALT_RUNNING)
1515-
reason = target_halt_poll(target, NULL);
1516-
if (reason != TARGET_HALT_REQUEST) {
1517-
DEBUG_ERROR("Failed to halt the core\n");
1518-
return false;
1519-
}
1520-
return true;
1512+
/*
1513+
* Check the target is already halted; return false as this function was not
1514+
* responsible for halting the target.
1515+
*/
1516+
if (cortex_dbg_read32(target, CORTEXAR_DBG_DSCR) & CORTEXAR_DBG_DSCR_HALTED)
1517+
return false;
1518+
1519+
platform_timeout_s timeout;
1520+
cortexar_halt_request(target);
1521+
platform_timeout_set(&timeout, 250);
1522+
target_halt_reason_e reason = TARGET_HALT_RUNNING;
1523+
while (!platform_timeout_is_expired(&timeout) && reason == TARGET_HALT_RUNNING)
1524+
reason = target_halt_poll(target, NULL);
1525+
if (reason != TARGET_HALT_REQUEST) {
1526+
DEBUG_ERROR("Failed to halt the core\n");
1527+
/* This function tried to halt the target but ultimately was not successful. */
1528+
return false;
15211529
}
1522-
return false;
1530+
1531+
/* Return true as this function successfully halted the target. */
1532+
return true;
15231533
}
15241534

15251535
void cortexar_invalidate_all_caches(target_s *const target)

0 commit comments

Comments
 (0)