From: Richard Henderson <richard.henderson@linaro.org>
To: qemu-devel@nongnu.org
Cc: marex@denx.de, peter.maydell@linaro.org, amir.gonnen@neuroblade.ai
Subject: [PATCH v5 25/48] target/nios2: Clean up handling of tlbmisc in do_exception
Date: Thu, 10 Mar 2022 03:27:02 -0800 [thread overview]
Message-ID: <20220310112725.570053-26-richard.henderson@linaro.org> (raw)
In-Reply-To: <20220310112725.570053-1-richard.henderson@linaro.org>
The 4 lower bits, D, PERM, BAD, DBL, are unconditionally set on any
exception with EH=0, or so says Table 42 (Processor Status After
Taking Exception).
We currently do not set PERM or BAD at all, and only set/clear
DBL for tlb miss, and do not clear DBL for any other exception.
It is a bit confusing to set D in tlb_fill and the rest during
do_interrupt, so move the setting of D to do_interrupt as well.
To do this, split EXP_TLBD into two cases, EXCP_TLB_X and EXCP_TLB_D,
which allows us to distinguish them during do_interrupt. Choose
a value for EXCP_TLB_D such that when truncated it produces the
correct value for exception.CAUSE.
Rename EXCP_TLB[RWX] to EXCP_PERM_[RWX], to emphasize that the
exception is permissions related. Rename EXCP_SUPER[AD] to
EXCP_SUPERA_[DX] to emphasize that they are both "supervisor
address" exceptions, data and execute.
Retain the setting of tlbmisc.WE for the fast-tlb-miss path, as it
is being relied upon, but remove it from the permission path.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/nios2/cpu.h | 13 +++---
target/nios2/helper.c | 102 +++++++++++++++++++++++++++++-------------
2 files changed, 77 insertions(+), 38 deletions(-)
diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h
index d003af5afc..c925cdd8e3 100644
--- a/target/nios2/cpu.h
+++ b/target/nios2/cpu.h
@@ -166,13 +166,14 @@ FIELD(CR_TLBMISC, EE, 24, 1)
#define EXCP_UNALIGN 6
#define EXCP_UNALIGND 7
#define EXCP_DIV 8
-#define EXCP_SUPERA 9
+#define EXCP_SUPERA_X 9
#define EXCP_SUPERI 10
-#define EXCP_SUPERD 11
-#define EXCP_TLBD 12
-#define EXCP_TLBX 13
-#define EXCP_TLBR 14
-#define EXCP_TLBW 15
+#define EXCP_SUPERA_D 11
+#define EXCP_TLB_X 12
+#define EXCP_TLB_D (0x1000 | EXCP_TLB_X)
+#define EXCP_PERM_X 13
+#define EXCP_PERM_R 14
+#define EXCP_PERM_W 15
#define EXCP_MPUI 16
#define EXCP_MPUD 17
diff --git a/target/nios2/helper.c b/target/nios2/helper.c
index afbafd1fdc..8b69918ba3 100644
--- a/target/nios2/helper.c
+++ b/target/nios2/helper.c
@@ -49,7 +49,8 @@ void nios2_cpu_record_sigsegv(CPUState *cs, vaddr addr,
#else /* !CONFIG_USER_ONLY */
-static void do_exception(Nios2CPU *cpu, uint32_t exception_addr, bool is_break)
+static void do_exception(Nios2CPU *cpu, uint32_t exception_addr,
+ uint32_t tlbmisc_set, bool is_break)
{
CPUNios2State *env = &cpu->env;
CPUState *cs = CPU(cpu);
@@ -68,6 +69,16 @@ static void do_exception(Nios2CPU *cpu, uint32_t exception_addr, bool is_break)
if (cpu->mmu_present) {
new_status |= CR_STATUS_EH;
+
+ /*
+ * There are 4 bits that are always written.
+ * Explicitly clear them, to be set via the argument.
+ */
+ env->ctrl[CR_TLBMISC] &= ~(CR_TLBMISC_D |
+ CR_TLBMISC_PERM |
+ CR_TLBMISC_BAD |
+ CR_TLBMISC_DBL);
+ env->ctrl[CR_TLBMISC] |= tlbmisc_set;
}
}
@@ -83,13 +94,14 @@ static void do_exception(Nios2CPU *cpu, uint32_t exception_addr, bool is_break)
static void do_iic_irq(Nios2CPU *cpu)
{
- do_exception(cpu, cpu->exception_addr, false);
+ do_exception(cpu, cpu->exception_addr, 0, false);
}
void nios2_cpu_do_interrupt(CPUState *cs)
{
Nios2CPU *cpu = NIOS2_CPU(cs);
CPUNios2State *env = &cpu->env;
+ uint32_t tlbmisc_set = 0;
if (qemu_loglevel_mask(CPU_LOG_INT)) {
const char *name = NULL;
@@ -98,20 +110,21 @@ void nios2_cpu_do_interrupt(CPUState *cs)
case EXCP_IRQ:
name = "interrupt";
break;
- case EXCP_TLBD:
+ case EXCP_TLB_X:
+ case EXCP_TLB_D:
if (env->ctrl[CR_STATUS] & CR_STATUS_EH) {
name = "TLB MISS (double)";
} else {
name = "TLB MISS (fast)";
}
break;
- case EXCP_TLBR:
- case EXCP_TLBW:
- case EXCP_TLBX:
+ case EXCP_PERM_R:
+ case EXCP_PERM_W:
+ case EXCP_PERM_X:
name = "TLB PERM";
break;
- case EXCP_SUPERA:
- case EXCP_SUPERD:
+ case EXCP_SUPERA_X:
+ case EXCP_SUPERA_D:
name = "SUPERVISOR (address)";
break;
case EXCP_SUPERI:
@@ -149,38 +162,60 @@ void nios2_cpu_do_interrupt(CPUState *cs)
do_iic_irq(cpu);
break;
- case EXCP_TLBD:
- if ((env->ctrl[CR_STATUS] & CR_STATUS_EH) == 0) {
- env->ctrl[CR_TLBMISC] &= ~CR_TLBMISC_DBL;
- env->ctrl[CR_TLBMISC] |= CR_TLBMISC_WE;
- do_exception(cpu, cpu->fast_tlb_miss_addr, false);
+ case EXCP_TLB_D:
+ tlbmisc_set = CR_TLBMISC_D;
+ /* fall through */
+ case EXCP_TLB_X:
+ if (env->ctrl[CR_STATUS] & CR_STATUS_EH) {
+ tlbmisc_set |= CR_TLBMISC_DBL;
+ /*
+ * Normally, we don't write to tlbmisc unless !EH,
+ * so do it manually for the double-tlb miss exception.
+ */
+ env->ctrl[CR_TLBMISC] &= ~(CR_TLBMISC_D |
+ CR_TLBMISC_PERM |
+ CR_TLBMISC_BAD);
+ env->ctrl[CR_TLBMISC] |= tlbmisc_set;
+ do_exception(cpu, cpu->exception_addr, 0, false);
} else {
- env->ctrl[CR_TLBMISC] |= CR_TLBMISC_DBL;
- do_exception(cpu, cpu->exception_addr, false);
+ /*
+ * ??? Implicitly setting tlbmisc.WE for the fast-tlb-miss
+ * handler appears to be out of spec. But, the linux kernel
+ * handler relies on it, writing to tlbacc without first
+ * setting tlbmisc.WE.
+ */
+ tlbmisc_set |= CR_TLBMISC_WE;
+ do_exception(cpu, cpu->fast_tlb_miss_addr, tlbmisc_set, false);
}
break;
- case EXCP_TLBR:
- case EXCP_TLBW:
- case EXCP_TLBX:
- if ((env->ctrl[CR_STATUS] & CR_STATUS_EH) == 0) {
- env->ctrl[CR_TLBMISC] |= CR_TLBMISC_WE;
- }
- do_exception(cpu, cpu->exception_addr, false);
+ case EXCP_PERM_R:
+ case EXCP_PERM_W:
+ tlbmisc_set = CR_TLBMISC_D;
+ /* fall through */
+ case EXCP_PERM_X:
+ tlbmisc_set |= CR_TLBMISC_PERM;
+ do_exception(cpu, cpu->exception_addr, tlbmisc_set, false);
+ break;
+
+ case EXCP_SUPERA_D:
+ case EXCP_UNALIGN:
+ tlbmisc_set = CR_TLBMISC_D;
+ /* fall through */
+ case EXCP_SUPERA_X:
+ case EXCP_UNALIGND:
+ tlbmisc_set |= CR_TLBMISC_BAD;
+ do_exception(cpu, cpu->exception_addr, tlbmisc_set, false);
break;
- case EXCP_SUPERA:
case EXCP_SUPERI:
- case EXCP_SUPERD:
case EXCP_ILLEGAL:
case EXCP_TRAP:
- case EXCP_UNALIGN:
- case EXCP_UNALIGND:
- do_exception(cpu, cpu->exception_addr, false);
+ do_exception(cpu, cpu->exception_addr, 0, false);
break;
case EXCP_BREAK:
- do_exception(cpu, cpu->exception_addr, true);
+ do_exception(cpu, cpu->exception_addr, 0, true);
break;
case EXCP_SEMIHOST:
@@ -235,7 +270,7 @@ bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
{
Nios2CPU *cpu = NIOS2_CPU(cs);
CPUNios2State *env = &cpu->env;
- unsigned int excp = EXCP_TLBD;
+ unsigned int excp;
target_ulong vaddr, paddr;
Nios2MMULookup lu;
unsigned int hit;
@@ -262,7 +297,8 @@ bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
if (probe) {
return false;
}
- cs->exception_index = EXCP_SUPERA;
+ cs->exception_index = (access_type == MMU_INST_FETCH
+ ? EXCP_SUPERA_X : EXCP_SUPERA_D);
env->ctrl[CR_BADADDR] = address;
cpu_loop_exit_restore(cs, retaddr);
}
@@ -283,8 +319,10 @@ bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
}
/* Permission violation */
- excp = (access_type == MMU_DATA_LOAD ? EXCP_TLBR :
- access_type == MMU_DATA_STORE ? EXCP_TLBW : EXCP_TLBX);
+ excp = (access_type == MMU_DATA_LOAD ? EXCP_PERM_R :
+ access_type == MMU_DATA_STORE ? EXCP_PERM_W : EXCP_PERM_X);
+ } else {
+ excp = (access_type == MMU_INST_FETCH ? EXCP_TLB_X: EXCP_TLB_D);
}
if (probe) {
--
2.25.1
next prev parent reply other threads:[~2022-03-10 12:21 UTC|newest]
Thread overview: 62+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-10 11:26 [PATCH v5 00/48] target/nios2: Shadow register set, EIC and VIC Richard Henderson
2022-03-10 11:26 ` [PATCH v5 01/48] target/nios2: Check supervisor on eret Richard Henderson
2022-03-10 11:26 ` [PATCH v5 02/48] target/nios2: Stop generating code if gen_check_supervisor fails Richard Henderson
2022-03-10 11:26 ` [PATCH v5 03/48] target/nios2: Add NUM_GP_REGS and NUM_CP_REGS Richard Henderson
2022-03-10 11:26 ` [PATCH v5 04/48] target/nios2: Split PC out of env->regs[] Richard Henderson
2022-03-10 11:26 ` [PATCH v5 05/48] target/nios2: Split out helper for eret instruction Richard Henderson
2022-03-10 11:26 ` [PATCH v5 06/48] target/nios2: Fix BRET instruction Richard Henderson
2022-03-10 12:17 ` Peter Maydell
2022-03-10 11:26 ` [PATCH v5 07/48] target/nios2: Do not create TCGv for control registers Richard Henderson
2022-03-10 11:26 ` [PATCH v5 08/48] linux-user/nios2: Only initialize SP and PC in target_cpu_copy_regs Richard Henderson
2022-03-10 12:18 ` Peter Maydell
2022-03-10 11:26 ` [PATCH v5 09/48] target/nios2: Remove cpu_interrupts_enabled Richard Henderson
2022-03-10 11:26 ` [PATCH v5 10/48] target/nios2: Split control registers away from general registers Richard Henderson
2022-03-10 11:26 ` [PATCH v5 11/48] target/nios2: Do not zero the general registers on reset Richard Henderson
2022-03-10 12:21 ` Peter Maydell
2022-03-10 18:45 ` Richard Henderson
2022-03-10 11:26 ` [PATCH v5 12/48] target/nios2: Clean up nios2_cpu_dump_state Richard Henderson
2022-03-10 11:26 ` [PATCH v5 13/48] target/nios2: Use hw/registerfields.h for CR_STATUS fields Richard Henderson
2022-03-10 11:26 ` [PATCH v5 14/48] target/nios2: Use hw/registerfields.h for CR_EXCEPTION fields Richard Henderson
2022-03-10 12:26 ` Peter Maydell
2022-03-10 17:52 ` Richard Henderson
2022-03-10 11:26 ` [PATCH v5 15/48] target/nios2: Use hw/registerfields.h for CR_TLBADDR fields Richard Henderson
2022-03-10 11:26 ` [PATCH v5 16/48] target/nios2: Use hw/registerfields.h for CR_TLBACC fields Richard Henderson
2022-03-10 11:26 ` [PATCH v5 17/48] target/nios2: Rename CR_TLBMISC_WR to CR_TLBMISC_WE Richard Henderson
2022-03-10 12:26 ` Peter Maydell
2022-03-10 11:26 ` [PATCH v5 18/48] target/nios2: Use hw/registerfields.h for CR_TLBMISC fields Richard Henderson
2022-03-10 11:26 ` [PATCH v5 19/48] target/nios2: Move R_FOO and CR_BAR into enumerations Richard Henderson
2022-03-10 11:26 ` [PATCH v5 20/48] target/nios2: Create EXCP_SEMIHOST for semi-hosting Richard Henderson
2022-03-10 11:26 ` [PATCH v5 21/48] target/nios2: Clean up nios2_cpu_do_interrupt Richard Henderson
2022-03-10 11:26 ` [PATCH v5 22/48] target/nios2: Hoist CPU_LOG_INT logging Richard Henderson
2022-03-10 11:27 ` [PATCH v5 23/48] target/nios2: Handle EXCP_UNALIGN and EXCP_UALIGND Richard Henderson
2022-03-10 11:27 ` [PATCH v5 24/48] target/nios2: Cleanup set of CR_EXCEPTION for do_interrupt Richard Henderson
2022-03-10 11:27 ` Richard Henderson [this message]
2022-03-10 11:27 ` [PATCH v5 26/48] target/nios2: Prevent writes to read-only or reserved control fields Richard Henderson
2022-03-10 11:27 ` [PATCH v5 27/48] target/nios2: Implement cpuid Richard Henderson
2022-03-10 11:27 ` [PATCH v5 28/48] target/nios2: Implement CR_STATUS.RSIE Richard Henderson
2022-03-10 11:27 ` [PATCH v5 29/48] target/nios2: Remove CPU_INTERRUPT_NMI Richard Henderson
2022-03-10 11:27 ` [PATCH v5 30/48] target/nios2: Support division error exception Richard Henderson
2022-03-10 11:27 ` [PATCH v5 31/48] target/nios2: Use tcg_constant_tl Richard Henderson
2022-03-10 11:27 ` [PATCH v5 32/48] target/nios2: Introduce dest_gpr Richard Henderson
2022-03-10 11:27 ` [PATCH v5 33/48] target/nios2: Drop CR_STATUS_EH from tb->flags Richard Henderson
2022-03-10 11:27 ` [PATCH v5 34/48] target/nios2: Enable unaligned traps for system mode Richard Henderson
2022-03-10 11:27 ` [PATCH v5 35/48] target/nios2: Create gen_jumpr Richard Henderson
2022-03-10 11:27 ` [PATCH v5 36/48] target/nios2: Hoist set of is_jmp into gen_goto_tb Richard Henderson
2022-03-10 11:27 ` [PATCH v5 37/48] target/nios2: Use gen_goto_tb for DISAS_TOO_MANY Richard Henderson
2022-03-10 11:27 ` [PATCH v5 38/48] target/nios2: Use tcg_gen_lookup_and_goto_ptr Richard Henderson
2022-03-10 11:27 ` [PATCH v5 39/48] target/nios2: Implement Misaligned destination exception Richard Henderson
2022-03-10 11:27 ` [PATCH v5 40/48] linux-user/nios2: Handle various SIGILL exceptions Richard Henderson
2022-03-10 11:27 ` [PATCH v5 41/48] target/nios2: Introduce shadow register sets Richard Henderson
2022-03-13 11:55 ` Amir Gonnen
2022-03-13 16:53 ` Richard Henderson
2022-03-10 11:27 ` [PATCH v5 42/48] target/nios2: Implement rdprs, wrprs Richard Henderson
2022-03-15 16:26 ` Amir Gonnen
2022-03-15 19:12 ` Richard Henderson
2022-03-10 11:27 ` [PATCH v5 43/48] target/nios2: Update helper_eret for shadow registers Richard Henderson
2022-03-10 11:27 ` [PATCH v5 44/48] target/nios2: Implement EIC interrupt processing Richard Henderson
2022-03-10 11:27 ` [PATCH v5 45/48] hw/intc: Vectored Interrupt Controller (VIC) Richard Henderson
2022-03-10 11:27 ` [PATCH v5 46/48] hw/nios2: Introduce Nios2MachineState Richard Henderson
2022-03-12 15:31 ` Mark Cave-Ayland
2022-03-10 11:27 ` [PATCH v5 47/48] hw/nios2: Move memory regions into Nios2Machine Richard Henderson
2022-03-10 11:27 ` [PATCH v5 48/48] hw/nios2: Machine with a Vectored Interrupt Controller Richard Henderson
2022-03-12 15:40 ` Mark Cave-Ayland
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=20220310112725.570053-26-richard.henderson@linaro.org \
--to=richard.henderson@linaro.org \
--cc=amir.gonnen@neuroblade.ai \
--cc=marex@denx.de \
--cc=peter.maydell@linaro.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).