All of lore.kernel.org
 help / color / mirror / Atom feed
From: Richard Henderson <richard.henderson@linaro.org>
To: qemu-devel@nongnu.org
Cc: edgar.iglesias@gmail.com
Subject: [PATCH 58/77] target/microblaze: Use cc->do_unaligned_access
Date: Tue, 25 Aug 2020 13:59:31 -0700	[thread overview]
Message-ID: <20200825205950.730499-59-richard.henderson@linaro.org> (raw)
In-Reply-To: <20200825205950.730499-1-richard.henderson@linaro.org>

This fixes the problem in which unaligned stores succeeded,
but then we raised the exception after modifying memory.
Store the ESS for the unaligned data access in the iflags
for the insn, so that it can be found during unwind.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h       | 10 ++++-
 target/microblaze/helper.h    |  1 -
 target/microblaze/cpu.c       |  1 +
 target/microblaze/helper.c    | 28 ++++++++++++++
 target/microblaze/op_helper.c | 21 ----------
 target/microblaze/translate.c | 72 +++++++++++++----------------------
 6 files changed, 64 insertions(+), 69 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index 83fadd36a5..63b8d93d41 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -79,10 +79,13 @@ typedef struct CPUMBState CPUMBState;
 
 /* Exception State Register (ESR) Fields */
 #define          ESR_DIZ       (1<<11) /* Zone Protection */
+#define          ESR_W         (1<<11) /* Unaligned word access */
 #define          ESR_S         (1<<10) /* Store instruction */
 
 #define          ESR_ESS_FSL_OFFSET     5
 
+#define          ESR_ESS_MASK  (0x7f << 5)
+
 #define          ESR_EC_FSL             0
 #define          ESR_EC_UNALIGNED_DATA  1
 #define          ESR_EC_ILLEGAL_OP      2
@@ -256,9 +259,11 @@ struct CPUMBState {
     /* Internal flags.  */
 #define IMM_FLAG        (1 << 0)
 #define BIMM_FLAG       (1 << 1)
-/* MSR_EE               (1 << 8)  */
+#define ESR_ESS_FLAG    (1 << 2)  /* indicates ESR_ESS_MASK is present */
+/* MSR_EE               (1 << 8)  -- these 3 are not in iflags but tb_flags */
 /* MSR_UM               (1 << 11) */
 /* MSR_VM               (1 << 13) */
+/* ESR_ESS_MASK         [11:5]    -- unwind into iflags for unaligned excp */
 #define DRTI_FLAG	(1 << 16)
 #define DRTE_FLAG	(1 << 17)
 #define DRTB_FLAG	(1 << 18)
@@ -330,6 +335,9 @@ struct MicroBlazeCPU {
 
 void mb_cpu_do_interrupt(CPUState *cs);
 bool mb_cpu_exec_interrupt(CPUState *cs, int int_req);
+void mb_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
+                                MMUAccessType access_type,
+                                int mmu_idx, uintptr_t retaddr);
 void mb_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int mb_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/microblaze/helper.h b/target/microblaze/helper.h
index a473c1867b..3980fba797 100644
--- a/target/microblaze/helper.h
+++ b/target/microblaze/helper.h
@@ -25,7 +25,6 @@ DEF_HELPER_3(mmu_read, i32, env, i32, i32)
 DEF_HELPER_4(mmu_write, void, env, i32, i32, i32)
 #endif
 
-DEF_HELPER_5(memalign, void, env, tl, i32, i32, i32)
 DEF_HELPER_FLAGS_2(stackprot, TCG_CALL_NO_WG, void, env, tl)
 
 DEF_HELPER_2(get, i32, i32, i32)
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index 1eabf5cc3f..67017ecc33 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -317,6 +317,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = mb_cpu_class_by_name;
     cc->has_work = mb_cpu_has_work;
     cc->do_interrupt = mb_cpu_do_interrupt;
+    cc->do_unaligned_access = mb_cpu_do_unaligned_access;
     cc->cpu_exec_interrupt = mb_cpu_exec_interrupt;
     cc->dump_state = mb_cpu_dump_state;
     cc->set_pc = mb_cpu_set_pc;
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index 06f4322e09..0e3be251a7 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -296,3 +296,31 @@ bool mb_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
     }
     return false;
 }
+
+void mb_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
+                                MMUAccessType access_type,
+                                int mmu_idx, uintptr_t retaddr)
+{
+    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+    uint32_t esr, iflags;
+
+    /* Recover the pc and iflags from the corresponding insn_start.  */
+    cpu_restore_state(cs, retaddr, true);
+    iflags = cpu->env.iflags;
+
+    qemu_log_mask(CPU_LOG_INT,
+                  "Unaligned access addr=" TARGET_FMT_lx
+                  " pc=%x iflags=%x\n", addr, cpu->env.pc, iflags);
+
+    esr = ESR_EC_UNALIGNED_DATA;
+    if (likely(iflags & ESR_ESS_FLAG)) {
+        esr |= iflags & ESR_ESS_MASK;
+    } else {
+        qemu_log_mask(LOG_UNIMP, "Unaligned access without ESR_ESS_FLAG\n");
+    }
+
+    cpu->env.ear = addr;
+    cpu->env.esr = esr;
+    cs->exception_index = EXCP_HW_EXCP;
+    cpu_loop_exit(cs);
+}
diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index a99c467364..4a07d0ce3c 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -365,27 +365,6 @@ uint32_t helper_pcmpbf(uint32_t a, uint32_t b)
     return 0;
 }
 
-void helper_memalign(CPUMBState *env, target_ulong addr,
-                     uint32_t dr, uint32_t wr,
-                     uint32_t mask)
-{
-    if (addr & mask) {
-            qemu_log_mask(CPU_LOG_INT,
-                          "unaligned access addr=" TARGET_FMT_lx
-                          " mask=%x, wr=%d dr=r%d\n",
-                          addr, mask, wr, dr);
-            env->ear = addr;
-            env->esr = ESR_EC_UNALIGNED_DATA | (wr << 10) | (dr & 31) << 5;
-            if (mask == 3) {
-                env->esr |= 1 << 11;
-            }
-            if (!(env->msr & MSR_EE)) {
-                return;
-            }
-            helper_raise_exception(env, EXCP_HW_EXCP);
-    }
-}
-
 void helper_stackprot(CPUMBState *env, target_ulong addr)
 {
     if (addr < env->slr || addr > env->shr) {
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 930b8a9600..6e70873333 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -751,10 +751,22 @@ static TCGv compute_ldst_addr_ea(DisasContext *dc, int ra, int rb)
     return ret;
 }
 
+static void record_unaligned_ess(DisasContext *dc, int rd,
+                                 MemOp size, bool store)
+{
+    uint32_t iflags = tcg_get_insn_start_param(dc->insn_start, 1);
+
+    iflags |= ESR_ESS_FLAG;
+    iflags |= rd << 5;
+    iflags |= store * ESR_S;
+    iflags |= (size == MO_32) * ESR_W;
+
+    tcg_set_insn_start_param(dc->insn_start, 1, iflags);
+}
+
 static bool do_load(DisasContext *dc, int rd, TCGv addr, MemOp mop,
                     int mem_index, bool rev)
 {
-    TCGv_i32 v;
     MemOp size = mop & MO_SIZE;
 
     /*
@@ -774,34 +786,15 @@ static bool do_load(DisasContext *dc, int rd, TCGv addr, MemOp mop,
 
     sync_jmpstate(dc);
 
-    /*
-     * Microblaze gives MMU faults priority over faults due to
-     * unaligned addresses. That's why we speculatively do the load
-     * into v. If the load succeeds, we verify alignment of the
-     * address and if that succeeds we write into the destination reg.
-     */
-    v = tcg_temp_new_i32();
-    tcg_gen_qemu_ld_i32(v, addr, mem_index, mop);
-
-    /* TODO: Convert to CPUClass::do_unaligned_access.  */
-    if (dc->cpu->cfg.unaligned_exceptions && size > MO_8) {
-        TCGv_i32 t0 = tcg_const_i32(0);
-        TCGv_i32 treg = tcg_const_i32(rd);
-        TCGv_i32 tsize = tcg_const_i32((1 << size) - 1);
-
-        tcg_gen_movi_i32(cpu_pc, dc->base.pc_next);
-        gen_helper_memalign(cpu_env, addr, treg, t0, tsize);
-
-        tcg_temp_free_i32(t0);
-        tcg_temp_free_i32(treg);
-        tcg_temp_free_i32(tsize);
+    if (size > MO_8 &&
+        (dc->tb_flags & MSR_EE) &&
+        dc->cpu->cfg.unaligned_exceptions) {
+        record_unaligned_ess(dc, rd, size, false);
+        mop |= MO_ALIGN;
     }
 
-    if (rd) {
-        tcg_gen_mov_i32(cpu_R[rd], v);
-    }
+    tcg_gen_qemu_ld_i32(reg_for_write(dc, rd), addr, mem_index, mop);
 
-    tcg_temp_free_i32(v);
     tcg_temp_free(addr);
     return true;
 }
@@ -931,28 +924,15 @@ static bool do_store(DisasContext *dc, int rd, TCGv addr, MemOp mop,
 
     sync_jmpstate(dc);
 
-    tcg_gen_qemu_st_i32(reg_for_read(dc, rd), addr, mem_index, mop);
-
-    /* TODO: Convert to CPUClass::do_unaligned_access.  */
-    if (dc->cpu->cfg.unaligned_exceptions && size > MO_8) {
-        TCGv_i32 t1 = tcg_const_i32(1);
-        TCGv_i32 treg = tcg_const_i32(rd);
-        TCGv_i32 tsize = tcg_const_i32((1 << size) - 1);
-
-        tcg_gen_movi_i32(cpu_pc, dc->base.pc_next);
-        /* FIXME: if the alignment is wrong, we should restore the value
-         *        in memory. One possible way to achieve this is to probe
-         *        the MMU prior to the memaccess, thay way we could put
-         *        the alignment checks in between the probe and the mem
-         *        access.
-         */
-        gen_helper_memalign(cpu_env, addr, treg, t1, tsize);
-
-        tcg_temp_free_i32(t1);
-        tcg_temp_free_i32(treg);
-        tcg_temp_free_i32(tsize);
+    if (size > MO_8 &&
+        (dc->tb_flags & MSR_EE) &&
+        dc->cpu->cfg.unaligned_exceptions) {
+        record_unaligned_ess(dc, rd, size, true);
+        mop |= MO_ALIGN;
     }
 
+    tcg_gen_qemu_st_i32(reg_for_read(dc, rd), addr, mem_index, mop);
+
     tcg_temp_free(addr);
     return true;
 }
-- 
2.25.1



  parent reply	other threads:[~2020-08-25 21:34 UTC|newest]

Thread overview: 102+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-25 20:58 [PATCH 00/77] target/microblaze improvements Richard Henderson
2020-08-25 20:58 ` [PATCH 01/77] tests/tcg: Add microblaze to arches filter Richard Henderson
2020-08-26 16:20   ` Edgar E. Iglesias
2020-08-25 20:58 ` [PATCH 02/77] tests/tcg: Do not require FE_TOWARDZERO Richard Henderson
2020-08-26 16:20   ` Edgar E. Iglesias
2020-08-25 20:58 ` [PATCH 03/77] tests/tcg: Do not require FE_* exception bits Richard Henderson
2020-08-26 16:21   ` Edgar E. Iglesias
2020-08-25 20:58 ` [PATCH 04/77] target/microblaze: Tidy gdbstub Richard Henderson
2020-08-25 20:58 ` [PATCH 05/77] target/microblaze: Split out PC from env->sregs Richard Henderson
2020-08-25 20:58 ` [PATCH 06/77] target/microblaze: Split out MSR " Richard Henderson
2020-08-25 20:58 ` [PATCH 07/77] target/microblaze: Split out EAR " Richard Henderson
2020-08-25 20:58 ` [PATCH 08/77] target/microblaze: Split out ESR " Richard Henderson
2020-08-25 20:58 ` [PATCH 09/77] target/microblaze: Split out FSR " Richard Henderson
2020-08-25 20:58 ` [PATCH 10/77] target/microblaze: Split out BTR " Richard Henderson
2020-08-25 20:58 ` [PATCH 11/77] target/microblaze: Split out EDR " Richard Henderson
2020-08-25 20:58 ` [PATCH 12/77] target/microblaze: Split the cpu_SR array Richard Henderson
2020-08-25 20:58 ` [PATCH 13/77] target/microblaze: Fix width of PC and BTARGET Richard Henderson
2020-08-25 20:58 ` [PATCH 14/77] target/microblaze: Fix width of MSR Richard Henderson
2020-08-25 20:58 ` [PATCH 15/77] target/microblaze: Fix width of ESR Richard Henderson
2020-08-25 20:58 ` [PATCH 16/77] target/microblaze: Fix width of FSR Richard Henderson
2020-08-25 20:58 ` [PATCH 17/77] target/microblaze: Fix width of BTR Richard Henderson
2020-08-25 20:58 ` [PATCH 18/77] target/microblaze: Fix width of EDR Richard Henderson
2020-08-25 20:58 ` [PATCH 19/77] target/microblaze: Remove cpu_ear Richard Henderson
2020-08-25 20:58 ` [PATCH 20/77] target/microblaze: Tidy raising of exceptions Richard Henderson
2020-08-25 20:58 ` [PATCH 21/77] target/microblaze: Mark raise_exception as noreturn Richard Henderson
2020-08-25 20:58 ` [PATCH 22/77] target/microblaze: Remove helper_debug and env->debug Richard Henderson
2020-08-25 20:58 ` [PATCH 23/77] target/microblaze: Rename env_* tcg variables to cpu_* Richard Henderson
2020-08-25 20:58 ` [PATCH 24/77] target/microblaze: Tidy mb_tcg_init Richard Henderson
2020-08-25 20:58 ` [PATCH 25/77] target/microblaze: Split out MSR[C] to its own variable Richard Henderson
2020-08-25 20:58 ` [PATCH 26/77] target/microblaze: Use DISAS_NORETURN Richard Henderson
2020-08-25 20:59 ` [PATCH 27/77] target/microblaze: Check singlestep_enabled in gen_goto_tb Richard Henderson
2020-08-25 20:59 ` [PATCH 28/77] target/microblaze: Convert to DisasContextBase Richard Henderson
2020-08-25 20:59 ` [PATCH 29/77] target/microblaze: Convert to translator_loop Richard Henderson
2020-08-25 20:59 ` [PATCH 30/77] target/microblaze: Remove SIM_COMPAT Richard Henderson
2020-08-25 20:59 ` [PATCH 31/77] target/microblaze: Remove DISAS_GNU Richard Henderson
2020-08-25 20:59 ` [PATCH 32/77] target/microblaze: Remove empty D macros Richard Henderson
2020-08-25 20:59 ` [PATCH 33/77] target/microblaze: Remove LOG_DIS Richard Henderson
2020-08-25 20:59 ` [PATCH 34/77] target/microblaze: Ensure imm constant is always available Richard Henderson
2020-08-25 20:59 ` [PATCH 35/77] target/microblaze: Add decodetree infrastructure Richard Henderson
2020-08-25 20:59 ` [PATCH 36/77] target/microblaze: Convert dec_add to decodetree Richard Henderson
2020-08-25 20:59 ` [PATCH 37/77] target/microblaze: Convert dec_sub " Richard Henderson
2020-08-25 20:59 ` [PATCH 38/77] target/microblaze: Implement cmp and cmpu inline Richard Henderson
2020-08-25 20:59 ` [PATCH 39/77] target/microblaze: Convert dec_pattern to decodetree Richard Henderson
2020-08-25 20:59 ` [PATCH 40/77] target/microblaze: Convert dec_and, dec_or, dec_xor " Richard Henderson
2020-08-25 20:59 ` [PATCH 41/77] target/microblaze: Convert dec_mul " Richard Henderson
2020-08-25 20:59 ` [PATCH 42/77] target/microblaze: Convert dec_div " Richard Henderson
2020-08-25 20:59 ` [PATCH 43/77] target/microblaze: Unwind properly when raising divide-by-zero Richard Henderson
2020-08-25 20:59 ` [PATCH 44/77] target/microblaze: Convert dec_bit to decodetree Richard Henderson
2020-08-25 20:59 ` [PATCH 45/77] target/microblaze: Convert dec_barrel " Richard Henderson
2020-08-25 20:59 ` [PATCH 46/77] target/microblaze: Convert dec_imm " Richard Henderson
2020-08-25 20:59 ` [PATCH 47/77] target/microblaze: Convert dec_fpu " Richard Henderson
2020-08-25 20:59 ` [PATCH 48/77] target/microblaze: Fix cpu unwind for fpu exceptions Richard Henderson
2020-08-25 20:59 ` [PATCH 49/77] target/microblaze: Mark fpu helpers TCG_CALL_NO_WG Richard Henderson
2020-08-25 20:59 ` [PATCH 50/77] target/microblaze: Replace MSR_EE_FLAG with MSR_EE Richard Henderson
2020-08-25 20:59 ` [PATCH 51/77] target/microblaze: Cache mem_index in DisasContext Richard Henderson
2020-08-25 20:59 ` [PATCH 52/77] target/microblaze: Fix cpu unwind for stackprot Richard Henderson
2020-08-25 20:59 ` [PATCH 53/77] target/microblaze: Convert dec_load and dec_store to decodetree Richard Henderson
2020-08-25 20:59 ` [PATCH 54/77] target/microblaze: Assert no overlap in flags making up tb_flags Richard Henderson
2020-08-25 20:59 ` [PATCH 55/77] target/microblaze: Move bimm to BIMM_FLAG Richard Henderson
2020-08-25 20:59 ` [PATCH 56/77] target/microblaze: Store "current" iflags in insn_start Richard Henderson
2020-08-25 20:59 ` [PATCH 57/77] tcg: Add tcg_get_insn_start_param Richard Henderson
2020-08-25 20:59 ` Richard Henderson [this message]
2020-08-25 20:59 ` [PATCH 59/77] target/microblaze: Replace clear_imm with tb_flags_to_set Richard Henderson
2020-08-25 20:59 ` [PATCH 60/77] target/microblaze: Replace delayed_branch " Richard Henderson
2020-08-25 20:59 ` [PATCH 61/77] target/microblaze: Tidy mb_cpu_dump_state Richard Henderson
2020-08-25 20:59 ` [PATCH 62/77] target/microblaze: Try to keep imm and delay slot together Richard Henderson
2020-08-27 19:17   ` Edgar E. Iglesias
2020-08-27 21:33     ` Richard Henderson
2020-08-29 15:27     ` Richard Henderson
2020-08-25 20:59 ` [PATCH 63/77] target/microblaze: Convert brk and brki to decodetree Richard Henderson
2020-08-25 20:59 ` [PATCH 64/77] target/microblaze: Convert mbar " Richard Henderson
2020-08-27  9:24   ` Edgar E. Iglesias
2020-08-27  9:58     ` Richard Henderson
2020-08-27 10:08       ` Edgar E. Iglesias
2020-08-27 11:11         ` Richard Henderson
2020-08-25 20:59 ` [PATCH 65/77] target/microblaze: Reorganize branching Richard Henderson
2020-08-25 20:59 ` [PATCH 66/77] target/microblaze: Use tcg_gen_lookup_and_goto_ptr Richard Henderson
2020-08-28  6:33   ` Edgar E. Iglesias
2020-08-28 13:32     ` Richard Henderson
2020-08-25 20:59 ` [PATCH 67/77] target/microblaze: Convert dec_br to decodetree Richard Henderson
2020-08-25 20:59 ` [PATCH 68/77] target/microblaze: Convert dec_bcc " Richard Henderson
2020-08-25 20:59 ` [PATCH 69/77] target/microblaze: Convert dec_rts " Richard Henderson
2020-08-25 20:59 ` [PATCH 70/77] target/microblaze: Tidy do_rti, do_rtb, do_rte Richard Henderson
2020-08-25 20:59 ` [PATCH 71/77] target/microblaze: Convert msrclr, msrset to decodetree Richard Henderson
2020-08-25 20:59 ` [PATCH 72/77] target/microblaze: Convert dec_msr " Richard Henderson
2020-08-25 20:59 ` [PATCH 73/77] target/microblaze: Convert dec_stream " Richard Henderson
2020-08-27 21:10   ` Edgar E. Iglesias
2020-08-27 21:12     ` Richard Henderson
2020-08-25 20:59 ` [PATCH 74/77] target/microblaze: Remove last of old decoder Richard Henderson
2020-08-25 20:59 ` [PATCH 75/77] target/microblaze: Remove cpu_R[0] Richard Henderson
2020-08-25 20:59 ` [PATCH 76/77] target/microblaze: Add flags markup to some helpers Richard Henderson
2020-08-25 20:59 ` [PATCH 77/77] target/microblaze: Reduce linux-user address space to 32-bit Richard Henderson
2020-08-26 15:27 ` [PATCH 00/77] target/microblaze improvements Edgar E. Iglesias
2020-08-26 18:07 ` Edgar E. Iglesias
2020-08-27  9:11 ` Edgar E. Iglesias
2020-08-27 10:01   ` Richard Henderson
2020-08-27 10:22     ` Edgar E. Iglesias
2020-08-27 11:19       ` Richard Henderson
2020-08-27 17:09         ` Edgar E. Iglesias
2020-08-28 13:36           ` Richard Henderson
2020-08-28 14:04             ` Edgar E. Iglesias
2020-08-28 13:19 ` Edgar E. Iglesias

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200825205950.730499-59-richard.henderson@linaro.org \
    --to=richard.henderson@linaro.org \
    --cc=edgar.iglesias@gmail.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.