+ /* Excavate the device ID code */
+ struct jtag_tap *tap = dap->jtag_info->tap;
+ while (tap != NULL) {
+ if (tap->hasidcode)
+ break;
+ tap = tap->next_tap;
+ }
+ if (tap == NULL || !tap->hasidcode)
+ return ERROR_OK;
+
+ dap_ap_select(dap, ap_old);
+
+ /* The asignment happens only here to prevent modification of these
+ * values before they are certain. */
+ *out_dbgbase = dbgbase;
+ *out_apid = apid;
+
+ return ERROR_OK;
+}
+
+int dap_lookup_cs_component(struct adiv5_dap *dap, int ap,
+ uint32_t dbgbase, uint8_t type, uint32_t *addr)
+{
+ uint32_t ap_old;
+ uint32_t romentry, entry_offset = 0, component_base, devtype;
+ int retval = ERROR_FAIL;
+
+ if (ap >= 256)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ ap_old = dap->ap_current;
+ dap_ap_select(dap, ap);
+
+ do {
+ retval = mem_ap_read_atomic_u32(dap, (dbgbase&0xFFFFF000) |
+ entry_offset, &romentry);
+ if (retval != ERROR_OK)
+ return retval;
+
+ component_base = (dbgbase & 0xFFFFF000)
+ + (romentry & 0xFFFFF000);
+
+ if (romentry & 0x1) {
+ retval = mem_ap_read_atomic_u32(dap,
+ (component_base & 0xfffff000) | 0xfcc,
+ &devtype);
+ if (retval != ERROR_OK)
+ return retval;
+ if ((devtype & 0xff) == type) {
+ *addr = component_base;
+ retval = ERROR_OK;
+ break;
+ }
+ }
+ entry_offset += 4;
+ } while (romentry > 0);
+
+ dap_ap_select(dap, ap_old);
+
+ return retval;
+}
+
+static int dap_info_command(struct command_context *cmd_ctx,
+ struct adiv5_dap *dap, int ap)
+{
+ int retval;
+ uint32_t dbgbase = 0, apid = 0; /* Silence gcc by initializing */
+ int romtable_present = 0;
+ uint8_t mem_ap;
+ uint32_t ap_old;
+
+ retval = dap_get_debugbase(dap, ap, &dbgbase, &apid);
+ if (retval != ERROR_OK)
+ return retval;
+
+ ap_old = dap->ap_current;
+ dap_ap_select(dap, ap);
+