]> git.sur5r.net Git - openocd/blobdiff - src/target/cortex_m3.c
Uwe Hermann tightned up comments, etc. to follow OpenOCD policy
[openocd] / src / target / cortex_m3.c
index 4b383274d93ef2ed79aeb24e1a56f2084a2b26d1..91911f9ee990d0b08560e23dbe722d0c61ccab40 100644 (file)
@@ -1,6 +1,7 @@
 /***************************************************************************
  *   Copyright (C) 2005 by Dominic Rath                                    *
  *   Dominic.Rath@gmx.de                                                   *
+ *                                                                         *
  *   Copyright (C) 2006 by Magnus Lundin                                   *
  *   lundin@mlu.mine.nu                                                    *
  *                                                                         *
@@ -30,6 +31,7 @@
 
 #include "register.h"
 #include "target.h"
+#include "target_request.h"
 #include "log.h"
 #include "jtag.h"
 #include "arm_jtag.h"
@@ -50,7 +52,8 @@ int cortex_m3_init_target(struct command_context_s *cmd_ctx, struct target_s *ta
 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);
+
 target_type_t cortexm3_target =
 {
        .name = "cortex_m3",
@@ -58,8 +61,8 @@ target_type_t cortexm3_target =
        .poll = cortex_m3_poll,
        .arch_state = armv7m_arch_state,
 
-       .target_request_data = NULL,
-
+       .target_request_data = cortex_m3_target_request_data,
+       
        .halt = cortex_m3_halt,
        .resume = cortex_m3_resume,
        .step = cortex_m3_step,
@@ -135,7 +138,7 @@ int cortex_m3_exec_opcode(target_t *target,u32 opcode, int len /* MODE, r0_inval
        ahbap_write_system_u32(swjdp, 0x20000000, opcode);
        ahbap_write_coreregister_u32(swjdp, 0x20000000, 15);
        cortex_m3_single_step_core(target);
-       armv7m->core_cache->reg_list[15].dirty = 1;
+       armv7m->core_cache->reg_list[15].dirty = armv7m->core_cache->reg_list[15].valid;
        retvalue = ahbap_write_system_atomic_u32(swjdp, 0x20000000, savedram);          
        
        return retvalue;
@@ -168,6 +171,8 @@ int cortex_m3_endreset_event(target_t *target)
        ahbap_read_system_atomic_u32(swjdp, DCB_DEMCR, &dcb_demcr);
        DEBUG("DCB_DEMCR = 0x%8.8x",dcb_demcr);
        
+       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))
@@ -216,15 +221,15 @@ int cortex_m3_examine_debug_reason(target_t *target)
        if ((target->debug_reason != DBG_REASON_DBGRQ)
                && (target->debug_reason != DBG_REASON_SINGLESTEP))
        {
-               /*  INCOPMPLETE */
+               /*  INCOMPLETE */
 
-               if (cortex_m3->nvic_dfsr & 0x2)
+               if (cortex_m3->nvic_dfsr & DFSR_BKPT)
                {
                        target->debug_reason = DBG_REASON_BREAKPOINT;
-                       if (cortex_m3->nvic_dfsr & 0x4)
+                       if (cortex_m3->nvic_dfsr & DFSR_DWTTRAP)
                                target->debug_reason = DBG_REASON_WPTANDBKPT;
                }
-               else if (cortex_m3->nvic_dfsr & 0x4)
+               else if (cortex_m3->nvic_dfsr & DFSR_DWTTRAP)
                        target->debug_reason = DBG_REASON_WATCHPOINT;
        }
 
@@ -316,7 +321,7 @@ int cortex_m3_debug_entry(target_t *target)
        /* For IT instructions xPSR must be reloaded on resume and clear on debug exec*/
        if (xPSR & 0xf00)
        {
-               armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty = 1;
+               armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty = armv7m->core_cache->reg_list[ARMV7M_xPSR].valid;
                cortex_m3_store_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 16, xPSR &~ 0xff);
        }
 
@@ -344,7 +349,7 @@ int cortex_m3_debug_entry(target_t *target)
        return ERROR_OK;
 }
 
-enum target_state cortex_m3_poll(target_t *target)
+int cortex_m3_poll(target_t *target)
 {
        int retval;
        u32 prev_target_state = target->state;
@@ -359,7 +364,7 @@ enum target_state cortex_m3_poll(target_t *target)
        if (retval != ERROR_OK)
        {
                target->state = TARGET_UNKNOWN;
-               return TARGET_UNKNOWN;
+               return retval;
        }
        
        if (cortex_m3->dcb_dhcsr & S_RESET_ST)
@@ -370,7 +375,7 @@ enum target_state cortex_m3_poll(target_t *target)
                if (cortex_m3->dcb_dhcsr & S_RESET_ST)
                {
                        target->state = TARGET_RESET;
-                       return target->state;
+                       return ERROR_OK;
                }
        }
        
@@ -390,7 +395,7 @@ enum target_state cortex_m3_poll(target_t *target)
                if ((prev_target_state == TARGET_RUNNING) || (prev_target_state == TARGET_RESET))
                {
                        if ((retval = cortex_m3_debug_entry(target)) != ERROR_OK)
-                               return TARGET_UNKNOWN;
+                               return retval;
                        
                        target_call_event_callbacks(target, TARGET_EVENT_HALTED);
                }
@@ -398,7 +403,7 @@ enum target_state cortex_m3_poll(target_t *target)
                {
                        DEBUG(" ");
                        if ((retval = cortex_m3_debug_entry(target)) != ERROR_OK)
-                               return TARGET_UNKNOWN;
+                               return retval;
 
                        target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
                }
@@ -412,7 +417,7 @@ enum target_state cortex_m3_poll(target_t *target)
     /* 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);
        DEBUG("dcb_dhcsr 0x%x, nvic_dfsr 0x%x, target->state: %s", cortex_m3->dcb_dhcsr, cortex_m3->nvic_dfsr, target_state_strings[target->state]);    
-       return target->state;
+       return ERROR_OK;
 }
 
 int cortex_m3_halt(target_t *target)
@@ -634,7 +639,7 @@ int cortex_m3_resume(struct target_s *target, int current, u32 address, int hand
        return ERROR_OK;
 }
 
-//int irqstepcount=0;
+/* int irqstepcount=0; */
 int cortex_m3_step(struct target_s *target, int current, u32 address, int handle_breakpoints)
 {
        /* get pointers to arch-specific information */
@@ -701,6 +706,8 @@ int cortex_m3_assert_reset(target_t *target)
        
        DEBUG("target->state: %s", target_state_strings[target->state]);
        
+       ahbap_write_system_u32(swjdp, DCB_DCRDR, 0 );
+       
        if (target->reset_mode == RESET_RUN)
        {
                /* Set/Clear C_MASKINTS in a separate operation */
@@ -1127,7 +1134,7 @@ int cortex_m3_load_core_reg_u32(struct target_s *target, enum armv7m_regtype typ
                        ERROR("JTAG failure %i",retval);
                        return ERROR_JTAG_DEVICE_ERROR;
                }
-               //DEBUG("load from core reg %i  value 0x%x",num,*value);
+               /* DEBUG("load from core reg %i  value 0x%x",num,*value); */
        }
        else if (type == ARMV7M_REGISTER_CORE_SP) /* Special purpose core register */
        {
@@ -1143,8 +1150,8 @@ int cortex_m3_load_core_reg_u32(struct target_s *target, enum armv7m_regtype typ
                ahbap_write_coreregister_u32(swjdp, 0x20000000, 15);
                cortex_m3_single_step_core(target);
                ahbap_read_coreregister_u32(swjdp, value, 0);
-               armv7m->core_cache->reg_list[0].dirty = 1;
-               armv7m->core_cache->reg_list[15].dirty = 1;
+               armv7m->core_cache->reg_list[0].dirty = armv7m->core_cache->reg_list[0].valid;
+               armv7m->core_cache->reg_list[15].dirty = armv7m->core_cache->reg_list[15].valid;
                ahbap_write_system_u32(swjdp, 0x20000000, savedram);
                swjdp_transaction_endcheck(swjdp);
                DEBUG("load from special reg %i value 0x%x", SYSm, *value);
@@ -1169,7 +1176,7 @@ int cortex_m3_store_core_reg_u32(struct target_s *target, enum armv7m_regtype ty
                if (retval != ERROR_OK)
                {
                        ERROR("JTAG failure %i", retval);
-                       armv7m->core_cache->reg_list[num].dirty = 1;
+                       armv7m->core_cache->reg_list[num].dirty = armv7m->core_cache->reg_list[num].valid;
                        return ERROR_JTAG_DEVICE_ERROR;
                }
                DEBUG("write core reg %i value 0x%x", num, value);
@@ -1189,7 +1196,7 @@ int cortex_m3_store_core_reg_u32(struct target_s *target, enum armv7m_regtype ty
                ahbap_write_coreregister_u32(swjdp, 0x20000000, 15);
                cortex_m3_single_step_core(target);
                ahbap_write_coreregister_u32(swjdp, tempr0, 0);
-               armv7m->core_cache->reg_list[15].dirty = 1;
+               armv7m->core_cache->reg_list[15].dirty = armv7m->core_cache->reg_list[15].valid;
                ahbap_write_system_u32(swjdp, 0x20000000, savedram);
                swjdp_transaction_endcheck(swjdp);
                DEBUG("write special reg %i value 0x%x ", SYSm, value);
@@ -1353,6 +1360,82 @@ int cortex_m3_quit()
        return ERROR_OK;
 }
 
+int cortex_m3_dcc_read(swjdp_common_t *swjdp, u8 *value, u8 *ctrl)
+{
+       u16 dcrdr;
+       
+       ahbap_read_buf_u16( swjdp, (u8*)&dcrdr, 1, DCB_DCRDR);
+       *ctrl = (u8)dcrdr;
+       *value = (u8)(dcrdr >> 8);
+       
+       DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
+       
+       /* write ack back to software dcc register
+        * signify we have read data */
+       if (dcrdr & (1 << 0))
+       {
+               dcrdr = 0;
+               ahbap_write_buf_u16( swjdp, (u8*)&dcrdr, 1, DCB_DCRDR);
+       }
+       
+       return ERROR_OK;
+}
+
+int cortex_m3_target_request_data(target_t *target, u32 size, u8 *buffer)
+{
+       armv7m_common_t *armv7m = target->arch_info;
+       cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
+       swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
+       u8 data;
+       u8 ctrl;
+       int i;
+       
+       for (i = 0; i < (size * 4); i++)
+       {
+               cortex_m3_dcc_read(swjdp, &data, &ctrl);
+               buffer[i] = data;
+       }
+       
+       return ERROR_OK;
+}
+
+int cortex_m3_handle_target_request(void *priv)
+{
+       target_t *target = priv;
+       armv7m_common_t *armv7m = target->arch_info;
+       cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
+       swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
+       
+       if (!target->dbg_msg_enabled)
+               return ERROR_OK;
+       
+       if (target->state == TARGET_RUNNING)
+       {
+               u8 data;
+               u8 ctrl;
+                               
+               cortex_m3_dcc_read(swjdp, &data, &ctrl);
+               
+               /* check if we have data */
+               if (ctrl & (1 << 0))
+               {
+                       u32 request;
+                       
+                       /* we assume target is quick enough */
+                       request = data;
+                       cortex_m3_dcc_read(swjdp, &data, &ctrl);
+                       request |= (data << 8);
+                       cortex_m3_dcc_read(swjdp, &data, &ctrl);
+                       request |= (data << 16);
+                       cortex_m3_dcc_read(swjdp, &data, &ctrl);
+                       request |= (data << 24);
+                       target_request(target, request);
+               }
+       }
+       
+       return ERROR_OK;
+}
+
 int cortex_m3_init_arch_info(target_t *target, cortex_m3_common_t *cortex_m3, int chain_pos, char *variant)
 {
        armv7m_common_t *armv7m;
@@ -1385,7 +1468,9 @@ int cortex_m3_init_arch_info(target_t *target, cortex_m3_common_t *cortex_m3, in
        armv7m->arch_info = cortex_m3;
        armv7m->load_core_reg_u32 = cortex_m3_load_core_reg_u32;
        armv7m->store_core_reg_u32 = cortex_m3_store_core_reg_u32;
-//     armv7m->full_context = cortex_m3_full_context;
+       /* armv7m->full_context = cortex_m3_full_context; */
+       
+       target_register_timer_callback(cortex_m3_handle_target_request, 1, 1, target);
        
        return ERROR_OK;
 }