uint32_t dcrdr;
/* because the DCB_DCRDR is used for the emulated dcc channel
- * we gave to save/restore the DCB_DCRDR when used */
+ * we have to save/restore the DCB_DCRDR when used */
mem_ap_read_u32(swjdp, DCB_DCRDR, &dcrdr);
dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRDR & 0xFFFFFFF0);
dap_ap_read_reg_u32(swjdp, AP_REG_BD0 | (DCB_DCRDR & 0xC), value);
- mem_ap_write_u32(swjdp, DCB_DCRDR, dcrdr);
retval = swjdp_transaction_endcheck(swjdp);
+
+ /* restore DCB_DCRDR - this needs to be in a seperate
+ * transaction otherwise the emulated DCC channel breaks */
+ if (retval == ERROR_OK)
+ retval = mem_ap_write_atomic_u32(swjdp, DCB_DCRDR, dcrdr);
+
return retval;
}
uint32_t dcrdr;
/* because the DCB_DCRDR is used for the emulated dcc channel
- * we gave to save/restore the DCB_DCRDR when used */
+ * we have to save/restore the DCB_DCRDR when used */
mem_ap_read_u32(swjdp, DCB_DCRDR, &dcrdr);
dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRSR & 0xFFFFFFF0);
dap_ap_write_reg_u32(swjdp, AP_REG_BD0 | (DCB_DCRSR & 0xC), regnum | DCRSR_WnR);
- mem_ap_write_u32(swjdp, DCB_DCRDR, dcrdr);
retval = swjdp_transaction_endcheck(swjdp);
+
+ /* restore DCB_DCRDR - this needs to be in a seperate
+ * transaction otherwise the emulated DCC channel breaks */
+ if (retval == ERROR_OK)
+ retval = mem_ap_write_atomic_u32(swjdp, DCB_DCRDR, dcrdr);
+
return retval;
}
-
int cortex_m3_write_debug_halt_mask(target_t *target, uint32_t mask_on, uint32_t mask_off)
{
/* get pointers to arch-specific information */
/* Single step past breakpoint at current address */
if ((breakpoint = breakpoint_find(target, resume_pc)))
{
- LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (ID: %d)",
+ LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (ID: %d)",
breakpoint->address,
breakpoint->unique_id );
cortex_m3_unset_breakpoint(target, breakpoint);
target_state_name(target));
enum reset_types jtag_reset_config = jtag_get_reset_config();
+
+ /*
+ * We can reset Cortex-M3 targets using just the NVIC without
+ * requiring SRST, getting a SoC reset (or a core-only reset)
+ * instead of a system reset.
+ */
if (!(jtag_reset_config & RESET_HAS_SRST))
- {
- LOG_ERROR("Can't assert SRST");
- return ERROR_FAIL;
- }
+ assert_srst = 0;
/* Enable debug requests */
mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
mem_ap_write_atomic_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
}
- /* following hack is to handle luminary reset
- * when srst is asserted the luminary device seesm to also clear the debug registers
- * which does not match the armv7 debug TRM */
-
+ /*
+ * When nRST is asserted on most Stellaris devices, it clears some of
+ * the debug state. The ARMv7M and Cortex-M3 TRMs say that's wrong;
+ * and OpenOCD depends on those TRMs. So we won't use SRST on those
+ * chips. (Only power-on reset should affect debug state, beyond a
+ * few specified bits; not the chip's nRST input, wired to SRST.)
+ *
+ * REVISIT current errata specs don't seem to cover this issue.
+ * Do we have more details than this email?
+ * https://lists.berlios.de/pipermail
+ * /openocd-development/2008-August/003065.html
+ */
if (strcmp(target->variant, "lm3s") == 0)
{
- /* get revision of lm3s target, only early silicon has this issue
- * Fury Rev B, DustDevil Rev B, Tempest all ok */
-
+ /* Check for silicon revisions with the issue. */
uint32_t did0;
if (target_read_u32(target, 0x400fe000, &did0) == ERROR_OK)
case 1:
case 3:
- /* only Fury/DustDevil rev A suffer reset problems */
+ /* Fury and DustDevil rev A have
+ * this nRST problem. It should
+ * be fixed in rev B silicon.
+ */
if (((did0 >> 8) & 0xff) == 0)
assert_srst = 0;
break;
+ case 4:
+ /* Tempest should be fine. */
+ break;
}
}
}
}
else
{
- /* this causes the luminary device to reset using the watchdog */
- mem_ap_write_atomic_u32(swjdp, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ);
- LOG_DEBUG("Using Luminary Reset: SYSRESETREQ");
+ /* Use a standard Cortex-M3 software reset mechanism.
+ * SYSRESETREQ will reset SoC peripherals outside the
+ * core, like watchdog timers, if the SoC wires it up
+ * correctly. Else VECRESET can reset just the core.
+ */
+ mem_ap_write_atomic_u32(swjdp, NVIC_AIRCR,
+ AIRCR_VECTKEY | AIRCR_SYSRESETREQ);
+ LOG_DEBUG("Using Cortex-M3 SYSRESETREQ");
{
- /* I do not know why this is necessary, but it fixes strange effects
- * (step/resume cause a NMI after reset) on LM3S6918 -- Michael Schwingen */
+ /* I do not know why this is necessary, but it
+ * fixes strange effects (step/resume cause NMI
+ * after reset) on LM3S6918 -- Michael Schwingen
+ */
uint32_t tmp;
mem_ap_read_atomic_u32(swjdp, NVIC_AIRCR, &tmp);
}
breakpoint->set = 0x11; /* Any nice value but 0 */
}
- LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32 " Length: %d (set=%d)",
+ LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32 " Length: %d (set=%d)",
breakpoint->unique_id,
(int)(breakpoint->type),
breakpoint->address,
return ERROR_OK;
}
- LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32 " Length: %d (set=%d)",
+ LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32 " Length: %d (set=%d)",
breakpoint->unique_id,
(int)(breakpoint->type),
breakpoint->address,
watchpoint->unique_id );
return ERROR_OK;
}
- LOG_DEBUG("Watchpoint (ID: %d) address: 0x%08" PRIx32 " set=%d ",
+ LOG_DEBUG("Watchpoint (ID: %d) address: 0x%08" PRIx32 " set=%d ",
watchpoint->unique_id, watchpoint->address, watchpoint->set );
return ERROR_OK;
return ERROR_OK;
}
- LOG_DEBUG("Watchpoint (ID: %d) address: 0x%08" PRIx32 " set=%d ",
+ LOG_DEBUG("Watchpoint (ID: %d) address: 0x%08" PRIx32 " set=%d ",
watchpoint->unique_id, watchpoint->address,watchpoint->set );
dwt_num = watchpoint->set - 1;
int retval = ERROR_OK;
target_t *target = get_current_target(cmd_ctx);
uint32_t address;
- unsigned long count;
+ unsigned long count = 1;
arm_instruction_t cur_instruction;
- if (argc != 2) {
+ errno = 0;
+ switch (argc) {
+ case 2:
+ count = strtoul(args[1], NULL, 0);
+ if (errno)
+ return ERROR_FAIL;
+ /* FALL THROUGH */
+ case 1:
+ address = strtoul(args[0], NULL, 0);
+ if (errno)
+ return ERROR_FAIL;
+ break;
+ default:
command_print(cmd_ctx,
- "usage: cortex_m3 disassemble <address> <count>");
+ "usage: cortex_m3 disassemble <address> [<count>]");
return ERROR_OK;
}
- errno = 0;
- address = strtoul(args[0], NULL, 0);
- if (errno)
- return ERROR_FAIL;
- count = strtoul(args[1], NULL, 0);
- if (errno)
- return ERROR_FAIL;
-
while (count--) {
retval = thumb2_opcode(target, address, &cur_instruction);
if (retval != ERROR_OK)
register_command(cmd_ctx, cortex_m3_cmd, "disassemble",
handle_cortex_m3_disassemble_command, COMMAND_EXEC,
- "disassemble Thumb2 instructions <address> <count>");
+ "disassemble Thumb2 instructions <address> [<count>]");
register_command(cmd_ctx, cortex_m3_cmd, "maskisr",
handle_cortex_m3_mask_interrupts_command, COMMAND_EXEC,
"mask cortex_m3 interrupts ['on'|'off']");