TARGET/MIPS32_PRACC: review scope of functions
[fw/openocd] / src / target / xscale.c
index 55323ae370dc56b8ecde82e93fef3c06cc697b0a..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);
@@ -234,8 +234,6 @@ 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, TAP_DRPAUSE);
 
        /* DANGER!!! this must be here. It will make sure that the arguments
@@ -285,9 +283,9 @@ 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);
+               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 */
@@ -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;
@@ -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);
 
@@ -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;
@@ -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);
@@ -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.
@@ -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);
@@ -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 */
@@ -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;