More fixes thanks to Kees Jongenburger
[fw/openocd] / src / target / arm9tdmi.c
index adb21f79b464e8c2605bca6b74e422402727d594..70ee62390f2eae5917705effa23980085fb7e930 100644 (file)
@@ -2,6 +2,12 @@
  *   Copyright (C) 2005 by Dominic Rath                                    *
  *   Dominic.Rath@gmx.de                                                   *
  *                                                                         *
+ *   Copyright (C) 2008 by Spencer Oliver                                  *
+ *   spen@spen-soft.co.uk                                                  *
+ *                                                                         *
+ *   Copyright (C) 2008 by Hongtao Zheng                                   *
+ *   hontor@126.com                                                        *
+ *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
  *   the Free Software Foundation; either version 2 of the License, or     *
@@ -46,9 +52,10 @@ int arm9tdmi_register_commands(struct command_context_s *cmd_ctx);
 int handle_arm9tdmi_catch_vectors_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 
 /* forward declarations */
-int arm9tdmi_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
+int arm9tdmi_target_create( struct target_s *target, Jim_Interp *interp );
+
 int arm9tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
-int arm9tdmi_quit();
+int arm9tdmi_quit(void);
                
 target_type_t arm9tdmi_target =
 {
@@ -83,7 +90,7 @@ target_type_t arm9tdmi_target =
        .remove_watchpoint = arm7_9_remove_watchpoint,
 
        .register_commands = arm9tdmi_register_commands,
-       .target_command = arm9tdmi_target_command,
+       .target_create = arm9tdmi_target_create,
        .init_target = arm9tdmi_init_target,
        .examine = arm9tdmi_examine,
        .quit = arm9tdmi_quit
@@ -104,6 +111,7 @@ arm9tdmi_vector_t arm9tdmi_vectors[] =
 
 int arm9tdmi_examine_debug_reason(target_t *target)
 {
+       int retval = ERROR_OK;
        /* 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;
@@ -119,7 +127,7 @@ int arm9tdmi_examine_debug_reason(target_t *target)
 
                jtag_add_end_state(TAP_PD);
 
-               fields[0].device = arm7_9->jtag_info.chain_pos;
+               fields[0].tap = arm7_9->jtag_info.tap;
                fields[0].num_bits = 32;
                fields[0].out_value = NULL;
                fields[0].out_mask = NULL;
@@ -129,7 +137,7 @@ int arm9tdmi_examine_debug_reason(target_t *target)
                fields[0].in_handler = NULL;
                fields[0].in_handler_priv = NULL;
                
-               fields[1].device = arm7_9->jtag_info.chain_pos;
+               fields[1].tap = arm7_9->jtag_info.tap;
                fields[1].num_bits = 3;
                fields[1].out_value = NULL;
                fields[1].out_mask = NULL;
@@ -139,7 +147,7 @@ int arm9tdmi_examine_debug_reason(target_t *target)
                fields[1].in_handler = NULL;
                fields[1].in_handler_priv = NULL;
                
-               fields[2].device = arm7_9->jtag_info.chain_pos;
+               fields[2].tap = arm7_9->jtag_info.tap;
                fields[2].num_bits = 32;
                fields[2].out_value = NULL;
                fields[2].out_mask = NULL;
@@ -149,11 +157,17 @@ int arm9tdmi_examine_debug_reason(target_t *target)
                fields[2].in_handler = NULL;
                fields[2].in_handler_priv = NULL;
                
-               arm_jtag_scann(&arm7_9->jtag_info, 0x1);
+               if((retval = arm_jtag_scann(&arm7_9->jtag_info, 0x1)) != ERROR_OK)
+               {
+                       return retval;
+               }
                arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL);
 
                jtag_add_dr_scan(3, fields, TAP_PD);
-               jtag_execute_queue();
+               if((retval = jtag_execute_queue()) != ERROR_OK)
+               {
+                       return retval;
+               }
                
                fields[0].in_value = NULL;
                fields[0].out_value = databus;
@@ -179,6 +193,7 @@ int arm9tdmi_examine_debug_reason(target_t *target)
 /* put an instruction in the ARM9TDMI pipeline or write the data bus, and optionally read data */
 int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int sysspeed)
 {
+       int retval = ERROR_OK;
        scan_field_t fields[3];
        u8 out_buf[4];
        u8 instr_buf[4];
@@ -193,11 +208,14 @@ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int s
                buf_set_u32(&sysspeed_buf, 2, 1, 1);
        
        jtag_add_end_state(TAP_PD);
-       arm_jtag_scann(jtag_info, 0x1);
+       if((retval = arm_jtag_scann(jtag_info, 0x1)) != ERROR_OK)
+       {
+               return retval;
+       }
        
        arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
                
-       fields[0].device = jtag_info->chain_pos;
+       fields[0].tap = jtag_info->tap;
        fields[0].num_bits = 32;
        fields[0].out_value = out_buf;
        fields[0].out_mask = NULL;
@@ -215,7 +233,7 @@ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int s
        fields[0].in_check_value = NULL;
        fields[0].in_check_mask = NULL;
        
-       fields[1].device = jtag_info->chain_pos;
+       fields[1].tap = jtag_info->tap;
        fields[1].num_bits = 3;
        fields[1].out_value = &sysspeed_buf;
        fields[1].out_mask = NULL;
@@ -225,7 +243,7 @@ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int s
        fields[1].in_handler = NULL;
        fields[1].in_handler_priv = NULL;
                
-       fields[2].device = jtag_info->chain_pos;
+       fields[2].tap = jtag_info->tap;
        fields[2].num_bits = 32;
        fields[2].out_value = instr_buf;
        fields[2].out_mask = NULL;
@@ -241,7 +259,10 @@ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int s
        
 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
        {
-               jtag_execute_queue();
+               if((retval = jtag_execute_queue()) != ERROR_OK)
+               {
+                       return retval;
+               }
                
                if (in)
                {
@@ -258,14 +279,18 @@ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int s
 /* just read data (instruction and data-out = don't care) */
 int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in)
 {
+       int retval = ERROR_OK;;
        scan_field_t fields[3];
 
        jtag_add_end_state(TAP_PD);
-       arm_jtag_scann(jtag_info, 0x1);
+       if((retval = arm_jtag_scann(jtag_info, 0x1)) != ERROR_OK)
+       {
+               return retval;
+       }
        
        arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
                
-       fields[0].device = jtag_info->chain_pos;
+       fields[0].tap = jtag_info->tap;
        fields[0].num_bits = 32;
        fields[0].out_value = NULL;
        fields[0].out_mask = NULL;
@@ -275,7 +300,7 @@ int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in)
        fields[0].in_check_value = NULL;
        fields[0].in_check_mask = NULL;
        
-       fields[1].device = jtag_info->chain_pos;
+       fields[1].tap = jtag_info->tap;
        fields[1].num_bits = 3;
        fields[1].out_value = NULL;
        fields[1].out_mask = NULL;
@@ -285,7 +310,7 @@ int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in)
        fields[1].in_check_value = NULL;
        fields[1].in_check_mask = NULL;
 
-       fields[2].device = jtag_info->chain_pos;
+       fields[2].tap = jtag_info->tap;
        fields[2].num_bits = 32;
        fields[2].out_value = NULL;
        fields[2].out_mask = NULL;
@@ -301,8 +326,11 @@ int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in)
        
 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
        {
-               jtag_execute_queue();
-                       
+               if((retval = jtag_execute_queue()) != ERROR_OK)
+               {
+                       return retval;
+               }
+               
                if (in)
                {
                        LOG_DEBUG("in: 0x%8.8x", *in);
@@ -323,14 +351,18 @@ int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in)
  */
 int arm9tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, int be)
 {
+       int retval = ERROR_OK;
        scan_field_t fields[3];
        
        jtag_add_end_state(TAP_PD);
-       arm_jtag_scann(jtag_info, 0x1);
+       if((retval = arm_jtag_scann(jtag_info, 0x1)) != ERROR_OK)
+       {
+               return retval;
+       }
        
        arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
                
-       fields[0].device = jtag_info->chain_pos;
+       fields[0].tap = jtag_info->tap;
        fields[0].num_bits = 32;
        fields[0].out_value = NULL;
        fields[0].out_mask = NULL;
@@ -351,7 +383,7 @@ int arm9tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size,
        fields[0].in_check_value = NULL;
        fields[0].in_check_mask = NULL;
        
-       fields[1].device = jtag_info->chain_pos;
+       fields[1].tap = jtag_info->tap;
        fields[1].num_bits = 3;
        fields[1].out_value = NULL;
        fields[1].out_mask = NULL;
@@ -361,7 +393,7 @@ int arm9tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size,
        fields[1].in_check_value = NULL;
        fields[1].in_check_mask = NULL;
 
-       fields[2].device = jtag_info->chain_pos;
+       fields[2].tap = jtag_info->tap;
        fields[2].num_bits = 32;
        fields[2].out_value = NULL;
        fields[2].out_mask = NULL;
@@ -377,8 +409,11 @@ int arm9tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size,
        
 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
        {
-               jtag_execute_queue();
-                       
+               if((retval = jtag_execute_queue()) != ERROR_OK)
+               {
+                       return retval;
+               }
+               
                if (in)
                {
                        LOG_DEBUG("in: 0x%8.8x", *(u32*)in);
@@ -395,6 +430,7 @@ int arm9tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size,
 
 void arm9tdmi_change_to_arm(target_t *target, u32 *r0, u32 *pc)
 {
+       int retval = ERROR_OK;
        /* 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;
@@ -435,7 +471,10 @@ void arm9tdmi_change_to_arm(target_t *target, u32 *r0, u32 *pc)
        /* NOP fetched, BX in Execute (1) */
        arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
        
-       jtag_execute_queue();
+       if((retval = jtag_execute_queue()) != ERROR_OK)
+       {
+               return;
+       }
        
        /* fix program counter:
         * MOV r0, r15 was the 5th instruction (+8)
@@ -805,7 +844,7 @@ void arm9tdmi_branch_resume_thumb(target_t *target)
 
 }
 
-void arm9tdmi_enable_single_step(target_t *target)
+void arm9tdmi_enable_single_step(target_t *target, u32 next_pc)
 {
        /* get pointers to arch-specific information */
        armv4_5_common_t *armv4_5 = target->arch_info;
@@ -818,7 +857,7 @@ void arm9tdmi_enable_single_step(target_t *target)
        }
        else
        {
-               arm7_9_enable_eice_step(target);
+               arm7_9_enable_eice_step(target, next_pc);
        }
 }
 
@@ -896,13 +935,13 @@ int arm9tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *tar
        
 }
 
-int arm9tdmi_quit()
+int arm9tdmi_quit(void)
 {
        
        return ERROR_OK;
 }
 
-int arm9tdmi_init_arch_info(target_t *target, arm9tdmi_common_t *arm9tdmi, int chain_pos, char *variant)
+int arm9tdmi_init_arch_info(target_t *target, arm9tdmi_common_t *arm9tdmi, jtag_tap_t *tap, const char *variant)
 {
        armv4_5_common_t *armv4_5;
        arm7_9_common_t *arm7_9;
@@ -911,7 +950,7 @@ int arm9tdmi_init_arch_info(target_t *target, arm9tdmi_common_t *arm9tdmi, int c
        armv4_5 = &arm7_9->armv4_5_common;
        
        /* prepare JTAG information for the new target */
-       arm7_9->jtag_info.chain_pos = chain_pos;
+       arm7_9->jtag_info.tap = tap;
        arm7_9->jtag_info.scann_size = 5;
        
        /* register arch-specific functions */
@@ -950,8 +989,6 @@ int arm9tdmi_init_arch_info(target_t *target, arm9tdmi_common_t *arm9tdmi, int c
        arm7_9->arm_bkpt = 0xdeeedeee;
        arm7_9->thumb_bkpt = 0xdeee;
        
-       arm7_9->sw_bkpts_use_wp = 1;
-       arm7_9->sw_bkpts_enabled = 0;
        arm7_9->dbgreq_adjust_pc = 3;
        arm7_9->arch_info = arm9tdmi;
        
@@ -1009,26 +1046,12 @@ int arm9tdmi_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, a
 }
 
 
-/* target arm9tdmi <endianess> <startup_mode> <chain_pos> <variant>*/
-int arm9tdmi_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
+
+int arm9tdmi_target_create(struct target_s *target, Jim_Interp *interp)
 {
-       int chain_pos;
-       char *variant = NULL;
-       arm9tdmi_common_t *arm9tdmi = malloc(sizeof(arm9tdmi_common_t));
-       memset(arm9tdmi, 0, sizeof(*arm9tdmi));
+       arm9tdmi_common_t *arm9tdmi = calloc(1,sizeof(arm9tdmi_common_t));
 
-       if (argc < 4)
-       {
-               LOG_ERROR("'target arm9tdmi' requires at least one additional argument");
-               exit(-1);
-       }
-       
-       chain_pos = strtoul(args[3], NULL, 0);
-       
-       if (argc >= 5)
-               variant = args[4];
-       
-       arm9tdmi_init_arch_info(target, arm9tdmi, chain_pos, variant);
+       arm9tdmi_init_arch_info(target, arm9tdmi, target->tap, target->variant);
        
        return ERROR_OK;
 }
@@ -1047,7 +1070,7 @@ int arm9tdmi_register_commands(struct command_context_s *cmd_ctx)
        register_command(cmd_ctx, arm9tdmi_cmd, "vector_catch", handle_arm9tdmi_catch_vectors_command, COMMAND_EXEC, "catch arm920t vectors ['all'|'none'|'<vec1 vec2 ...>']");
        
        
-       return ERROR_OK;
+       return retval;
 
 }