Michael Bruck <mbruck@digenius.de> ARM11 various updates + fix formatting.

git-svn-id: svn://svn.berlios.de/openocd/trunk@1512 b42882b7-edfa-0310-969c-e2dbd0fdcd60
This commit is contained in:
oharboe 2009-04-22 18:39:59 +00:00
parent a247833a5a
commit 23de60e6bd
3 changed files with 844 additions and 805 deletions

File diff suppressed because it is too large Load Diff

View File

@ -45,9 +45,12 @@
#define ARM11_REGCACHE_FREGS 0 #define ARM11_REGCACHE_FREGS 0
#define ARM11_REGCACHE_COUNT (20 + \ #define ARM11_REGCACHE_COUNT (20 + \
23 * ARM11_REGCACHE_MODEREGS + \ 23 * ARM11_REGCACHE_MODEREGS + \
9 * ARM11_REGCACHE_FREGS) 9 * ARM11_REGCACHE_FREGS)
#define ARM11_TAP_DEFAULT TAP_INVALID
typedef struct arm11_register_history_s typedef struct arm11_register_history_s
{ {
u32 value; u32 value;
@ -56,17 +59,17 @@ typedef struct arm11_register_history_s
enum arm11_debug_version enum arm11_debug_version
{ {
ARM11_DEBUG_V6 = 0x01, ARM11_DEBUG_V6 = 0x01,
ARM11_DEBUG_V61 = 0x02, ARM11_DEBUG_V61 = 0x02,
ARM11_DEBUG_V7 = 0x03, ARM11_DEBUG_V7 = 0x03,
ARM11_DEBUG_V7_CP14 = 0x04, ARM11_DEBUG_V7_CP14 = 0x04,
}; };
typedef struct arm11_common_s typedef struct arm11_common_s
{ {
target_t * target; target_t * target; /**< Reference back to the owner */
arm_jtag_t jtag_info; arm_jtag_t jtag_info; /**< Handler to access assigned JTAG device */
/** \name Processor type detection */ /** \name Processor type detection */
/*@{*/ /*@{*/
@ -83,11 +86,13 @@ typedef struct arm11_common_s
/*@}*/ /*@}*/
u32 last_dscr; /**< Last retrieved DSCR value; u32 last_dscr; /**< Last retrieved DSCR value;
* Can be used to detect changes */ Use only for debug message generation */
bool trst_active; bool trst_active;
bool halt_requested; bool halt_requested; /**< Keep track if arm11_halt() calls occured
bool simulate_reset_on_next_halt; during reset. Otherwise do it ASAP. */
bool simulate_reset_on_next_halt; /**< Perform cleanups of the ARM state on next halt */
/** \name Shadow registers to save processor state */ /** \name Shadow registers to save processor state */
/*@{*/ /*@{*/
@ -127,23 +132,24 @@ enum arm11_instructions
enum arm11_dscr enum arm11_dscr
{ {
ARM11_DSCR_CORE_HALTED = 1 << 0, ARM11_DSCR_CORE_HALTED = 1 << 0,
ARM11_DSCR_CORE_RESTARTED = 1 << 1, ARM11_DSCR_CORE_RESTARTED = 1 << 1,
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_MASK = 0x0F << 2, ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_MASK = 0x0F << 2,
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_HALT = 0x00 << 2, ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_HALT = 0x00 << 2,
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BREAKPOINT = 0x01 << 2, ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BREAKPOINT = 0x01 << 2,
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_WATCHPOINT = 0x02 << 2, ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_WATCHPOINT = 0x02 << 2,
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BKPT_INSTRUCTION = 0x03 << 2, ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BKPT_INSTRUCTION = 0x03 << 2,
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_EDBGRQ = 0x04 << 2, ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_EDBGRQ = 0x04 << 2,
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_VECTOR_CATCH = 0x05 << 2, ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_VECTOR_CATCH = 0x05 << 2,
ARM11_DSCR_STICKY_PRECISE_DATA_ABORT = 1 << 6, ARM11_DSCR_STICKY_PRECISE_DATA_ABORT = 1 << 6,
ARM11_DSCR_STICKY_IMPRECISE_DATA_ABORT = 1 << 7, ARM11_DSCR_STICKY_IMPRECISE_DATA_ABORT = 1 << 7,
ARM11_DSCR_EXECUTE_ARM_INSTRUCTION_ENABLE = 1 << 13, ARM11_DSCR_INTERRUPTS_DISABLE = 1 << 11,
ARM11_DSCR_MODE_SELECT = 1 << 14, ARM11_DSCR_EXECUTE_ARM_INSTRUCTION_ENABLE = 1 << 13,
ARM11_DSCR_WDTR_FULL = 1 << 29, ARM11_DSCR_MODE_SELECT = 1 << 14,
ARM11_DSCR_RDTR_FULL = 1 << 30, ARM11_DSCR_WDTR_FULL = 1 << 29,
ARM11_DSCR_RDTR_FULL = 1 << 30,
}; };
enum arm11_cpsr enum arm11_cpsr
@ -229,23 +235,23 @@ void arm11_dump_reg_changes(arm11_common_t * arm11);
/* internals */ /* internals */
void arm11_setup_field (arm11_common_t * arm11, int num_bits, void * in_data, void * out_data, scan_field_t * field); void arm11_setup_field (arm11_common_t * arm11, int num_bits, void * in_data, void * out_data, scan_field_t * field);
void arm11_add_IR (arm11_common_t * arm11, u8 instr, tap_state_t state); void arm11_add_IR (arm11_common_t * arm11, u8 instr, tap_state_t state);
void arm11_add_debug_SCAN_N (arm11_common_t * arm11, u8 chain, tap_state_t state); void arm11_add_debug_SCAN_N (arm11_common_t * arm11, u8 chain, tap_state_t state);
void arm11_add_debug_INST (arm11_common_t * arm11, u32 inst, u8 * flag, tap_state_t state); void arm11_add_debug_INST (arm11_common_t * arm11, u32 inst, u8 * flag, tap_state_t state);
u32 arm11_read_DSCR (arm11_common_t * arm11); u32 arm11_read_DSCR (arm11_common_t * arm11);
void arm11_write_DSCR (arm11_common_t * arm11, u32 dscr); void arm11_write_DSCR (arm11_common_t * arm11, u32 dscr);
enum target_debug_reason arm11_get_DSCR_debug_reason(u32 dscr); enum target_debug_reason arm11_get_DSCR_debug_reason(u32 dscr);
void arm11_run_instr_data_prepare (arm11_common_t * arm11); void arm11_run_instr_data_prepare (arm11_common_t * arm11);
void arm11_run_instr_data_finish (arm11_common_t * arm11); void arm11_run_instr_data_finish (arm11_common_t * arm11);
void arm11_run_instr_no_data (arm11_common_t * arm11, u32 * opcode, size_t count); void arm11_run_instr_no_data (arm11_common_t * arm11, u32 * opcode, size_t count);
void arm11_run_instr_no_data1 (arm11_common_t * arm11, u32 opcode); void arm11_run_instr_no_data1 (arm11_common_t * arm11, u32 opcode);
void arm11_run_instr_data_to_core (arm11_common_t * arm11, u32 opcode, u32 * data, size_t count); void arm11_run_instr_data_to_core (arm11_common_t * arm11, u32 opcode, u32 * data, size_t count);
void arm11_run_instr_data_to_core_noack (arm11_common_t * arm11, u32 opcode, u32 * data, size_t count); void arm11_run_instr_data_to_core_noack (arm11_common_t * arm11, u32 opcode, u32 * data, size_t count);
void arm11_run_instr_data_to_core1 (arm11_common_t * arm11, u32 opcode, u32 data); void arm11_run_instr_data_to_core1 (arm11_common_t * arm11, u32 opcode, u32 data);
void arm11_run_instr_data_from_core (arm11_common_t * arm11, u32 opcode, u32 * data, size_t count); void arm11_run_instr_data_from_core (arm11_common_t * arm11, u32 opcode, u32 * data, size_t count);
void arm11_run_instr_data_from_core_via_r0 (arm11_common_t * arm11, u32 opcode, u32 * data); void arm11_run_instr_data_from_core_via_r0 (arm11_common_t * arm11, u32 opcode, u32 * data);
void arm11_run_instr_data_to_core_via_r0 (arm11_common_t * arm11, u32 opcode, u32 data); void arm11_run_instr_data_to_core_via_r0 (arm11_common_t * arm11, u32 opcode, u32 data);
@ -259,10 +265,10 @@ int arm11_add_ir_scan_vc(int num_fields, scan_field_t *fields, tap_state_t state
typedef struct arm11_sc7_action_s typedef struct arm11_sc7_action_s
{ {
bool write; /**< Access mode: true for write, false for read. */ bool write; /**< Access mode: true for write, false for read. */
u8 address; /**< Register address mode. Use enum #arm11_sc7 */ u8 address; /**< Register address mode. Use enum #arm11_sc7 */
u32 value; /**< If write then set this to value to be written. u32 value; /**< If write then set this to value to be written.
In read mode this receives the read value when the In read mode this receives the read value when the
function returns. */ function returns. */
} arm11_sc7_action_t; } arm11_sc7_action_t;
void arm11_sc7_run(arm11_common_t * arm11, arm11_sc7_action_t * actions, size_t count); void arm11_sc7_run(arm11_common_t * arm11, arm11_sc7_action_t * actions, size_t count);

View File

@ -44,83 +44,79 @@ tap_state_t arm11_move_pi_to_si_via_ci[] =
int arm11_add_ir_scan_vc(int num_fields, scan_field_t *fields, tap_state_t state) int arm11_add_ir_scan_vc(int num_fields, scan_field_t *fields, tap_state_t state)
{ {
if (cmd_queue_cur_state == TAP_IRPAUSE) if (cmd_queue_cur_state == TAP_IRPAUSE)
jtag_add_pathmove(asizeof(arm11_move_pi_to_si_via_ci), arm11_move_pi_to_si_via_ci); jtag_add_pathmove(asizeof(arm11_move_pi_to_si_via_ci), arm11_move_pi_to_si_via_ci);
jtag_add_ir_scan(num_fields, fields, state); jtag_add_ir_scan(num_fields, fields, state);
return ERROR_OK; return ERROR_OK;
} }
tap_state_t arm11_move_pd_to_sd_via_cd[] = tap_state_t arm11_move_pd_to_sd_via_cd[] =
{ {
TAP_DREXIT2, TAP_DRUPDATE, TAP_DRSELECT, TAP_DRCAPTURE, TAP_DRSHIFT TAP_DREXIT2, TAP_DRUPDATE, TAP_DRSELECT, TAP_DRCAPTURE, TAP_DRSHIFT
}; };
int arm11_add_dr_scan_vc(int num_fields, scan_field_t *fields, tap_state_t state) int arm11_add_dr_scan_vc(int num_fields, scan_field_t *fields, tap_state_t state)
{ {
if (cmd_queue_cur_state == TAP_DRPAUSE) if (cmd_queue_cur_state == TAP_DRPAUSE)
jtag_add_pathmove(asizeof(arm11_move_pd_to_sd_via_cd), arm11_move_pd_to_sd_via_cd); jtag_add_pathmove(asizeof(arm11_move_pd_to_sd_via_cd), arm11_move_pd_to_sd_via_cd);
jtag_add_dr_scan(num_fields, fields, state); jtag_add_dr_scan(num_fields, fields, state);
return ERROR_OK; return ERROR_OK;
} }
/** Code de-clutter: Construct scan_field_t to write out a value /** Code de-clutter: Construct scan_field_t to write out a value
* *
* \param arm11 Target state variable. * \param arm11 Target state variable.
* \param num_bits Length of the data field * \param num_bits Length of the data field
* \param out_data pointer to the data that will be sent out * \param out_data pointer to the data that will be sent out
* <em>(data is read when it is added to the JTAG queue)</em> * <em>(data is read when it is added to the JTAG queue)</em>
* \param in_data pointer to the memory that will receive data that was clocked in * \param in_data pointer to the memory that will receive data that was clocked in
* <em>(data is written when the JTAG queue is executed)</em> * <em>(data is written when the JTAG queue is executed)</em>
* \param field target data structure that will be initialized * \param field target data structure that will be initialized
*/ */
void arm11_setup_field(arm11_common_t * arm11, int num_bits, void * out_data, void * in_data, scan_field_t * field) void arm11_setup_field(arm11_common_t * arm11, int num_bits, void * out_data, void * in_data, scan_field_t * field)
{ {
field->tap = arm11->jtag_info.tap; field->tap = arm11->jtag_info.tap;
field->num_bits = num_bits; field->num_bits = num_bits;
field->out_mask = NULL; field->out_mask = NULL;
field->in_check_mask = NULL; field->in_check_mask = NULL;
field->in_check_value = NULL; field->in_check_value = NULL;
field->in_handler = NULL; field->in_handler = NULL;
field->in_handler_priv = NULL; field->in_handler_priv = NULL;
field->out_value = out_data; field->out_value = out_data;
field->in_value = in_data; field->in_value = in_data;
} }
/** Write JTAG instruction register /** Write JTAG instruction register
* *
* \param arm11 Target state variable. * \param arm11 Target state variable.
* \param instr An ARM11 DBGTAP instruction. Use enum #arm11_instructions. * \param instr An ARM11 DBGTAP instruction. Use enum #arm11_instructions.
* \param state Pass the final TAP state or TAP_INVALID for the default value (Pause-IR). * \param state Pass the final TAP state or ARM11_TAP_DEFAULT for the default value (Pause-IR).
* *
* \remarks This adds to the JTAG command queue but does \em not execute it. * \remarks This adds to the JTAG command queue but does \em not execute it.
*/ */
void arm11_add_IR(arm11_common_t * arm11, u8 instr, tap_state_t state) void arm11_add_IR(arm11_common_t * arm11, u8 instr, tap_state_t state)
{ {
jtag_tap_t *tap; jtag_tap_t *tap;
tap = arm11->jtag_info.tap; tap = arm11->jtag_info.tap;
if( tap == NULL ){
/* FIX!!!! error is logged, but not propagated back up the call stack... */
LOG_ERROR( "tap is null here! This is bad!");
return;
}
if (buf_get_u32(tap->cur_instr, 0, 5) == instr){ if (buf_get_u32(tap->cur_instr, 0, 5) == instr)
{
JTAG_DEBUG("IR <= 0x%02x SKIPPED", instr); JTAG_DEBUG("IR <= 0x%02x SKIPPED", instr);
return; return;
} }
JTAG_DEBUG("IR <= 0x%02x", instr); JTAG_DEBUG("IR <= 0x%02x", instr);
scan_field_t field; scan_field_t field;
arm11_setup_field(arm11, 5, &instr, NULL, &field); arm11_setup_field(arm11, 5, &instr, NULL, &field);
arm11_add_ir_scan_vc(1, &field, state == TAP_INVALID ? TAP_IRPAUSE : state); arm11_add_ir_scan_vc(1, &field, state == ARM11_TAP_DEFAULT ? TAP_IRPAUSE : state);
} }
/** Verify shifted out data from Scan Chain Register (SCREG) /** Verify shifted out data from Scan Chain Register (SCREG)
@ -130,17 +126,17 @@ void arm11_add_IR(arm11_common_t * arm11, u8 instr, tap_state_t state)
*/ */
static int arm11_in_handler_SCAN_N(u8 *in_value, void *priv, struct scan_field_s *field) static int arm11_in_handler_SCAN_N(u8 *in_value, void *priv, struct scan_field_s *field)
{ {
/** \todo TODO: clarify why this isnt properly masked in jtag.c jtag_read_buffer() */ /** \todo TODO: clarify why this isnt properly masked in jtag.c jtag_read_buffer() */
u8 v = *in_value & 0x1F; u8 v = *in_value & 0x1F;
if (v != 0x10) if (v != 0x10)
{ {
LOG_ERROR("'arm11 target' JTAG communication error SCREG SCAN OUT 0x%02x (expected 0x10)", v); LOG_ERROR("'arm11 target' JTAG communication error SCREG SCAN OUT 0x%02x (expected 0x10)", v);
return ERROR_FAIL; return ERROR_FAIL;
} }
JTAG_DEBUG("SCREG SCAN OUT 0x%02x", v); JTAG_DEBUG("SCREG SCAN OUT 0x%02x", v);
return ERROR_OK; return ERROR_OK;
} }
/** Select and write to Scan Chain Register (SCREG) /** Select and write to Scan Chain Register (SCREG)
@ -152,165 +148,165 @@ static int arm11_in_handler_SCAN_N(u8 *in_value, void *priv, struct scan_field_s
* *
* \param arm11 Target state variable. * \param arm11 Target state variable.
* \param chain Scan chain that will be selected. * \param chain Scan chain that will be selected.
* \param state Pass the final TAP state or TAP_INVALID for the default * \param state Pass the final TAP state or ARM11_TAP_DEFAULT for the default
* value (Pause-DR). * value (Pause-DR).
* *
* The chain takes effect when Update-DR is passed (usually when subsequently * The chain takes effect when Update-DR is passed (usually when subsequently
* the INTEXT/EXTEST instructions are written). * the INTEXT/EXTEST instructions are written).
* *
* \warning (Obsolete) Using this twice in a row will \em fail. The first call will end * \warning (Obsolete) Using this twice in a row will \em fail. The first
* in Pause-DR. The second call, due to the IR caching, will not * call will end in Pause-DR. The second call, due to the IR
* go through Capture-DR when shifting in the new scan chain number. * caching, will not go through Capture-DR when shifting in the
* As a result the verification in arm11_in_handler_SCAN_N() must * new scan chain number. As a result the verification in
* fail. * arm11_in_handler_SCAN_N() must fail.
* *
* \remarks This adds to the JTAG command queue but does \em not execute it. * \remarks This adds to the JTAG command queue but does \em not execute it.
*/ */
void arm11_add_debug_SCAN_N(arm11_common_t * arm11, u8 chain, tap_state_t state) void arm11_add_debug_SCAN_N(arm11_common_t * arm11, u8 chain, tap_state_t state)
{ {
JTAG_DEBUG("SCREG <= 0x%02x", chain); JTAG_DEBUG("SCREG <= 0x%02x", chain);
arm11_add_IR(arm11, ARM11_SCAN_N, TAP_INVALID); arm11_add_IR(arm11, ARM11_SCAN_N, ARM11_TAP_DEFAULT);
scan_field_t field; scan_field_t field;
arm11_setup_field(arm11, 5, &chain, NULL, &field); arm11_setup_field(arm11, 5, &chain, NULL, &field);
field.in_handler = arm11_in_handler_SCAN_N; field.in_handler = arm11_in_handler_SCAN_N;
arm11_add_dr_scan_vc(1, &field, state == TAP_INVALID ? TAP_DRPAUSE : state); arm11_add_dr_scan_vc(1, &field, state == ARM11_TAP_DEFAULT ? TAP_DRPAUSE : state);
} }
/** Write an instruction into the ITR register /** Write an instruction into the ITR register
* *
* \param arm11 Target state variable. * \param arm11 Target state variable.
* \param inst An ARM11 processor instruction/opcode. * \param inst An ARM11 processor instruction/opcode.
* \param flag Optional parameter to retrieve the InstCompl flag * \param flag Optional parameter to retrieve the InstCompl flag
* (this will be written when the JTAG chain is executed). * (this will be written when the JTAG chain is executed).
* \param state Pass the final TAP state or TAP_INVALID for the default * \param state Pass the final TAP state or ARM11_TAP_DEFAULT for the default
* value (Run-Test/Idle). * value (Run-Test/Idle).
* *
* \remarks By default this ends with Run-Test/Idle state * \remarks By default this ends with Run-Test/Idle state
* and causes the instruction to be executed. If * and causes the instruction to be executed. If
* a subsequent write to DTR is needed before * a subsequent write to DTR is needed before
* executing the instruction then TAP_DRPAUSE should be * executing the instruction then TAP_DRPAUSE should be
* passed to \p state. * passed to \p state.
* *
* \remarks This adds to the JTAG command queue but does \em not execute it. * \remarks This adds to the JTAG command queue but does \em not execute it.
*/ */
void arm11_add_debug_INST(arm11_common_t * arm11, u32 inst, u8 * flag, tap_state_t state) void arm11_add_debug_INST(arm11_common_t * arm11, u32 inst, u8 * flag, tap_state_t state)
{ {
JTAG_DEBUG("INST <= 0x%08x", inst); JTAG_DEBUG("INST <= 0x%08x", inst);
scan_field_t itr[2]; scan_field_t itr[2];
arm11_setup_field(arm11, 32, &inst, NULL, itr + 0); arm11_setup_field(arm11, 32, &inst, NULL, itr + 0);
arm11_setup_field(arm11, 1, NULL, flag, itr + 1); arm11_setup_field(arm11, 1, NULL, flag, itr + 1);
arm11_add_dr_scan_vc(asizeof(itr), itr, state == TAP_INVALID ? TAP_IDLE : state); arm11_add_dr_scan_vc(asizeof(itr), itr, state == ARM11_TAP_DEFAULT ? TAP_IDLE : state);
} }
/** Read the Debug Status and Control Register (DSCR) /** Read the Debug Status and Control Register (DSCR)
* *
* same as CP14 c1 * same as CP14 c1
* *
* \param arm11 Target state variable. * \param arm11 Target state variable.
* \return DSCR content * \return DSCR content
* *
* \remarks This is a stand-alone function that executes the JTAG command queue. * \remarks This is a stand-alone function that executes the JTAG command queue.
*/ */
u32 arm11_read_DSCR(arm11_common_t * arm11) u32 arm11_read_DSCR(arm11_common_t * arm11)
{ {
arm11_add_debug_SCAN_N(arm11, 0x01, TAP_INVALID); arm11_add_debug_SCAN_N(arm11, 0x01, ARM11_TAP_DEFAULT);
arm11_add_IR(arm11, ARM11_INTEST, TAP_INVALID); arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);
u32 dscr; u32 dscr;
scan_field_t chain1_field; scan_field_t chain1_field;
arm11_setup_field(arm11, 32, NULL, &dscr, &chain1_field); arm11_setup_field(arm11, 32, NULL, &dscr, &chain1_field);
arm11_add_dr_scan_vc(1, &chain1_field, TAP_DRPAUSE); arm11_add_dr_scan_vc(1, &chain1_field, TAP_DRPAUSE);
jtag_execute_queue(); jtag_execute_queue();
if (arm11->last_dscr != dscr) if (arm11->last_dscr != dscr)
JTAG_DEBUG("DSCR = %08x (OLD %08x)", dscr, arm11->last_dscr); JTAG_DEBUG("DSCR = %08x (OLD %08x)", dscr, arm11->last_dscr);
arm11->last_dscr = dscr; arm11->last_dscr = dscr;
return dscr; return dscr;
} }
/** Write the Debug Status and Control Register (DSCR) /** Write the Debug Status and Control Register (DSCR)
* *
* same as CP14 c1 * same as CP14 c1
* *
* \param arm11 Target state variable. * \param arm11 Target state variable.
* \param dscr DSCR content * \param dscr DSCR content
* *
* \remarks This is a stand-alone function that executes the JTAG command queue. * \remarks This is a stand-alone function that executes the JTAG command queue.
*/ */
void arm11_write_DSCR(arm11_common_t * arm11, u32 dscr) void arm11_write_DSCR(arm11_common_t * arm11, u32 dscr)
{ {
arm11_add_debug_SCAN_N(arm11, 0x01, TAP_INVALID); arm11_add_debug_SCAN_N(arm11, 0x01, ARM11_TAP_DEFAULT);
arm11_add_IR(arm11, ARM11_EXTEST, TAP_INVALID); arm11_add_IR(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT);
scan_field_t chain1_field; scan_field_t chain1_field;
arm11_setup_field(arm11, 32, &dscr, NULL, &chain1_field); arm11_setup_field(arm11, 32, &dscr, NULL, &chain1_field);
arm11_add_dr_scan_vc(1, &chain1_field, TAP_DRPAUSE); arm11_add_dr_scan_vc(1, &chain1_field, TAP_DRPAUSE);
jtag_execute_queue(); jtag_execute_queue();
JTAG_DEBUG("DSCR <= %08x (OLD %08x)", dscr, arm11->last_dscr); JTAG_DEBUG("DSCR <= %08x (OLD %08x)", dscr, arm11->last_dscr);
arm11->last_dscr = dscr; arm11->last_dscr = dscr;
} }
/** Get the debug reason from Debug Status and Control Register (DSCR) /** Get the debug reason from Debug Status and Control Register (DSCR)
* *
* \param dscr DSCR value to analyze * \param dscr DSCR value to analyze
* \return Debug reason * \return Debug reason
* *
*/ */
enum target_debug_reason arm11_get_DSCR_debug_reason(u32 dscr) enum target_debug_reason arm11_get_DSCR_debug_reason(u32 dscr)
{ {
switch (dscr & ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_MASK) switch (dscr & ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_MASK)
{ {
case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_HALT: case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_HALT:
LOG_INFO("Debug entry: JTAG HALT"); LOG_INFO("Debug entry: JTAG HALT");
return DBG_REASON_DBGRQ; return DBG_REASON_DBGRQ;
case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BREAKPOINT: case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BREAKPOINT:
LOG_INFO("Debug entry: breakpoint"); LOG_INFO("Debug entry: breakpoint");
return DBG_REASON_BREAKPOINT; return DBG_REASON_BREAKPOINT;
case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_WATCHPOINT: case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_WATCHPOINT:
LOG_INFO("Debug entry: watchpoint"); LOG_INFO("Debug entry: watchpoint");
return DBG_REASON_WATCHPOINT; return DBG_REASON_WATCHPOINT;
case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BKPT_INSTRUCTION: case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BKPT_INSTRUCTION:
LOG_INFO("Debug entry: BKPT instruction"); LOG_INFO("Debug entry: BKPT instruction");
return DBG_REASON_BREAKPOINT; return DBG_REASON_BREAKPOINT;
case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_EDBGRQ: case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_EDBGRQ:
LOG_INFO("Debug entry: EDBGRQ signal"); LOG_INFO("Debug entry: EDBGRQ signal");
return DBG_REASON_DBGRQ; return DBG_REASON_DBGRQ;
case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_VECTOR_CATCH: case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_VECTOR_CATCH:
LOG_INFO("Debug entry: VCR vector catch"); LOG_INFO("Debug entry: VCR vector catch");
return DBG_REASON_BREAKPOINT; return DBG_REASON_BREAKPOINT;
default: default:
LOG_INFO("Debug entry: unknown"); LOG_INFO("Debug entry: unknown");
return DBG_REASON_DBGRQ; return DBG_REASON_DBGRQ;
} }
}; };
@ -326,12 +322,12 @@ enum target_debug_reason arm11_get_DSCR_debug_reason(u32 dscr)
* shortcut is used instead of actually changing the Scan_N * shortcut is used instead of actually changing the Scan_N
* register. * register.
* *
* \param arm11 Target state variable. * \param arm11 Target state variable.
* *
*/ */
void arm11_run_instr_data_prepare(arm11_common_t * arm11) void arm11_run_instr_data_prepare(arm11_common_t * arm11)
{ {
arm11_add_debug_SCAN_N(arm11, 0x05, TAP_INVALID); arm11_add_debug_SCAN_N(arm11, 0x05, ARM11_TAP_DEFAULT);
} }
/** Cleanup after ITR/DTR operations /** Cleanup after ITR/DTR operations
@ -345,12 +341,12 @@ void arm11_run_instr_data_prepare(arm11_common_t * arm11)
* INTEST or EXTEST. So we must disable that before * INTEST or EXTEST. So we must disable that before
* any following activities lead to an IDLE. * any following activities lead to an IDLE.
* *
* \param arm11 Target state variable. * \param arm11 Target state variable.
* *
*/ */
void arm11_run_instr_data_finish(arm11_common_t * arm11) void arm11_run_instr_data_finish(arm11_common_t * arm11)
{ {
arm11_add_debug_SCAN_N(arm11, 0x00, TAP_INVALID); arm11_add_debug_SCAN_N(arm11, 0x00, ARM11_TAP_DEFAULT);
} }
@ -365,24 +361,24 @@ void arm11_run_instr_data_finish(arm11_common_t * arm11)
*/ */
void arm11_run_instr_no_data(arm11_common_t * arm11, u32 * opcode, size_t count) void arm11_run_instr_no_data(arm11_common_t * arm11, u32 * opcode, size_t count)
{ {
arm11_add_IR(arm11, ARM11_ITRSEL, TAP_INVALID); arm11_add_IR(arm11, ARM11_ITRSEL, ARM11_TAP_DEFAULT);
while (count--) while (count--)
{
arm11_add_debug_INST(arm11, *opcode++, NULL, TAP_IDLE);
while (1)
{ {
u8 flag; arm11_add_debug_INST(arm11, *opcode++, NULL, TAP_IDLE);
arm11_add_debug_INST(arm11, 0, &flag, count ? TAP_IDLE : TAP_DRPAUSE); while (1)
{
u8 flag;
jtag_execute_queue(); arm11_add_debug_INST(arm11, 0, &flag, count ? TAP_IDLE : TAP_DRPAUSE);
if (flag) jtag_execute_queue();
break;
if (flag)
break;
}
} }
}
} }
/** Execute one instruction via ITR /** Execute one instruction via ITR
@ -395,7 +391,7 @@ void arm11_run_instr_no_data(arm11_common_t * arm11, u32 * opcode, size_t count)
*/ */
void arm11_run_instr_no_data1(arm11_common_t * arm11, u32 opcode) void arm11_run_instr_no_data1(arm11_common_t * arm11, u32 opcode)
{ {
arm11_run_instr_no_data(arm11, &opcode, 1); arm11_run_instr_no_data(arm11, &opcode, 1);
} }
@ -414,50 +410,50 @@ void arm11_run_instr_no_data1(arm11_common_t * arm11, u32 opcode)
*/ */
void arm11_run_instr_data_to_core(arm11_common_t * arm11, u32 opcode, u32 * data, size_t count) void arm11_run_instr_data_to_core(arm11_common_t * arm11, u32 opcode, u32 * data, size_t count)
{ {
arm11_add_IR(arm11, ARM11_ITRSEL, TAP_INVALID); arm11_add_IR(arm11, ARM11_ITRSEL, ARM11_TAP_DEFAULT);
arm11_add_debug_INST(arm11, opcode, NULL, TAP_DRPAUSE); arm11_add_debug_INST(arm11, opcode, NULL, TAP_DRPAUSE);
arm11_add_IR(arm11, ARM11_EXTEST, TAP_INVALID); arm11_add_IR(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT);
scan_field_t chain5_fields[3]; scan_field_t chain5_fields[3];
u32 Data; u32 Data;
u8 Ready; u8 Ready;
u8 nRetry; u8 nRetry;
arm11_setup_field(arm11, 32, &Data, NULL, chain5_fields + 0); arm11_setup_field(arm11, 32, &Data, NULL, chain5_fields + 0);
arm11_setup_field(arm11, 1, NULL, &Ready, chain5_fields + 1); arm11_setup_field(arm11, 1, NULL, &Ready, chain5_fields + 1);
arm11_setup_field(arm11, 1, NULL, &nRetry, chain5_fields + 2); arm11_setup_field(arm11, 1, NULL, &nRetry, chain5_fields + 2);
while (count--)
{
do
{
Data = *data;
arm11_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, TAP_IDLE);
jtag_execute_queue();
JTAG_DEBUG("DTR Ready %d nRetry %d", Ready, nRetry);
}
while (!Ready);
data++;
}
arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);
while (count--)
{
do do
{ {
Data = *data; Data = 0;
arm11_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, TAP_IDLE); arm11_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, TAP_DRPAUSE);
jtag_execute_queue(); jtag_execute_queue();
JTAG_DEBUG("DTR Ready %d nRetry %d", Ready, nRetry); JTAG_DEBUG("DTR Data %08x Ready %d nRetry %d", Data, Ready, nRetry);
} }
while (!Ready); while (!Ready);
data++;
}
arm11_add_IR(arm11, ARM11_INTEST, TAP_INVALID);
do
{
Data = 0;
arm11_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, TAP_DRPAUSE);
jtag_execute_queue();
JTAG_DEBUG("DTR Data %08x Ready %d nRetry %d", Data, Ready, nRetry);
}
while (!Ready);
} }
/** JTAG path for arm11_run_instr_data_to_core_noack /** JTAG path for arm11_run_instr_data_to_core_noack
@ -473,7 +469,7 @@ void arm11_run_instr_data_to_core(arm11_common_t * arm11, u32 opcode, u32 * data
*/ */
tap_state_t arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay[] = tap_state_t arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay[] =
{ {
TAP_DREXIT2, TAP_DRUPDATE, TAP_IDLE, TAP_IDLE, TAP_IDLE, TAP_DRSELECT, TAP_DRCAPTURE, TAP_DRSHIFT TAP_DREXIT2, TAP_DRUPDATE, TAP_IDLE, TAP_IDLE, TAP_IDLE, TAP_DRSELECT, TAP_DRCAPTURE, TAP_DRSHIFT
}; };
@ -495,60 +491,60 @@ tap_state_t arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay[] =
*/ */
void arm11_run_instr_data_to_core_noack(arm11_common_t * arm11, u32 opcode, u32 * data, size_t count) void arm11_run_instr_data_to_core_noack(arm11_common_t * arm11, u32 opcode, u32 * data, size_t count)
{ {
arm11_add_IR(arm11, ARM11_ITRSEL, TAP_INVALID); arm11_add_IR(arm11, ARM11_ITRSEL, ARM11_TAP_DEFAULT);
arm11_add_debug_INST(arm11, opcode, NULL, TAP_DRPAUSE); arm11_add_debug_INST(arm11, opcode, NULL, TAP_DRPAUSE);
arm11_add_IR(arm11, ARM11_EXTEST, TAP_INVALID); arm11_add_IR(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT);
scan_field_t chain5_fields[3]; scan_field_t chain5_fields[3];
arm11_setup_field(arm11, 32, NULL/*&Data*/, NULL, chain5_fields + 0); arm11_setup_field(arm11, 32, NULL/*&Data*/, NULL, chain5_fields + 0);
arm11_setup_field(arm11, 1, NULL, NULL /*&Ready*/, chain5_fields + 1); arm11_setup_field(arm11, 1, NULL, NULL /*&Ready*/, chain5_fields + 1);
arm11_setup_field(arm11, 1, NULL, NULL, chain5_fields + 2); arm11_setup_field(arm11, 1, NULL, NULL, chain5_fields + 2);
u8 Readies[count + 1]; u8 Readies[count + 1];
u8 * ReadyPos = Readies; u8 * ReadyPos = Readies;
while (count--) while (count--)
{
chain5_fields[0].out_value = (void *)(data++);
chain5_fields[1].in_value = ReadyPos++;
if (count)
{ {
jtag_add_dr_scan(asizeof(chain5_fields), chain5_fields, TAP_DRPAUSE); chain5_fields[0].out_value = (void *)(data++);
jtag_add_pathmove(asizeof(arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay), chain5_fields[1].in_value = ReadyPos++;
arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay);
if (count)
{
jtag_add_dr_scan(asizeof(chain5_fields), chain5_fields, TAP_DRPAUSE);
jtag_add_pathmove(asizeof(arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay),
arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay);
}
else
{
jtag_add_dr_scan(asizeof(chain5_fields), chain5_fields, TAP_IDLE);
}
} }
else
arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);
chain5_fields[0].out_value = 0;
chain5_fields[1].in_value = ReadyPos++;
arm11_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, TAP_DRPAUSE);
jtag_execute_queue();
size_t error_count = 0;
{size_t i;
for (i = 0; i < asizeof(Readies); i++)
{ {
jtag_add_dr_scan(asizeof(chain5_fields), chain5_fields, TAP_IDLE); if (Readies[i] != 1)
} {
} error_count++;
}
}}
arm11_add_IR(arm11, ARM11_INTEST, TAP_INVALID); if (error_count)
LOG_ERROR("Transfer errors " ZU, error_count);
chain5_fields[0].out_value = 0;
chain5_fields[1].in_value = ReadyPos++;
arm11_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, TAP_DRPAUSE);
jtag_execute_queue();
size_t error_count = 0;
{size_t i;
for (i = 0; i < asizeof(Readies); i++)
{
if (Readies[i] != 1)
{
error_count++;
}
}}
if (error_count)
LOG_ERROR("Transfer errors " ZU, error_count);
} }
@ -565,7 +561,7 @@ void arm11_run_instr_data_to_core_noack(arm11_common_t * arm11, u32 opcode, u32
*/ */
void arm11_run_instr_data_to_core1(arm11_common_t * arm11, u32 opcode, u32 data) void arm11_run_instr_data_to_core1(arm11_common_t * arm11, u32 opcode, u32 data)
{ {
arm11_run_instr_data_to_core(arm11, opcode, &data, 1); arm11_run_instr_data_to_core(arm11, opcode, &data, 1);
} }
@ -584,35 +580,35 @@ void arm11_run_instr_data_to_core1(arm11_common_t * arm11, u32 opcode, u32 data)
*/ */
void arm11_run_instr_data_from_core(arm11_common_t * arm11, u32 opcode, u32 * data, size_t count) void arm11_run_instr_data_from_core(arm11_common_t * arm11, u32 opcode, u32 * data, size_t count)
{ {
arm11_add_IR(arm11, ARM11_ITRSEL, TAP_INVALID); arm11_add_IR(arm11, ARM11_ITRSEL, ARM11_TAP_DEFAULT);
arm11_add_debug_INST(arm11, opcode, NULL, TAP_IDLE); arm11_add_debug_INST(arm11, opcode, NULL, TAP_IDLE);
arm11_add_IR(arm11, ARM11_INTEST, TAP_INVALID); arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);
scan_field_t chain5_fields[3]; scan_field_t chain5_fields[3];
u32 Data; u32 Data;
u8 Ready; u8 Ready;
u8 nRetry; u8 nRetry;
arm11_setup_field(arm11, 32, NULL, &Data, chain5_fields + 0); arm11_setup_field(arm11, 32, NULL, &Data, chain5_fields + 0);
arm11_setup_field(arm11, 1, NULL, &Ready, chain5_fields + 1); arm11_setup_field(arm11, 1, NULL, &Ready, chain5_fields + 1);
arm11_setup_field(arm11, 1, NULL, &nRetry, chain5_fields + 2); arm11_setup_field(arm11, 1, NULL, &nRetry, chain5_fields + 2);
while (count--) while (count--)
{
do
{ {
arm11_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, count ? TAP_IDLE : TAP_DRPAUSE); do
jtag_execute_queue(); {
arm11_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, count ? TAP_IDLE : TAP_DRPAUSE);
jtag_execute_queue();
JTAG_DEBUG("DTR Data %08x Ready %d nRetry %d", Data, Ready, nRetry); JTAG_DEBUG("DTR Data %08x Ready %d nRetry %d", Data, Ready, nRetry);
}
while (!Ready);
*data++ = Data;
} }
while (!Ready);
*data++ = Data;
}
} }
/** Execute one instruction via ITR /** Execute one instruction via ITR
@ -629,10 +625,10 @@ void arm11_run_instr_data_from_core(arm11_common_t * arm11, u32 opcode, u32 * da
*/ */
void arm11_run_instr_data_from_core_via_r0(arm11_common_t * arm11, u32 opcode, u32 * data) void arm11_run_instr_data_from_core_via_r0(arm11_common_t * arm11, u32 opcode, u32 * data)
{ {
arm11_run_instr_no_data1(arm11, opcode); arm11_run_instr_no_data1(arm11, opcode);
/* MCR p14,0,R0,c0,c5,0 (move r0 -> wDTR -> local var) */ /* MCR p14,0,R0,c0,c5,0 (move r0 -> wDTR -> local var) */
arm11_run_instr_data_from_core(arm11, 0xEE000E15, data, 1); arm11_run_instr_data_from_core(arm11, 0xEE000E15, data, 1);
} }
/** Load data into core via DTR then move it to r0 then /** Load data into core via DTR then move it to r0 then
@ -649,10 +645,10 @@ void arm11_run_instr_data_from_core_via_r0(arm11_common_t * arm11, u32 opcode, u
*/ */
void arm11_run_instr_data_to_core_via_r0(arm11_common_t * arm11, u32 opcode, u32 data) void arm11_run_instr_data_to_core_via_r0(arm11_common_t * arm11, u32 opcode, u32 data)
{ {
/* MRC p14,0,r0,c0,c5,0 */ /* MRC p14,0,r0,c0,c5,0 */
arm11_run_instr_data_to_core1(arm11, 0xEE100E15, data); arm11_run_instr_data_to_core1(arm11, 0xEE100E15, data);
arm11_run_instr_no_data1(arm11, opcode); arm11_run_instr_no_data1(arm11, opcode);
} }
/** Apply reads and writes to scan chain 7 /** Apply reads and writes to scan chain 7
@ -666,76 +662,76 @@ void arm11_run_instr_data_to_core_via_r0(arm11_common_t * arm11, u32 opcode, u32
*/ */
void arm11_sc7_run(arm11_common_t * arm11, arm11_sc7_action_t * actions, size_t count) void arm11_sc7_run(arm11_common_t * arm11, arm11_sc7_action_t * actions, size_t count)
{ {
arm11_add_debug_SCAN_N(arm11, 0x07, TAP_INVALID); arm11_add_debug_SCAN_N(arm11, 0x07, ARM11_TAP_DEFAULT);
arm11_add_IR(arm11, ARM11_EXTEST, TAP_INVALID); arm11_add_IR(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT);
scan_field_t chain7_fields[3]; scan_field_t chain7_fields[3];
u8 nRW; u8 nRW;
u32 DataOut; u32 DataOut;
u8 AddressOut; u8 AddressOut;
u8 Ready; u8 Ready;
u32 DataIn; u32 DataIn;
u8 AddressIn; u8 AddressIn;
arm11_setup_field(arm11, 1, &nRW, &Ready, chain7_fields + 0); arm11_setup_field(arm11, 1, &nRW, &Ready, chain7_fields + 0);
arm11_setup_field(arm11, 32, &DataOut, &DataIn, chain7_fields + 1); arm11_setup_field(arm11, 32, &DataOut, &DataIn, chain7_fields + 1);
arm11_setup_field(arm11, 7, &AddressOut, &AddressIn, chain7_fields + 2); arm11_setup_field(arm11, 7, &AddressOut, &AddressIn, chain7_fields + 2);
{size_t i; {size_t i;
for (i = 0; i < count + 1; i++) for (i = 0; i < count + 1; i++)
{
if (i < count)
{ {
nRW = actions[i].write ? 1 : 0; if (i < count)
DataOut = actions[i].value;
AddressOut = actions[i].address;
}
else
{
nRW = 0;
DataOut = 0;
AddressOut = 0;
}
do
{
JTAG_DEBUG("SC7 <= Address %02x Data %08x nRW %d", AddressOut, DataOut, nRW);
arm11_add_dr_scan_vc(asizeof(chain7_fields), chain7_fields, TAP_DRPAUSE);
jtag_execute_queue();
JTAG_DEBUG("SC7 => Address %02x Data %08x Ready %d", AddressIn, DataIn, Ready);
}
while (!Ready); /* 'nRW' is 'Ready' on read out */
if (i > 0)
{
if (actions[i - 1].address != AddressIn)
{
LOG_WARNING("Scan chain 7 shifted out unexpected address");
}
if (!actions[i - 1].write)
{
actions[i - 1].value = DataIn;
}
else
{
if (actions[i - 1].value != DataIn)
{ {
LOG_WARNING("Scan chain 7 shifted out unexpected data"); nRW = actions[i].write ? 1 : 0;
DataOut = actions[i].value;
AddressOut = actions[i].address;
}
else
{
nRW = 0;
DataOut = 0;
AddressOut = 0;
} }
}
}
}}
{size_t i; do
for (i = 0; i < count; i++) {
{ JTAG_DEBUG("SC7 <= Address %02x Data %08x nRW %d", AddressOut, DataOut, nRW);
JTAG_DEBUG("SC7 %02d: %02x %s %08x", i, actions[i].address, actions[i].write ? "<=" : "=>", actions[i].value);
}} arm11_add_dr_scan_vc(asizeof(chain7_fields), chain7_fields, TAP_DRPAUSE);
jtag_execute_queue();
JTAG_DEBUG("SC7 => Address %02x Data %08x Ready %d", AddressIn, DataIn, Ready);
}
while (!Ready); /* 'nRW' is 'Ready' on read out */
if (i > 0)
{
if (actions[i - 1].address != AddressIn)
{
LOG_WARNING("Scan chain 7 shifted out unexpected address");
}
if (!actions[i - 1].write)
{
actions[i - 1].value = DataIn;
}
else
{
if (actions[i - 1].value != DataIn)
{
LOG_WARNING("Scan chain 7 shifted out unexpected data");
}
}
}
}}
{size_t i;
for (i = 0; i < count; i++)
{
JTAG_DEBUG("SC7 %02d: %02x %s %08x", i, actions[i].address, actions[i].write ? "<=" : "=>", actions[i].value);
}}
} }
/** Clear VCR and all breakpoints and watchpoints via scan chain 7 /** Clear VCR and all breakpoints and watchpoints via scan chain 7
@ -745,29 +741,29 @@ void arm11_sc7_run(arm11_common_t * arm11, arm11_sc7_action_t * actions, size_t
*/ */
void arm11_sc7_clear_vbw(arm11_common_t * arm11) void arm11_sc7_clear_vbw(arm11_common_t * arm11)
{ {
arm11_sc7_action_t clear_bw[arm11->brp + arm11->wrp + 1]; arm11_sc7_action_t clear_bw[arm11->brp + arm11->wrp + 1];
arm11_sc7_action_t * pos = clear_bw; arm11_sc7_action_t * pos = clear_bw;
{size_t i; {size_t i;
for (i = 0; i < asizeof(clear_bw); i++) for (i = 0; i < asizeof(clear_bw); i++)
{ {
clear_bw[i].write = true; clear_bw[i].write = true;
clear_bw[i].value = 0; clear_bw[i].value = 0;
}} }}
{size_t i; {size_t i;
for (i = 0; i < arm11->brp; i++) for (i = 0; i < arm11->brp; i++)
(pos++)->address = ARM11_SC7_BCR0 + i; (pos++)->address = ARM11_SC7_BCR0 + i;
} }
{size_t i; {size_t i;
for (i = 0; i < arm11->wrp; i++) for (i = 0; i < arm11->wrp; i++)
(pos++)->address = ARM11_SC7_WCR0 + i; (pos++)->address = ARM11_SC7_WCR0 + i;
} }
(pos++)->address = ARM11_SC7_VCR; (pos++)->address = ARM11_SC7_VCR;
arm11_sc7_run(arm11, clear_bw, asizeof(clear_bw)); arm11_sc7_run(arm11, clear_bw, asizeof(clear_bw));
} }
/** Write VCR register /** Write VCR register
@ -777,14 +773,14 @@ void arm11_sc7_clear_vbw(arm11_common_t * arm11)
*/ */
void arm11_sc7_set_vcr(arm11_common_t * arm11, u32 value) void arm11_sc7_set_vcr(arm11_common_t * arm11, u32 value)
{ {
arm11_sc7_action_t set_vcr; arm11_sc7_action_t set_vcr;
set_vcr.write = true; set_vcr.write = true;
set_vcr.address = ARM11_SC7_VCR; set_vcr.address = ARM11_SC7_VCR;
set_vcr.value = value; set_vcr.value = value;
arm11_sc7_run(arm11, &set_vcr, 1); arm11_sc7_run(arm11, &set_vcr, 1);
} }
@ -798,15 +794,15 @@ void arm11_sc7_set_vcr(arm11_common_t * arm11, u32 value)
*/ */
void arm11_read_memory_word(arm11_common_t * arm11, u32 address, u32 * result) void arm11_read_memory_word(arm11_common_t * arm11, u32 address, u32 * result)
{ {
arm11_run_instr_data_prepare(arm11); arm11_run_instr_data_prepare(arm11);
/* MRC p14,0,r0,c0,c5,0 (r0 = address) */ /* MRC p14,0,r0,c0,c5,0 (r0 = address) */
arm11_run_instr_data_to_core1(arm11, 0xee100e15, address); arm11_run_instr_data_to_core1(arm11, 0xee100e15, address);
/* LDC p14,c5,[R0],#4 (DTR = [r0]) */ /* LDC p14,c5,[R0],#4 (DTR = [r0]) */
arm11_run_instr_data_from_core(arm11, 0xecb05e01, result, 1); arm11_run_instr_data_from_core(arm11, 0xecb05e01, result, 1);
arm11_run_instr_data_finish(arm11); arm11_run_instr_data_finish(arm11);
} }