arm_adi_v5: make dap_lookup_cs_component() traverse subtables and handle multicore
authorPaul Fertser <fercerpav@gmail.com>
Sun, 2 Feb 2014 21:19:00 +0000 (01:19 +0400)
committerSpencer Oliver <spen@spen-soft.co.uk>
Mon, 6 Oct 2014 11:54:54 +0000 (11:54 +0000)
When looking for a debug base address of a core, one should search
through all the ROM tables, not just the top-level one.

This code also assumes that the first found entry (in a depth-first
search) will correspond to core 0, the second to core 1 etc.

The patch is supposed to be an alternative implementation of
http://openocd.zylin.com/#/c/1313/.

Change-Id: Ifc88971a02fe3d9c00d9bf72a822ade5804d4e09
Signed-off-by: Paul Fertser <fercerpav@gmail.com>
Reviewed-on: http://openocd.zylin.com/1920
Tested-by: jenkins
Reviewed-by: Andreas Fritiofson <andreas.fritiofson@gmail.com>
Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
src/target/arm_adi_v5.c
src/target/arm_adi_v5.h
src/target/cortex_a.c

index a18101daff380b390d3d288207d3289b9c3bc136..9f66070204a6d7ddf61ad71d6001d5a9d1cf0093 100644 (file)
@@ -857,15 +857,16 @@ int dap_get_debugbase(struct adiv5_dap *dap, int ap,
 }
 
 int dap_lookup_cs_component(struct adiv5_dap *dap, int ap,
-                       uint32_t dbgbase, uint8_t type, uint32_t *addr)
+                       uint32_t dbgbase, uint8_t type, uint32_t *addr, int32_t *idx)
 {
        uint32_t ap_old;
        uint32_t romentry, entry_offset = 0, component_base, devtype;
-       int retval = ERROR_FAIL;
+       int retval;
 
        if (ap >= 256)
                return ERROR_COMMAND_SYNTAX_ERROR;
 
+       *addr = 0;
        ap_old = dap->ap_current;
        dap_ap_select(dap, ap);
 
@@ -879,15 +880,33 @@ int dap_lookup_cs_component(struct adiv5_dap *dap, int ap,
                        + (romentry & 0xFFFFF000);
 
                if (romentry & 0x1) {
+                       uint32_t c_cid1;
+                       retval = mem_ap_read_atomic_u32(dap, component_base | 0xff4, &c_cid1);
+                       if (retval != ERROR_OK) {
+                               LOG_ERROR("Can't read component with base address 0x%" PRIx32
+                                         ", the corresponding core might be turned off", component_base);
+                               return retval;
+                       }
+                       if (((c_cid1 >> 4) & 0x0f) == 1) {
+                               retval = dap_lookup_cs_component(dap, ap, component_base,
+                                                       type, addr, idx);
+                               if (retval == ERROR_OK)
+                                       break;
+                               if (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
+                                       return retval;
+                       }
+
                        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;
+                               if (!*idx) {
+                                       *addr = component_base;
+                                       break;
+                               } else
+                                       (*idx)--;
                        }
                }
                entry_offset += 4;
@@ -895,7 +914,10 @@ int dap_lookup_cs_component(struct adiv5_dap *dap, int ap,
 
        dap_ap_select(dap, ap_old);
 
-       return retval;
+       if (!*addr)
+               return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+
+       return ERROR_OK;
 }
 
 static int dap_rom_display(struct command_context *cmd_ctx,
index 047900ad2cd4c55aeee9c9c6bf59a7444dbab589..dee3117e4e7fa659c1f99bfd5412536b4ecfae35 100644 (file)
@@ -470,7 +470,7 @@ int dap_find_ap(struct adiv5_dap *dap,
 
 /* Lookup CoreSight component */
 int dap_lookup_cs_component(struct adiv5_dap *dap, int ap,
-                       uint32_t dbgbase, uint8_t type, uint32_t *addr);
+                       uint32_t dbgbase, uint8_t type, uint32_t *addr, int32_t *idx);
 
 struct target;
 
index 7d58ab34b4699a5a11d3f4f62d7f81478e44a5ef..0393a442073d63ea7a65227102b25bd9b95fae3b 100644 (file)
@@ -2393,14 +2393,19 @@ static int cortex_a_examine_first(struct target *target)
                uint32_t dbgbase;
                /* Get ROM Table base */
                uint32_t apid;
+               int32_t coreidx = target->coreid;
+               LOG_DEBUG("%s's dbgbase is not set, trying to detect using the ROM table",
+                         target->cmd_name);
                retval = dap_get_debugbase(swjdp, 1, &dbgbase, &apid);
                if (retval != ERROR_OK)
                        return retval;
                /* Lookup 0x15 -- Processor DAP */
                retval = dap_lookup_cs_component(swjdp, 1, dbgbase, 0x15,
-                               &armv7a->debug_base);
+                               &armv7a->debug_base, &coreidx);
                if (retval != ERROR_OK)
                        return retval;
+               LOG_DEBUG("Detected core %" PRId32 " dbgbase: %08" PRIx32,
+                         coreidx, armv7a->debug_base);
        } else
                armv7a->debug_base = target->dbgbase;