* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
* *
* Cortex-M3(tm) TRM, ARM DDI 0337E (r1p1) and 0337G (r2p0) *
/* Enable debug requests */
int retval;
retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr);
- if (retval != ERROR_OK)
- return retval;
- if (!(cortex_m->dcb_dhcsr & C_DEBUGEN)) {
+ /* Store important errors instead of failing and proceed to reset assert */
+
+ if (retval != ERROR_OK || !(cortex_m->dcb_dhcsr & C_DEBUGEN))
retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DHCSR, DBGKEY | C_DEBUGEN);
- if (retval != ERROR_OK)
- return retval;
- }
/* If the processor is sleeping in a WFI or WFE instruction, the
* C_HALT bit must be asserted to regain control */
- if (cortex_m->dcb_dhcsr & S_SLEEP) {
+ if (retval == ERROR_OK && (cortex_m->dcb_dhcsr & S_SLEEP))
retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN);
- if (retval != ERROR_OK)
- return retval;
- }
- retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRDR, 0);
- if (retval != ERROR_OK)
- return retval;
+ mem_ap_write_u32(armv7m->debug_ap, DCB_DCRDR, 0);
+ /* Ignore less important errors */
if (!target->reset_halt) {
/* Set/Clear C_MASKINTS in a separate operation */
- if (cortex_m->dcb_dhcsr & C_MASKINTS) {
- retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DHCSR,
+ if (cortex_m->dcb_dhcsr & C_MASKINTS)
+ mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DHCSR,
DBGKEY | C_DEBUGEN | C_HALT);
- if (retval != ERROR_OK)
- return retval;
- }
/* clear any debug flags before resuming */
cortex_m_clear_halt(target);
* bad vector table entries. Should this include MMERR or
* other flags too?
*/
- retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DEMCR,
+ int retval2;
+ retval2 = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DEMCR,
TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
- if (retval != ERROR_OK)
- return retval;
+ if (retval != ERROR_OK || retval2 != ERROR_OK)
+ LOG_INFO("AP write error, reset will not halt");
}
if (jtag_reset_config & RESET_HAS_SRST) {
/* default to asserting srst */
if (!srst_asserted)
adapter_assert_reset();
+
+ /* srst is asserted, ignore AP access errors */
+ retval = ERROR_OK;
} else {
/* Use a standard Cortex-M3 software reset mechanism.
* We default to using VECRESET as it is supported on all current cores.
"handler to reset any peripherals or configure hardware srst support.");
}
- retval = mem_ap_write_atomic_u32(armv7m->debug_ap, NVIC_AIRCR,
+ int retval3;
+ retval3 = mem_ap_write_atomic_u32(armv7m->debug_ap, NVIC_AIRCR,
AIRCR_VECTKEY | ((reset_config == CORTEX_M_RESET_SYSRESETREQ)
? AIRCR_SYSRESETREQ : AIRCR_VECTRESET));
- if (retval != ERROR_OK)
+ if (retval3 != ERROR_OK)
LOG_DEBUG("Ignoring AP write error right after reset");
- retval = dap_dp_init(armv7m->debug_ap->dap);
- if (retval != ERROR_OK) {
+ retval3 = dap_dp_init(armv7m->debug_ap->dap);
+ if (retval3 != ERROR_OK)
LOG_ERROR("DP initialisation failed");
- return retval;
- }
- {
+ else {
/* 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;
- retval = mem_ap_read_atomic_u32(armv7m->debug_ap, NVIC_AIRCR, &tmp);
- if (retval != ERROR_OK)
- return retval;
+ mem_ap_read_atomic_u32(armv7m->debug_ap, NVIC_AIRCR, &tmp);
}
}
register_cache_invalidate(cortex_m->armv7m.arm.core_cache);
+ /* now return stored error code if any */
+ if (retval != ERROR_OK)
+ return retval;
+
if (target->reset_halt) {
retval = target_halt(target);
if (retval != ERROR_OK)
#define MVFR0_DEFAULT_M4 0x10110021
#define MVFR1_DEFAULT_M4 0x11000011
+#define MVFR0_DEFAULT_M7_SP 0x10110021
+#define MVFR0_DEFAULT_M7_DP 0x10110221
+#define MVFR1_DEFAULT_M7_SP 0x11000011
+#define MVFR1_DEFAULT_M7_DP 0x12000011
+
int cortex_m_examine(struct target *target)
{
int retval;
struct adiv5_dap *swjdp = cortex_m->armv7m.arm.dap;
struct armv7m_common *armv7m = target_to_armv7m(target);
- retval = dap_dp_init(swjdp);
- if (retval != ERROR_OK) {
- LOG_ERROR("Could not initialize the debug port");
- return retval;
- }
-
- /* Search for the MEM-AP */
- retval = dap_find_ap(swjdp, AP_TYPE_AHB_AP, &armv7m->debug_ap);
- if (retval != ERROR_OK) {
- LOG_ERROR("Could not find MEM-AP to control the core");
- return retval;
- }
-
- /* Leave (only) generic DAP stuff for debugport_init(); */
- armv7m->debug_ap->memaccess_tck = 8;
-
/* stlink shares the examine handler but does not support
* all its calls */
if (!armv7m->stlink) {
+ retval = dap_dp_init(swjdp);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Could not initialize the debug port");
+ return retval;
+ }
+
+ /* Search for the MEM-AP */
+ retval = dap_find_ap(swjdp, AP_TYPE_AHB_AP, &armv7m->debug_ap);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Could not find MEM-AP to control the core");
+ return retval;
+ }
+
+ /* Leave (only) generic DAP stuff for debugport_init(); */
+ armv7m->debug_ap->memaccess_tck = 8;
+
retval = mem_ap_init(armv7m->debug_ap);
if (retval != ERROR_OK)
return retval;
LOG_DEBUG("Cortex-M%d r%" PRId8 "p%" PRId8 " processor detected",
i, (uint8_t)((cpuid >> 20) & 0xf), (uint8_t)((cpuid >> 0) & 0xf));
+ if (i == 7) {
+ uint8_t rev, patch;
+ rev = (cpuid >> 20) & 0xf;
+ patch = (cpuid >> 0) & 0xf;
+ if ((rev == 0) && (patch < 2))
+ LOG_WARNING("Silicon bug: single stepping will enter pending exception handler!");
+ }
LOG_DEBUG("cpuid: 0x%8.8" PRIx32 "", cpuid);
- /* test for floating point feature on cortex-m4 */
if (i == 4) {
target_read_u32(target, MVFR0, &mvfr0);
target_read_u32(target, MVFR1, &mvfr1);
+ /* test for floating point feature on Cortex-M4 */
if ((mvfr0 == MVFR0_DEFAULT_M4) && (mvfr1 == MVFR1_DEFAULT_M4)) {
LOG_DEBUG("Cortex-M%d floating point feature FPv4_SP found", i);
armv7m->fp_feature = FPv4_SP;
}
+ } else if (i == 7) {
+ target_read_u32(target, MVFR0, &mvfr0);
+ target_read_u32(target, MVFR1, &mvfr1);
+
+ /* test for floating point features on Cortex-M7 */
+ if ((mvfr0 == MVFR0_DEFAULT_M7_SP) && (mvfr1 == MVFR1_DEFAULT_M7_SP)) {
+ LOG_DEBUG("Cortex-M%d floating point feature FPv5_SP found", i);
+ armv7m->fp_feature = FPv5_SP;
+ } else if ((mvfr0 == MVFR0_DEFAULT_M7_DP) && (mvfr1 == MVFR1_DEFAULT_M7_DP)) {
+ LOG_DEBUG("Cortex-M%d floating point feature FPv5_DP found", i);
+ armv7m->fp_feature = FPv5_DP;
+ }
} else if (i == 0) {
/* Cortex-M0 does not support unaligned memory access */
armv7m->arm.is_armv6m = true;
}
- if (armv7m->fp_feature != FPv4_SP &&
+ if (armv7m->fp_feature == FP_NONE &&
armv7m->arm.core_cache->num_regs > ARMV7M_NUM_CORE_REGS_NOFP) {
/* free unavailable FPU registers */
size_t idx;
armv7m->arm.core_cache->num_regs = ARMV7M_NUM_CORE_REGS_NOFP;
}
- if (i == 4 || i == 3) {
- /* Cortex-M3/M4 has 4096 bytes autoincrement range */
- armv7m->debug_ap->tar_autoincr_block = (1 << 12);
+ if (!armv7m->stlink) {
+ if (i == 3 || i == 4)
+ /* Cortex-M3/M4 have 4096 bytes autoincrement range,
+ * s. ARM IHI 0031C: MEM-AP 7.2.2 */
+ armv7m->debug_ap->tar_autoincr_block = (1 << 12);
+ else if (i == 7)
+ /* Cortex-M7 has only 1024 bytes autoincrement range */
+ armv7m->debug_ap->tar_autoincr_block = (1 << 10);
}
/* Configure trace modules */
armv7m->arm.dap = tap->dap;
- /* Leave (only) generic DAP stuff for debugport_init(); */
- tap->dap->ap[dap_ap_get_select(tap->dap)].memaccess_tck = 8;
-
/* register arch-specific functions */
armv7m->examine_debug_reason = cortex_m_examine_debug_reason;