- added patch to access cp15 register (XScale)
[openocd.git] / src / target / xscale.c
index 92cc1422c34ce74a8e6569f9ad60ee4c3894e8de..ec49a8c6b311fbc2f59c28167f4b722c8b062ade 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;
@@ -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
@@ -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;

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)