From: "vimoon.zheng" <[email protected]>
Detect the MEM-AP type (APB, AXI, or AHB) by reading the IDR register
during initialization and configure the default CSW register value
accordingly.
This ensures the correct cache and domain settings are
applied for AXI-APs, specifically setting the domain to system shareable.
Additionally, move the mem_ap_init call earlier in the examination
process to handle initialization errors before setting the target state.
---
src/target/arm_adi_v5.c | 21 +++++++++++++++++++++
src/target/arm_adi_v5.h | 7 ++++++-
src/target/mem_ap.c | 6 +++++-
3 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c
index 67a3fcc57..810ebebdc 100644
--- a/src/target/arm_adi_v5.c
+++ b/src/target/arm_adi_v5.c
@@ -899,6 +899,7 @@ int mem_ap_init(struct adiv5_ap *ap)
uint32_t cfg;
int retval;
struct adiv5_dap *dap = ap->dap;
+ uint32_t id_val = 0;
/* Set ap->cfg_reg before calling mem_ap_setup_transfer(). */
/* mem_ap_setup_transfer() needs to know if the MEM_AP supports LPAE. */
@@ -939,6 +940,26 @@ int mem_ap_init(struct adiv5_ap *ap)
* operations are supported on other processors. */
ap->unaligned_access_bad = dap->ti_be_32_quirks;
+ retval = dap_queue_ap_read(ap, AP_REG_IDR(dap), &id_val);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = dap_run(dap);
+ if (retval != ERROR_OK)
+ return retval;
+
+ id_val = id_val & AP_TYPE_MASK;
+ if (id_val == AP_TYPE_APB_AP || id_val == AP_TYPE_APB4_AP) {
+ LOG_DEBUG("MEM_AP APB-AP");
+ ap->csw_default = CSW_APB_DEFAULT;
+ } else if (id_val == AP_TYPE_AXI_AP || id_val == AP_TYPE_AXI5_AP) {
+ LOG_DEBUG("MEM_AP AXI-AP");
+ ap->csw_default = CSW_AXI_DEFAULT;
+ } else {
+ LOG_DEBUG("Unknown MEM_AP %d AP type", id_val);
+ ap->csw_default = CSW_AHB_DEFAULT;
+ }
+
LOG_DEBUG("MEM_AP CFG: large data %d, long address %d, big-endian %d",
!!(cfg & MEM_AP_REG_CFG_LD), !!(cfg &
MEM_AP_REG_CFG_LA), !!(cfg & MEM_AP_REG_CFG_BE));
diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h
index ebd2752bd..c78265396 100644
--- a/src/target/arm_adi_v5.h
+++ b/src/target/arm_adi_v5.h
@@ -196,8 +196,13 @@
#define CSW_AXI_ARPROT0_PRIV (1UL << 28)
/* AXI: Non-secure */
#define CSW_AXI_ARPROT1_NONSEC (1UL << 29)
+/* AXI: DOMAIN */
+#define CSW_AXI_DOM_NON_SHAREABLE (0UL << 13)
+#define CSW_AXI_DOM_INNER_SHAREABLE (1UL << 13)
+#define CSW_AXI_DOM_OUTER_SHAREABLE (2UL << 13)
+#define CSW_AXI_DOM_SYSTEM (3UL << 13)
/* AXI: initial value of csw_default */
-#define CSW_AXI_DEFAULT (CSW_AXI_ARPROT0_PRIV | CSW_AXI_ARPROT1_NONSEC
| CSW_DBGSWENABLE)
+#define CSW_AXI_DEFAULT (CSW_AXI_DOM_SYSTEM | CSW_AXI_ARPROT0_PRIV |
CSW_AXI_ARPROT1_NONSEC | CSW_DBGSWENABLE)
/* APB: initial value of csw_default */
#define CSW_APB_DEFAULT (CSW_DBGSWENABLE)
diff --git a/src/target/mem_ap.c b/src/target/mem_ap.c
index c5618c9cc..65f65f43c 100644
--- a/src/target/mem_ap.c
+++ b/src/target/mem_ap.c
@@ -143,10 +143,14 @@ static int mem_ap_examine(struct target *target)
return ERROR_FAIL;
}
}
+ if (mem_ap_init(mem_ap->ap)) {
+ dap_put_ap(mem_ap->ap);
+ mem_ap->ap = NULL;
+ return ERROR_FAIL;
+ }
target_set_examined(target);
target->state = TARGET_UNKNOWN;
target->debug_reason = DBG_REASON_UNDEFINED;
- return mem_ap_init(mem_ap->ap);
}
return ERROR_OK;
--
2.52.0