X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Fxscale.c;h=24c07941b549765c4db7d7b3bec2098b8371cd1f;hp=f1afc71f127102b7c0edc342a8773576a0713e84;hb=33e5dd12729d995b351ece716e8c835dd8331c71;hpb=12b8c7b89b021c882e68bb0e28863c802fe36ac4 diff --git a/src/target/xscale.c b/src/target/xscale.c index f1afc71f12..24c07941b5 100644 --- a/src/target/xscale.c +++ b/src/target/xscale.c @@ -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; @@ -169,12 +169,11 @@ static int xscale_jtag_set_instr(struct jtag_tap *tap, uint32_t new_instr) uint8_t scratch[4]; memset(&field, 0, sizeof field); - field.tap = tap; 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(1, &field, jtag_get_end_state()); + jtag_add_ir_scan(tap, &field, end_state); } return ERROR_OK; @@ -192,32 +191,29 @@ 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); memset(&fields, 0, sizeof fields); - fields[0].tap = target->tap; fields[0].num_bits = 3; fields[0].out_value = &field0; uint8_t tmp; fields[0].in_value = &tmp; - fields[1].tap = target->tap; fields[1].num_bits = 32; fields[1].in_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value; - fields[2].tap = target->tap; fields[2].num_bits = 1; fields[2].out_value = &field2; uint8_t tmp2; fields[2].in_value = &tmp2; - jtag_add_dr_scan(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); @@ -238,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(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! */ @@ -279,23 +273,20 @@ static int xscale_receive(struct target *target, uint32_t *buffer, int num_words memset(&fields, 0, sizeof fields); - fields[0].tap = target->tap; fields[0].num_bits = 3; fields[0].check_value = &field0_check_value; fields[0].check_mask = &field0_check_mask; - fields[1].tap = target->tap; fields[1].num_bits = 32; - fields[2].tap = target->tap; fields[2].num_bits = 1; 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; @@ -311,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(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)); @@ -374,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; @@ -392,15 +382,12 @@ static int xscale_read_tx(struct target *target, int consume) memset(&fields, 0, sizeof fields); - fields[0].tap = target->tap; fields[0].num_bits = 3; fields[0].in_value = &field0_in; - fields[1].tap = target->tap; fields[1].num_bits = 32; fields[1].in_value = xscale->reg_cache->reg_list[XSCALE_TX].value; - fields[2].tap = target->tap; fields[2].num_bits = 1; uint8_t tmp; fields[2].in_value = &tmp; @@ -421,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(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); @@ -473,23 +460,19 @@ 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); - fields[0].tap = target->tap; fields[0].num_bits = 3; fields[0].out_value = &field0_out; fields[0].in_value = &field0_in; - fields[1].tap = target->tap; fields[1].num_bits = 32; fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_RX].value; - fields[2].tap = target->tap; fields[2].num_bits = 1; fields[2].out_value = &field2; uint8_t tmp; @@ -502,7 +485,7 @@ static int xscale_write_rx(struct target *target) LOG_DEBUG("polling RX"); for (;;) { - jtag_add_dr_scan(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); @@ -534,7 +517,7 @@ static int xscale_write_rx(struct target *target) /* set rx_valid */ field2 = 0x1; - jtag_add_dr_scan(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) { @@ -554,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; @@ -598,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; } @@ -637,32 +619,29 @@ 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); memset(&fields, 0, sizeof fields); - fields[0].tap = target->tap; fields[0].num_bits = 3; fields[0].out_value = &field0; uint8_t tmp; fields[0].in_value = &tmp; - fields[1].tap = target->tap; fields[1].num_bits = 32; fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value; - fields[2].tap = target->tap; fields[2].num_bits = 1; fields[2].out_value = &field2; uint8_t tmp2; fields[2].in_value = &tmp2; - jtag_add_dr_scan(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); @@ -702,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. @@ -717,15 +696,13 @@ static int xscale_load_ic(struct target *target, uint32_t va, uint32_t buffer[8] memset(&fields, 0, sizeof fields); - fields[0].tap = target->tap; fields[0].num_bits = 6; fields[0].out_value = &cmd; - fields[1].tap = target->tap; fields[1].num_bits = 27; fields[1].out_value = packet; - jtag_add_dr_scan(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; @@ -742,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(2, fields, jtag_get_end_state()); + jtag_add_dr_scan(target->tap, 2, fields, TAP_IDLE); } return jtag_execute_queue(); @@ -755,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); @@ -767,15 +744,13 @@ static int xscale_invalidate_ic_line(struct target *target, uint32_t va) memset(&fields, 0, sizeof fields); - fields[0].tap = target->tap; fields[0].num_bits = 6; fields[0].out_value = &cmd; - fields[1].tap = target->tap; fields[1].num_bits = 27; fields[1].out_value = packet; - jtag_add_dr_scan(2, fields, jtag_get_end_state()); + jtag_add_dr_scan(target->tap, 2, fields, TAP_IDLE); return ERROR_OK; } @@ -941,9 +916,9 @@ static int xscale_debug_entry(struct target *target) LOG_DEBUG("r0: 0x%8.8" PRIx32 "", buffer[0]); /* move pc from buffer to register cache */ - buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, buffer[1]); - armv4_5->core_cache->reg_list[15].dirty = 1; - armv4_5->core_cache->reg_list[15].valid = 1; + buf_set_u32(armv4_5->pc->value, 0, 32, buffer[1]); + armv4_5->pc->dirty = 1; + armv4_5->pc->valid = 1; LOG_DEBUG("pc: 0x%8.8" PRIx32 "", buffer[1]); /* move data from buffer to register cache */ @@ -995,7 +970,7 @@ static int xscale_debug_entry(struct target *target) moe = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 2, 3); /* stored PC (for calculating fixup) */ - pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32); + pc = buf_get_u32(armv4_5->pc->value, 0, 32); switch (moe) { @@ -1042,7 +1017,7 @@ static int xscale_debug_entry(struct target *target) } /* apply PC fixup */ - buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, pc); + buf_set_u32(armv4_5->pc->value, 0, 32, pc); /* on the first debug entry, identify cache type */ if (xscale->armv4_5_mmu.armv4_5_cache.ctype == -1) @@ -1212,23 +1187,26 @@ static int xscale_resume(struct target *target, int current, /* current = 1: continue on current pc, otherwise continue at
*/ if (!current) - buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, address); + buf_set_u32(armv4_5->pc->value, 0, 32, address); - current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32); + current_pc = buf_get_u32(armv4_5->pc->value, 0, 32); /* if we're at the reset vector, we have to simulate the branch */ if (current_pc == 0x0) { arm_simulate_step(target, NULL); - current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32); + current_pc = buf_get_u32(armv4_5->pc->value, 0, 32); } /* the front-end may request us not to handle breakpoints */ if (handle_breakpoints) { - if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32)))) + breakpoint = breakpoint_find(target, + buf_get_u32(armv4_5->pc->value, 0, 32)); + 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); @@ -1248,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, @@ -1272,12 +1243,21 @@ static int xscale_resume(struct target *target, int current, } /* send PC */ - xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32)); - LOG_DEBUG("writing PC with value 0x%8.8" PRIx32 "", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32)); + xscale_send_u32(target, + buf_get_u32(armv4_5->pc->value, 0, 32)); + 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); @@ -1297,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); } @@ -1316,8 +1302,9 @@ static int xscale_resume(struct target *target, int current, } /* send PC */ - xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32)); - LOG_DEBUG("writing PC with value 0x%8.8" PRIx32 "", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32)); + xscale_send_u32(target, buf_get_u32(armv4_5->pc->value, 0, 32)); + LOG_DEBUG("wrote PC with value 0x%8.8" PRIx32, + buf_get_u32(armv4_5->pc->value, 0, 32)); target->debug_reason = DBG_REASON_NOTHALTED; @@ -1354,7 +1341,7 @@ static int xscale_step_inner(struct target *target, int current, if ((retval = arm_simulate_step(target, &next_pc)) != ERROR_OK) { uint32_t current_opcode, current_pc; - current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32); + current_pc = buf_get_u32(armv4_5->pc->value, 0, 32); target_read_u32(target, current_pc, ¤t_opcode); LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8" PRIx32 "", current_opcode); @@ -1399,9 +1386,12 @@ static int xscale_step_inner(struct target *target, int current, } /* send PC */ - if ((retval = xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))) != ERROR_OK) + retval = xscale_send_u32(target, + buf_get_u32(armv4_5->pc->value, 0, 32)); + if (retval != ERROR_OK) return retval; - LOG_DEBUG("writing PC with value 0x%8.8" PRIx32, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32)); + LOG_DEBUG("wrote PC with value 0x%8.8" PRIx32, + buf_get_u32(armv4_5->pc->value, 0, 32)); target_call_event_callbacks(target, TARGET_EVENT_RESUMED); @@ -1425,7 +1415,7 @@ static int xscale_step(struct target *target, int current, uint32_t address, int handle_breakpoints) { struct arm *armv4_5 = target_to_arm(target); - struct breakpoint *breakpoint = target->breakpoints; + struct breakpoint *breakpoint = NULL; uint32_t current_pc; int retval; @@ -1438,16 +1428,16 @@ static int xscale_step(struct target *target, int current, /* current = 1: continue on current pc, otherwise continue at
*/ if (!current) - buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, address); + buf_set_u32(armv4_5->pc->value, 0, 32, address); - current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32); + current_pc = buf_get_u32(armv4_5->pc->value, 0, 32); /* if we're at the reset vector, we have to simulate the step */ if (current_pc == 0x0) { if ((retval = arm_simulate_step(target, NULL)) != ERROR_OK) return retval; - current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32); + current_pc = buf_get_u32(armv4_5->pc->value, 0, 32); target->debug_reason = DBG_REASON_SINGLESTEP; target_call_event_callbacks(target, TARGET_EVENT_HALTED); @@ -1457,11 +1447,13 @@ static int xscale_step(struct target *target, int current, /* the front-end may request us not to handle breakpoints */ if (handle_breakpoints) - if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32)))) - { - if ((retval = xscale_unset_breakpoint(target, breakpoint)) != ERROR_OK) - return retval; - } + breakpoint = breakpoint_find(target, + buf_get_u32(armv4_5->pc->value, 0, 32)); + if (breakpoint != NULL) { + retval = xscale_unset_breakpoint(target, breakpoint); + if (retval != ERROR_OK) + return retval; + } retval = xscale_step_inner(target, current, address, handle_breakpoints); @@ -1486,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); @@ -1496,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 */ @@ -1566,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 */ @@ -1623,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); @@ -2140,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; @@ -2153,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; @@ -2240,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; @@ -2568,7 +2570,8 @@ static int xscale_read_trace(struct target *target) (*trace_data_p)->next = NULL; (*trace_data_p)->chkpt0 = trace_buffer[256]; (*trace_data_p)->chkpt1 = trace_buffer[257]; - (*trace_data_p)->last_instruction = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32); + (*trace_data_p)->last_instruction = + buf_get_u32(armv4_5->pc->value, 0, 32); (*trace_data_p)->entries = malloc(sizeof(struct xscale_trace_entry) * (256 - j)); (*trace_data_p)->depth = 256 - j; @@ -3206,21 +3209,26 @@ COMMAND_HANDLER(xscale_handle_idcache_command) return ERROR_OK; } - bool icache; - COMMAND_PARSE_BOOL(CMD_NAME, icache, "icache", "dcache"); - + bool icache = false; + if (strcmp(CMD_NAME, "icache") == 0) + icache = true; if (CMD_ARGC >= 1) { 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 ? @@ -3375,7 +3383,8 @@ COMMAND_HANDLER(xscale_handle_trace_buffer_command) /* if we enable the trace buffer in fill-once * mode we know the address of the first instruction */ xscale->trace.pc_ok = 1; - xscale->trace.current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32); + xscale->trace.current_pc = + buf_get_u32(armv4_5->pc->value, 0, 32); } else { @@ -3427,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 { @@ -3607,94 +3616,101 @@ COMMAND_HANDLER(xscale_handle_cp15) static const struct command_registration xscale_exec_command_handlers[] = { { .name = "cache_info", - .handler = &xscale_handle_cache_info_command, - .mode = COMMAND_EXEC, NULL, + .handler = xscale_handle_cache_info_command, + .mode = COMMAND_EXEC, + .help = "display information about CPU caches", }, - { .name = "mmu", - .handler = &xscale_handle_mmu_command, + .handler = xscale_handle_mmu_command, .mode = COMMAND_EXEC, - .usage = "[enable|disable]", .help = "enable or disable the MMU", + .usage = "['enable'|'disable']", }, { .name = "icache", - .handler = &xscale_handle_idcache_command, + .handler = xscale_handle_idcache_command, .mode = COMMAND_EXEC, - .usage = "[enable|disable]", - .help = "enable or disable the ICache", + .help = "display ICache state, optionally enabling or " + "disabling it", + .usage = "['enable'|'disable']", }, { .name = "dcache", - .handler = &xscale_handle_idcache_command, + .handler = xscale_handle_idcache_command, .mode = COMMAND_EXEC, - .usage = "[enable|disable]", - .help = "enable or disable the DCache", + .help = "display DCache state, optionally enabling or " + "disabling it", + .usage = "['enable'|'disable']", }, - { .name = "vector_catch", - .handler = &xscale_handle_vector_catch_command, + .handler = xscale_handle_vector_catch_command, .mode = COMMAND_EXEC, - .help = "mask of vectors that should be caught", - .usage = "[]", + .help = "set or display 8-bit mask of vectors " + "that should trigger debug entry", + .usage = "[mask]", }, { .name = "vector_table", - .handler = &xscale_handle_vector_table_command, + .handler = xscale_handle_vector_table_command, .mode = COMMAND_EXEC, - .usage = " ", - .help = "set static code for exception handler entry", + .help = "set vector table entry in mini-ICache, " + "or display current tables", + .usage = "[('high'|'low') index code]", }, - { .name = "trace_buffer", - .handler = &xscale_handle_trace_buffer_command, + .handler = xscale_handle_trace_buffer_command, .mode = COMMAND_EXEC, - .usage = " [fill [n]|wrap]", + .help = "display trace buffer status, enable or disable " + "tracing, and optionally reconfigure trace mode", + .usage = "['enable'|'disable' ['fill' number|'wrap']]", }, { .name = "dump_trace", - .handler = &xscale_handle_dump_trace_command, + .handler = xscale_handle_dump_trace_command, .mode = COMMAND_EXEC, - .help = "dump content of trace buffer to ", - .usage = "", + .help = "dump content of trace buffer to file", + .usage = "filename", }, { .name = "analyze_trace", - .handler = &xscale_handle_analyze_trace_buffer_command, + .handler = xscale_handle_analyze_trace_buffer_command, .mode = COMMAND_EXEC, .help = "analyze content of trace buffer", + .usage = "", }, { .name = "trace_image", - .handler = &xscale_handle_trace_image_command, - COMMAND_EXEC, - .help = "load image from [base address]", - .usage = " [address] [type]", + .handler = xscale_handle_trace_image_command, + .mode = COMMAND_EXEC, + .help = "load image from file to address (default 0)", + .usage = "filename [offset [filetype]]", }, - { .name = "cp15", - .handler = &xscale_handle_cp15, + .handler = xscale_handle_cp15, .mode = COMMAND_EXEC, - .help = "access coproc 15", - .usage = " [value]", + .help = "Read or write coprocessor 15 register.", + .usage = "register [value]", }, COMMAND_REGISTRATION_DONE }; static const struct command_registration xscale_any_command_handlers[] = { { .name = "debug_handler", - .handler = &xscale_handle_debug_handler_command, + .handler = xscale_handle_debug_handler_command, .mode = COMMAND_ANY, - .usage = "
", + .help = "Change address used for debug handler.", + .usage = "target address", }, { .name = "cache_clean_address", - .handler = &xscale_handle_cache_clean_address_command, + .handler = xscale_handle_cache_clean_address_command, .mode = COMMAND_ANY, + .help = "Change address used for cleaning data cache.", + .usage = "address", }, { .chain = xscale_exec_command_handlers, @@ -3731,6 +3747,7 @@ struct target_type xscale_target = .deassert_reset = xscale_deassert_reset, .soft_reset_halt = NULL, + /* REVISIT on some cores, allow exporting iwmmxt registers ... */ .get_gdb_reg_list = arm_get_gdb_reg_list, .read_memory = xscale_read_memory,