[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH for-7.1 v6 25/51] target/nios2: Clean up handling of tlbmisc
From: |
Peter Maydell |
Subject: |
Re: [PATCH for-7.1 v6 25/51] target/nios2: Clean up handling of tlbmisc in do_exception |
Date: |
Thu, 17 Mar 2022 15:41:33 +0000 |
On Thu, 17 Mar 2022 at 05:23, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> 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.
> + */
On page 3-21 of
https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/hb/nios2/n2cpu_nii5v1_01.pdf
the description of the WE flag says
"Hardware sets the WE flag to one on a TLB permission violation
exception, and on a TLB miss exception when status.EH = 0."
This is the second of those two cases, isn't it ?
> + 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);
And this change is incorrectly dropping the "sets WE on
TLB permission violation exception" part.
Other than that,
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
- [PATCH for-7.1 v6 20/51] target/nios2: Create EXCP_SEMIHOST for semi-hosting, (continued)
- [PATCH for-7.1 v6 20/51] target/nios2: Create EXCP_SEMIHOST for semi-hosting, Richard Henderson, 2022/03/17
- [PATCH for-7.1 v6 19/51] target/nios2: Move R_FOO and CR_BAR into enumerations, Richard Henderson, 2022/03/17
- [PATCH for-7.1 v6 22/51] target/nios2: Hoist CPU_LOG_INT logging, Richard Henderson, 2022/03/17
- [PATCH for-7.1 v6 21/51] target/nios2: Clean up nios2_cpu_do_interrupt, Richard Henderson, 2022/03/17
- [PATCH for-7.1 v6 23/51] target/nios2: Handle EXCP_UNALIGN and EXCP_UALIGND, Richard Henderson, 2022/03/17
- [PATCH for-7.1 v6 25/51] target/nios2: Clean up handling of tlbmisc in do_exception, Richard Henderson, 2022/03/17
- Re: [PATCH for-7.1 v6 25/51] target/nios2: Clean up handling of tlbmisc in do_exception,
Peter Maydell <=
- [PATCH for-7.1 v6 29/51] target/nios2: Remove CPU_INTERRUPT_NMI, Richard Henderson, 2022/03/17
- [PATCH for-7.1 v6 24/51] target/nios2: Cleanup set of CR_EXCEPTION for do_interrupt, Richard Henderson, 2022/03/17
- [PATCH for-7.1 v6 27/51] target/nios2: Implement cpuid, Richard Henderson, 2022/03/17
- [PATCH for-7.1 v6 31/51] target/nios2: Use tcg_constant_tl, Richard Henderson, 2022/03/17
- [PATCH for-7.1 v6 32/51] target/nios2: Introduce dest_gpr, Richard Henderson, 2022/03/17
- [PATCH for-7.1 v6 37/51] target/nios2: Use gen_goto_tb for DISAS_TOO_MANY, Richard Henderson, 2022/03/17
- [PATCH for-7.1 v6 26/51] target/nios2: Prevent writes to read-only or reserved control fields, Richard Henderson, 2022/03/17