- fix xscale memory leak and warnings. Thanks Øyvind Harboe
[fw/openocd] / src / target / xscale.c
index 92cc1422c34ce74a8e6569f9ad60ee4c3894e8de..f652ee35d0f11e417480f65dbd5a5d5ecd4f7359 100644 (file)
@@ -218,7 +218,7 @@ int xscale_jtag_set_instr(int chain_pos, u32 new_instr)
                field.out_mask = NULL;
                field.in_value = NULL;
                jtag_set_check_value(&field, device->expected, device->expected_mask, NULL);
-               
+
                jtag_add_ir_scan(1, &field, -1, NULL);
 
                free(field.out_value);
@@ -283,8 +283,8 @@ int xscale_read_dcsr(target_t *target)
        fields[1].in_handler_priv = NULL;
        fields[1].in_check_value = NULL;
        fields[1].in_check_mask = NULL;
-       
-       
+
+
 
        fields[2].device = xscale->jtag_info.chain_pos;
        fields[2].num_bits = 1;
@@ -358,8 +358,8 @@ int xscale_receive(target_t *target, u32 *buffer, int num_words)
        fields[1].in_handler_priv = NULL;
        fields[1].in_check_value = NULL;
        fields[1].in_check_mask = NULL;
-       
-       
+
+
 
        fields[2].device = xscale->jtag_info.chain_pos;
        fields[2].num_bits = 1;
@@ -460,8 +460,8 @@ int xscale_read_tx(target_t *target, int consume)
        fields[1].in_handler_priv = NULL;
        fields[1].in_check_value = NULL;
        fields[1].in_check_mask = NULL;
-       
-       
+
+
 
        fields[2].device = xscale->jtag_info.chain_pos;
        fields[2].num_bits = 1;
@@ -543,8 +543,8 @@ int xscale_write_rx(target_t *target)
        fields[1].in_handler_priv = NULL;
        fields[1].in_check_value = NULL;
        fields[1].in_check_mask = NULL;
-       
-       
+
+
 
        fields[2].device = xscale->jtag_info.chain_pos;
        fields[2].num_bits = 1;
@@ -629,8 +629,8 @@ int xscale_send(target_t *target, u8 *buffer, int count, int size)
        fields[1].in_handler_priv = NULL;
        fields[1].in_check_value = NULL;
        fields[1].in_check_mask = NULL;
-       
-       
+
+
 
        fields[2].device = xscale->jtag_info.chain_pos;
        fields[2].num_bits = 1;
@@ -725,8 +725,8 @@ int xscale_write_dcsr(target_t *target, int hold_rst, int ext_dbg_brk)
        fields[1].in_handler_priv = NULL;
        fields[1].in_check_value = NULL;
        fields[1].in_check_mask = NULL;
-       
-       
+
+
 
        fields[2].device = xscale->jtag_info.chain_pos;
        fields[2].num_bits = 1;
@@ -1014,7 +1014,7 @@ int xscale_debug_entry(target_t *target)
        armv4_5_common_t *armv4_5 = target->arch_info;
        xscale_common_t *xscale = armv4_5->arch_info;
        u32 pc;
-       u32 *buffer = malloc(4 * 10);
+       u32 buffer[10];
        int i;
 
        u32 moe;
@@ -1199,7 +1199,7 @@ int xscale_halt(target_t *target)
        {
                /* this must not happen for a xscale target */
                ERROR("target was in unknown state when halt was requested");
-               exit(-1);
+               return ERROR_TARGET_INVALID;
        }
        else if (target->state == TARGET_RESET)
        {
@@ -1680,7 +1680,7 @@ int xscale_deassert_reset(target_t *target)
                        /* resume the target */
                        xscale_resume(target, 1, 0x0, 1, 0);
                }
-               
+
                fileio_close(&debug_handler);
        }
        else
@@ -2269,7 +2269,7 @@ int xscale_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
 {
        armv4_5_common_t *armv4_5 = target->arch_info;
        xscale_common_t *xscale = armv4_5->arch_info;
-       u8 enable;
+       u8 enable = 0;
        reg_t *dbcon = &xscale->reg_cache->reg_list[XSCALE_DBCON];
        u32 dbcon_value = buf_get_u32(dbcon->value, 0, 32);
 
@@ -3579,6 +3579,96 @@ int xscale_handle_analyze_trace_buffer_command(struct command_context_s *cmd_ctx
        return ERROR_OK;
 }
 
+int xscale_handle_cp15(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
+{
+       target_t *target = get_current_target(cmd_ctx);
+       armv4_5_common_t *armv4_5;
+       xscale_common_t *xscale;
+       
+       if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
+       {
+               command_print(cmd_ctx, "target isn't an XScale target");
+               return ERROR_OK;
+       }
+       
+       if (target->state != TARGET_HALTED)
+       {
+               command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
+               return ERROR_OK;
+       }
+       u32 reg_no = 0;
+       reg_t *reg = NULL;
+       if(argc > 0)
+       {
+               reg_no = strtoul(args[0], NULL, 0);
+               /*translate from xscale cp15 register no to openocd register*/
+               switch(reg_no)
+               {
+               case 0:
+                       reg_no = XSCALE_MAINID;
+                       break;
+               case 1:
+                       reg_no = XSCALE_CTRL;
+                       break;
+               case 2:
+                       reg_no = XSCALE_TTB;
+                       break; 
+               case 3:
+                       reg_no = XSCALE_DAC;
+                       break;
+               case 5:
+                       reg_no = XSCALE_FSR;
+                       break;
+               case 6:
+                       reg_no = XSCALE_FAR;
+                       break;
+               case 13:
+                       reg_no = XSCALE_PID;
+                       break;
+               case 15:
+                       reg_no = XSCALE_CPACCESS;
+                       break;
+               default:
+                       command_print(cmd_ctx, "invalid register number");
+                       return ERROR_INVALID_ARGUMENTS;
+               }
+               reg = &xscale->reg_cache->reg_list[reg_no];
+               
+       }
+       if(argc == 1)
+       {
+               u32 value;
+               
+               /* read cp15 control register */
+               xscale_get_reg(reg);
+               value = buf_get_u32(reg->value, 0, 32);
+               command_print(cmd_ctx, "%s (/%i): 0x%x", reg->name, reg->size, value);
+       }
+       else if(argc == 2)
+       {   
+
+               u32 value = strtoul(args[1], NULL, 0);
+               
+               /* send CP write request (command 0x41) */
+               xscale_send_u32(target, 0x41);
+               
+               /* send CP register number */
+               xscale_send_u32(target, reg_no);
+               
+               /* send CP register value */
+               xscale_send_u32(target, value);
+               
+               /* execute cpwait to ensure outstanding operations complete */
+               xscale_send_u32(target, 0x53);
+       }
+       else
+       {
+               command_print(cmd_ctx, "usage: cp15 [register]<, [value]>");    
+       }
+       
+       return ERROR_OK;
+}
+
 int xscale_register_commands(struct command_context_s *cmd_ctx)
 {
        command_t *xscale_cmd;
@@ -3603,6 +3693,8 @@ int xscale_register_commands(struct command_context_s *cmd_ctx)
        register_command(cmd_ctx, xscale_cmd, "trace_image", xscale_handle_trace_image_command,
                COMMAND_EXEC, "load image from <file> [base address]");
 
+       register_command(cmd_ctx, xscale_cmd, "cp15", xscale_handle_cp15, COMMAND_EXEC, "access coproc 15 <register> [value]");
+       
        armv4_5_register_commands(cmd_ctx);
 
        return ERROR_OK;