XScale: initial PXA3xx support
[openocd.git] / src / target / xscale.c
index 965ac52e732a7ba9d92063873fdb95b728b83c55..b4cb4ffb1c321f733e5e4f6844357c8d996b4c62 100644 (file)
@@ -191,7 +191,8 @@ static int xscale_read_dcsr(struct target *target)
        uint8_t field2_check_mask = 0x1;
 
        jtag_set_end_state(TAP_DRPAUSE);
-       xscale_jtag_set_instr(target->tap, XSCALE_SELDCSR);
+       xscale_jtag_set_instr(target->tap,
+               XSCALE_SELDCSR << xscale->xscale_variant);
 
        buf_set_u32(&field0, 1, 1, xscale->hold_rst);
        buf_set_u32(&field0, 2, 1, xscale->external_debug_break);
@@ -256,6 +257,7 @@ static int xscale_receive(struct target *target, uint32_t *buffer, int num_words
        if (num_words == 0)
                return ERROR_INVALID_ARGUMENTS;
 
+       struct xscale_common *xscale = target_to_xscale(target);
        int retval = ERROR_OK;
        tap_state_t path[3];
        struct scan_field fields[3];
@@ -289,7 +291,8 @@ static int xscale_receive(struct target *target, uint32_t *buffer, int num_words
        fields[2].check_mask = &field2_check_mask;
 
        jtag_set_end_state(TAP_IDLE);
-       xscale_jtag_set_instr(target->tap, XSCALE_DBGTX);
+       xscale_jtag_set_instr(target->tap,
+               XSCALE_DBGTX << xscale->xscale_variant);
        jtag_add_runtest(1, jtag_get_end_state()); /* ensures that we're in the TAP_IDLE state as the above could be a no-op */
 
        /* repeat until all words have been collected */
@@ -371,7 +374,8 @@ static int xscale_read_tx(struct target *target, int consume)
 
        jtag_set_end_state(TAP_IDLE);
 
-       xscale_jtag_set_instr(target->tap, XSCALE_DBGTX);
+       xscale_jtag_set_instr(target->tap,
+               XSCALE_DBGTX << xscale->xscale_variant);
 
        path[0] = TAP_DRSELECT;
        path[1] = TAP_DRCAPTURE;
@@ -412,7 +416,7 @@ static int xscale_read_tx(struct target *target, int consume)
                        jtag_add_pathmove(3, path);
                else
                {
-                       jtag_add_pathmove(sizeof(noconsume_path)/sizeof(*noconsume_path), noconsume_path);
+                       jtag_add_pathmove(ARRAY_SIZE(noconsume_path), noconsume_path);
                }
 
                jtag_add_dr_scan(3, fields, jtag_set_end_state(TAP_IDLE));
@@ -469,7 +473,8 @@ static int xscale_write_rx(struct target *target)
 
        jtag_set_end_state(TAP_IDLE);
 
-       xscale_jtag_set_instr(target->tap, XSCALE_DBGRX);
+       xscale_jtag_set_instr(target->tap,
+               XSCALE_DBGRX << xscale->xscale_variant);
 
        memset(&fields, 0, sizeof fields);
 
@@ -541,6 +546,7 @@ static int xscale_write_rx(struct target *target)
 /* send count elements of size byte to the debug handler */
 static int xscale_send(struct target *target, uint8_t *buffer, int count, int size)
 {
+       struct xscale_common *xscale = target_to_xscale(target);
        uint32_t t[3];
        int bits[3];
        int retval;
@@ -548,7 +554,8 @@ static int xscale_send(struct target *target, uint8_t *buffer, int count, int si
 
        jtag_set_end_state(TAP_IDLE);
 
-       xscale_jtag_set_instr(target->tap, XSCALE_DBGRX);
+       xscale_jtag_set_instr(target->tap,
+               XSCALE_DBGRX << xscale->xscale_variant);
 
        bits[0]=3;
        t[0]=0;
@@ -629,7 +636,8 @@ static int xscale_write_dcsr(struct target *target, int hold_rst, int ext_dbg_br
                xscale->external_debug_break = ext_dbg_brk;
 
        jtag_set_end_state(TAP_IDLE);
-       xscale_jtag_set_instr(target->tap, XSCALE_SELDCSR);
+       xscale_jtag_set_instr(target->tap,
+               XSCALE_SELDCSR << xscale->xscale_variant);
 
        buf_set_u32(&field0, 1, 1, xscale->hold_rst);
        buf_set_u32(&field0, 2, 1, xscale->external_debug_break);
@@ -683,6 +691,7 @@ static unsigned int parity (unsigned int v)
 
 static int xscale_load_ic(struct target *target, uint32_t va, uint32_t buffer[8])
 {
+       struct xscale_common *xscale = target_to_xscale(target);
        uint8_t packet[4];
        uint8_t cmd;
        int word;
@@ -692,7 +701,8 @@ static int xscale_load_ic(struct target *target, uint32_t va, uint32_t buffer[8]
 
        /* LDIC into IR */
        jtag_set_end_state(TAP_IDLE);
-       xscale_jtag_set_instr(target->tap, XSCALE_LDIC);
+       xscale_jtag_set_instr(target->tap,
+               XSCALE_LDIC << xscale->xscale_variant);
 
        /* CMD is b011 to load a cacheline into the Mini ICache.
         * Loading into the main ICache is deprecated, and unused.
@@ -738,12 +748,14 @@ static int xscale_load_ic(struct target *target, uint32_t va, uint32_t buffer[8]
 
 static int xscale_invalidate_ic_line(struct target *target, uint32_t va)
 {
+       struct xscale_common *xscale = target_to_xscale(target);
        uint8_t packet[4];
        uint8_t cmd;
        struct scan_field fields[2];
 
        jtag_set_end_state(TAP_IDLE);
-       xscale_jtag_set_instr(target->tap, XSCALE_LDIC);
+       xscale_jtag_set_instr(target->tap,
+               XSCALE_LDIC << xscale->xscale_variant);
 
        /* CMD for invalidate IC line b000, bits [6:4] b000 */
        buf_set_u32(&cmd, 0, 6, 0x0);
@@ -1479,7 +1491,8 @@ static int xscale_assert_reset(struct target *target)
         * end up in T-L-R, which would reset JTAG
         */
        jtag_set_end_state(TAP_IDLE);
-       xscale_jtag_set_instr(target->tap, XSCALE_SELDCSR);
+       xscale_jtag_set_instr(target->tap,
+               XSCALE_SELDCSR << xscale->xscale_variant);
 
        /* set Hold reset, Halt mode and Trap Reset */
        buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
@@ -1881,6 +1894,15 @@ static int xscale_read_memory(struct target *target, uint32_t address,
        return ERROR_OK;
 }
 
+static int xscale_read_phys_memory(struct target *target, uint32_t address,
+               uint32_t size, uint32_t count, uint8_t *buffer)
+{
+       /** \todo: provide a non-stub implementtion of this routine. */
+       LOG_ERROR("%s: %s is not implemented.  Disable MMU?",
+                       target_name(target), __func__);
+       return ERROR_FAIL;
+}
+
 static int xscale_write_memory(struct target *target, uint32_t address,
                uint32_t size, uint32_t count, uint8_t *buffer)
 {
@@ -1959,6 +1981,15 @@ static int xscale_write_memory(struct target *target, uint32_t address,
        return ERROR_OK;
 }
 
+static int xscale_write_phys_memory(struct target *target, uint32_t address,
+               uint32_t size, uint32_t count, uint8_t *buffer)
+{
+       /** \todo: provide a non-stub implementtion of this routine. */
+       LOG_ERROR("%s: %s is not implemented.  Disable MMU?",
+                       target_name(target), __func__);
+       return ERROR_FAIL;
+}
+
 static int xscale_bulk_write_memory(struct target *target, uint32_t address,
                uint32_t count, uint8_t *buffer)
 {
@@ -2119,12 +2150,6 @@ static int xscale_add_breakpoint(struct target *target,
 {
        struct xscale_common *xscale = target_to_xscale(target);
 
-       if (target->state != TARGET_HALTED)
-       {
-               LOG_WARNING("target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-
        if ((breakpoint->type == BKPT_HARD) && (xscale->ibcr_available < 1))
        {
                LOG_INFO("no breakpoint unit available for hardware breakpoint");
@@ -2282,12 +2307,6 @@ static int xscale_add_watchpoint(struct target *target,
 {
        struct xscale_common *xscale = target_to_xscale(target);
 
-       if (target->state != TARGET_HALTED)
-       {
-               LOG_WARNING("target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-
        if (xscale->dbr_available < 1)
        {
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
@@ -2825,7 +2844,7 @@ static void xscale_build_reg_cache(struct target *target)
        struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
        struct xscale_reg *arch_info = malloc(sizeof(xscale_reg_arch_info));
        int i;
-       int num_regs = sizeof(xscale_reg_arch_info) / sizeof(struct xscale_reg);
+       int num_regs = ARRAY_SIZE(xscale_reg_arch_info);
 
        (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
 
@@ -2870,10 +2889,10 @@ static int xscale_init_arch_info(struct target *target,
 
        armv4_5 = &xscale->armv4_5_common;
 
-       /* store architecture specfic data (none so far) */
+       /* store architecture specfic data */
        xscale->common_magic = XSCALE_COMMON_MAGIC;
 
-       /* we don't really *need* variant info ... */
+       /* we don't really *need* a variant param ... */
        if (variant) {
                int ir_length = 0;
 
@@ -2886,6 +2905,8 @@ static int xscale_init_arch_info(struct target *target,
                                || strcmp(variant, "ixp45x") == 0
                                || strcmp(variant, "ixp46x") == 0)
                        ir_length = 7;
+               else if (strcmp(variant, "pxa3xx") == 0)
+                       ir_length = 11;
                else
                        LOG_WARNING("%s: unrecognized variant %s",
                                tap->dotted_name, variant);
@@ -2897,6 +2918,12 @@ static int xscale_init_arch_info(struct target *target,
                }
        }
 
+       /* PXA3xx shifts the JTAG instructions */
+       if (tap->ir_length == 11)
+               xscale->xscale_variant = XSCALE_PXA3XX;
+       else
+               xscale->xscale_variant = XSCALE_IXP4XX_PXA2XX;
+
        /* the debug handler isn't installed (and thus not running) at this time */
        xscale->handler_address = 0xfe000800;
 
@@ -3652,6 +3679,9 @@ static const struct command_registration xscale_any_command_handlers[] = {
        COMMAND_REGISTRATION_DONE
 };
 static const struct command_registration xscale_command_handlers[] = {
+       {
+               .chain = arm_command_handlers,
+       },
        {
                .name = "xscale",
                .mode = COMMAND_ANY,
@@ -3661,14 +3691,6 @@ static const struct command_registration xscale_command_handlers[] = {
        COMMAND_REGISTRATION_DONE
 };
 
-static int xscale_register_commands(struct command_context *cmd_ctx)
-{
-
-       armv4_5_register_commands(cmd_ctx);
-
-       return ERROR_OK;
-}
-
 struct target_type xscale_target =
 {
        .name = "xscale",
@@ -3689,7 +3711,9 @@ struct target_type xscale_target =
        .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
 
        .read_memory = xscale_read_memory,
+       .read_phys_memory = xscale_read_phys_memory,
        .write_memory = xscale_write_memory,
+       .write_phys_memory = xscale_write_phys_memory,
        .bulk_write_memory = xscale_bulk_write_memory,
 
        .checksum_memory = arm_checksum_memory,
@@ -3702,7 +3726,7 @@ struct target_type xscale_target =
        .add_watchpoint = xscale_add_watchpoint,
        .remove_watchpoint = xscale_remove_watchpoint,
 
-       .register_commands = xscale_register_commands,
+       .commands = xscale_command_handlers,
        .target_create = xscale_target_create,
        .init_target = xscale_init_target,
 

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)