Fix resume when core state has been modified
[openocd.git] / src / target / arm_dpm.c
index b602b80e4a592ba66065980c00d421257ad55005..8ad6575cf697d74985660994b4e3b91d3832bbd3 100644 (file)
@@ -12,9 +12,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the
- * Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -230,6 +228,18 @@ static int dpm_write_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
        return retval;
 }
 
+/**
+ * Write to program counter and switch the core state (arm/thumb) according to
+ * the address.
+ */
+static int dpm_write_pc_core_state(struct arm_dpm *dpm, struct reg *r)
+{
+       uint32_t value = buf_get_u32(r->value, 0, 32);
+
+       /* read r0 from DCC; then "BX r0" */
+       return dpm->instr_write_data_r0(dpm, ARMV4_5_BX(0), value);
+}
+
 /**
  * Read basic registers of the the current context:  R0 to R15, and CPSR;
  * sets the core mode (such as USR or IRQ) and state (such as ARM or Thumb).
@@ -467,6 +477,19 @@ int arm_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp)
                goto done;
        arm->cpsr->dirty = false;
 
+       /* restore the PC, make sure to also switch the core state
+        * to whatever it was set to with "arm core_state" command.
+        * target code will have set PC to an appropriate resume address.
+        */
+       retval = dpm_write_pc_core_state(dpm, arm->pc);
+       if (retval != ERROR_OK)
+               goto done;
+       /* on Cortex-A5 (as found on NXP VF610 SoC), BX instruction
+        * executed in debug state doesn't appear to set the PC,
+        * explicitly set it with a "MOV pc, r0". This doesn't influence
+        * CPSR on Cortex-A9 so it should be OK. Maybe due to different
+        * debug version?
+        */
        retval = dpm_write_reg(dpm, arm->pc, 15);
        if (retval != ERROR_OK)
                goto done;
@@ -571,7 +594,7 @@ fail:
 }
 
 static int arm_dpm_write_core_reg(struct target *target, struct reg *r,
-       int regnum, enum arm_mode mode, uint32_t value)
+       int regnum, enum arm_mode mode, uint8_t *value)
 {
        struct arm_dpm *dpm = target_to_arm(target)->dpm;
        int retval;
@@ -648,14 +671,15 @@ static int arm_dpm_full_context(struct target *target)
                                did_read = true;
                                mode = r->mode;
 
-                               /* For R8..R12 when we've entered debug
-                                * state in FIQ mode... patch mode.
+                               /* For regular (ARM_MODE_ANY) R8..R12
+                                * in case we've entered debug state
+                                * in FIQ mode we need to patch mode.
                                 */
-                               if (mode == ARM_MODE_ANY)
-                                       mode = ARM_MODE_USR;
+                               if (mode != ARM_MODE_ANY)
+                                       retval = dpm_modeswitch(dpm, mode);
+                               else
+                                       retval = dpm_modeswitch(dpm, ARM_MODE_USR);
 
-                               /* REVISIT error checks */
-                               retval = dpm_modeswitch(dpm, mode);
                                if (retval != ERROR_OK)
                                        goto done;
                        }

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)