summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2021-03-12 18:56:56 +0000
committerPeter Maydell <peter.maydell@linaro.org>2021-03-12 18:56:56 +0000
commit8e6bc6cdc82d45f203bc9fc4342c0452214c74fe (patch)
tree04bfff6f6d509d0d3e63e2d7eecc9529fd20d9b3
parent3f8d1885e48e4d72eab0688f604de62e0aea7a38 (diff)
parenta9431a03f70c8c711a870d4c1a0439bdbb4703cf (diff)
downloadfocaccia-qemu-8e6bc6cdc82d45f203bc9fc4342c0452214c74fe.tar.gz
focaccia-qemu-8e6bc6cdc82d45f203bc9fc4342c0452214c74fe.zip
Merge remote-tracking branch 'remotes/vivier/tags/m68k-for-6.0-pull-request' into staging
Prepare MacOS ROM support:
  - add RTR instruction
  - fix unaligned access requirement
  - fix ATC bit (68040 MMU)

# gpg: Signature made Thu 11 Mar 2021 22:18:11 GMT
# gpg:                using RSA key CD2F75DDC8E3A4DC2E4F5173F30C38BD3F2FBE3C
# gpg:                issuer "laurent@vivier.eu"
# gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" [full]
# gpg:                 aka "Laurent Vivier <laurent@vivier.eu>" [full]
# gpg:                 aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" [full]
# Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F  5173 F30C 38BD 3F2F BE3C

* remotes/vivier/tags/m68k-for-6.0-pull-request:
  target/m68k: add M68K_FEATURE_UNALIGNED_DATA feature
  target/m68k: reformat m68k_features enum
  target/m68k: don't set SSW ATC bit for physical bus errors
  target/m68k: implement rtr instruction

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--target/m68k/cpu.c1
-rw-r--r--target/m68k/cpu.h68
-rw-r--r--target/m68k/op_helper.c17
-rw-r--r--target/m68k/translate.c20
4 files changed, 82 insertions, 24 deletions
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index 37d2ed9dc7..a14874b4da 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -161,6 +161,7 @@ static void m68020_cpu_initfn(Object *obj)
     m68k_set_feature(env, M68K_FEATURE_CAS);
     m68k_set_feature(env, M68K_FEATURE_CHK2);
     m68k_set_feature(env, M68K_FEATURE_MSP);
+    m68k_set_feature(env, M68K_FEATURE_UNALIGNED_DATA);
 }
 
 /*
diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
index 7c3feeaf8a..402c86c876 100644
--- a/target/m68k/cpu.h
+++ b/target/m68k/cpu.h
@@ -475,36 +475,60 @@ void do_m68k_semihosting(CPUM68KState *env, int nr);
  */
 
 enum m68k_features {
-    M68K_FEATURE_M68000,   /* Base m68k instruction set */
+    /* Base m68k instruction set */
+    M68K_FEATURE_M68000,
     M68K_FEATURE_M68010,
     M68K_FEATURE_M68020,
     M68K_FEATURE_M68030,
     M68K_FEATURE_M68040,
     M68K_FEATURE_M68060,
-    M68K_FEATURE_CF_ISA_A, /* Base Coldfire set Rev A. */
-    M68K_FEATURE_CF_ISA_B, /* (ISA B or C). */
-    M68K_FEATURE_CF_ISA_APLUSC, /* BIT/BITREV, FF1, STRLDSR (ISA A+ or C). */
-    M68K_FEATURE_BRAL, /* BRA with Long branch. (680[2346]0, ISA A+ or B). */
+    /* Base Coldfire set Rev A. */
+    M68K_FEATURE_CF_ISA_A,
+    /* (ISA B or C). */
+    M68K_FEATURE_CF_ISA_B,
+    /* BIT/BITREV, FF1, STRLDSR (ISA A+ or C). */
+    M68K_FEATURE_CF_ISA_APLUSC,
+    /* BRA with Long branch. (680[2346]0, ISA A+ or B). */
+    M68K_FEATURE_BRAL,
     M68K_FEATURE_CF_FPU,
     M68K_FEATURE_CF_MAC,
     M68K_FEATURE_CF_EMAC,
-    M68K_FEATURE_CF_EMAC_B,   /* Revision B EMAC (dual accumulate). */
-    M68K_FEATURE_USP, /* User Stack Pointer. (680[012346]0, ISA A+, B or C).*/
-    M68K_FEATURE_MSP, /* Master Stack Pointer. (680[234]0) */
-    M68K_FEATURE_EXT_FULL,    /* 68020+ full extension word. */
-    M68K_FEATURE_WORD_INDEX,  /* word sized address index registers. */
-    M68K_FEATURE_SCALED_INDEX, /* scaled address index registers. */
-    M68K_FEATURE_LONG_MULDIV, /* 32 bit mul/div. (680[2346]0, and CPU32) */
-    M68K_FEATURE_QUAD_MULDIV, /* 64 bit mul/div. (680[2346]0, and CPU32) */
-    M68K_FEATURE_BCCL,  /* Bcc with Long branches. (680[2346]0, and CPU32) */
-    M68K_FEATURE_BITFIELD, /* BFxxx Bit field insns. (680[2346]0) */
-    M68K_FEATURE_FPU,   /* fpu insn. (680[46]0) */
-    M68K_FEATURE_CAS,   /* CAS/CAS2[WL] insns. (680[2346]0) */
-    M68K_FEATURE_BKPT,  /* BKPT insn. (680[12346]0, and CPU32) */
-    M68K_FEATURE_RTD,   /* RTD insn. (680[12346]0, and CPU32) */
-    M68K_FEATURE_CHK2,  /* CHK2 insn. (680[2346]0, and CPU32) */
-    M68K_FEATURE_MOVEP, /* MOVEP insn. (680[01234]0, and CPU32) */
-    M68K_FEATURE_MOVEC, /* MOVEC insn. (from 68010) */
+    /* Revision B EMAC (dual accumulate). */
+    M68K_FEATURE_CF_EMAC_B,
+    /* User Stack Pointer. (680[012346]0, ISA A+, B or C). */
+    M68K_FEATURE_USP,
+    /* Master Stack Pointer. (680[234]0) */
+    M68K_FEATURE_MSP,
+    /* 68020+ full extension word. */
+    M68K_FEATURE_EXT_FULL,
+    /* word sized address index registers. */
+    M68K_FEATURE_WORD_INDEX,
+    /* scaled address index registers. */
+    M68K_FEATURE_SCALED_INDEX,
+    /* 32 bit mul/div. (680[2346]0, and CPU32) */
+    M68K_FEATURE_LONG_MULDIV,
+    /* 64 bit mul/div. (680[2346]0, and CPU32) */
+    M68K_FEATURE_QUAD_MULDIV,
+    /* Bcc with Long branches. (680[2346]0, and CPU32) */
+    M68K_FEATURE_BCCL,
+    /* BFxxx Bit field insns. (680[2346]0) */
+    M68K_FEATURE_BITFIELD,
+    /* fpu insn. (680[46]0) */
+    M68K_FEATURE_FPU,
+    /* CAS/CAS2[WL] insns. (680[2346]0) */
+    M68K_FEATURE_CAS,
+    /* BKPT insn. (680[12346]0, and CPU32) */
+    M68K_FEATURE_BKPT,
+    /* RTD insn. (680[12346]0, and CPU32) */
+    M68K_FEATURE_RTD,
+    /* CHK2 insn. (680[2346]0, and CPU32) */
+    M68K_FEATURE_CHK2,
+    /* MOVEP insn. (680[01234]0, and CPU32) */
+    M68K_FEATURE_MOVEP,
+    /* MOVEC insn. (from 68010) */
+    M68K_FEATURE_MOVEC,
+    /* Unaligned data accesses (680[2346]0) */
+    M68K_FEATURE_UNALIGNED_DATA,
 };
 
 static inline int m68k_feature(CPUM68KState *env, int feature)
diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
index 9b0698f267..ae1ba4b437 100644
--- a/target/m68k/op_helper.c
+++ b/target/m68k/op_helper.c
@@ -348,7 +348,10 @@ static void m68k_interrupt_all(CPUM68KState *env, int is_hw)
     cpu_m68k_set_sr(env, sr);
     sp = env->aregs[7];
 
-    sp &= ~1;
+    if (!m68k_feature(env, M68K_FEATURE_UNALIGNED_DATA)) {
+        sp &= ~1;
+    }
+
     if (cs->exception_index == EXCP_ACCESS) {
         if (env->mmu.fault) {
             cpu_abort(cs, "DOUBLE MMU FAULT\n");
@@ -468,7 +471,17 @@ void m68k_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
 
     if (m68k_feature(env, M68K_FEATURE_M68040)) {
         env->mmu.mmusr = 0;
-        env->mmu.ssw |= M68K_ATC_040;
+
+        /*
+         * According to the MC68040 users manual the ATC bit of the SSW is
+         * used to distinguish between ATC faults and physical bus errors.
+         * In the case of a bus error e.g. during nubus read from an empty
+         * slot this bit should not be set
+         */
+        if (response != MEMTX_DECODE_ERROR) {
+            env->mmu.ssw |= M68K_ATC_040;
+        }
+
         /* FIXME: manage MMU table access error */
         env->mmu.ssw &= ~M68K_TM_040;
         if (env->sr & SR_S) { /* SUPERVISOR */
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index ac936ebe8f..200018ae6a 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -2969,6 +2969,25 @@ DISAS_INSN(rtd)
     gen_jmp(s, tmp);
 }
 
+DISAS_INSN(rtr)
+{
+    TCGv tmp;
+    TCGv ccr;
+    TCGv sp;
+
+    sp = tcg_temp_new();
+    ccr = gen_load(s, OS_WORD, QREG_SP, 0, IS_USER(s));
+    tcg_gen_addi_i32(sp, QREG_SP, 2);
+    tmp = gen_load(s, OS_LONG, sp, 0, IS_USER(s));
+    tcg_gen_addi_i32(QREG_SP, sp, 4);
+    tcg_temp_free(sp);
+
+    gen_set_sr(s, ccr, true);
+    tcg_temp_free(ccr);
+
+    gen_jmp(s, tmp);
+}
+
 DISAS_INSN(rts)
 {
     TCGv tmp;
@@ -6015,6 +6034,7 @@ void register_m68k_insns (CPUM68KState *env)
     BASE(nop,       4e71, ffff);
     INSN(rtd,       4e74, ffff, RTD);
     BASE(rts,       4e75, ffff);
+    INSN(rtr,       4e77, ffff, M68000);
     BASE(jump,      4e80, ffc0);
     BASE(jump,      4ec0, ffc0);
     INSN(addsubq,   5000, f080, M68000);