ARMv7M: review scope of functions
[fw/openocd] / src / target / xscale.c
index 50c9595006e9336f08bb30ddd9c57cb91c86ce0a..24c07941b549765c4db7d7b3bec2098b8371cd1f 100644 (file)
@@ -158,7 +158,7 @@ static int xscale_verify_pointer(struct command_context *cmd_ctx,
        return ERROR_OK;
 }
 
-static int xscale_jtag_set_instr(struct jtag_tap *tap, uint32_t new_instr)
+static int xscale_jtag_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_state_t end_state)
 {
        if (tap == NULL)
                return ERROR_FAIL;
@@ -171,9 +171,9 @@ static int xscale_jtag_set_instr(struct jtag_tap *tap, uint32_t new_instr)
                memset(&field, 0, sizeof field);
                field.num_bits = tap->ir_length;
                field.out_value = scratch;
-               buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
+               buf_set_u32(scratch, 0, field.num_bits, new_instr);
 
-               jtag_add_ir_scan(tap, &field, jtag_get_end_state());
+               jtag_add_ir_scan(tap, &field, end_state);
        }
 
        return ERROR_OK;
@@ -191,9 +191,9 @@ static int xscale_read_dcsr(struct target *target)
        uint8_t field2_check_value = 0x0;
        uint8_t field2_check_mask = 0x1;
 
-       jtag_set_end_state(TAP_DRPAUSE);
        xscale_jtag_set_instr(target->tap,
-               XSCALE_SELDCSR << xscale->xscale_variant);
+               XSCALE_SELDCSR << xscale->xscale_variant,
+               TAP_DRPAUSE);
 
        buf_set_u32(&field0, 1, 1, xscale->hold_rst);
        buf_set_u32(&field0, 2, 1, xscale->external_debug_break);
@@ -213,7 +213,7 @@ static int xscale_read_dcsr(struct target *target)
        uint8_t tmp2;
        fields[2].in_value = &tmp2;
 
-       jtag_add_dr_scan(target->tap, 3, fields, jtag_get_end_state());
+       jtag_add_dr_scan(target->tap, 3, fields, TAP_DRPAUSE);
 
        jtag_check_value_mask(fields + 0, &field0_check_value, &field0_check_mask);
        jtag_check_value_mask(fields + 2, &field2_check_value, &field2_check_mask);
@@ -234,9 +234,7 @@ static int xscale_read_dcsr(struct target *target)
        fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value;
        fields[1].in_value = NULL;
 
-       jtag_set_end_state(TAP_IDLE);
-
-       jtag_add_dr_scan(target->tap, 3, fields, jtag_get_end_state());
+       jtag_add_dr_scan(target->tap, 3, fields, TAP_DRPAUSE);
 
        /* DANGER!!! this must be here. It will make sure that the arguments
         * to jtag_set_check_value() does not go out of scope! */
@@ -285,10 +283,10 @@ static int xscale_receive(struct target *target, uint32_t *buffer, int num_words
        fields[2].check_value = &field2_check_value;
        fields[2].check_mask = &field2_check_mask;
 
-       jtag_set_end_state(TAP_IDLE);
        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 */
+               XSCALE_DBGTX << xscale->xscale_variant,
+               TAP_IDLE);
+       jtag_add_runtest(1, TAP_IDLE); /* ensures that we're in the TAP_IDLE state as the above could be a no-op */
 
        /* repeat until all words have been collected */
        int attempts = 0;
@@ -304,7 +302,7 @@ static int xscale_receive(struct target *target, uint32_t *buffer, int num_words
 
                        fields[1].in_value = (uint8_t *)(field1 + i);
 
-                       jtag_add_dr_scan_check(target->tap, 3, fields, jtag_set_end_state(TAP_IDLE));
+                       jtag_add_dr_scan_check(target->tap, 3, fields, TAP_IDLE);
 
                        jtag_add_callback(xscale_getbuf, (jtag_callback_data_t)(field1 + i));
 
@@ -367,10 +365,9 @@ static int xscale_read_tx(struct target *target, int consume)
        uint8_t field2_check_value = 0x0;
        uint8_t field2_check_mask = 0x1;
 
-       jtag_set_end_state(TAP_IDLE);
-
        xscale_jtag_set_instr(target->tap,
-               XSCALE_DBGTX << xscale->xscale_variant);
+               XSCALE_DBGTX << xscale->xscale_variant,
+               TAP_IDLE);
 
        path[0] = TAP_DRSELECT;
        path[1] = TAP_DRCAPTURE;
@@ -411,7 +408,7 @@ static int xscale_read_tx(struct target *target, int consume)
                        jtag_add_pathmove(ARRAY_SIZE(noconsume_path), noconsume_path);
                }
 
-               jtag_add_dr_scan(target->tap, 3, fields, jtag_set_end_state(TAP_IDLE));
+               jtag_add_dr_scan(target->tap, 3, fields, TAP_IDLE);
 
                jtag_check_value_mask(fields + 0, &field0_check_value, &field0_check_mask);
                jtag_check_value_mask(fields + 2, &field2_check_value, &field2_check_mask);
@@ -463,10 +460,9 @@ static int xscale_write_rx(struct target *target)
        uint8_t field2_check_value = 0x0;
        uint8_t field2_check_mask = 0x1;
 
-       jtag_set_end_state(TAP_IDLE);
-
        xscale_jtag_set_instr(target->tap,
-               XSCALE_DBGRX << xscale->xscale_variant);
+               XSCALE_DBGRX << xscale->xscale_variant,
+               TAP_IDLE);
 
        memset(&fields, 0, sizeof fields);
 
@@ -489,7 +485,7 @@ static int xscale_write_rx(struct target *target)
        LOG_DEBUG("polling RX");
        for (;;)
        {
-               jtag_add_dr_scan(target->tap, 3, fields, jtag_set_end_state(TAP_IDLE));
+               jtag_add_dr_scan(target->tap, 3, fields, TAP_IDLE);
 
                jtag_check_value_mask(fields + 0, &field0_check_value, &field0_check_mask);
                jtag_check_value_mask(fields + 2, &field2_check_value, &field2_check_mask);
@@ -521,7 +517,7 @@ static int xscale_write_rx(struct target *target)
 
        /* set rx_valid */
        field2 = 0x1;
-       jtag_add_dr_scan(target->tap, 3, fields, jtag_set_end_state(TAP_IDLE));
+       jtag_add_dr_scan(target->tap, 3, fields, TAP_IDLE);
 
        if ((retval = jtag_execute_queue()) != ERROR_OK)
        {
@@ -541,10 +537,9 @@ static int xscale_send(struct target *target, uint8_t *buffer, int count, int si
        int retval;
        int done_count = 0;
 
-       jtag_set_end_state(TAP_IDLE);
-
        xscale_jtag_set_instr(target->tap,
-               XSCALE_DBGRX << xscale->xscale_variant);
+               XSCALE_DBGRX << xscale->xscale_variant,
+               TAP_IDLE);
 
        bits[0]=3;
        t[0]=0;
@@ -585,7 +580,7 @@ static int xscale_send(struct target *target, uint8_t *buffer, int count, int si
                                3,
                                bits,
                                t,
-                               jtag_set_end_state(TAP_IDLE));
+                               TAP_IDLE);
                buffer += size;
        }
 
@@ -624,9 +619,9 @@ static int xscale_write_dcsr(struct target *target, int hold_rst, int ext_dbg_br
        if (ext_dbg_brk != -1)
                xscale->external_debug_break = ext_dbg_brk;
 
-       jtag_set_end_state(TAP_IDLE);
        xscale_jtag_set_instr(target->tap,
-               XSCALE_SELDCSR << xscale->xscale_variant);
+               XSCALE_SELDCSR << xscale->xscale_variant,
+               TAP_IDLE);
 
        buf_set_u32(&field0, 1, 1, xscale->hold_rst);
        buf_set_u32(&field0, 2, 1, xscale->external_debug_break);
@@ -646,7 +641,7 @@ static int xscale_write_dcsr(struct target *target, int hold_rst, int ext_dbg_br
        uint8_t tmp2;
        fields[2].in_value = &tmp2;
 
-       jtag_add_dr_scan(target->tap, 3, fields, jtag_get_end_state());
+       jtag_add_dr_scan(target->tap, 3, fields, TAP_IDLE);
 
        jtag_check_value_mask(fields + 0, &field0_check_value, &field0_check_mask);
        jtag_check_value_mask(fields + 2, &field2_check_value, &field2_check_mask);
@@ -686,9 +681,9 @@ static int xscale_load_ic(struct target *target, uint32_t va, uint32_t buffer[8]
        LOG_DEBUG("loading miniIC at 0x%8.8" PRIx32 "", va);
 
        /* LDIC into IR */
-       jtag_set_end_state(TAP_IDLE);
        xscale_jtag_set_instr(target->tap,
-               XSCALE_LDIC << xscale->xscale_variant);
+               XSCALE_LDIC << xscale->xscale_variant,
+               TAP_IDLE);
 
        /* CMD is b011 to load a cacheline into the Mini ICache.
         * Loading into the main ICache is deprecated, and unused.
@@ -707,7 +702,7 @@ static int xscale_load_ic(struct target *target, uint32_t va, uint32_t buffer[8]
        fields[1].num_bits = 27;
        fields[1].out_value = packet;
 
-       jtag_add_dr_scan(target->tap, 2, fields, jtag_get_end_state());
+       jtag_add_dr_scan(target->tap, 2, fields, TAP_IDLE);
 
        /* rest of packet is a cacheline: 8 instructions, with parity */
        fields[0].num_bits = 32;
@@ -724,7 +719,7 @@ static int xscale_load_ic(struct target *target, uint32_t va, uint32_t buffer[8]
                memcpy(&value, packet, sizeof(uint32_t));
                cmd = parity(value);
 
-               jtag_add_dr_scan(target->tap, 2, fields, jtag_get_end_state());
+               jtag_add_dr_scan(target->tap, 2, fields, TAP_IDLE);
        }
 
        return jtag_execute_queue();
@@ -737,9 +732,9 @@ static int xscale_invalidate_ic_line(struct target *target, uint32_t va)
        uint8_t cmd;
        struct scan_field fields[2];
 
-       jtag_set_end_state(TAP_IDLE);
        xscale_jtag_set_instr(target->tap,
-               XSCALE_LDIC << xscale->xscale_variant);
+               XSCALE_LDIC << xscale->xscale_variant,
+               TAP_IDLE);
 
        /* CMD for invalidate IC line b000, bits [6:4] b000 */
        buf_set_u32(&cmd, 0, 6, 0x0);
@@ -755,7 +750,7 @@ static int xscale_invalidate_ic_line(struct target *target, uint32_t va)
        fields[1].num_bits = 27;
        fields[1].out_value = packet;
 
-       jtag_add_dr_scan(target->tap, 2, fields, jtag_get_end_state());
+       jtag_add_dr_scan(target->tap, 2, fields, TAP_IDLE);
 
        return ERROR_OK;
 }
@@ -1211,6 +1206,7 @@ static int xscale_resume(struct target *target, int current,
                if (breakpoint != NULL)
                {
                        uint32_t next_pc;
+                       int saved_trace_buffer_enabled;
 
                        /* there's a breakpoint at the current PC, we have to step over it */
                        LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
@@ -1230,15 +1226,8 @@ static int xscale_resume(struct target *target, int current,
                        /* restore banked registers */
                        retval = xscale_restore_banked(target);
 
-                       /* send resume request (command 0x30 or 0x31)
-                        * clean the trace buffer if it is to be enabled (0x62) */
-                       if (xscale->trace.buffer_enabled)
-                       {
-                               xscale_send_u32(target, 0x62);
-                               xscale_send_u32(target, 0x31);
-                       }
-                       else
-                               xscale_send_u32(target, 0x30);
+                       /* send resume request */
+                       xscale_send_u32(target, 0x30);
 
                        /* send CPSR */
                        xscale_send_u32(target,
@@ -1259,9 +1248,16 @@ static int xscale_resume(struct target *target, int current,
                        LOG_DEBUG("writing PC with value 0x%8.8" PRIx32,
                                        buf_get_u32(armv4_5->pc->value, 0, 32));
 
+                       /* disable trace data collection in xscale_debug_entry() */
+                       saved_trace_buffer_enabled = xscale->trace.buffer_enabled;
+                       xscale->trace.buffer_enabled = 0;
+
                        /* wait for and process debug entry */
                        xscale_debug_entry(target);
 
+                       /* re-enable trace buffer, if enabled previously */
+                       xscale->trace.buffer_enabled = saved_trace_buffer_enabled;
+
                        LOG_DEBUG("disable single-step");
                        xscale_disable_single_step(target);
 
@@ -1281,6 +1277,12 @@ static int xscale_resume(struct target *target, int current,
         * clean the trace buffer if it is to be enabled (0x62) */
        if (xscale->trace.buffer_enabled)
        {
+               /* if trace buffer is set to 'fill' mode, save starting pc */
+               if (xscale->trace.buffer_fill > 0)
+               {
+                       xscale->trace.pc_ok = 1;
+                       xscale->trace.current_pc = buf_get_u32(armv4_5->pc->value, 0, 32);
+               }
                xscale_send_u32(target, 0x62);
                xscale_send_u32(target, 0x31);
        }
@@ -1476,9 +1478,9 @@ static int xscale_assert_reset(struct target *target)
        /* select DCSR instruction (set endstate to R-T-I to ensure we don't
         * 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->xscale_variant);
+               XSCALE_SELDCSR << xscale->xscale_variant,
+               TAP_IDLE);
 
        /* set Hold reset, Halt mode and Trap Reset */
        buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
@@ -1486,7 +1488,7 @@ static int xscale_assert_reset(struct target *target)
        xscale_write_dcsr(target, 1, 0);
 
        /* select BYPASS, because having DCSR selected caused problems on the PXA27x */
-       xscale_jtag_set_instr(target->tap, ~0);
+       xscale_jtag_set_instr(target->tap, ~0, TAP_IDLE);
        jtag_execute_queue();
 
        /* assert reset */
@@ -1556,7 +1558,7 @@ static int xscale_deassert_reset(struct target *target)
                /* wait 300ms; 150 and 100ms were not enough */
                jtag_add_sleep(300*1000);
 
-               jtag_add_runtest(2030, jtag_set_end_state(TAP_IDLE));
+               jtag_add_runtest(2030, TAP_IDLE);
                jtag_execute_queue();
 
                /* set Hold reset, Halt mode and Trap Reset */
@@ -1613,7 +1615,7 @@ static int xscale_deassert_reset(struct target *target)
                if (retval != ERROR_OK)
                        return retval;
 
-               jtag_add_runtest(30, jtag_set_end_state(TAP_IDLE));
+               jtag_add_runtest(30, TAP_IDLE);
 
                jtag_add_sleep(100000);
 
@@ -2130,7 +2132,7 @@ static int xscale_set_breakpoint(struct target *target,
                        {
                                return retval;
                        }
-                       /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
+                       /* write the bkpt instruction in target endianness (arm7_9->arm_bkpt is host endian) */
                        if ((retval = target_write_u32(target, breakpoint->address, xscale->arm_bkpt)) != ERROR_OK)
                        {
                                return retval;
@@ -2143,13 +2145,18 @@ static int xscale_set_breakpoint(struct target *target,
                        {
                                return retval;
                        }
-                       /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
+                       /* write the bkpt instruction in target endianness (arm7_9->arm_bkpt is host endian) */
                        if ((retval = target_write_u32(target, breakpoint->address, xscale->thumb_bkpt)) != ERROR_OK)
                        {
                                return retval;
                        }
                }
                breakpoint->set = 1;
+
+               xscale_send_u32(target, 0x50);   /* clean dcache */
+               xscale_send_u32(target, xscale->cache_clean_address);
+               xscale_send_u32(target, 0x51);   /* invalidate dcache */
+               xscale_send_u32(target, 0x52);   /* invalidate icache and flush fetch buffers */
        }
 
        return ERROR_OK;
@@ -2230,6 +2237,11 @@ static int xscale_unset_breakpoint(struct target *target,
                        }
                }
                breakpoint->set = 0;
+
+               xscale_send_u32(target, 0x50);   /* clean dcache */
+               xscale_send_u32(target, xscale->cache_clean_address);
+               xscale_send_u32(target, 0x51);   /* invalidate dcache */
+               xscale_send_u32(target, 0x52);   /* invalidate icache and flush fetch buffers */
        }
 
        return ERROR_OK;
@@ -3204,14 +3216,19 @@ COMMAND_HANDLER(xscale_handle_idcache_command)
        {
                bool enable;
                COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
-               if (enable)
-                       xscale_enable_mmu_caches(target, 1, 0, 0);
-               else
-                       xscale_disable_mmu_caches(target, 1, 0, 0);
-               if (icache)
+               if (icache) {
                        xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = enable;
-               else
+                       if (enable)
+                               xscale_enable_mmu_caches(target, 0, 0, 1);
+                       else
+                               xscale_disable_mmu_caches(target, 0, 0, 1);
+               } else {
                        xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = enable;
+                       if (enable)
+                               xscale_enable_mmu_caches(target, 0, 1, 0);
+                       else
+                               xscale_disable_mmu_caches(target, 0, 1, 0);
+               }
        }
 
        bool enabled = icache ?
@@ -3419,7 +3436,7 @@ COMMAND_HANDLER(xscale_handle_trace_image_command)
        if (CMD_ARGC >= 2)
        {
                xscale->trace.image->base_address_set = 1;
-               COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], xscale->trace.image->base_address);
+               COMMAND_PARSE_NUMBER(llong, CMD_ARGV[1], xscale->trace.image->base_address);
        }
        else
        {