]> git.sur5r.net Git - openocd/blobdiff - src/target/cortex_m3.c
retire daemon_startup
[openocd] / src / target / cortex_m3.c
index 6bdb1df67b4c4b899e5df0989bf39a04ecf088f3..e3ed4cfbb81dcbaf0875246844241b99b6364b41 100644 (file)
@@ -51,6 +51,12 @@ 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);
+
+#ifdef ARMV7_GDB_HACKS
+extern u8 armv7m_gdb_dummy_cpsr_value[];
+extern reg_t armv7m_gdb_dummy_cpsr_reg;
+#endif
 
 target_type_t cortexm3_target =
 {
@@ -75,6 +81,7 @@ target_type_t cortexm3_target =
        .write_memory = cortex_m3_write_memory,
        .bulk_write_memory = cortex_m3_bulk_write_memory,
        .checksum_memory = armv7m_checksum_memory,
+       .blank_check_memory = armv7m_blank_check_memory,
        
        .run_algorithm = armv7m_run_algorithm,
        
@@ -86,6 +93,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
 };
 
@@ -311,7 +319,15 @@ int cortex_m3_debug_entry(target_t *target)
        }
 
        xPSR = buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32);
-       
+
+#ifdef ARMV7_GDB_HACKS
+       /* copy real xpsr reg for gdb, setting thumb bit */
+       buf_set_u32(armv7m_gdb_dummy_cpsr_value, 0, 32, xPSR);
+       buf_set_u32(armv7m_gdb_dummy_cpsr_value, 5, 1, 1);
+       armv7m_gdb_dummy_cpsr_reg.valid = armv7m->core_cache->reg_list[ARMV7M_xPSR].valid;
+       armv7m_gdb_dummy_cpsr_reg.dirty = armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty;
+#endif
+
        /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
        if (xPSR & 0xf00)
        {
@@ -658,6 +674,7 @@ int cortex_m3_assert_reset(target_t *target)
        armv7m_common_t *armv7m = target->arch_info;
        cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
        swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
+       int assert_srst = 1;
        
        LOG_DEBUG("target->state: %s", target_state_strings[target->state]);
        
@@ -674,7 +691,7 @@ int cortex_m3_assert_reset(target_t *target)
                
        ahbap_write_system_u32(swjdp, DCB_DCRDR, 0 );
        
-       if (target->reset_mode == RESET_RUN)
+       if (!target->reset_halt)
        {
                /* Set/Clear C_MASKINTS in a separate operation */
                if (cortex_m3->dcb_dhcsr & C_MASKINTS)
@@ -691,13 +708,53 @@ int cortex_m3_assert_reset(target_t *target)
                ahbap_write_system_atomic_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET );
        }
        
-       if (jtag_reset_config & RESET_SRST_PULLS_TRST)
+       /* 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 */
+               
+       if (strcmp(cortex_m3->variant, "lm3s") == 0)
+       {
+               /* get revision of lm3s target, only early silicon has this issue
+                * Fury Rev B, DustDevil Rev B, Tempest all ok */
+               
+               u32 did0;
+               
+               if (target_read_u32(target, 0x400fe000, &did0) == ERROR_OK)
+               {
+                       switch ((did0 >> 16) & 0xff)
+                       {
+                               case 0:
+                                       /* all Sandstorm suffer issue */
+                                       assert_srst = 0;
+                                       break;
+                               
+                               case 1:
+                               case 3:
+                                       /* only Fury/DustDevil rev A suffer reset problems */
+                                       if (((did0 >> 8) & 0xff) == 0)
+                                               assert_srst = 0;
+                                       break;
+                       }
+               }
+       }
+       
+       if (assert_srst)
        {
-               jtag_add_reset(1, 1);
+               /* default to asserting srst */
+               if (jtag_reset_config & RESET_SRST_PULLS_TRST)
+               {
+                       jtag_add_reset(1, 1);
+               }
+               else
+               {
+                       jtag_add_reset(0, 1);
+               }
        }
        else
        {
-               jtag_add_reset(0, 1);
+               /* this causes the luminary device to reset using the watchdog */
+               ahbap_write_system_atomic_u32(swjdp, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ );
+               LOG_DEBUG("Using Luminary Reset: SYSRESETREQ");
        }
        
        target->state = TARGET_RESET;
@@ -747,7 +804,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 +886,18 @@ 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;
+#ifdef ARMV7_GDB_HACKS
+               if (breakpoint->length != 2) {
+                       /* XXX Hack: Replace all breakpoints with length != 2 with
+                        * a hardware breakpoint. */ 
+                       breakpoint->type = BKPT_HARD;
+                       breakpoint->length = 2;
+               }
+#endif
        }
 
        if ((breakpoint->type == BKPT_HARD) && (breakpoint->address >= 0x20000000))
@@ -1103,6 +1168,17 @@ 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;
 
+#ifdef ARMV7_GDB_HACKS
+       /* 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;
+#endif
+        
        if ((type == ARMV7M_REGISTER_CORE_GP) && (num <= ARMV7M_PSP))
        {
                retval = ahbap_write_coreregister_u32(swjdp, value, num);
@@ -1227,6 +1303,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 +1317,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);
@@ -1392,6 +1479,15 @@ int cortex_m3_init_arch_info(target_t *target, cortex_m3_common_t *cortex_m3, in
        armv7m->pre_restore_context = NULL;
        armv7m->post_restore_context = NULL;
        
+       if (variant)
+       {
+               cortex_m3->variant = strdup(variant);
+       }
+       else
+       {
+               cortex_m3->variant = strdup("");
+       }
+       
        armv7m_init_arch_info(target, armv7m);  
        armv7m->arch_info = cortex_m3;
        armv7m->load_core_reg_u32 = cortex_m3_load_core_reg_u32;
@@ -1422,7 +1518,6 @@ int cortex_m3_target_command(struct command_context_s *cmd_ctx, char *cmd, char
                variant = args[4];
        
        cortex_m3_init_arch_info(target, cortex_m3, chain_pos, variant);
-       cortex_m3_register_commands(cmd_ctx);
        
        return ERROR_OK;
 }