From 00dbc185ee56e68fac04935f388259d13ecef315 Mon Sep 17 00:00:00 2001 From: Andreas Fritiofson Date: Sun, 6 Dec 2015 14:04:24 +0100 Subject: [PATCH] arm_adi_v5: Split ahbap_debugport_init This function does two separate things, powering up the DP and setting up a MEM-AP. But the DP needs to be powered before even searching for a MEM-AP to initialize and targets may have multiple MEM-APs that need initializing. Split the function into dap_dp_init() and mem_ap_init() and change all call sites to use the appropriate one. Change-Id: I92f55e09754a93f3f01dd8e5aa1ffdf60c856126 Signed-off-by: Andreas Fritiofson Reviewed-on: http://openocd.zylin.com/3151 Tested-by: jenkins Reviewed-by: Matthias Welwarsky --- src/target/adi_v5_swd.c | 2 ++ src/target/arm_adi_v5.c | 71 +++++++++++++++++++++++------------------ src/target/arm_adi_v5.h | 3 +- src/target/cortex_a.c | 32 ++++++++++++------- src/target/cortex_m.c | 12 +++++-- 5 files changed, 74 insertions(+), 46 deletions(-) diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c index f8321422..9bd1f93e 100644 --- a/src/target/adi_v5_swd.c +++ b/src/target/adi_v5_swd.c @@ -112,7 +112,9 @@ static int swd_connect(struct adiv5_dap *dap) /* Note, debugport_init() does setup too */ jtag_interface->swd->switch_seq(JTAG_TO_SWD); + /* Make sure we don't try to perform any other accesses before the DPIDR read. */ dap->do_reconnect = false; + dap->dp_bank_value = 0; swd_queue_dp_read(dap, DP_IDCODE, &idcode); diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index 5d55d516..0cc1b5c1 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -645,45 +645,33 @@ struct adiv5_dap *dap_init(void) /* Number of bits for tar autoincrement, impl. dep. at least 10 */ dap->ap[i].tar_autoincr_block = (1<<10); } + dap->ap_current = -1; + dap->ap_bank_value = -1; + dap->dp_bank_value = -1; return dap; } /** * Initialize a DAP. This sets up the power domains, prepares the DP - * for further use, and arranges to use AP #0 for all AP operations - * until dap_ap-select() changes that policy. + * for further use and activates overrun checking. * * @param dap The DAP being initialized. - * - * @todo Rename this. We also need an initialization scheme which account - * for SWD transports not just JTAG; that will need to address differences - * in layering. (JTAG is useful without any debug target; but not SWD.) - * And this may not even use an AHB-AP ... e.g. DAP-Lite uses an APB-AP. */ -int ahbap_debugport_init(struct adiv5_ap *ap) +int dap_dp_init(struct adiv5_dap *dap) { - /* check that we support packed transfers */ - uint32_t csw, cfg; int retval; - struct adiv5_dap *dap = ap->dap; LOG_DEBUG(" "); - /* JTAG-DP or SWJ-DP, in JTAG mode * ... for SWD mode this is patched as part * of link switchover + * FIXME: This should already be setup by the respective transport specific DAP creation. */ if (!dap->ops) dap->ops = &jtag_dp_ops; - /* Default MEM-AP setup. - * - * REVISIT AP #0 may be an inappropriate default for this. - * Should we probe, or take a hint from the caller? - * Presumably we can ignore the possibility of multiple APs. - */ dap->ap_current = -1; - dap_ap_select(dap, ap->ap_num); + dap->ap_bank_value = -1; dap->last_read = NULL; for (size_t i = 0; i < 10; i++) { @@ -726,6 +714,7 @@ int ahbap_debugport_init(struct adiv5_ap *ap) retval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL); if (retval != ERROR_OK) continue; + /* With debug power on we can activate OVERRUN checking */ dap->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ | CORUNDETECT; retval = dap_queue_dp_write(dap, DP_CTRL_STAT, dap->dp_ctrl_stat); @@ -735,18 +724,6 @@ int ahbap_debugport_init(struct adiv5_ap *ap) if (retval != ERROR_OK) continue; - retval = dap_setup_accessport(dap, CSW_8BIT | CSW_ADDRINC_PACKED, 0); - if (retval != ERROR_OK) - continue; - - retval = dap_queue_ap_read(dap, MEM_AP_REG_CSW, &csw); - if (retval != ERROR_OK) - continue; - - retval = dap_queue_ap_read(dap, MEM_AP_REG_CFG, &cfg); - if (retval != ERROR_OK) - continue; - retval = dap_run(dap); if (retval != ERROR_OK) continue; @@ -754,6 +731,38 @@ int ahbap_debugport_init(struct adiv5_ap *ap) break; } + return retval; +} + +/** + * Initialize a DAP. This sets up the power domains, prepares the DP + * for further use, and arranges to use AP #0 for all AP operations + * until dap_ap-select() changes that policy. + * + * @param ap The MEM-AP being initialized. + */ +int mem_ap_init(struct adiv5_ap *ap) +{ + /* check that we support packed transfers */ + uint32_t csw, cfg; + int retval; + struct adiv5_dap *dap = ap->dap; + + dap_ap_select(dap, ap->ap_num); + + retval = dap_setup_accessport(dap, CSW_8BIT | CSW_ADDRINC_PACKED, 0); + if (retval != ERROR_OK) + return retval; + + retval = dap_queue_ap_read(dap, MEM_AP_REG_CSW, &csw); + if (retval != ERROR_OK) + return retval; + + retval = dap_queue_ap_read(dap, MEM_AP_REG_CFG, &cfg); + if (retval != ERROR_OK) + return retval; + + retval = dap_run(dap); if (retval != ERROR_OK) return retval; diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h index faf725fc..8672036f 100644 --- a/src/target/arm_adi_v5.h +++ b/src/target/arm_adi_v5.h @@ -488,7 +488,8 @@ int mem_ap_sel_write_buf_noincr(struct adiv5_ap *ap, struct adiv5_dap *dap_init(void); /* Initialisation of the debug system, power domains and registers */ -int ahbap_debugport_init(struct adiv5_ap *ap); +int dap_dp_init(struct adiv5_dap *dap); +int mem_ap_init(struct adiv5_ap *ap); /* Probe the AP for ROM Table location */ int dap_get_debugbase(struct adiv5_ap *ap, diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index f95985a7..0923f880 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -2910,6 +2910,12 @@ static int cortex_a_examine_first(struct target *target) int retval = ERROR_OK; uint32_t didr, ctypr, ttypr, cpuid, dbg_osreg; + retval = dap_dp_init(swjdp); + if (retval != ERROR_OK) { + LOG_ERROR("Could not initialize the debug port"); + return retval; + } + /* Search for the APB-AB - it is needed for access to debug registers */ retval = dap_find_ap(swjdp, AP_TYPE_APB_AP, &armv7a->debug_ap); if (retval != ERROR_OK) { @@ -2917,24 +2923,28 @@ static int cortex_a_examine_first(struct target *target) return retval; } - /* We do one extra read to ensure DAP is configured, - * we call ahbap_debugport_init(swjdp) instead - */ - retval = ahbap_debugport_init(armv7a->debug_ap); - if (retval != ERROR_OK) + retval = mem_ap_init(armv7a->debug_ap); + if (retval != ERROR_OK) { + LOG_ERROR("Could not initialize the APB-AP"); return retval; + } - /* Search for the AHB-AB */ + /* Search for the AHB-AB. + * REVISIT: We should search for AXI-AP as well and make sure the AP's MEMTYPE says it + * can access system memory. */ + armv7a->memory_ap_available = false; retval = dap_find_ap(swjdp, AP_TYPE_AHB_AP, &armv7a->memory_ap); - if (retval != ERROR_OK) { + if (retval == ERROR_OK) { + retval = mem_ap_init(armv7a->memory_ap); + if (retval == ERROR_OK) + armv7a->memory_ap_available = true; + else + LOG_WARNING("Could not initialize AHB-AP for memory access - using APB-AP"); + } else { /* AHB-AP not found - use APB-AP */ LOG_DEBUG("Could not find AHB-AP - using APB-AP for memory access"); - armv7a->memory_ap_available = false; - } else { - armv7a->memory_ap_available = true; } - if (!target->dbgbase_set) { uint32_t dbgbase; /* Get ROM Table base */ diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index d92cfce2..ca230f37 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -1063,7 +1063,7 @@ static int cortex_m_assert_reset(struct target *target) if (retval != ERROR_OK) LOG_DEBUG("Ignoring AP write error right after reset"); - retval = ahbap_debugport_init(armv7m->debug_ap); + retval = dap_dp_init(armv7m->debug_ap->dap); if (retval != ERROR_OK) { LOG_ERROR("DP initialisation failed"); return retval; @@ -1109,7 +1109,7 @@ static int cortex_m_deassert_reset(struct target *target) if ((jtag_reset_config & RESET_HAS_SRST) && !(jtag_reset_config & RESET_SRST_NO_GATING)) { - int retval = ahbap_debugport_init(armv7m->debug_ap); + int retval = dap_dp_init(armv7m->debug_ap->dap); if (retval != ERROR_OK) { LOG_ERROR("DP initialisation failed"); return retval; @@ -1891,6 +1891,12 @@ int cortex_m_examine(struct target *target) struct adiv5_dap *swjdp = cortex_m->armv7m.arm.dap; struct armv7m_common *armv7m = target_to_armv7m(target); + retval = dap_dp_init(swjdp); + if (retval != ERROR_OK) { + LOG_ERROR("Could not initialize the debug port"); + return retval; + } + /* Search for the MEM-AP */ retval = dap_find_ap(swjdp, AP_TYPE_AHB_AP, &armv7m->debug_ap); if (retval != ERROR_OK) { @@ -1904,7 +1910,7 @@ int cortex_m_examine(struct target *target) /* stlink shares the examine handler but does not support * all its calls */ if (!armv7m->stlink) { - retval = ahbap_debugport_init(armv7m->debug_ap); + retval = mem_ap_init(armv7m->debug_ap); if (retval != ERROR_OK) return retval; } -- 2.39.5