target: don't implicitly include "breakpoint.h"
[openocd.git] / src / target / arm7_9_common.c
index ce2d4f027fac0fcad4315eda5b5b9d2981d5f137..b07111eb8f37959bd72decb7078086491faba6db 100644 (file)
@@ -30,6 +30,7 @@
 #include "config.h"
 #endif
 
+#include "breakpoints.h"
 #include "embeddedice.h"
 #include "target_request.h"
 #include "arm7_9_common.h"
 #include "arm_simulator.h"
 
 
-int arm7_9_debug_entry(struct target *target);
+/**
+ * @file
+ * Hold common code supporting the ARM7 and ARM9 core generations.
+ *
+ * While the ARM core implementations evolved substantially during these
+ * two generations, they look quite similar from the JTAG perspective.
+ * Both have similar debug facilities, based on the same two scan chains
+ * providing access to the core and to an EmbeddedICE module.  Both can
+ * support similar ETM and ETB modules, for tracing.  And both expose
+ * what could be viewed as "ARM Classic", with multiple processor modes,
+ * shadowed registers, and support for the Thumb instruction set.
+ *
+ * Processor differences include things like presence or absence of MMU
+ * and cache, pipeline sizes, use of a modified Harvard Architecure
+ * (with separate instruction and data busses from the CPU), support
+ * for cpu clock gating during idle, and more.
+ */
+
+static int arm7_9_debug_entry(struct target *target);
 
 /**
  * Clear watchpoints for an ARM7/9 target.
@@ -166,39 +185,6 @@ int arm7_9_setup(struct target *target)
        return arm7_9_clear_watchpoints(arm7_9);
 }
 
-/**
- * Retrieves the architecture information pointers for ARMv4/5 and ARM7/9
- * targets.  A return of ERROR_OK signifies that the target is a valid target
- * and that the pointers have been set properly.
- *
- * @param target Pointer to the target device to get the pointers from
- * @param armv4_5_p Pointer to be filled in with the common struct for ARMV4/5
- *                  targets
- * @param arm7_9_p Pointer to be filled in with the common struct for ARM7/9
- *                 targets
- * @return ERROR_OK if successful
- */
-int arm7_9_get_arch_pointers(struct target *target, struct arm **armv4_5_p, struct arm7_9_common **arm7_9_p)
-{
-       struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
-       struct armv4_5_common_s *armv4_5 = &arm7_9->armv4_5_common;
-
-       /* FIXME stop using this routine; just target_to_arm7_9() and
-        * verify the resulting pointer using a replacement routine
-        * that emits a usage message.
-        */
-       if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
-               return ERROR_TARGET_INVALID;
-
-       if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
-               return ERROR_TARGET_INVALID;
-
-       *armv4_5_p = armv4_5;
-       *arm7_9_p = arm7_9;
-
-       return ERROR_OK;
-}
-
 /**
  * Set either a hardware or software breakpoint on an ARM7/9 target.  The
  * breakpoint is set up even if it is already set.  Some actions, e.g. reset,
@@ -1344,7 +1330,7 @@ int arm7_9_halt(struct target *target)
  * @param target Pointer to target that is entering debug mode
  * @return Error code if anything fails, otherwise ERROR_OK
  */
-int arm7_9_debug_entry(struct target *target)
+static int arm7_9_debug_entry(struct target *target)
 {
        int i;
        uint32_t context[16];
@@ -2721,155 +2707,41 @@ int arm7_9_bulk_write_memory(struct target *target, uint32_t address, uint32_t c
        return retval;
 }
 
-int arm7_9_checksum_memory(struct target *target, uint32_t address, uint32_t count, uint32_t* checksum)
+/**
+ * Perform per-target setup that requires JTAG access.
+ */
+int arm7_9_examine(struct target *target)
 {
-       struct working_area *crc_algorithm;
-       struct armv4_5_algorithm armv4_5_info;
-       struct reg_param reg_params[2];
+       struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
        int retval;
 
-       static const uint32_t arm7_9_crc_code[] = {
-               0xE1A02000,                             /* mov          r2, r0 */
-               0xE3E00000,                             /* mov          r0, #0xffffffff */
-               0xE1A03001,                             /* mov          r3, r1 */
-               0xE3A04000,                             /* mov          r4, #0 */
-               0xEA00000B,                             /* b            ncomp */
-                                                               /* nbyte: */
-               0xE7D21004,                             /* ldrb r1, [r2, r4] */
-               0xE59F7030,                             /* ldr          r7, CRC32XOR */
-               0xE0200C01,                             /* eor          r0, r0, r1, asl 24 */
-               0xE3A05000,                             /* mov          r5, #0 */
-                                                               /* loop: */
-               0xE3500000,                             /* cmp          r0, #0 */
-               0xE1A06080,                             /* mov          r6, r0, asl #1 */
-               0xE2855001,                             /* add          r5, r5, #1 */
-               0xE1A00006,                             /* mov          r0, r6 */
-               0xB0260007,                             /* eorlt        r0, r6, r7 */
-               0xE3550008,                             /* cmp          r5, #8 */
-               0x1AFFFFF8,                             /* bne          loop */
-               0xE2844001,                             /* add          r4, r4, #1 */
-                                                               /* ncomp: */
-               0xE1540003,                             /* cmp          r4, r3 */
-               0x1AFFFFF1,                             /* bne          nbyte */
-                                                               /* end: */
-               0xEAFFFFFE,                             /* b            end */
-               0x04C11DB7                              /* CRC32XOR:    .word 0x04C11DB7 */
-       };
+       if (!target_was_examined(target)) {
+               struct reg_cache *t, **cache_p;
 
-       uint32_t i;
+               t = embeddedice_build_reg_cache(target, arm7_9);
+               if (t == NULL)
+                       return ERROR_FAIL;
 
-       if (target_alloc_working_area(target, sizeof(arm7_9_crc_code), &crc_algorithm) != ERROR_OK)
-       {
-               return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
-       }
+               cache_p = register_get_last_cache_p(&target->reg_cache);
+               (*cache_p) = t;
+               arm7_9->eice_cache = (*cache_p);
 
-       /* convert flash writing code into a buffer in target endianness */
-       for (i = 0; i < (sizeof(arm7_9_crc_code)/sizeof(uint32_t)); i++)
-       {
-               if ((retval = target_write_u32(target, crc_algorithm->address + i*sizeof(uint32_t), arm7_9_crc_code[i])) != ERROR_OK)
-               {
-                       return retval;
-               }
-       }
-
-       armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
-       armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
-       armv4_5_info.core_state = ARMV4_5_STATE_ARM;
-
-       init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
-       init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
-
-       buf_set_u32(reg_params[0].value, 0, 32, address);
-       buf_set_u32(reg_params[1].value, 0, 32, count);
-
-       /* 20 second timeout/megabyte */
-       int timeout = 20000 * (1 + (count / (1024*1024)));
+               if (arm7_9->armv4_5_common.etm)
+                       (*cache_p)->next = etm_build_reg_cache(target,
+                                       &arm7_9->jtag_info,
+                                       arm7_9->armv4_5_common.etm);
 
-       if ((retval = target_run_algorithm(target, 0, NULL, 2, reg_params,
-               crc_algorithm->address, crc_algorithm->address + (sizeof(arm7_9_crc_code) - 8), timeout, &armv4_5_info)) != ERROR_OK)
-       {
-               LOG_ERROR("error executing arm7_9 crc algorithm");
-               destroy_reg_param(&reg_params[0]);
-               destroy_reg_param(&reg_params[1]);
-               target_free_working_area(target, crc_algorithm);
-               return retval;
+               target_set_examined(target);
        }
 
-       *checksum = buf_get_u32(reg_params[0].value, 0, 32);
-
-       destroy_reg_param(&reg_params[0]);
-       destroy_reg_param(&reg_params[1]);
-
-       target_free_working_area(target, crc_algorithm);
-
-       return ERROR_OK;
+       retval = embeddedice_setup(target);
+       if (retval == ERROR_OK)
+               retval = arm7_9_setup(target);
+       if (retval == ERROR_OK && arm7_9->armv4_5_common.etm)
+               retval = etm_setup(target);
+       return retval;
 }
 
-int arm7_9_blank_check_memory(struct target *target, uint32_t address, uint32_t count, uint32_t* blank)
-{
-       struct working_area *erase_check_algorithm;
-       struct reg_param reg_params[3];
-       struct armv4_5_algorithm armv4_5_info;
-       int retval;
-       uint32_t i;
-
-       static const uint32_t erase_check_code[] =
-       {
-               /* loop: */
-               0xe4d03001,             /* ldrb r3, [r0], #1 */
-               0xe0022003,             /* and r2, r2, r3    */
-               0xe2511001,             /* subs r1, r1, #1   */
-               0x1afffffb,             /* bne loop          */
-               /* end: */
-               0xeafffffe              /* b end             */
-       };
-
-       /* make sure we have a working area */
-       if (target_alloc_working_area(target, sizeof(erase_check_code), &erase_check_algorithm) != ERROR_OK)
-       {
-               return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
-       }
-
-       /* convert flash writing code into a buffer in target endianness */
-       for (i = 0; i < (sizeof(erase_check_code)/sizeof(uint32_t)); i++)
-               if ((retval = target_write_u32(target, erase_check_algorithm->address + i*sizeof(uint32_t), erase_check_code[i])) != ERROR_OK)
-               {
-                       return retval;
-               }
-
-       armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
-       armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
-       armv4_5_info.core_state = ARMV4_5_STATE_ARM;
-
-       init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
-       buf_set_u32(reg_params[0].value, 0, 32, address);
-
-       init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
-       buf_set_u32(reg_params[1].value, 0, 32, count);
-
-       init_reg_param(&reg_params[2], "r2", 32, PARAM_IN_OUT);
-       buf_set_u32(reg_params[2].value, 0, 32, 0xff);
-
-       if ((retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
-                       erase_check_algorithm->address, erase_check_algorithm->address + (sizeof(erase_check_code) - 4), 10000, &armv4_5_info)) != ERROR_OK)
-       {
-               destroy_reg_param(&reg_params[0]);
-               destroy_reg_param(&reg_params[1]);
-               destroy_reg_param(&reg_params[2]);
-               target_free_working_area(target, erase_check_algorithm);
-               return 0;
-       }
-
-       *blank = buf_get_u32(reg_params[2].value, 0, 32);
-
-       destroy_reg_param(&reg_params[0]);
-       destroy_reg_param(&reg_params[1]);
-       destroy_reg_param(&reg_params[2]);
-
-       target_free_working_area(target, erase_check_algorithm);
-
-       return ERROR_OK;
-}
 
 COMMAND_HANDLER(handle_arm7_9_write_xpsr_command)
 {
@@ -2877,25 +2749,24 @@ COMMAND_HANDLER(handle_arm7_9_write_xpsr_command)
        int spsr;
        int retval;
        struct target *target = get_current_target(cmd_ctx);
-       struct arm *armv4_5;
-       struct arm7_9_common *arm7_9;
+       struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
 
-       if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
+       if (!is_arm7_9(arm7_9))
        {
                command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
-               return ERROR_OK;
+               return ERROR_TARGET_INVALID;
        }
 
        if (target->state != TARGET_HALTED)
        {
                command_print(cmd_ctx, "can't write registers while running");
-               return ERROR_OK;
+               return ERROR_FAIL;
        }
 
        if (argc < 2)
        {
                command_print(cmd_ctx, "usage: write_xpsr <value> <not cpsr | spsr>");
-               return ERROR_OK;
+               return ERROR_FAIL;
        }
 
        COMMAND_PARSE_NUMBER(u32, args[0], value);
@@ -2922,25 +2793,24 @@ COMMAND_HANDLER(handle_arm7_9_write_xpsr_im8_command)
        int spsr;
        int retval;
        struct target *target = get_current_target(cmd_ctx);
-       struct arm *armv4_5;
-       struct arm7_9_common *arm7_9;
+       struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
 
-       if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
+       if (!is_arm7_9(arm7_9))
        {
                command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
-               return ERROR_OK;
+               return ERROR_TARGET_INVALID;
        }
 
        if (target->state != TARGET_HALTED)
        {
                command_print(cmd_ctx, "can't write registers while running");
-               return ERROR_OK;
+               return ERROR_FAIL;
        }
 
        if (argc < 3)
        {
                command_print(cmd_ctx, "usage: write_xpsr_im8 <im8> <rotate> <not cpsr | spsr>");
-               return ERROR_OK;
+               return ERROR_FAIL;
        }
 
        COMMAND_PARSE_NUMBER(u32, args[0], value);
@@ -2963,25 +2833,24 @@ COMMAND_HANDLER(handle_arm7_9_write_core_reg_command)
        uint32_t mode;
        int num;
        struct target *target = get_current_target(cmd_ctx);
-       struct arm *armv4_5;
-       struct arm7_9_common *arm7_9;
+       struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
 
-       if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
+       if (!is_arm7_9(arm7_9))
        {
                command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
-               return ERROR_OK;
+               return ERROR_TARGET_INVALID;
        }
 
        if (target->state != TARGET_HALTED)
        {
                command_print(cmd_ctx, "can't write registers while running");
-               return ERROR_OK;
+               return ERROR_FAIL;
        }
 
        if (argc < 3)
        {
                command_print(cmd_ctx, "usage: write_core_reg <num> <mode> <value>");
-               return ERROR_OK;
+               return ERROR_FAIL;
        }
 
        COMMAND_PARSE_NUMBER(int, args[0], num);
@@ -2994,13 +2863,12 @@ COMMAND_HANDLER(handle_arm7_9_write_core_reg_command)
 COMMAND_HANDLER(handle_arm7_9_dbgrq_command)
 {
        struct target *target = get_current_target(cmd_ctx);
-       struct arm *armv4_5;
-       struct arm7_9_common *arm7_9;
+       struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
 
-       if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
+       if (!is_arm7_9(arm7_9))
        {
                command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
-               return ERROR_OK;
+               return ERROR_TARGET_INVALID;
        }
 
        if (argc > 0)
@@ -3027,13 +2895,12 @@ COMMAND_HANDLER(handle_arm7_9_dbgrq_command)
 COMMAND_HANDLER(handle_arm7_9_fast_memory_access_command)
 {
        struct target *target = get_current_target(cmd_ctx);
-       struct arm *armv4_5;
-       struct arm7_9_common *arm7_9;
+       struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
 
-       if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
+       if (!is_arm7_9(arm7_9))
        {
                command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
-               return ERROR_OK;
+               return ERROR_TARGET_INVALID;
        }
 
        if (argc > 0)
@@ -3060,13 +2927,12 @@ COMMAND_HANDLER(handle_arm7_9_fast_memory_access_command)
 COMMAND_HANDLER(handle_arm7_9_dcc_downloads_command)
 {
        struct target *target = get_current_target(cmd_ctx);
-       struct arm *armv4_5;
-       struct arm7_9_common *arm7_9;
+       struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
 
-       if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
+       if (!is_arm7_9(arm7_9))
        {
                command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
-               return ERROR_OK;
+               return ERROR_TARGET_INVALID;
        }
 
        if (argc > 0)

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)