bool arm11_config_memwrite_burst = true;
bool arm11_config_memwrite_error_fatal = true;
uint32_t arm11_vcr = 0;
-bool arm11_config_memrw_no_increment = false;
bool arm11_config_step_irq_enable = false;
bool arm11_config_hardware_step = false;
if (DSCR & (ARM11_DSCR_RDTR_FULL | ARM11_DSCR_WDTR_FULL))
{
+ /*
+ The wDTR/rDTR two registers that are used to send/receive data to/from
+ the core in tandem with corresponding instruction codes that are
+ written into the core. The RDTR FULL/WDTR FULL flag indicates that the
+ registers hold data that was written by one side (CPU or JTAG) and not
+ read out by the other side.
+ */
LOG_ERROR("wDTR/rDTR inconsistent (DSCR %08" PRIx32 ")", DSCR);
+ return ERROR_FAIL;
}
}
arm11_common_t * arm11 = target->arch_info;
- if (arm11->trst_active)
- return ERROR_OK;
-
uint32_t dscr;
CHECK_RETVAL(arm11_read_DSCR(arm11, &dscr));
return ERROR_OK;
}
- if (arm11->trst_active)
- {
- arm11->halt_requested = true;
- return ERROR_OK;
- }
-
arm11_add_IR(arm11, ARM11_HALT, TAP_IDLE);
CHECK_RETVAL(jtag_execute_queue());
return ERROR_OK;
}
-/* target reset control */
-int arm11_assert_reset(struct target_s *target)
+int arm11_assert_reset(target_t *target)
{
FNC_INFO;
-#if 0
- /* assert reset lines */
- /* resets only the DBGTAP, not the ARM */
-
- jtag_add_reset(1, 0);
- jtag_add_sleep(5000);
-
- arm11_common_t * arm11 = target->arch_info;
- arm11->trst_active = true;
-#endif
-
+ /* FIX! we really should assert srst here, but
+ * how do we reset the target into the halted state?
+ *
+ * Also arm11 behaves "funny" when srst is asserted
+ * (as of writing the rules are not understood).
+ */
if (target->reset_halt)
{
CHECK_RETVAL(target_halt(target));
return ERROR_OK;
}
-int arm11_deassert_reset(struct target_s *target)
+int arm11_deassert_reset(target_t *target)
{
- FNC_INFO;
-
-#if 0
- LOG_DEBUG("target->state: %s",
- target_state_name(target));
-
-
- /* deassert reset lines */
- jtag_add_reset(0, 0);
-
- arm11_common_t * arm11 = target->arch_info;
- arm11->trst_active = false;
-
- if (arm11->halt_requested)
- return arm11_halt(target);
-#endif
-
return ERROR_OK;
}
/* target memory access
* size: 1 = byte (8bit), 2 = half-word (16bit), 4 = word (32bit)
* count: number of items of <size>
+ *
+ * arm11_config_memrw_no_increment - in the future we may want to be able
+ * to read/write a range of data to a "port". a "port" is an action on
+ * read memory address for some peripheral.
*/
-int arm11_read_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
+int arm11_read_memory_inner(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer,
+ bool arm11_config_memrw_no_increment)
{
/** \todo TODO: check if buffer cast to uint32_t* and uint16_t* might cause alignment problems */
int retval;
return arm11_run_instr_data_finish(arm11);
}
-int arm11_write_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
+int arm11_read_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
+{
+ return arm11_read_memory_inner(target, address, size, count, buffer, false);
+}
+
+/*
+* arm11_config_memrw_no_increment - in the future we may want to be able
+* to read/write a range of data to a "port". a "port" is an action on
+* read memory address for some peripheral.
+*/
+int arm11_write_memory_inner(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer,
+ bool arm11_config_memrw_no_increment)
{
int retval;
FNC_INFO;
arm11_common_t * arm11 = target->arch_info;
- arm11_run_instr_data_prepare(arm11);
+ retval = arm11_run_instr_data_prepare(arm11);
+ if (retval != ERROR_OK)
+ return retval;
/* MRC p14,0,r0,c0,c5,0 */
retval = arm11_run_instr_data_to_core1(arm11, 0xee100e15, address);
if (retval != ERROR_OK)
return retval;
+ /* burst writes are not used for single words as those may well be
+ * reset init script writes.
+ *
+ * The other advantage is that as burst writes are default, we'll
+ * now exercise both burst and non-burst code paths with the
+ * default settings, increasing code coverage.
+ */
+ bool burst = arm11_config_memwrite_burst && (count > 1);
+
switch (size)
{
case 1:
/** \todo TODO: buffer cast to uint32_t* causes alignment warnings */
uint32_t *words = (uint32_t*)buffer;
- if (!arm11_config_memwrite_burst)
+ if (!burst)
{
/* STC p14,c5,[R0],#4 */
/* STC p14,c5,[R0]*/
if (address + size * count != r0)
{
- LOG_ERROR("Data transfer failed. Expected end address 0x%08x, got 0x%08x",
- address + size * count, r0);
+ LOG_ERROR("Data transfer failed. Expected end "
+ "address 0x%08x, got 0x%08x",
+ (unsigned) (address + size * count),
+ (unsigned) r0);
- if (arm11_config_memwrite_burst)
+ if (burst)
LOG_ERROR("use 'arm11 memwrite burst disable' to disable fast burst mode");
if (arm11_config_memwrite_error_fatal)
return arm11_run_instr_data_finish(arm11);
}
+int arm11_write_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
+{
+ return arm11_write_memory_inner(target, address, size, count, buffer, false);
+}
/* write target memory in multiples of 4 byte, optimized for writing large quantities of data */
int arm11_bulk_write_memory(struct target_s *target, uint32_t address, uint32_t count, uint8_t *buffer)
/* talk to the target and set things up */
int arm11_examine(struct target_s *target)
{
+ int retval;
+
FNC_INFO;
arm11_common_t * arm11 = target->arch_info;
* as suggested by the spec.
*/
- arm11_check_init(arm11, NULL);
+ retval = arm11_check_init(arm11, NULL);
+ if (retval != ERROR_OK)
+ return retval;
target_set_examined(target);
BOOL_WRAPPER(memwrite_burst, "memory write burst mode")
BOOL_WRAPPER(memwrite_error_fatal, "fatal error mode for memory writes")
-BOOL_WRAPPER(memrw_no_increment, "\"no increment\" mode for memory transfers")
BOOL_WRAPPER(step_irq_enable, "IRQs while stepping")
BOOL_WRAPPER(hardware_step, "hardware single step")
register_command(cmd_ctx, top_cmd, "mrc",
arm11_handle_mrc, COMMAND_ANY,
"Read Coprocessor register. mrc <jtag_target> <coprocessor> <opcode 1> <CRn> <CRm> <opcode 2>. All parameters are numbers only.");
- register_command(cmd_ctx, top_cmd, "no_increment",
- arm11_handle_bool_memrw_no_increment, COMMAND_ANY,
- "Don't increment address on multi-read/-write"
- " (default: disabled)");
register_command(cmd_ctx, top_cmd, "step_irq_enable",
arm11_handle_bool_step_irq_enable, COMMAND_ANY,
"Enable interrupts while stepping"