XScale: context restore, cleanup/bugfix
authorDavid Brownell <dbrownell@users.sourceforge.net>
Tue, 1 Dec 2009 03:14:19 +0000 (19:14 -0800)
committerDavid Brownell <dbrownell@users.sourceforge.net>
Tue, 1 Dec 2009 03:14:19 +0000 (19:14 -0800)
This "loop over all registers" routine shared the same mess as
full_context() in terms of dozens of needless number_to_mode()
calls.  Fix that, and comments, with related cleanup.

The misnamed xscale_restore_context() had a related bug.  It
was restoring the *WRONG REGISTERS* ... always from whatever
the current mode was, instead of using the copy from whichever
register bank it was trying to restore.  (But it marked the
intended register as having been restored...)  Fixed that.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
src/target/xscale.c

index bf5d0afa87cc9c13979377df8294d0be12cc44c0..0680c520c8d2b07cdfca16f4bbb4495d632d37d5 100644 (file)
@@ -1768,37 +1768,45 @@ static int xscale_restore_context(struct target *target)
        }
 
        /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
-       * we can't enter User mode on an XScale (unpredictable),
-       * but User shares registers with SYS
-       */
+        * and check if any banked registers need to be written.  Ignore
+        * USR mode (number 0) in favor of SYS; we can't enter User mode on
+        * an XScale (unpredictable), but they share all registers.
+        */
        for (i = 1; i < 7; i++)
        {
                int dirty = 0;
+               enum armv4_5_mode mode = armv4_5_number_to_mode(i);
 
-               /* check if there are invalid registers in the current mode
-               */
+               if (mode == ARMV4_5_MODE_USR)
+                       continue;
+
+               /* check if there are dirty registers in this mode */
                for (j = 8; j <= 14; j++)
                {
-                       if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty == 1)
+                       if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
+                                       mode, j).dirty)
                                dirty = 1;
                }
 
                /* if not USR/SYS, check if the SPSR needs to be written */
-               if ((armv4_5_number_to_mode(i) != ARMV4_5_MODE_USR) && (armv4_5_number_to_mode(i) != ARMV4_5_MODE_SYS))
+               if (mode != ARMV4_5_MODE_SYS)
                {
-                       if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty == 1)
+                       if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
+                                       mode, 16).dirty)
                                dirty = 1;
                }
 
+               /* is there anything to flush for this mode? */
                if (dirty)
                {
                        uint32_t tmp_cpsr;
+                       struct reg *r;
 
-                       /* send banked registers */
+                       /* command 0x1:  "send banked registers" */
                        xscale_send_u32(target, 0x1);
 
                        tmp_cpsr = 0x0;
-                       tmp_cpsr |= armv4_5_number_to_mode(i);
+                       tmp_cpsr |= mode;
                        tmp_cpsr |= 0xc0; /* I/F bits */
 
                        /* send CPSR for desired mode */
@@ -1807,14 +1815,20 @@ static int xscale_restore_context(struct target *target)
                        /* send banked registers, r8 to r14, and spsr if not in USR/SYS mode */
                        for (j = 8; j <= 14; j++)
                        {
-                               xscale_send_u32(target, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, j).value, 0, 32));
-                               ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty = 0;
+                               r = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
+                                               mode, j);
+                               xscale_send_u32(target,
+                                               buf_get_u32(r->value, 0, 32));
+                               r->dirty = false;
                        }
 
-                       if ((armv4_5_number_to_mode(i) != ARMV4_5_MODE_USR) && (armv4_5_number_to_mode(i) != ARMV4_5_MODE_SYS))
+                       if (mode != ARMV4_5_MODE_SYS)
                        {
-                               xscale_send_u32(target, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32));
-                               ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty = 0;
+                               r = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
+                                               mode, 16);
+                               xscale_send_u32(target,
+                                               buf_get_u32(r->value, 0, 32));
+                               r->dirty = false;
                        }
                }
        }

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)