]> git.sur5r.net Git - openocd/commitdiff
Added target_read/write_phys_memory() fn's. mdX/mwX commands updated to support phys...
authorØyvind Harboe <oyvind.harboe@zylin.com>
Wed, 21 Oct 2009 12:45:39 +0000 (14:45 +0200)
committerØyvind Harboe <oyvind.harboe@zylin.com>
Wed, 21 Oct 2009 12:45:39 +0000 (14:45 +0200)
doc/openocd.texi
src/target/target.c
src/target/target_type.h

index 500faf9a590dd05c147ff1c610c2c5db5b33dd60..4f228325c122c33a35cf1f7ec0bb8dccf1e45a55 100644 (file)
@@ -4938,23 +4938,27 @@ Please use their TARGET object siblings to avoid making assumptions
 about what TAP is the current target, or about MMU configuration.
 @end enumerate
 
-@deffn Command mdw addr [count]
-@deffnx Command mdh addr [count]
-@deffnx Command mdb addr [count]
+@deffn Command mdw [phys] addr [count]
+@deffnx Command mdh [phys] addr [count]
+@deffnx Command mdb [phys] addr [count]
 Display contents of address @var{addr}, as
 32-bit words (@command{mdw}), 16-bit halfwords (@command{mdh}),
 or 8-bit bytes (@command{mdb}).
 If @var{count} is specified, displays that many units.
+@var{phys} is an optional flag to indicate to use
+physical address and bypass MMU
 (If you want to manipulate the data instead of displaying it,
 see the @code{mem2array} primitives.)
 @end deffn
 
-@deffn Command mww addr word
-@deffnx Command mwh addr halfword
-@deffnx Command mwb addr byte
+@deffn Command mww [phys] addr word
+@deffnx Command mwh [phys] addr halfword
+@deffnx Command mwb [phys] addr byte
 Writes the specified @var{word} (32 bits),
 @var{halfword} (16 bits), or @var{byte} (8-bit) pattern,
 at the specified address @var{addr}.
+@var{phys} is an optional flag to indicate to use
+physical address and bypass MMU
 @end deffn
 
 
index 7763b95644d65d3dfce0d86e39e65e43dbde5112..45162070183de1b659bbf3a7160c361e0a21f3a5 100644 (file)
@@ -601,11 +601,24 @@ int target_read_memory(struct target_s *target,
        return target->type->read_memory(target, address, size, count, buffer);
 }
 
+int target_read_phys_memory(struct target_s *target,
+               uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
+{
+       return target->type->read_phys_memory(target, address, size, count, buffer);
+}
+
 int target_write_memory(struct target_s *target,
                uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
 {
        return target->type->write_memory(target, address, size, count, buffer);
 }
+
+int target_write_phys_memory(struct target_s *target,
+               uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
+{
+       return target->type->write_phys_memory(target, address, size, count, buffer);
+}
+
 int target_bulk_write_memory(struct target_s *target,
                uint32_t address, uint32_t count, uint8_t *buffer)
 {
@@ -698,6 +711,17 @@ int target_init(struct command_context_s *cmd_ctx)
                {
                        target->type->virt2phys = default_virt2phys;
                }
+
+               if (target->type->read_phys_memory == NULL)
+               {
+                       target->type->read_phys_memory = target->type->read_memory;
+               }
+
+               if (target->type->write_phys_memory == NULL)
+               {
+                       target->type->write_phys_memory = target->type->write_memory;
+               }
+
                /* a non-invasive way(in terms of patches) to add some code that
                 * runs before the type->write/read_memory implementation
                 */
@@ -1531,13 +1555,13 @@ int target_register_user_commands(struct command_context_s *cmd_ctx)
        register_command(cmd_ctx,  NULL, "reset", handle_reset_command, COMMAND_EXEC, "reset target [run | halt | init] - default is run");
        register_command(cmd_ctx,  NULL, "soft_reset_halt", handle_soft_reset_halt_command, COMMAND_EXEC, "halt the target and do a soft reset");
 
-       register_command(cmd_ctx,  NULL, "mdw", handle_md_command, COMMAND_EXEC, "display memory words <addr> [count]");
-       register_command(cmd_ctx,  NULL, "mdh", handle_md_command, COMMAND_EXEC, "display memory half-words <addr> [count]");
-       register_command(cmd_ctx,  NULL, "mdb", handle_md_command, COMMAND_EXEC, "display memory bytes <addr> [count]");
+       register_command(cmd_ctx,  NULL, "mdw", handle_md_command, COMMAND_EXEC, "display memory words [phys] <addr> [count]");
+       register_command(cmd_ctx,  NULL, "mdh", handle_md_command, COMMAND_EXEC, "display memory half-words [phys] <addr> [count]");
+       register_command(cmd_ctx,  NULL, "mdb", handle_md_command, COMMAND_EXEC, "display memory bytes [phys] <addr> [count]");
 
-       register_command(cmd_ctx,  NULL, "mww", handle_mw_command, COMMAND_EXEC, "write memory word <addr> <value> [count]");
-       register_command(cmd_ctx,  NULL, "mwh", handle_mw_command, COMMAND_EXEC, "write memory half-word <addr> <value> [count]");
-       register_command(cmd_ctx,  NULL, "mwb", handle_mw_command, COMMAND_EXEC, "write memory byte <addr> <value> [count]");
+       register_command(cmd_ctx,  NULL, "mww", handle_mw_command, COMMAND_EXEC, "write memory word [phys]  <addr> <value> [count]");
+       register_command(cmd_ctx,  NULL, "mwh", handle_mw_command, COMMAND_EXEC, "write memory half-word [phys]  <addr> <value> [count]");
+       register_command(cmd_ctx,  NULL, "mwb", handle_mw_command, COMMAND_EXEC, "write memory byte [phys] <addr> <value> [count]");
 
        register_command(cmd_ctx,  NULL, "bp",
                        handle_bp_command, COMMAND_EXEC,
@@ -2183,6 +2207,22 @@ static int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char
        default: return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
+       bool physical=strcmp(args[0], "phys")==0;
+       int (*fn)(struct target_s *target,
+                       uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
+       if (physical)
+       {
+               argc--;
+               args++;
+               fn=target_read_phys_memory;
+       } else
+       {
+               fn=target_read_memory;
+       }
+       if ((argc < 1) || (argc > 2))
+       {
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
        uint32_t address;
        int retval = parse_u32(args[0], &address);
        if (ERROR_OK != retval)
@@ -2199,8 +2239,7 @@ static int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char
        uint8_t *buffer = calloc(count, size);
 
        target_t *target = get_current_target(cmd_ctx);
-       retval = target_read_memory(target,
-                               address, size, count, buffer);
+       retval = fn(target, address, size, count, buffer);
        if (ERROR_OK == retval)
                handle_md_output(cmd_ctx, target, address, size, count, buffer);
 
@@ -2211,7 +2250,23 @@ static int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char
 
 static int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
-        if ((argc < 2) || (argc > 3))
+       if (argc < 2)
+       {
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+       bool physical=strcmp(args[0], "phys")==0;
+       int (*fn)(struct target_s *target,
+                       uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
+       if (physical)
+       {
+               argc--;
+               args++;
+               fn=target_write_phys_memory;
+       } else
+       {
+               fn=target_write_memory;
+       }
+       if ((argc < 2) || (argc > 3))
                return ERROR_COMMAND_SYNTAX_ERROR;
 
        uint32_t address;
@@ -2254,7 +2309,7 @@ static int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char
        }
        for (unsigned i = 0; i < count; i++)
        {
-               retval = target_write_memory(target,
+               retval = fn(target,
                                address + i * wordsize, wordsize, 1, value_buf);
                if (ERROR_OK != retval)
                        return retval;
index d28608fe2db652727e43c7450ae99c904da2882c..aab4321ff5797b9e8c889d93b9b9eef41c70d78b 100644 (file)
@@ -180,7 +180,26 @@ struct target_type_s
        int (*init_target)(struct command_context_s *cmd_ctx, struct target_s *target);
        int (*quit)(void);
 
+       /* translate from virtual to physical address. Default implementation is successful
+        * no-op(i.e. virtual==physical).
+        */
        int (*virt2phys)(struct target_s *target, uint32_t address, uint32_t *physical);
+
+       /* read directly from physical memory. caches are bypassed and untouched.
+        *
+        * If the target does not support disabling caches, leaving them untouched,
+        * then minimally the actual physical memory location will be read even
+        * if cache states are unchanged, flushed, etc.
+        *
+        * Default implementation is to call read_memory.
+        */
+       int (*read_phys_memory)(struct target_s *target, uint32_t phys_address, uint32_t size, uint32_t count, uint8_t *buffer);
+
+       /*
+        * same as read_phys_memory, except that it writes...
+        */
+       int (*write_phys_memory)(struct target_s *target, uint32_t phys_address, uint32_t size, uint32_t count, uint8_t *buffer);
+
        int (*mmu)(struct target_s *target, int *enabled);
 
 };