]> git.sur5r.net Git - openocd/blobdiff - src/target/cortex_m3.c
- 16 and 32 bit unaligned accesses supported
[openocd] / src / target / cortex_m3.c
index 279d986a6b9b049df9b4f584b5240be6671d059a..ca629cc6ff9cdbb49048ab3f9084716e9f1d32cb 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                                                    *
  *                                                                         *
@@ -137,12 +138,13 @@ 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;
 }
 
+#if 0
 /* Enable interrupts */
 int cortex_m3_cpsie(target_t *target, u32 IF)
 {
@@ -154,6 +156,7 @@ int cortex_m3_cpsid(target_t *target, u32 IF)
 {
        return cortex_m3_exec_opcode(target, ARMV7M_T_CPSID(IF), 2);
 }
+#endif
 
 int cortex_m3_endreset_event(target_t *target)
 {
@@ -320,11 +323,10 @@ 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);
        }
 
-
        /* Now we can load SP core registers */ 
        for (i = ARMV7M_PRIMASK; i < ARMV7NUMCOREREGS; i++)
        {
@@ -348,7 +350,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;
@@ -363,7 +365,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)
@@ -374,7 +376,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;
                }
        }
        
@@ -394,7 +396,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);
                }
@@ -402,7 +404,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);
                }
@@ -416,7 +418,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)
@@ -431,7 +433,7 @@ int cortex_m3_halt(target_t *target)
        if (target->state == TARGET_HALTED)
        {
                WARNING("target was already halted");
-               return ERROR_TARGET_ALREADY_HALTED;
+               return ERROR_OK;
        }
        
        if (target->state == TARGET_UNKNOWN)
@@ -638,7 +640,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 */
@@ -1133,7 +1135,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 */
        {
@@ -1149,8 +1151,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);
@@ -1175,7 +1177,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);
@@ -1195,7 +1197,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);
@@ -1211,39 +1213,31 @@ int cortex_m3_read_memory(struct target_s *target, u32 address, u32 size, u32 co
        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 retval;
        
        /* sanitize arguments */
        if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
                return ERROR_INVALID_ARGUMENTS;
-
-       if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
-               return ERROR_TARGET_UNALIGNED_ACCESS;
        
-       /* Is not optimal, autoincrement of tar should be used (  ahbap_block_read and CSW_ADDRINC_SINGLE ) */
+       /* cortex_m3 handles unaligned memory access */
+               
        switch (size)
        {
                case 4:
-                       /* TODOLATER Check error return value ! */
-                       {
-                               ahbap_read_buf(swjdp, buffer, 4 * count, address);
-                       }
+                       retval = ahbap_read_buf_u32(swjdp, buffer, 4 * count, address);
                        break;
                case 2:
-                       {
-                               ahbap_read_buf_u16(swjdp, buffer, 2 * count, address);
-                       }       
+                       retval = ahbap_read_buf_u16(swjdp, buffer, 2 * count, address);
                        break;
                case 1:
-                       {
-                               ahbap_read_buf(swjdp, buffer, count, address);
-                       }       
+                       retval = ahbap_read_buf_u8(swjdp, buffer, count, address);
                        break;
                default:
                        ERROR("BUG: we shouldn't get here");
                        exit(-1);
        }
        
-       return ERROR_OK;
+       return retval;
 }
 
 int cortex_m3_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
@@ -1252,45 +1246,34 @@ int cortex_m3_write_memory(struct target_s *target, u32 address, u32 size, u32 c
        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 retval;
        
        /* sanitize arguments */
        if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
                return ERROR_INVALID_ARGUMENTS;
-
-       if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
-               return ERROR_TARGET_UNALIGNED_ACCESS;
-               
+       
        switch (size)
        {
                case 4:
-                       /* TODOLATER Check error return value ! */
-                       {
-                               ahbap_write_buf(swjdp, buffer, 4 * count, address);
-                       }
+                       retval = ahbap_write_buf_u32(swjdp, buffer, 4 * count, address);
                        break;
                case 2:
-                       {
-                               ahbap_write_buf_u16(swjdp, buffer, 2 * count, address);
-                       }       
+                       retval = ahbap_write_buf_u16(swjdp, buffer, 2 * count, address);
                        break;
                case 1:
-                       {
-                               ahbap_write_buf(swjdp, buffer, count, address);
-                       }       
+                       retval = ahbap_write_buf_u8(swjdp, buffer, count, address);     
                        break;
                default:
                        ERROR("BUG: we shouldn't get here");
                        exit(-1);
        }
        
-       return ERROR_OK;
+       return retval;
 }
 
 int cortex_m3_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
 {
-       cortex_m3_write_memory(target, address, 4, count, buffer);
-       
-       return ERROR_OK;
+       return cortex_m3_write_memory(target, address, 4, count, buffer);
 }
 
 void cortex_m3_build_reg_cache(target_t *target)
@@ -1371,8 +1354,12 @@ int cortex_m3_dcc_read(swjdp_common_t *swjdp, u8 *value, u8 *ctrl)
        
        /* write ack back to software dcc register
         * signify we have read data */
-       dcrdr = 0;
-       ahbap_write_buf_u16( swjdp, (u8*)&dcrdr, 1, DCB_DCRDR);
+       if (dcrdr & (1 << 0))
+       {
+               dcrdr = 0;
+               ahbap_write_buf_u16( swjdp, (u8*)&dcrdr, 1, DCB_DCRDR);
+       }
+       
        return ERROR_OK;
 }
 
@@ -1412,10 +1399,11 @@ int cortex_m3_handle_target_request(void *priv)
                cortex_m3_dcc_read(swjdp, &data, &ctrl);
                
                /* check if we have data */
-               if (ctrl & (1<<0))
+               if (ctrl & (1 << 0))
                {
                        u32 request;
                        
+                       /* we assume target is quick enough */
                        request = data;
                        cortex_m3_dcc_read(swjdp, &data, &ctrl);
                        request |= (data << 8);
@@ -1462,7 +1450,7 @@ 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);
        
@@ -1475,6 +1463,7 @@ int cortex_m3_target_command(struct command_context_s *cmd_ctx, char *cmd, char
        int chain_pos;
        char *variant = NULL;
        cortex_m3_common_t *cortex_m3 = malloc(sizeof(cortex_m3_common_t));
+       memset(cortex_m3, 0, sizeof(*cortex_m3));
 
        if (argc < 4)
        {