Nicolas Pitre fixed regression.
[fw/openocd] / src / target / cortex_m3.c
index 6bdb1df67b4c4b899e5df0989bf39a04ecf088f3..fb303a8be2943c9017e7604ef8b917d3eb3c8853 100644 (file)
@@ -51,6 +51,7 @@ int cortex_m3_quit();
 int cortex_m3_load_core_reg_u32(target_t *target, enum armv7m_regtype type, u32 num, u32 *value);
 int cortex_m3_store_core_reg_u32(target_t *target, enum armv7m_regtype type, u32 num, u32 value);
 int cortex_m3_target_request_data(target_t *target, u32 size, u8 *buffer);
+int cortex_m3_examine(struct command_context_s *cmd_ctx, struct target_s *target);
 
 target_type_t cortexm3_target =
 {
@@ -86,6 +87,7 @@ target_type_t cortexm3_target =
        .register_commands = cortex_m3_register_commands,
        .target_command = cortex_m3_target_command,
        .init_target = cortex_m3_init_target,
+       .examine = cortex_m3_examine,
        .quit = cortex_m3_quit
 };
 
@@ -747,7 +749,7 @@ int cortex_m3_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
                LOG_WARNING("breakpoint already set");
                return ERROR_OK;
        }
-
+    
        if (cortex_m3->auto_bp_type)
        {
                breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
@@ -829,10 +831,16 @@ int cortex_m3_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
        /* get pointers to arch-specific information */
        armv7m_common_t *armv7m = target->arch_info;
        cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
-       
+
        if (cortex_m3->auto_bp_type)
        {
                breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
+        if (breakpoint->length != 2) {
+            // XXX Hack: Replace all breakpoints with length != 2 with
+            // a hardware breakpoint. 
+            breakpoint->type = BKPT_HARD;
+            breakpoint->length = 2;
+        }
        }
 
        if ((breakpoint->type == BKPT_HARD) && (breakpoint->address >= 0x20000000))
@@ -1103,6 +1111,14 @@ int cortex_m3_store_core_reg_u32(struct target_s *target, enum armv7m_regtype ty
        cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
        swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
 
+    // If the LR register is being modified, make sure it will put us
+    // in "thumb" mode, or an INVSTATE exception will occur. This is a
+    // hack to deal with the fact that gdb will sometimes "forge"
+    // return addresses, and doesn't set the LSB correctly (i.e., when
+    // printing expressions containing function calls, it sets LR=0.)
+    if (num==14)
+        value |= 0x01;
+
        if ((type == ARMV7M_REGISTER_CORE_GP) && (num <= ARMV7M_PSP))
        {
                retval = ahbap_write_coreregister_u32(swjdp, value, num);
@@ -1227,6 +1243,13 @@ void cortex_m3_build_reg_cache(target_t *target)
 
 int cortex_m3_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
 {
+       cortex_m3_build_reg_cache(target);
+       return ERROR_OK;
+}
+
+int cortex_m3_examine(struct command_context_s *cmd_ctx, struct target_s *target)
+{
+       int retval;
        u32 cpuid, fpcr, dwtcr, ictr;
        int i;
        
@@ -1234,12 +1257,16 @@ int cortex_m3_init_target(struct command_context_s *cmd_ctx, struct target_s *ta
        armv7m_common_t *armv7m = target->arch_info;
        cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
        swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
+       
+       target->type->examined = 1;
 
-       cortex_m3_build_reg_cache(target);
-       ahbap_debugport_init(swjdp);
+       if ((retval=ahbap_debugport_init(swjdp))!=ERROR_OK)
+               return retval;
 
        /* Read from Device Identification Registers */
-       target_read_u32(target, CPUID, &cpuid);
+       if ((retval=target_read_u32(target, CPUID, &cpuid))!=ERROR_OK)
+               return retval;
+       
        if (((cpuid >> 4) & 0xc3f) == 0xc23)
                LOG_DEBUG("CORTEX-M3 processor detected");
        LOG_DEBUG("cpuid: 0x%8.8x", cpuid);
@@ -1280,6 +1307,7 @@ int cortex_m3_init_target(struct command_context_s *cmd_ctx, struct target_s *ta
        return ERROR_OK;
 }
 
+
 int cortex_m3_quit()
 {
        
@@ -1435,3 +1463,4 @@ int cortex_m3_register_commands(struct command_context_s *cmd_ctx)
        
        return retval;
 }
+