aboutsummaryrefslogtreecommitdiff
path: root/target/microblaze
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2021-07-29 11:56:00 -1000
committerRichard Henderson <richard.henderson@linaro.org>2021-11-02 07:00:52 -0400
commitb414df757d73d0a1d37f14a866ff1338b93a4a27 (patch)
tree5fc9f41a1b3f66c16650e765a08c6b176ceb606e /target/microblaze
parentee8e0807de6f0ec70454ffbbb778c1246c45af2b (diff)
downloadqemu-b414df757d73d0a1d37f14a866ff1338b93a4a27.zip
qemu-b414df757d73d0a1d37f14a866ff1338b93a4a27.tar.gz
qemu-b414df757d73d0a1d37f14a866ff1338b93a4a27.tar.bz2
target/microblaze: Do not set MO_ALIGN for user-only
The kernel will fix up unaligned accesses, so emulate that by allowing unaligned accesses to succeed. Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/microblaze')
-rw-r--r--target/microblaze/translate.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 437bbed..2561b90 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -722,6 +722,7 @@ static TCGv compute_ldst_addr_ea(DisasContext *dc, int ra, int rb)
}
#endif
+#ifndef CONFIG_USER_ONLY
static void record_unaligned_ess(DisasContext *dc, int rd,
MemOp size, bool store)
{
@@ -734,6 +735,7 @@ static void record_unaligned_ess(DisasContext *dc, int rd,
tcg_set_insn_start_param(dc->insn_start, 1, iflags);
}
+#endif
static bool do_load(DisasContext *dc, int rd, TCGv addr, MemOp mop,
int mem_index, bool rev)
@@ -755,12 +757,19 @@ static bool do_load(DisasContext *dc, int rd, TCGv addr, MemOp mop,
}
}
+ /*
+ * For system mode, enforce alignment if the cpu configuration
+ * requires it. For user-mode, the Linux kernel will have fixed up
+ * any unaligned access, so emulate that by *not* setting MO_ALIGN.
+ */
+#ifndef CONFIG_USER_ONLY
if (size > MO_8 &&
(dc->tb_flags & MSR_EE) &&
dc->cfg->unaligned_exceptions) {
record_unaligned_ess(dc, rd, size, false);
mop |= MO_ALIGN;
}
+#endif
tcg_gen_qemu_ld_i32(reg_for_write(dc, rd), addr, mem_index, mop);
@@ -901,12 +910,19 @@ static bool do_store(DisasContext *dc, int rd, TCGv addr, MemOp mop,
}
}
+ /*
+ * For system mode, enforce alignment if the cpu configuration
+ * requires it. For user-mode, the Linux kernel will have fixed up
+ * any unaligned access, so emulate that by *not* setting MO_ALIGN.
+ */
+#ifndef CONFIG_USER_ONLY
if (size > MO_8 &&
(dc->tb_flags & MSR_EE) &&
dc->cfg->unaligned_exceptions) {
record_unaligned_ess(dc, rd, size, true);
mop |= MO_ALIGN;
}
+#endif
tcg_gen_qemu_st_i32(reg_for_read(dc, rd), addr, mem_index, mop);