cortex_a: allow physical memory access through AHB-AP again
authorMatthias Welwarsky <matthias.welwarsky@sysgo.com>
Mon, 22 Feb 2016 14:23:10 +0000 (15:23 +0100)
committerPaul Fertser <fercerpav@gmail.com>
Thu, 24 Mar 2016 12:32:43 +0000 (12:32 +0000)
This feature is required for boards that use a programmatical way
to reset the cpu, like the TI Pandaboard with OMAP4. The board only
has a 14 pin JTAG header that doesn't feature SRST and is reset by
direct write to the PRM_RSTCTL register.

iMX6 can be reset through triggering the on-chip watchdog, but for these
methods to work reliably, access through the AHB-AP without interaction
with the CPU core is necessary.

Change-Id: I9a07a536adda83cc2f93e504384c8c7f0306220b
Signed-off-by: Matthias Welwarsky <matthias.welwarsky@sysgo.com>
Reviewed-on: http://openocd.zylin.com/3359
Tested-by: jenkins
Reviewed-by: Paul Fertser <fercerpav@gmail.com>
src/target/cortex_a.c

index b8304c4149939a750fe3cd25c9b12ec330745b9a..27a8a9b9c10e66947bdb7b84ea4fbe171ea90c86 100644 (file)
@@ -2668,17 +2668,25 @@ static int cortex_a_read_phys_memory(struct target *target,
        uint32_t address, uint32_t size,
        uint32_t count, uint8_t *buffer)
 {
-       int retval = ERROR_COMMAND_SYNTAX_ERROR;
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct adiv5_dap *swjdp = armv7a->arm.dap;
+       uint8_t apsel = swjdp->apsel;
+       int retval;
+
+       if (!count || !buffer)
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
        LOG_DEBUG("Reading memory at real address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32,
                address, size, count);
 
-       if (count && buffer) {
-               /* read memory through APB-AP */
-               cortex_a_prep_memaccess(target, 1);
-               retval = cortex_a_read_apb_ab_memory(target, address, size, count, buffer);
-               cortex_a_post_memaccess(target, 1);
-       }
+       if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap->ap_num))
+               return mem_ap_read_buf(armv7a->memory_ap, buffer, size, count, address);
+
+       /* read memory through APB-AP */
+       cortex_a_prep_memaccess(target, 1);
+       retval = cortex_a_read_apb_ab_memory(target, address, size, count, buffer);
+       cortex_a_post_memaccess(target, 1);
+
        return retval;
 }
 
@@ -2745,17 +2753,24 @@ static int cortex_a_write_phys_memory(struct target *target,
        uint32_t address, uint32_t size,
        uint32_t count, const uint8_t *buffer)
 {
-       int retval = ERROR_COMMAND_SYNTAX_ERROR;
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct adiv5_dap *swjdp = armv7a->arm.dap;
+       uint8_t apsel = swjdp->apsel;
+       int retval;
+
+       if (!count || !buffer)
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
        LOG_DEBUG("Writing memory to real address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32, address,
                size, count);
 
-       if (count && buffer) {
-               /* write memory through APB-AP */
-               cortex_a_prep_memaccess(target, 1);
-               retval = cortex_a_write_apb_ab_memory(target, address, size, count, buffer);
-               cortex_a_post_memaccess(target, 1);
-       }
+       if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap->ap_num))
+               return mem_ap_write_buf(armv7a->memory_ap, buffer, size, count, address);
+
+       /* write memory through APB-AP */
+       cortex_a_prep_memaccess(target, 1);
+       retval = cortex_a_write_apb_ab_memory(target, address, size, count, buffer);
+       cortex_a_post_memaccess(target, 1);
 
        return retval;
 }