This is an automated email from Gerrit.

Antonio Borneo (borneo.anto...@gmail.com) just uploaded a new patch set to 
Gerrit, which you can find at http://openocd.zylin.com/5943

-- gerrit

commit 2207f5af930961430dd325aab2434d2088e71ad4
Author: Antonio Borneo <borneo.anto...@gmail.com>
Date:   Sun Nov 22 12:29:04 2020 +0100

    arm7_9_common: fix host endianness bug in arm7_9_full_context()
    
    The original code passes to ->read_core_regs() and to
    ->read_xpsr() the pointer to the little-endian buffer reg.value.
    This is incorrect because the two functions above require a
    pointer to uint32_t, since they already run the conversion with
    arm_le_to_h_u32() in the jtag callback.
    This causes a mismatch on big-endian host and the registers get
    read with the incorrect endianness.
    
    Use an intermediate buffer to read the registers as uint32_t and
    to track the destination reg.value pointer, then copy the value in
    reg.value after the call to jtag_execute_queue().
    
    Tested with qemu-armeb and an OpenOCD built through buildroot
    configured for cortex-a7 big-endian.
    
    Note that if jtag_execute_queue() fails, the openocd register
    cache is not updated, so the already modified flags 'valid' and
    'dirty' are incorrect. This part should be moved after the call to
    jtag_execute_queue() too.
    
    Change-Id: Iba70d964ffbb74bf0860bfd9d299f218e3bc65bf
    Signed-off-by: Antonio Borneo <borneo.anto...@gmail.com>

diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c
index d70d273..d992aa7 100644
--- a/src/target/arm7_9_common.c
+++ b/src/target/arm7_9_common.c
@@ -1391,6 +1391,11 @@ static int arm7_9_full_context(struct target *target)
        int retval;
        struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
        struct arm *arm = &arm7_9->arm;
+       struct {
+               uint32_t value;
+               void *reg_p;
+       } read_cache[6 * (16 + 1)];
+       int read_cache_idx = 0;
 
        LOG_DEBUG("-");
 
@@ -1433,10 +1438,12 @@ static int arm7_9_full_context(struct target *target)
                        for (j = 0; j < 15; j++) {
                                if (!ARMV4_5_CORE_REG_MODE(arm->core_cache,
                                                armv4_5_number_to_mode(i), 
j).valid) {
-                                       reg_p[j] = (uint32_t 
*)ARMV4_5_CORE_REG_MODE(
+                                       read_cache[read_cache_idx].reg_p = 
ARMV4_5_CORE_REG_MODE(
                                                        arm->core_cache,
                                                        
armv4_5_number_to_mode(i),
                                                        j).value;
+                                       reg_p[j] = 
&read_cache[read_cache_idx].value;
+                                       read_cache_idx++;
                                        mask |= 1 << j;
                                        ARMV4_5_CORE_REG_MODE(arm->core_cache,
                                                armv4_5_number_to_mode(i),
@@ -1454,9 +1461,10 @@ static int arm7_9_full_context(struct target *target)
                        /* check if the PSR has to be read */
                        if (!ARMV4_5_CORE_REG_MODE(arm->core_cache, 
armv4_5_number_to_mode(i),
                                        16).valid) {
-                               arm7_9->read_xpsr(target,
-                                       (uint32_t 
*)ARMV4_5_CORE_REG_MODE(arm->core_cache,
-                                               armv4_5_number_to_mode(i), 
16).value, 1);
+                               read_cache[read_cache_idx].reg_p = 
ARMV4_5_CORE_REG_MODE(arm->core_cache,
+                                       armv4_5_number_to_mode(i), 16).value;
+                               arm7_9->read_xpsr(target, 
&read_cache[read_cache_idx].value, 1);
+                               read_cache_idx++;
                                ARMV4_5_CORE_REG_MODE(arm->core_cache, 
armv4_5_number_to_mode(i),
                                        16).valid = true;
                                ARMV4_5_CORE_REG_MODE(arm->core_cache, 
armv4_5_number_to_mode(i),
@@ -1472,6 +1480,14 @@ static int arm7_9_full_context(struct target *target)
        retval = jtag_execute_queue();
        if (retval != ERROR_OK)
                return retval;
+       /*
+        * FIXME: regs in cache should be tagged as 'valid' only now,
+        * not before the jtag_execute_queue()
+        */
+       while (read_cache_idx) {
+               read_cache_idx--;
+               buf_set_u32(read_cache[read_cache_idx].reg_p, 0, 32, 
read_cache[read_cache_idx].value);
+       }
        return ERROR_OK;
 }
 

-- 


_______________________________________________
OpenOCD-devel mailing list
OpenOCD-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to