X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Fxscale.c;h=602034eb323ee02da20921803d8290a1ada0abbe;hp=6d2d81dd9467e843beb8676f66371a19423b338c;hb=57d7743639d5092770d79f7c4b12ae694c482750;hpb=8c8e53baf6a5842046a1d31057ec3c9a0906a0d5 diff --git a/src/target/xscale.c b/src/target/xscale.c index 6d2d81dd94..602034eb32 100644 --- a/src/target/xscale.c +++ b/src/target/xscale.c @@ -33,9 +33,11 @@ #include "arm_jtag.h" #include "arm_simulator.h" #include "arm_disassembler.h" -#include "time_support.h" +#include #include "register.h" #include "image.h" +#include "arm_opcodes.h" +#include "armv4_5.h" /* @@ -62,7 +64,7 @@ static int xscale_resume(struct target *, int current, uint32_t address, int handle_breakpoints, int debug_execution); static int xscale_debug_entry(struct target *); -static int xscale_restore_context(struct target *); +static int xscale_restore_banked(struct target *); static int xscale_get_reg(struct reg *reg); static int xscale_set_reg(struct reg *reg, uint8_t *buf); static int xscale_set_breakpoint(struct target *, struct breakpoint *); @@ -167,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); - jtag_add_ir_scan(1, &field, jtag_get_end_state()); + jtag_add_ir_scan(tap, &field, jtag_get_end_state()); } return ERROR_OK; @@ -199,23 +200,20 @@ static int xscale_read_dcsr(struct target *target) 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, jtag_get_end_state()); 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,7 +236,7 @@ static int xscale_read_dcsr(struct target *target) jtag_set_end_state(TAP_IDLE); - jtag_add_dr_scan(3, fields, jtag_get_end_state()); + jtag_add_dr_scan(target->tap, 3, fields, jtag_get_end_state()); /* DANGER!!! this must be here. It will make sure that the arguments * to jtag_set_check_value() does not go out of scope! */ @@ -277,15 +275,12 @@ 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; @@ -309,7 +304,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, jtag_set_end_state(TAP_IDLE)); jtag_add_callback(xscale_getbuf, (jtag_callback_data_t)(field1 + i)); @@ -390,15 +385,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; @@ -419,7 +411,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, jtag_set_end_state(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); @@ -478,16 +470,13 @@ static int xscale_write_rx(struct target *target) 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; @@ -500,7 +489,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, jtag_set_end_state(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); @@ -532,7 +521,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, jtag_set_end_state(TAP_IDLE)); if ((retval = jtag_execute_queue()) != ERROR_OK) { @@ -644,23 +633,20 @@ static int xscale_write_dcsr(struct target *target, int hold_rst, int ext_dbg_br 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, jtag_get_end_state()); jtag_check_value_mask(fields + 0, &field0_check_value, &field0_check_mask); jtag_check_value_mask(fields + 2, &field2_check_value, &field2_check_mask); @@ -715,15 +701,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, jtag_get_end_state()); /* rest of packet is a cacheline: 8 instructions, with parity */ fields[0].num_bits = 32; @@ -740,7 +724,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, jtag_get_end_state()); } return jtag_execute_queue(); @@ -765,15 +749,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, jtag_get_end_state()); return ERROR_OK; } @@ -857,21 +839,14 @@ static int xscale_arch_state(struct target *target) "", "\n(processor reset)", "\n(trace buffer full)" }; - if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC) + if (armv4_5->common_magic != ARM_COMMON_MAGIC) { LOG_ERROR("BUG: called for a non-ARMv4/5 target"); return ERROR_INVALID_ARGUMENTS; } - LOG_USER("target halted in %s state due to %s, current mode: %s\n" - "cpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "\n" - "MMU: %s, D-Cache: %s, I-Cache: %s" - "%s", - armv4_5_state_strings[armv4_5->core_state], - Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name , - arm_mode_name(armv4_5->core_mode), - buf_get_u32(armv4_5->cpsr->value, 0, 32), - buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32), + arm_arch_state(target); + LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s%s", state[xscale->armv4_5_mmu.mmu_enabled], state[xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled], state[xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled], @@ -946,9 +921,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 */ @@ -1000,7 +975,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) { @@ -1047,7 +1022,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) @@ -1217,21 +1192,23 @@ 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; @@ -1251,7 +1228,7 @@ static int xscale_resume(struct target *target, int current, xscale_enable_single_step(target, next_pc); /* restore banked registers */ - xscale_restore_context(target); + retval = xscale_restore_banked(target); /* send resume request (command 0x30 or 0x31) * clean the trace buffer if it is to be enabled (0x62) */ @@ -1277,8 +1254,10 @@ 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)); /* wait for and process debug entry */ xscale_debug_entry(target); @@ -1296,7 +1275,7 @@ static int xscale_resume(struct target *target, int current, xscale_enable_watchpoints(target); /* restore banked registers */ - xscale_restore_context(target); + retval = xscale_restore_banked(target); /* send resume request (command 0x30 or 0x31) * clean the trace buffer if it is to be enabled (0x62) */ @@ -1321,8 +1300,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; @@ -1359,7 +1339,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); @@ -1371,7 +1351,7 @@ static int xscale_step_inner(struct target *target, int current, return retval; /* restore banked registers */ - if ((retval = xscale_restore_context(target)) != ERROR_OK) + if ((retval = xscale_restore_banked(target)) != ERROR_OK) return retval; /* send resume request (command 0x30 or 0x31) @@ -1404,9 +1384,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); @@ -1429,8 +1412,8 @@ static int xscale_step_inner(struct target *target, int current, static int xscale_step(struct target *target, int current, uint32_t address, int handle_breakpoints) { - struct arm *armv4_5 = target_to_armv4_5(target); - struct breakpoint *breakpoint = target->breakpoints; + struct arm *armv4_5 = target_to_arm(target); + struct breakpoint *breakpoint = NULL; uint32_t current_pc; int retval; @@ -1443,16 +1426,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); @@ -1462,11 +1445,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); @@ -1501,7 +1486,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, 0x7f); + xscale_jtag_set_instr(target->tap, ~0); jtag_execute_queue(); /* assert reset */ @@ -1658,7 +1643,7 @@ static int xscale_deassert_reset(struct target *target) } static int xscale_read_core_reg(struct target *target, struct reg *r, - int num, enum armv4_5_mode mode) + int num, enum arm_mode mode) { /** \todo add debug handler support for core register reads */ LOG_ERROR("not implemented"); @@ -1666,7 +1651,7 @@ static int xscale_read_core_reg(struct target *target, struct reg *r, } static int xscale_write_core_reg(struct target *target, struct reg *r, - int num, enum armv4_5_mode mode, uint32_t value) + int num, enum arm_mode mode, uint32_t value) { /** \todo add debug handler support for core register writes */ LOG_ERROR("not implemented"); @@ -1675,7 +1660,7 @@ static int xscale_write_core_reg(struct target *target, struct reg *r, static int xscale_full_context(struct target *target) { - struct arm *armv4_5 = target_to_armv4_5(target); + struct arm *armv4_5 = target_to_arm(target); uint32_t *buffer; @@ -1697,11 +1682,11 @@ static int xscale_full_context(struct target *target) */ for (i = 1; i < 7; i++) { - enum armv4_5_mode mode = armv4_5_number_to_mode(i); + enum arm_mode mode = armv4_5_number_to_mode(i); bool valid = true; struct reg *r; - if (mode == ARMV4_5_MODE_USR) + if (mode == ARM_MODE_USR) continue; /* check if there are invalid registers in the current mode @@ -1712,50 +1697,41 @@ static int xscale_full_context(struct target *target) mode, j).valid) valid = false; } + if (valid) + continue; - if (!valid) - { - uint32_t tmp_cpsr; - - /* request banked registers */ - xscale_send_u32(target, 0x0); - - tmp_cpsr = 0x0; - tmp_cpsr |= mode; - tmp_cpsr |= 0xc0; /* I/F bits */ - - /* send CPSR for desired mode */ - xscale_send_u32(target, tmp_cpsr); - - /* get banked registers: r8 to r14; and SPSR - * if not in USR/SYS mode - */ - if (mode != ARMV4_5_MODE_SYS) { - /* SPSR */ - r = &ARMV4_5_CORE_REG_MODE( - armv4_5->core_cache, - mode, 16); - - xscale_receive(target, buffer, 8); - - buf_set_u32(r->value, 0, 32, buffer[7]); - r->dirty = false; - r->valid = true; - } else { - xscale_receive(target, buffer, 7); - } + /* request banked registers */ + xscale_send_u32(target, 0x0); - /* move data from buffer to register cache */ - for (j = 8; j <= 14; j++) - { - r = &ARMV4_5_CORE_REG_MODE( - armv4_5->core_cache, - mode, j); + /* send CPSR for desired bank mode */ + xscale_send_u32(target, mode | 0xc0 /* I/F bits */); - buf_set_u32(r->value, 0, 32, buffer[j - 8]); - r->dirty = false; - r->valid = true; - } + /* get banked registers: r8 to r14; and SPSR + * except in USR/SYS mode + */ + if (mode != ARM_MODE_SYS) { + /* SPSR */ + r = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, + mode, 16); + + xscale_receive(target, buffer, 8); + + buf_set_u32(r->value, 0, 32, buffer[7]); + r->dirty = false; + r->valid = true; + } else { + xscale_receive(target, buffer, 7); + } + + /* move data from buffer to register cache */ + for (j = 8; j <= 14; j++) + { + r = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, + mode, j); + + buf_set_u32(r->value, 0, 32, buffer[j - 8]); + r->dirty = false; + r->valid = true; } } @@ -1764,9 +1740,9 @@ static int xscale_full_context(struct target *target) return ERROR_OK; } -static int xscale_restore_context(struct target *target) +static int xscale_restore_banked(struct target *target) { - struct arm *armv4_5 = target_to_armv4_5(target); + struct arm *armv4_5 = target_to_arm(target); int i, j; @@ -1777,54 +1753,60 @@ static int xscale_restore_context(struct target *target) } /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS) - * we can't enter User mode on an XScale (unpredictable), - * but User shares registers with SYS - */ + * and check if any banked registers need to be written. Ignore + * USR mode (number 0) in favor of SYS; we can't enter User mode on + * an XScale (unpredictable), but they share all registers. + */ for (i = 1; i < 7; i++) { - int dirty = 0; + enum arm_mode mode = armv4_5_number_to_mode(i); + struct reg *r; - /* check if there are invalid registers in the current mode - */ + if (mode == ARM_MODE_USR) + continue; + + /* check if there are dirty registers in this mode */ for (j = 8; j <= 14; j++) { - if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty == 1) - dirty = 1; + if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, + mode, j).dirty) + goto dirty; } /* if not USR/SYS, check if the SPSR needs to be written */ - if ((armv4_5_number_to_mode(i) != ARMV4_5_MODE_USR) && (armv4_5_number_to_mode(i) != ARMV4_5_MODE_SYS)) + if (mode != ARM_MODE_SYS) { - if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty == 1) - dirty = 1; + if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, + mode, 16).dirty) + goto dirty; } - if (dirty) - { - uint32_t tmp_cpsr; - - /* send banked registers */ - xscale_send_u32(target, 0x1); + /* there's nothing to flush for this mode */ + continue; - tmp_cpsr = 0x0; - tmp_cpsr |= armv4_5_number_to_mode(i); - tmp_cpsr |= 0xc0; /* I/F bits */ +dirty: + /* command 0x1: "send banked registers" */ + xscale_send_u32(target, 0x1); - /* send CPSR for desired mode */ - xscale_send_u32(target, tmp_cpsr); + /* send CPSR for desired mode */ + xscale_send_u32(target, mode | 0xc0 /* I/F bits */); - /* send banked registers, r8 to r14, and spsr if not in USR/SYS mode */ - for (j = 8; j <= 14; j++) - { - xscale_send_u32(target, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, j).value, 0, 32)); - ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty = 0; - } + /* send r8 to r14/lr ... only FIQ needs more than r13..r14, + * but this protocol doesn't understand that nuance. + */ + for (j = 8; j <= 14; j++) { + r = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, + mode, j); + xscale_send_u32(target, buf_get_u32(r->value, 0, 32)); + r->dirty = false; + } - if ((armv4_5_number_to_mode(i) != ARMV4_5_MODE_USR) && (armv4_5_number_to_mode(i) != ARMV4_5_MODE_SYS)) - { - xscale_send_u32(target, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32)); - ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty = 0; - } + /* send spsr if not in USR/SYS mode */ + if (mode != ARM_MODE_SYS) { + r = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, + mode, 16); + xscale_send_u32(target, buf_get_u32(r->value, 0, 32)); + r->dirty = false; } } @@ -1913,7 +1895,13 @@ static int xscale_read_memory(struct target *target, uint32_t address, 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. */ + struct xscale_common *xscale = target_to_xscale(target); + + /* with MMU inactive, there are only physical addresses */ + if (!xscale->armv4_5_mmu.mmu_enabled) + return xscale_read_memory(target, address, size, count, buffer); + + /** \todo: provide a non-stub implementation of this routine. */ LOG_ERROR("%s: %s is not implemented. Disable MMU?", target_name(target), __func__); return ERROR_FAIL; @@ -2000,7 +1988,13 @@ static int xscale_write_memory(struct target *target, uint32_t address, 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. */ + struct xscale_common *xscale = target_to_xscale(target); + + /* with MMU inactive, there are only physical addresses */ + if (!xscale->armv4_5_mmu.mmu_enabled) + return xscale_read_memory(target, address, size, count, buffer); + + /** \todo: provide a non-stub implementation of this routine. */ LOG_ERROR("%s: %s is not implemented. Disable MMU?", target_name(target), __func__); return ERROR_FAIL; @@ -2564,7 +2558,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; @@ -2610,7 +2605,7 @@ static int xscale_read_instruction(struct target *target, return ERROR_TRACE_INSTRUCTION_UNAVAILABLE; } - if (xscale->trace.core_state == ARMV4_5_STATE_ARM) + if (xscale->trace.core_state == ARM_STATE_ARM) { uint8_t buf[4]; if ((retval = image_read_section(xscale->trace.image, section, @@ -2623,7 +2618,7 @@ static int xscale_read_instruction(struct target *target, opcode = target_buffer_get_u32(target, buf); arm_evaluate_opcode(opcode, xscale->trace.current_pc, instruction); } - else if (xscale->trace.core_state == ARMV4_5_STATE_THUMB) + else if (xscale->trace.core_state == ARM_STATE_THUMB) { uint8_t buf[2]; if ((retval = image_read_section(xscale->trace.image, section, @@ -2675,7 +2670,7 @@ static int xscale_analyze_trace(struct target *target, struct command_context *c int rollover; int branch; int exception; - xscale->trace.core_state = ARMV4_5_STATE_ARM; + xscale->trace.core_state = ARM_STATE_ARM; chkpt = 0; rollover = 0; @@ -2809,7 +2804,7 @@ static int xscale_analyze_trace(struct target *target, struct command_context *c } else { - xscale->trace.current_pc += (xscale->trace.core_state == ARMV4_5_STATE_ARM) ? 4 : 2; + xscale->trace.current_pc += (xscale->trace.core_state == ARM_STATE_ARM) ? 4 : 2; } command_print(cmd_ctx, "%s", instruction.text); } @@ -2824,7 +2819,7 @@ static int xscale_analyze_trace(struct target *target, struct command_context *c } } - for (; xscale->trace.current_pc < trace_data->last_instruction; xscale->trace.current_pc += (xscale->trace.core_state == ARMV4_5_STATE_ARM) ? 4 : 2) + for (; xscale->trace.current_pc < trace_data->last_instruction; xscale->trace.current_pc += (xscale->trace.core_state == ARM_STATE_ARM) ? 4 : 2) { struct arm_instruction instruction; if ((retval = xscale_read_instruction(target, &instruction)) != ERROR_OK) @@ -2862,7 +2857,7 @@ static void xscale_build_reg_cache(struct target *target) int i; int num_regs = ARRAY_SIZE(xscale_reg_arch_info); - (*cache_p) = armv4_5_build_reg_cache(target, armv4_5); + (*cache_p) = arm_build_reg_cache(target, armv4_5); (*cache_p)->next = malloc(sizeof(struct reg_cache)); cache_p = &(*cache_p)->next; @@ -2978,6 +2973,9 @@ static int xscale_init_arch_info(struct target *target, xscale->dbr0_used = 0; xscale->dbr1_used = 0; + LOG_INFO("%s: hardware has 2 breakpoints and 2 watchpoints", + target_name(target)); + xscale->arm_bkpt = ARMV5_BKPT(0x0); xscale->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff; @@ -2995,7 +2993,7 @@ static int xscale_init_arch_info(struct target *target, armv4_5->write_core_reg = xscale_write_core_reg; armv4_5->full_context = xscale_full_context; - armv4_5_init_arch_info(target, armv4_5); + arm_init_arch_info(target, armv4_5); xscale->armv4_5_mmu.armv4_5_cache.ctype = -1; xscale->armv4_5_mmu.get_ttb = xscale_get_ttb; @@ -3368,7 +3366,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 { @@ -3600,94 +3599,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, @@ -3724,7 +3730,8 @@ struct target_type xscale_target = .deassert_reset = xscale_deassert_reset, .soft_reset_halt = NULL, - .get_gdb_reg_list = armv4_5_get_gdb_reg_list, + /* REVISIT on some cores, allow exporting iwmmxt registers ... */ + .get_gdb_reg_list = arm_get_gdb_reg_list, .read_memory = xscale_read_memory, .read_phys_memory = xscale_read_phys_memory,