- endianess fixes everywhere but in the flash code. flashing might still be broken...
[openocd.git] / src / target / arm9tdmi.c
index be01dd604a9abca7a15c01f649f75f6972dc4437..c99fcb2a5c59a2ed4004e4f3c5fcbfe9f5158b07 100644 (file)
@@ -46,11 +46,6 @@ int arm9tdmi_register_commands(struct command_context_s *cmd_ctx);
 int arm9tdmi_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
 int arm9tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
 int arm9tdmi_quit();
-
-/* target function declarations */
-enum target_state arm9tdmi_poll(struct target_s *target);
-int arm9tdmi_halt(target_t *target);
-int arm9tdmi_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
                
 target_type_t arm9tdmi_target =
 {
@@ -169,8 +164,7 @@ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int s
        /* prepare buffer */
        buf_set_u32(out_buf, 0, 32, out);
        
-       instr = flip_u32(instr, 32);
-       buf_set_u32(instr_buf, 0, 32, instr);
+       buf_set_u32(instr_buf, 0, 32, flip_u32(instr, 32));
        
        if (sysspeed)
                buf_set_u32(&sysspeed_buf, 2, 1, 1);
@@ -183,17 +177,19 @@ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int s
        fields[0].num_bits = 32;
        fields[0].out_value = out_buf;
        fields[0].out_mask = NULL;
+       fields[0].in_value = NULL;
        if (in)
        {
-               fields[0].in_value = (u8*)in;
-       } else
+               fields[0].in_handler = arm_jtag_buf_to_u32;
+               fields[0].in_handler_priv = in;
+       }
+       else
        {
-               fields[0].in_value = NULL;
+               fields[0].in_handler = NULL;
+               fields[0].in_handler_priv = NULL;
        }
        fields[0].in_check_value = NULL;
        fields[0].in_check_mask = NULL;
-       fields[0].in_handler = NULL;
-       fields[0].in_handler_priv = NULL;
        
        fields[1].device = jtag_info->chain_pos;
        fields[1].num_bits = 3;
@@ -221,17 +217,14 @@ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int s
        
 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
        {
-               char* in_string;
                jtag_execute_queue();
                
                if (in)
                {
-                       in_string = buf_to_char((u8*)in, 32);
-                       DEBUG("instr: 0x%8.8x, out: 0x%8.8x, in: %s", flip_u32(instr, 32), out, in_string);
-                       free(in_string);
+                       DEBUG("instr: 0x%8.8x, out: 0x%8.8x, in: 0x%8.8x", instr, out, *in);
                }
                else
-                       DEBUG("instr: 0x%8.8x, out: 0x%8.8x", flip_u32(instr, 32), out);
+                       DEBUG("instr: 0x%8.8x, out: 0x%8.8x", instr, out);
        }
 #endif
 
@@ -251,9 +244,84 @@ int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in)
        fields[0].num_bits = 32;
        fields[0].out_value = NULL;
        fields[0].out_mask = NULL;
-       fields[0].in_value = (u8*)in;
-       fields[0].in_handler = NULL;
-       fields[0].in_handler_priv = NULL;
+       fields[0].in_value = NULL;
+       fields[0].in_handler = arm_jtag_buf_to_u32;
+       fields[0].in_handler_priv = in;
+       fields[0].in_check_value = NULL;
+       fields[0].in_check_mask = NULL;
+       
+       fields[1].device = jtag_info->chain_pos;
+       fields[1].num_bits = 3;
+       fields[1].out_value = NULL;
+       fields[1].out_mask = NULL;
+       fields[1].in_value = NULL;
+       fields[1].in_handler = NULL;
+       fields[1].in_handler_priv = NULL;
+       fields[1].in_check_value = NULL;
+       fields[1].in_check_mask = NULL;
+
+       fields[2].device = jtag_info->chain_pos;
+       fields[2].num_bits = 32;
+       fields[2].out_value = NULL;
+       fields[2].out_mask = NULL;
+       fields[2].in_value = NULL;
+       fields[2].in_check_value = NULL;
+       fields[2].in_check_mask = NULL;
+       fields[2].in_handler = NULL;
+       fields[2].in_handler_priv = NULL;
+       
+       jtag_add_dr_scan(3, fields, -1);
+
+       jtag_add_runtest(0, -1);
+       
+#ifdef _DEBUG_INSTRUCTION_EXECUTION_
+       {
+               jtag_execute_queue();
+                       
+               if (in)
+               {
+                       DEBUG("in: 0x%8.8x", *in);
+               }
+               else
+               {
+                       ERROR("BUG: called with in == NULL");
+               }
+       }
+#endif
+
+       return ERROR_OK;
+}
+
+/* clock the target, and read the databus
+ * the *in pointer points to a buffer where elements of 'size' bytes
+ * are stored in big (be==1) or little (be==0) endianness
+ */
+int arm9tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, int be)
+{
+       scan_field_t fields[3];
+
+       jtag_add_end_state(TAP_PD);
+       arm_jtag_scann(jtag_info, 0x1);
+       arm_jtag_set_instr(jtag_info, jtag_info->intest_instr);
+               
+       fields[0].device = jtag_info->chain_pos;
+       fields[0].num_bits = 32;
+       fields[0].out_value = NULL;
+       fields[0].out_mask = NULL;
+       fields[0].in_value = NULL;
+       switch (size)
+       {
+               case 4:
+                       fields[0].in_handler = (be) ? arm_jtag_buf_to_be32 : arm_jtag_buf_to_le32;
+                       break;
+               case 2:
+                       fields[0].in_handler = (be) ? arm_jtag_buf_to_be16 : arm_jtag_buf_to_le16;
+                       break;
+               case 1:
+                       fields[0].in_handler = arm_jtag_buf_to_8;
+                       break;
+       }
+       fields[0].in_handler_priv = in;
        fields[0].in_check_value = NULL;
        fields[0].in_check_mask = NULL;
        
@@ -283,14 +351,15 @@ int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in)
        
 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
        {
-               char* in_string;
                jtag_execute_queue();
                        
                if (in)
                {
-                       in_string = buf_to_char((u8*)in, 32);
-                       DEBUG("in: %s", in_string);
-                       free(in_string);
+                       DEBUG("in: 0x%8.8x", *in);
+               }
+               else
+               {
+                       ERROR("BUG: called with in == NULL");
                }
        }
 #endif
@@ -372,6 +441,48 @@ void arm9tdmi_read_core_regs(target_t *target, u32 mask, u32* core_regs[16])
 
 }
 
+void arm9tdmi_read_core_regs_target_buffer(target_t *target, u32 mask, void* buffer, int size)
+{
+       int i;
+       /* get pointers to arch-specific information */
+       armv4_5_common_t *armv4_5 = target->arch_info;
+       arm7_9_common_t *arm7_9 = armv4_5->arch_info;
+       arm_jtag_t *jtag_info = &arm7_9->jtag_info;
+       int be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0;
+       u32 *buf_u32 = buffer;
+       u16 *buf_u16 = buffer;
+       u8 *buf_u8 = buffer;
+       
+       /* STMIA r0-15, [r0] at debug speed
+        * register values will start to appear on 4th DCLK
+        */
+       arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
+
+       /* fetch NOP, STM in DECODE stage */
+       arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
+       /* fetch NOP, STM in EXECUTE stage (1st cycle) */
+       arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
+
+       for (i = 0; i <= 15; i++)
+       {
+               if (mask & (1 << i))
+                       /* nothing fetched, STM in MEMORY (i'th cycle) */
+                       switch (size)
+                       {
+                               case 4:
+                                       arm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);
+                                       break;
+                               case 2:
+                                       arm9tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be);
+                                       break;
+                               case 1:
+                                       arm9tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be);
+                                       break;
+                       }
+       }
+
+}
+
 void arm9tdmi_read_xpsr(target_t *target, u32 *xpsr, int spsr)
 {
        /* get pointers to arch-specific information */
@@ -711,11 +822,13 @@ void arm9tdmi_build_reg_cache(target_t *target)
        arm_jtag_t *jtag_info = &arm7_9->jtag_info;
        arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
 
+       embeddedice_reg_t *vec_catch_arch_info;
 
        (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
        armv4_5->core_cache = (*cache_p);
        
-       (*cache_p)->next = embeddedice_build_reg_cache(target, jtag_info, 0);
+       /* one extra register (vector catch) */
+       (*cache_p)->next = embeddedice_build_reg_cache(target, jtag_info, 1);
        arm7_9->eice_cache = (*cache_p)->next;
        
        if (arm9tdmi->has_monitor_mode)
@@ -725,6 +838,16 @@ void arm9tdmi_build_reg_cache(target_t *target)
        
        (*cache_p)->next->reg_list[EICE_DBG_STAT].size = 5;
 
+       (*cache_p)->next->reg_list[EICE_VEC_CATCH].name = "vector catch";
+       (*cache_p)->next->reg_list[EICE_VEC_CATCH].dirty = 0;
+       (*cache_p)->next->reg_list[EICE_VEC_CATCH].valid = 0;
+       (*cache_p)->next->reg_list[EICE_VEC_CATCH].bitfield_desc = NULL;
+       (*cache_p)->next->reg_list[EICE_VEC_CATCH].num_bitfields = 0;
+       (*cache_p)->next->reg_list[EICE_VEC_CATCH].size = 8;
+       (*cache_p)->next->reg_list[EICE_VEC_CATCH].value = calloc(1, 4);
+       vec_catch_arch_info = (*cache_p)->next->reg_list[EICE_VEC_CATCH].arch_info;
+       vec_catch_arch_info->addr = 0x2;
+       
 }
 
 int arm9tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
@@ -758,6 +881,7 @@ int arm9tdmi_init_arch_info(target_t *target, arm9tdmi_common_t *arm9tdmi, int c
        arm7_9->examine_debug_reason = arm9tdmi_examine_debug_reason;
        arm7_9->change_to_arm = arm9tdmi_change_to_arm;
        arm7_9->read_core_regs = arm9tdmi_read_core_regs;
+       arm7_9->read_core_regs_target_buffer = arm9tdmi_read_core_regs_target_buffer;
        arm7_9->read_xpsr = arm9tdmi_read_xpsr;
        
        arm7_9->write_xpsr = arm9tdmi_write_xpsr;
@@ -793,7 +917,6 @@ int arm9tdmi_init_arch_info(target_t *target, arm9tdmi_common_t *arm9tdmi, int c
        arm7_9->sw_bkpts_enabled = 0;
        arm7_9->dbgreq_adjust_pc = 3;
        arm7_9->arch_info = arm9tdmi;
-       arm7_9->use_dbgrq = 1;
        
        arm9tdmi->common_magic = ARM9TDMI_COMMON_MAGIC;
        arm9tdmi->has_monitor_mode = 0;
@@ -814,6 +937,9 @@ int arm9tdmi_init_arch_info(target_t *target, arm9tdmi_common_t *arm9tdmi, int c
                arm9tdmi->variant = strdup("");
        
        arm7_9_init_arch_info(target, arm7_9);
+
+       /* override use of DBGRQ, this is safe on ARM9TDMI */
+       arm7_9->use_dbgrq = 1;
        
        return ERROR_OK;
 }

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)