This is an automated email from Gerrit.

"Dietmar May <dietmar....@outlook.com>" just uploaded a new patch set to 
Gerrit, which you can find at https://review.openocd.org/c/openocd/+/6477

-- gerrit

commit 6755d33786370d6659075a520d481a674b2f7888
Author: Dietmar May <dietmar....@outlook.com>
Date:   Fri Aug 20 19:34:39 2021 -0400

    aarch64: reg cmd w/ force for rd & wr, sync
    
    In a multi-core (SMP) system, the 'reg' command is always associated
    with the last core to halt, which means that registers for another core
    can't be inspected. This patch adds a reg command to aarch64, allowing
    all cores to be inspected, and adds 'force' to register writes, causing
    an immediate flush of updated values to the target cpu register.
    
    By adding a reg command to the aarch64 command set, the correct target
    is already set at the time of the call. The existing target handler is
    invoked. Then, since the target handler only updates the cache, not the
    cpu, if 'force' is specified, the patch code flushes the register on
    write, and clears or displays the dirty flag.
    
    > ca53.0 aarch64 reg pc
    ca53.0:pc (/64): 0x00000000deadbeef (dirty)
    
    > ca53.1 aarch64 reg pc
    ca53.1:pc (/64): 0x000000000f1eaba11 (dirty)
    
    > ca53.0 aarch64 reg pc force
    ca53.0:pc (/64): 0x00000000codeace5
    
    Signed-off-by: Dietmar May <dietmar....@outlook.com>
    Change-Id: I4e8c27b34361ed31acad136f705dc9c9b340234c

diff --git a/src/target/aarch64.c b/src/target/aarch64.c
index 9e8a7cd91..79768c292 100644
--- a/src/target/aarch64.c
+++ b/src/target/aarch64.c
@@ -2971,6 +2971,64 @@ COMMAND_HANDLER(aarch64_mask_interrupts_command)
        return retval;
 }
 
+COMMAND_HANDLER(aarch64_handle_reg_command)
+{
+       extern __COMMAND_HANDLER(target_handle_reg_command);
+
+       struct target *target = get_current_target(CMD_CTX);
+
+       bool force = false;
+       bool write = false;
+
+       if (CMD_ARGC > 0) {
+               /* look for trailing "force" when a numeric value is being 
written */
+               force = (strcmp(CMD_ARGV[CMD_ARGC-1], "force") == 0);
+               write = ((CMD_ARGC >= 2) && (CMD_ARGV[1][0] >= '0') && 
(CMD_ARGV[1][0] <= '9'));
+       }
+
+       int retval = CALL_COMMAND_HANDLER(target_handle_reg_command);
+
+       if (retval == ERROR_OK) {
+               struct reg *reg = NULL;
+
+               /* reg->->set only sets the dirty flag, so flush immediately if 
'force' is specified */
+               if (write) {
+                       if ((CMD_ARGV[0][0] >= '0') && (CMD_ARGV[0][0] <= '9')) 
{
+                               unsigned num;
+                               COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);
+
+                               for (struct reg_cache *cache = 
target->reg_cache; cache && !reg; cache = cache->next) {
+                                       if (num >= cache->num_regs)
+                                               num -= cache->num_regs;
+                                       else
+                                               reg = &cache->reg_list[num];
+                               }
+                       } else {
+                               reg = register_get_by_name(target->reg_cache, 
CMD_ARGV[0], true);
+                       }
+
+               }
+
+               /* out of bounds register already reported in 
target_handle_reg_command */
+               if (!reg)
+                       return ERROR_OK;
+
+               if (force) {
+                       struct arm_reg *armv8_reg = reg->arch_info;
+                       struct arm *arm = target_to_arm(target);
+                       retval = arm->write_core_reg(target, reg, 
armv8_reg->num, arm->core_mode, reg->value);
+                       if(retval == ERROR_OK)
+                               reg->dirty = false;
+                       else
+                               LOG_ERROR("reg force failed while flushing 
register - %s", CMD_ARGV[0]);
+               } else if (write && reg->dirty) {
+                       command_print(CMD, "(dirty)");
+               }
+       }
+
+       return retval;
+}
+
 /* Move to ARM register from coprocessor
  * o0: Coprocessor number (0 - general, 1 - system)
  * op1: Coprocessor opcode
@@ -3281,6 +3339,14 @@ static const struct command_registration 
aarch64_exec_command_handlers[] = {
                .help = "read coprocessor register",
                .usage = "cpnum op1 CRn CRm op2",
        },
+       {
+               .name = "reg",
+               .mode = COMMAND_EXEC,
+               .handler = aarch64_handle_reg_command,
+               .help = "displays all registers, displays or sets a register, 
or marks all dirty: "
+                       "force causes a reread or flush",
+               .usage = "[((register_number|register_name) [value] [force]) | 
sync]",
+       },
        {
                .chain = smp_command_handlers,
        },

-- 

Reply via email to