aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>2021-03-08 12:11:55 +0000
committerLaurent Vivier <laurent@vivier.eu>2021-03-11 21:12:32 +0100
commita9431a03f70c8c711a870d4c1a0439bdbb4703cf (patch)
tree98a4da661d8f8093014142d086909a384c42ddf1
parent469949c90252d80693aa70652d8251d1d602557e (diff)
downloadqemu-a9431a03f70c8c711a870d4c1a0439bdbb4703cf.zip
qemu-a9431a03f70c8c711a870d4c1a0439bdbb4703cf.tar.gz
qemu-a9431a03f70c8c711a870d4c1a0439bdbb4703cf.tar.bz2
target/m68k: add M68K_FEATURE_UNALIGNED_DATA feature
According to the M68040UM Appendix D the requirement for data accesses to be word aligned is only for the 68000, 68008 and 68010 CPUs. Later CPUs from the 68020 onwards will allow unaligned data accesses but at the cost of being less efficient. Add a new M68K_FEATURE_UNALIGNED_DATA feature to specify that data accesses are not required to be word aligned, and don't perform the alignment on the stack pointer when taking an exception if this feature is not selected. This is required because the MacOS DAFB driver attempts to call an A-trap with a byte-aligned stack pointer during initialisation and without this the stack pointer is off by one when the A-trap returns. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20210308121155.2476-4-mark.cave-ayland@ilande.co.uk> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
-rw-r--r--target/m68k/cpu.c1
-rw-r--r--target/m68k/cpu.h2
-rw-r--r--target/m68k/op_helper.c5
3 files changed, 7 insertions, 1 deletions
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index 37d2ed9..a14874b 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 ce558e9..402c86c 100644
--- a/target/m68k/cpu.h
+++ b/target/m68k/cpu.h
@@ -527,6 +527,8 @@ enum m68k_features {
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 5f981e5..46ff81a 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");