- preserve cortex_m3 C_MASKINTS during resume/step
authorntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Thu, 20 Nov 2008 11:17:47 +0000 (11:17 +0000)
committerntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Thu, 20 Nov 2008 11:17:47 +0000 (11:17 +0000)
git-svn-id: svn://svn.berlios.de/openocd/trunk@1179 b42882b7-edfa-0310-969c-e2dbd0fdcd60

src/target/armv7m.c
src/target/cortex_m3.c

index 2258967a316821f2cdd7356cb115d8b3c45ef321..d4c6d3576f345c41fea80068b812326f2211fec1 100644 (file)
@@ -303,14 +303,14 @@ static int armv7m_run_and_wait(struct target_s *target, u32 entry_point, int tim
        u32 pc;
        int retval;
        /* This code relies on the target specific  resume() and  poll()->debug_entry()
-       sequence to write register values to the processor and the read them back */
+        * sequence to write register values to the processor and the read them back */
        if((retval = target_resume(target, 0, entry_point, 1, 1)) != ERROR_OK)
        {
                return retval;
        }
 
        retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
-       // If the target fails to halt due to the breakpoint, force a halt
+       /* If the target fails to halt due to the breakpoint, force a halt */
        if (retval != ERROR_OK || target->state != TARGET_HALTED)
        {
                if ((retval=target_halt(target))!=ERROR_OK)
@@ -322,7 +322,6 @@ static int armv7m_run_and_wait(struct target_s *target, u32 entry_point, int tim
                return ERROR_TARGET_TIMEOUT;
        }
 
-
        armv7m->load_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 15, &pc);
        if (pc != exit_point)
        {
index f94250b81562fdde228776fb88a63c15e8f974f2..d938210ad62d499736f31e4b22b4ed4902003631 100644 (file)
@@ -100,6 +100,21 @@ target_type_t cortexm3_target =
        .quit = cortex_m3_quit
 };
 
+int cortex_m3_write_debug_halt_mask(target_t *target, u32 mask_on, u32 mask_off)
+{
+       /* get pointers to arch-specific information */
+       armv7m_common_t *armv7m = target->arch_info;
+       cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
+       swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
+       
+       /* mask off status bits */
+       cortex_m3->dcb_dhcsr &= ~((0xFFFF << 16) | mask_off);
+       /* create new register mask */
+       cortex_m3->dcb_dhcsr |= DBGKEY | C_DEBUGEN | mask_on;
+       
+       return ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, cortex_m3->dcb_dhcsr);
+}
+
 int cortex_m3_clear_halt(target_t *target)
 {
        /* get pointers to arch-specific information */
@@ -107,6 +122,9 @@ int cortex_m3_clear_halt(target_t *target)
        cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
        swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
        
+       /* clear step if any */
+       cortex_m3_write_debug_halt_mask(target, C_HALT, C_STEP);
+       
        /* Read Debug Fault Status Register */
        ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
        /* Write Debug Fault Status Register to enable processing to resume ?? Try with and without this !! */
@@ -122,12 +140,19 @@ int cortex_m3_single_step_core(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;
-
+       u32 dhcsr_save;
+       
+       /* backup dhcsr reg */
+       dhcsr_save = cortex_m3->dcb_dhcsr;
+       
+       /* mask interrupts if not done already */
        if (!(cortex_m3->dcb_dhcsr & C_MASKINTS))
-               ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_MASKINTS | C_HALT | C_DEBUGEN );
-       ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_MASKINTS | C_STEP | C_DEBUGEN );
-       cortex_m3->dcb_dhcsr |= C_MASKINTS;
+               ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_MASKINTS | C_HALT | C_DEBUGEN);
+       ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_MASKINTS | C_STEP | C_DEBUGEN);
        LOG_DEBUG(" ");
+       
+       /* restore dhcsr reg */
+       cortex_m3->dcb_dhcsr = dhcsr_save;      
        cortex_m3_clear_halt(target);
        
        return ERROR_OK;
@@ -147,7 +172,7 @@ int cortex_m3_exec_opcode(target_t *target,u32 opcode, int len /* MODE, r0_inval
        ahbap_write_coreregister_u32(swjdp, 0x20000000, 15);
        cortex_m3_single_step_core(target);
        armv7m->core_cache->reg_list[15].dirty = armv7m->core_cache->reg_list[15].valid;
-       retvalue = ahbap_write_system_atomic_u32(swjdp, 0x20000000, savedram);          
+       retvalue = ahbap_write_system_atomic_u32(swjdp, 0x20000000, savedram);
        
        return retvalue;
 }
@@ -181,16 +206,21 @@ int cortex_m3_endreset_event(target_t *target)
        ahbap_read_system_atomic_u32(swjdp, DCB_DEMCR, &dcb_demcr);
        LOG_DEBUG("DCB_DEMCR = 0x%8.8x",dcb_demcr);
        
-       ahbap_write_system_u32(swjdp, DCB_DCRDR, 0 );
+       /* this regsiter is used for emulated dcc channel */
+       ahbap_write_system_u32(swjdp, DCB_DCRDR, 0);
        
        /* Enable debug requests */
        ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
        if (!(cortex_m3->dcb_dhcsr & C_DEBUGEN))
-               ahbap_write_system_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN );
+               ahbap_write_system_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN);
+       
+       /* clear any interrupt masking */
+       cortex_m3_write_debug_halt_mask(target, 0, C_MASKINTS);
+       
        /* Enable trace and dwt */
-       ahbap_write_system_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR );
+       ahbap_write_system_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR);
        /* Monitor bus faults */
-       ahbap_write_system_u32(swjdp, NVIC_SHCSR, SHCSR_BUSFAULTENA );
+       ahbap_write_system_u32(swjdp, NVIC_SHCSR, SHCSR_BUSFAULTENA);
 
        /* Enable FPB */
        target_write_u32(target, FP_CTRL, 3);
@@ -441,7 +471,7 @@ int cortex_m3_poll(target_t *target)
 #if 0
        /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script  */
        ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
-       LOG_DEBUG("dcb_dhcsr 0x%x, nvic_dfsr 0x%x, target->state: %s", cortex_m3->dcb_dhcsr, cortex_m3->nvic_dfsr, Jim_Nvp_value2name( nvp_target_state, target->state )->name );
+       LOG_DEBUG("dcb_dhcsr 0x%x, nvic_dfsr 0x%x, target->state: %s", cortex_m3->dcb_dhcsr, cortex_m3->nvic_dfsr, Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name );
 #endif
        
        return ERROR_OK;
@@ -449,13 +479,8 @@ int cortex_m3_poll(target_t *target)
 
 int cortex_m3_halt(target_t *target)
 {
-       /* get pointers to arch-specific information */
-       armv7m_common_t *armv7m = target->arch_info;
-       cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
-       swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
-       
        LOG_DEBUG("target->state: %s", 
-               Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name );
+               Jim_Nvp_value2name_simple(nvp_target_state, target->state )->name);
        
        if (target->state == TARGET_HALTED)
        {
@@ -487,7 +512,7 @@ int cortex_m3_halt(target_t *target)
        }
 
        /* Write to Debug Halting Control and Status Register */
-       ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN | C_HALT );
+       cortex_m3_write_debug_halt_mask(target, C_HALT, 0);
 
        target->debug_reason = DBG_REASON_DBGRQ;
        
@@ -504,10 +529,10 @@ int cortex_m3_soft_reset_halt(struct target_s *target)
        int retval, timeout = 0;
 
        /* Enter debug state on reset, cf. end_reset_event() */
-       ahbap_write_system_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET );
+       ahbap_write_system_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
        
        /* Request a reset */ 
-       ahbap_write_system_atomic_u32(swjdp, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_VECTRESET );
+       ahbap_write_system_atomic_u32(swjdp, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_VECTRESET);
        target->state = TARGET_RESET;
 
        /* registers are now invalid */
@@ -539,10 +564,8 @@ int cortex_m3_resume(struct target_s *target, int current, u32 address, int hand
 {
        /* get pointers to arch-specific information */
        armv7m_common_t *armv7m = target->arch_info;
-       cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
-       swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
        breakpoint_t *breakpoint = NULL;
-       u32 dcb_dhcsr, resume_pc;
+       u32 resume_pc;
        
        if (target->state != TARGET_HALTED)
        {
@@ -555,16 +578,13 @@ int cortex_m3_resume(struct target_s *target, int current, u32 address, int hand
                target_free_all_working_areas(target);
                cortex_m3_enable_breakpoints(target);
                cortex_m3_enable_watchpoints(target);
-
-               /* TODOLATER Interrupt handling/disable for debug execution, cache ... ... */
        }
        
-       dcb_dhcsr = DBGKEY | C_DEBUGEN;
        if (debug_execution)
        {
                /* Disable interrupts */
                /* We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
-                * This is probably the same inssue as Cortex-M3 Errata 377493: 
+                * This is probably the same issue as Cortex-M3 Errata  377493: 
                 * C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken. */
                buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_PRIMASK].value, 0, 32, 1);
                armv7m->core_cache->reg_list[ARMV7M_PRIMASK].dirty = 1;
@@ -601,13 +621,10 @@ int cortex_m3_resume(struct target_s *target, int current, u32 address, int hand
                        cortex_m3_set_breakpoint(target, breakpoint);
                }
        }
-
-       /* Set/Clear C_MASKINTS in a separate operation */
-       if ((cortex_m3->dcb_dhcsr & C_MASKINTS) != (dcb_dhcsr & C_MASKINTS))
-               ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, dcb_dhcsr | C_HALT );
        
        /* Restart core */
-       ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, dcb_dhcsr );
+       cortex_m3_write_debug_halt_mask(target, 0, C_HALT);
+       
        target->debug_reason = DBG_REASON_NOTHALTED;
 
        /* registers are now invalid */
@@ -616,13 +633,13 @@ int cortex_m3_resume(struct target_s *target, int current, u32 address, int hand
        {
                target->state = TARGET_RUNNING;
                target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
-               LOG_DEBUG("target resumed at 0x%x",resume_pc);
+               LOG_DEBUG("target resumed at 0x%x", resume_pc);
        }
        else
        {
                target->state = TARGET_DEBUG_RUNNING;
                target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
-               LOG_DEBUG("target debug resumed at 0x%x",resume_pc);
+               LOG_DEBUG("target debug resumed at 0x%x", resume_pc);
        }
        
        return ERROR_OK;
@@ -658,9 +675,8 @@ int cortex_m3_step(struct target_s *target, int current, u32 address, int handle
        
        target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
        
-       if (cortex_m3->dcb_dhcsr & C_MASKINTS)
-               ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN );
-       ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY| C_STEP | C_DEBUGEN);
+       /* set step and clear halt */
+       cortex_m3_write_debug_halt_mask(target, C_STEP, C_HALT);
        ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
 
        /* registers are now invalid */
@@ -697,7 +713,7 @@ int cortex_m3_assert_reset(target_t *target)
        /* Enable debug requests */
        ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
        if (!(cortex_m3->dcb_dhcsr & C_DEBUGEN))
-               ahbap_write_system_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN );
+               ahbap_write_system_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN);
                
        ahbap_write_system_u32(swjdp, DCB_DCRDR, 0 );
        
@@ -705,7 +721,7 @@ int cortex_m3_assert_reset(target_t *target)
        {
                /* Set/Clear C_MASKINTS in a separate operation */
                if (cortex_m3->dcb_dhcsr & C_MASKINTS)
-                       ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN | C_HALT );
+                       ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN | C_HALT);
        
                cortex_m3_clear_halt(target);
                                                        
@@ -715,7 +731,7 @@ int cortex_m3_assert_reset(target_t *target)
        else
        {
                /* Enter debug state on reset, cf. end_reset_event() */
-               ahbap_write_system_atomic_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET );
+               ahbap_write_system_atomic_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
        }
        
        /* following hack is to handle luminary reset
@@ -763,14 +779,14 @@ int cortex_m3_assert_reset(target_t *target)
        else
        {
                /* this causes the luminary device to reset using the watchdog */
-               ahbap_write_system_atomic_u32(swjdp, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ );
+               ahbap_write_system_atomic_u32(swjdp, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ);
                LOG_DEBUG("Using Luminary Reset: 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 */
                        u32 tmp;
-                       ahbap_read_system_atomic_u32(swjdp, NVIC_AIRCR, &tmp );
+                       ahbap_read_system_atomic_u32(swjdp, NVIC_AIRCR, &tmp);
                }
        }
        
@@ -792,7 +808,7 @@ int cortex_m3_assert_reset(target_t *target)
 int cortex_m3_deassert_reset(target_t *target)
 {              
        LOG_DEBUG("target->state: %s", 
-               Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
+               Jim_Nvp_value2name_simple(nvp_target_state, target->state )->name);
        
        /* deassert reset lines */
        jtag_add_reset(0, 0);

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)