* [PATCH v3 01/33] target/ppc: Fix gen_sc to use correct nip
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
@ 2024-05-08 0:14 ` BALATON Zoltan
2024-05-08 13:36 ` Nicholas Piggin
2024-05-08 0:14 ` [PATCH v3 02/33] target/ppc: Move patching nip from exception handler to helper_scv BALATON Zoltan
` (31 subsequent siblings)
32 siblings, 1 reply; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:14 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
Most exceptions are raised with nip pointing to the faulting
instruction but the sc instruction generating a syscall exception
leaves nip pointing to next instruction. Fix gen_sc to not use
gen_exception_err() which sets nip back but correctly set nip to
pc_next so we don't have to patch this in the exception handlers.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
target/ppc/excp_helper.c | 43 ++--------------------------------------
target/ppc/translate.c | 15 ++++++--------
2 files changed, 8 insertions(+), 50 deletions(-)
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 0712098cf7..92fe535815 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -116,7 +116,7 @@ static void dump_syscall(CPUPPCState *env)
ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3),
ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5),
ppc_dump_gpr(env, 6), ppc_dump_gpr(env, 7),
- ppc_dump_gpr(env, 8), env->nip);
+ ppc_dump_gpr(env, 8), env->nip - 4);
}
static void dump_hcall(CPUPPCState *env)
@@ -131,7 +131,7 @@ static void dump_hcall(CPUPPCState *env)
ppc_dump_gpr(env, 7), ppc_dump_gpr(env, 8),
ppc_dump_gpr(env, 9), ppc_dump_gpr(env, 10),
ppc_dump_gpr(env, 11), ppc_dump_gpr(env, 12),
- env->nip);
+ env->nip - 4);
}
#ifdef CONFIG_TCG
@@ -516,12 +516,6 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
break;
case POWERPC_EXCP_SYSCALL: /* System call exception */
dump_syscall(env);
-
- /*
- * We need to correct the NIP which in this case is supposed
- * to point to the next instruction
- */
- env->nip += 4;
break;
case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
trace_ppc_excp_print("FIT");
@@ -632,12 +626,6 @@ static void powerpc_excp_6xx(PowerPCCPU *cpu, int excp)
break;
case POWERPC_EXCP_SYSCALL: /* System call exception */
dump_syscall(env);
-
- /*
- * We need to correct the NIP which in this case is supposed
- * to point to the next instruction
- */
- env->nip += 4;
break;
case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
case POWERPC_EXCP_DECR: /* Decrementer exception */
@@ -780,13 +768,6 @@ static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp)
} else {
dump_syscall(env);
}
-
- /*
- * We need to correct the NIP which in this case is supposed
- * to point to the next instruction
- */
- env->nip += 4;
-
/*
* The Virtual Open Firmware (VOF) relies on the 'sc 1'
* instruction to communicate with QEMU. The pegasos2 machine
@@ -932,13 +913,6 @@ static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp)
} else {
dump_syscall(env);
}
-
- /*
- * We need to correct the NIP which in this case is supposed
- * to point to the next instruction
- */
- env->nip += 4;
-
/*
* The Virtual Open Firmware (VOF) relies on the 'sc 1'
* instruction to communicate with QEMU. The pegasos2 machine
@@ -1098,12 +1072,6 @@ static void powerpc_excp_booke(PowerPCCPU *cpu, int excp)
break;
case POWERPC_EXCP_SYSCALL: /* System call exception */
dump_syscall(env);
-
- /*
- * We need to correct the NIP which in this case is supposed
- * to point to the next instruction
- */
- env->nip += 4;
break;
case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
@@ -1428,13 +1396,6 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int excp)
} else {
dump_syscall(env);
}
-
- /*
- * We need to correct the NIP which in this case is supposed
- * to point to the next instruction
- */
- env->nip += 4;
-
/* "PAPR mode" built-in hypercall emulation */
if (lev == 1 && books_vhyp_handles_hcall(cpu)) {
PPCVirtualHypervisorClass *vhc =
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 93ffec787c..e112c44a02 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -4472,22 +4472,19 @@ static void gen_hrfid(DisasContext *ctx)
#endif
/* sc */
-#if defined(CONFIG_USER_ONLY)
-#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
-#else
-#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
-#endif
static void gen_sc(DisasContext *ctx)
{
- uint32_t lev;
-
/*
* LEV is a 7-bit field, but the top 6 bits are treated as a reserved
* field (i.e., ignored). ISA v3.1 changes that to 5 bits, but that is
* for Ultravisor which TCG does not support, so just ignore the top 6.
*/
- lev = (ctx->opcode >> 5) & 0x1;
- gen_exception_err(ctx, POWERPC_SYSCALL, lev);
+ uint32_t lev = (ctx->opcode >> 5) & 0x1;
+#ifdef CONFIG_USER_ONLY
+ gen_exception_err(ctx, POWERPC_EXCP_SYSCALL_USER, lev);
+#else
+ gen_exception_err_nip(ctx, POWERPC_EXCP_SYSCALL, lev, ctx->base.pc_next);
+#endif
}
#if defined(TARGET_PPC64)
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* Re: [PATCH v3 01/33] target/ppc: Fix gen_sc to use correct nip
2024-05-08 0:14 ` [PATCH v3 01/33] target/ppc: Fix gen_sc to use correct nip BALATON Zoltan
@ 2024-05-08 13:36 ` Nicholas Piggin
2024-05-08 15:17 ` BALATON Zoltan
0 siblings, 1 reply; 58+ messages in thread
From: Nicholas Piggin @ 2024-05-08 13:36 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel, qemu-ppc; +Cc: Daniel Henrique Barboza
On Wed May 8, 2024 at 10:14 AM AEST, BALATON Zoltan wrote:
> Most exceptions are raised with nip pointing to the faulting
> instruction but the sc instruction generating a syscall exception
> leaves nip pointing to next instruction. Fix gen_sc to not use
> gen_exception_err() which sets nip back but correctly set nip to
> pc_next so we don't have to patch this in the exception handlers.
>
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> ---
> target/ppc/excp_helper.c | 43 ++--------------------------------------
> target/ppc/translate.c | 15 ++++++--------
> 2 files changed, 8 insertions(+), 50 deletions(-)
>
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index 0712098cf7..92fe535815 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -116,7 +116,7 @@ static void dump_syscall(CPUPPCState *env)
> ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3),
> ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5),
> ppc_dump_gpr(env, 6), ppc_dump_gpr(env, 7),
> - ppc_dump_gpr(env, 8), env->nip);
> + ppc_dump_gpr(env, 8), env->nip - 4);
> }
>
> static void dump_hcall(CPUPPCState *env)
> @@ -131,7 +131,7 @@ static void dump_hcall(CPUPPCState *env)
> ppc_dump_gpr(env, 7), ppc_dump_gpr(env, 8),
> ppc_dump_gpr(env, 9), ppc_dump_gpr(env, 10),
> ppc_dump_gpr(env, 11), ppc_dump_gpr(env, 12),
> - env->nip);
> + env->nip - 4);
> }
>
> #ifdef CONFIG_TCG
> @@ -516,12 +516,6 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
> break;
> case POWERPC_EXCP_SYSCALL: /* System call exception */
> dump_syscall(env);
> -
> - /*
> - * We need to correct the NIP which in this case is supposed
> - * to point to the next instruction
> - */
> - env->nip += 4;
> break;
> case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
> trace_ppc_excp_print("FIT");
> @@ -632,12 +626,6 @@ static void powerpc_excp_6xx(PowerPCCPU *cpu, int excp)
> break;
> case POWERPC_EXCP_SYSCALL: /* System call exception */
> dump_syscall(env);
> -
> - /*
> - * We need to correct the NIP which in this case is supposed
> - * to point to the next instruction
> - */
> - env->nip += 4;
> break;
> case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
> case POWERPC_EXCP_DECR: /* Decrementer exception */
> @@ -780,13 +768,6 @@ static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp)
> } else {
> dump_syscall(env);
> }
> -
> - /*
> - * We need to correct the NIP which in this case is supposed
> - * to point to the next instruction
> - */
> - env->nip += 4;
> -
> /*
> * The Virtual Open Firmware (VOF) relies on the 'sc 1'
> * instruction to communicate with QEMU. The pegasos2 machine
> @@ -932,13 +913,6 @@ static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp)
> } else {
> dump_syscall(env);
> }
> -
> - /*
> - * We need to correct the NIP which in this case is supposed
> - * to point to the next instruction
> - */
> - env->nip += 4;
> -
> /*
> * The Virtual Open Firmware (VOF) relies on the 'sc 1'
> * instruction to communicate with QEMU. The pegasos2 machine
> @@ -1098,12 +1072,6 @@ static void powerpc_excp_booke(PowerPCCPU *cpu, int excp)
> break;
> case POWERPC_EXCP_SYSCALL: /* System call exception */
> dump_syscall(env);
> -
> - /*
> - * We need to correct the NIP which in this case is supposed
> - * to point to the next instruction
> - */
> - env->nip += 4;
> break;
> case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
> case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
> @@ -1428,13 +1396,6 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int excp)
> } else {
> dump_syscall(env);
> }
> -
> - /*
> - * We need to correct the NIP which in this case is supposed
> - * to point to the next instruction
> - */
> - env->nip += 4;
> -
> /* "PAPR mode" built-in hypercall emulation */
> if (lev == 1 && books_vhyp_handles_hcall(cpu)) {
> PPCVirtualHypervisorClass *vhc =
> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> index 93ffec787c..e112c44a02 100644
> --- a/target/ppc/translate.c
> +++ b/target/ppc/translate.c
> @@ -4472,22 +4472,19 @@ static void gen_hrfid(DisasContext *ctx)
> #endif
>
> /* sc */
> -#if defined(CONFIG_USER_ONLY)
> -#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
> -#else
> -#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
> -#endif
> static void gen_sc(DisasContext *ctx)
> {
> - uint32_t lev;
> -
> /*
> * LEV is a 7-bit field, but the top 6 bits are treated as a reserved
> * field (i.e., ignored). ISA v3.1 changes that to 5 bits, but that is
> * for Ultravisor which TCG does not support, so just ignore the top 6.
> */
> - lev = (ctx->opcode >> 5) & 0x1;
> - gen_exception_err(ctx, POWERPC_SYSCALL, lev);
> + uint32_t lev = (ctx->opcode >> 5) & 0x1;
> +#ifdef CONFIG_USER_ONLY
> + gen_exception_err(ctx, POWERPC_EXCP_SYSCALL_USER, lev);
> +#else
> + gen_exception_err_nip(ctx, POWERPC_EXCP_SYSCALL, lev, ctx->base.pc_next);
> +#endif
I think this is the nail in the coffin for this one. Let's shelve it.
Thanks,
Nick
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH v3 01/33] target/ppc: Fix gen_sc to use correct nip
2024-05-08 13:36 ` Nicholas Piggin
@ 2024-05-08 15:17 ` BALATON Zoltan
2024-05-09 5:48 ` Nicholas Piggin
0 siblings, 1 reply; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 15:17 UTC (permalink / raw)
To: Nicholas Piggin; +Cc: qemu-devel, qemu-ppc, Daniel Henrique Barboza
On Wed, 8 May 2024, Nicholas Piggin wrote:
> On Wed May 8, 2024 at 10:14 AM AEST, BALATON Zoltan wrote:
>> Most exceptions are raised with nip pointing to the faulting
>> instruction but the sc instruction generating a syscall exception
>> leaves nip pointing to next instruction. Fix gen_sc to not use
>> gen_exception_err() which sets nip back but correctly set nip to
>> pc_next so we don't have to patch this in the exception handlers.
>>
>> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
>> ---
>> target/ppc/excp_helper.c | 43 ++--------------------------------------
>> target/ppc/translate.c | 15 ++++++--------
>> 2 files changed, 8 insertions(+), 50 deletions(-)
>>
>> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
>> index 0712098cf7..92fe535815 100644
>> --- a/target/ppc/excp_helper.c
>> +++ b/target/ppc/excp_helper.c
>> @@ -116,7 +116,7 @@ static void dump_syscall(CPUPPCState *env)
>> ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3),
>> ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5),
>> ppc_dump_gpr(env, 6), ppc_dump_gpr(env, 7),
>> - ppc_dump_gpr(env, 8), env->nip);
>> + ppc_dump_gpr(env, 8), env->nip - 4);
>> }
>>
>> static void dump_hcall(CPUPPCState *env)
>> @@ -131,7 +131,7 @@ static void dump_hcall(CPUPPCState *env)
>> ppc_dump_gpr(env, 7), ppc_dump_gpr(env, 8),
>> ppc_dump_gpr(env, 9), ppc_dump_gpr(env, 10),
>> ppc_dump_gpr(env, 11), ppc_dump_gpr(env, 12),
>> - env->nip);
>> + env->nip - 4);
>> }
>>
>> #ifdef CONFIG_TCG
>> @@ -516,12 +516,6 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
>> break;
>> case POWERPC_EXCP_SYSCALL: /* System call exception */
>> dump_syscall(env);
>> -
>> - /*
>> - * We need to correct the NIP which in this case is supposed
>> - * to point to the next instruction
>> - */
>> - env->nip += 4;
>> break;
>> case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
>> trace_ppc_excp_print("FIT");
>> @@ -632,12 +626,6 @@ static void powerpc_excp_6xx(PowerPCCPU *cpu, int excp)
>> break;
>> case POWERPC_EXCP_SYSCALL: /* System call exception */
>> dump_syscall(env);
>> -
>> - /*
>> - * We need to correct the NIP which in this case is supposed
>> - * to point to the next instruction
>> - */
>> - env->nip += 4;
>> break;
>> case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
>> case POWERPC_EXCP_DECR: /* Decrementer exception */
>> @@ -780,13 +768,6 @@ static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp)
>> } else {
>> dump_syscall(env);
>> }
>> -
>> - /*
>> - * We need to correct the NIP which in this case is supposed
>> - * to point to the next instruction
>> - */
>> - env->nip += 4;
>> -
>> /*
>> * The Virtual Open Firmware (VOF) relies on the 'sc 1'
>> * instruction to communicate with QEMU. The pegasos2 machine
>> @@ -932,13 +913,6 @@ static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp)
>> } else {
>> dump_syscall(env);
>> }
>> -
>> - /*
>> - * We need to correct the NIP which in this case is supposed
>> - * to point to the next instruction
>> - */
>> - env->nip += 4;
>> -
>> /*
>> * The Virtual Open Firmware (VOF) relies on the 'sc 1'
>> * instruction to communicate with QEMU. The pegasos2 machine
>> @@ -1098,12 +1072,6 @@ static void powerpc_excp_booke(PowerPCCPU *cpu, int excp)
>> break;
>> case POWERPC_EXCP_SYSCALL: /* System call exception */
>> dump_syscall(env);
>> -
>> - /*
>> - * We need to correct the NIP which in this case is supposed
>> - * to point to the next instruction
>> - */
>> - env->nip += 4;
>> break;
>> case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
>> case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
>> @@ -1428,13 +1396,6 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int excp)
>> } else {
>> dump_syscall(env);
>> }
>> -
>> - /*
>> - * We need to correct the NIP which in this case is supposed
>> - * to point to the next instruction
>> - */
>> - env->nip += 4;
>> -
>> /* "PAPR mode" built-in hypercall emulation */
>> if (lev == 1 && books_vhyp_handles_hcall(cpu)) {
>> PPCVirtualHypervisorClass *vhc =
>> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
>> index 93ffec787c..e112c44a02 100644
>> --- a/target/ppc/translate.c
>> +++ b/target/ppc/translate.c
>> @@ -4472,22 +4472,19 @@ static void gen_hrfid(DisasContext *ctx)
>> #endif
>>
>> /* sc */
>> -#if defined(CONFIG_USER_ONLY)
>> -#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
>> -#else
>> -#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
>> -#endif
>> static void gen_sc(DisasContext *ctx)
>> {
>> - uint32_t lev;
>> -
>> /*
>> * LEV is a 7-bit field, but the top 6 bits are treated as a reserved
>> * field (i.e., ignored). ISA v3.1 changes that to 5 bits, but that is
>> * for Ultravisor which TCG does not support, so just ignore the top 6.
>> */
>> - lev = (ctx->opcode >> 5) & 0x1;
>> - gen_exception_err(ctx, POWERPC_SYSCALL, lev);
>> + uint32_t lev = (ctx->opcode >> 5) & 0x1;
>> +#ifdef CONFIG_USER_ONLY
>> + gen_exception_err(ctx, POWERPC_EXCP_SYSCALL_USER, lev);
>> +#else
>> + gen_exception_err_nip(ctx, POWERPC_EXCP_SYSCALL, lev, ctx->base.pc_next);
>> +#endif
>
> I think this is the nail in the coffin for this one. Let's shelve it.
I really would like to get rid of all the +4s and long comments in
excp_helper.c though so I won't let this go until we find a solution. I've
now found that linux-user/ppc/cpu_loop.c handles this case and that also
has a +4 that I've missed before so with that removed this should work.
I'll try again.
Regards,
BALATON Zoltan
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH v3 01/33] target/ppc: Fix gen_sc to use correct nip
2024-05-08 15:17 ` BALATON Zoltan
@ 2024-05-09 5:48 ` Nicholas Piggin
0 siblings, 0 replies; 58+ messages in thread
From: Nicholas Piggin @ 2024-05-09 5:48 UTC (permalink / raw)
To: BALATON Zoltan; +Cc: qemu-devel, qemu-ppc, Daniel Henrique Barboza
On Thu May 9, 2024 at 1:17 AM AEST, BALATON Zoltan wrote:
> On Wed, 8 May 2024, Nicholas Piggin wrote:
> > On Wed May 8, 2024 at 10:14 AM AEST, BALATON Zoltan wrote:
> >> Most exceptions are raised with nip pointing to the faulting
> >> instruction but the sc instruction generating a syscall exception
> >> leaves nip pointing to next instruction. Fix gen_sc to not use
> >> gen_exception_err() which sets nip back but correctly set nip to
> >> pc_next so we don't have to patch this in the exception handlers.
> >>
> >> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> >> ---
> >> target/ppc/excp_helper.c | 43 ++--------------------------------------
> >> target/ppc/translate.c | 15 ++++++--------
> >> 2 files changed, 8 insertions(+), 50 deletions(-)
> >>
> >> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> >> index 0712098cf7..92fe535815 100644
> >> --- a/target/ppc/excp_helper.c
> >> +++ b/target/ppc/excp_helper.c
> >> @@ -116,7 +116,7 @@ static void dump_syscall(CPUPPCState *env)
> >> ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3),
> >> ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5),
> >> ppc_dump_gpr(env, 6), ppc_dump_gpr(env, 7),
> >> - ppc_dump_gpr(env, 8), env->nip);
> >> + ppc_dump_gpr(env, 8), env->nip - 4);
> >> }
> >>
> >> static void dump_hcall(CPUPPCState *env)
> >> @@ -131,7 +131,7 @@ static void dump_hcall(CPUPPCState *env)
> >> ppc_dump_gpr(env, 7), ppc_dump_gpr(env, 8),
> >> ppc_dump_gpr(env, 9), ppc_dump_gpr(env, 10),
> >> ppc_dump_gpr(env, 11), ppc_dump_gpr(env, 12),
> >> - env->nip);
> >> + env->nip - 4);
> >> }
> >>
> >> #ifdef CONFIG_TCG
> >> @@ -516,12 +516,6 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
> >> break;
> >> case POWERPC_EXCP_SYSCALL: /* System call exception */
> >> dump_syscall(env);
> >> -
> >> - /*
> >> - * We need to correct the NIP which in this case is supposed
> >> - * to point to the next instruction
> >> - */
> >> - env->nip += 4;
> >> break;
> >> case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
> >> trace_ppc_excp_print("FIT");
> >> @@ -632,12 +626,6 @@ static void powerpc_excp_6xx(PowerPCCPU *cpu, int excp)
> >> break;
> >> case POWERPC_EXCP_SYSCALL: /* System call exception */
> >> dump_syscall(env);
> >> -
> >> - /*
> >> - * We need to correct the NIP which in this case is supposed
> >> - * to point to the next instruction
> >> - */
> >> - env->nip += 4;
> >> break;
> >> case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
> >> case POWERPC_EXCP_DECR: /* Decrementer exception */
> >> @@ -780,13 +768,6 @@ static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp)
> >> } else {
> >> dump_syscall(env);
> >> }
> >> -
> >> - /*
> >> - * We need to correct the NIP which in this case is supposed
> >> - * to point to the next instruction
> >> - */
> >> - env->nip += 4;
> >> -
> >> /*
> >> * The Virtual Open Firmware (VOF) relies on the 'sc 1'
> >> * instruction to communicate with QEMU. The pegasos2 machine
> >> @@ -932,13 +913,6 @@ static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp)
> >> } else {
> >> dump_syscall(env);
> >> }
> >> -
> >> - /*
> >> - * We need to correct the NIP which in this case is supposed
> >> - * to point to the next instruction
> >> - */
> >> - env->nip += 4;
> >> -
> >> /*
> >> * The Virtual Open Firmware (VOF) relies on the 'sc 1'
> >> * instruction to communicate with QEMU. The pegasos2 machine
> >> @@ -1098,12 +1072,6 @@ static void powerpc_excp_booke(PowerPCCPU *cpu, int excp)
> >> break;
> >> case POWERPC_EXCP_SYSCALL: /* System call exception */
> >> dump_syscall(env);
> >> -
> >> - /*
> >> - * We need to correct the NIP which in this case is supposed
> >> - * to point to the next instruction
> >> - */
> >> - env->nip += 4;
> >> break;
> >> case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
> >> case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
> >> @@ -1428,13 +1396,6 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int excp)
> >> } else {
> >> dump_syscall(env);
> >> }
> >> -
> >> - /*
> >> - * We need to correct the NIP which in this case is supposed
> >> - * to point to the next instruction
> >> - */
> >> - env->nip += 4;
> >> -
> >> /* "PAPR mode" built-in hypercall emulation */
> >> if (lev == 1 && books_vhyp_handles_hcall(cpu)) {
> >> PPCVirtualHypervisorClass *vhc =
> >> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> >> index 93ffec787c..e112c44a02 100644
> >> --- a/target/ppc/translate.c
> >> +++ b/target/ppc/translate.c
> >> @@ -4472,22 +4472,19 @@ static void gen_hrfid(DisasContext *ctx)
> >> #endif
> >>
> >> /* sc */
> >> -#if defined(CONFIG_USER_ONLY)
> >> -#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
> >> -#else
> >> -#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
> >> -#endif
> >> static void gen_sc(DisasContext *ctx)
> >> {
> >> - uint32_t lev;
> >> -
> >> /*
> >> * LEV is a 7-bit field, but the top 6 bits are treated as a reserved
> >> * field (i.e., ignored). ISA v3.1 changes that to 5 bits, but that is
> >> * for Ultravisor which TCG does not support, so just ignore the top 6.
> >> */
> >> - lev = (ctx->opcode >> 5) & 0x1;
> >> - gen_exception_err(ctx, POWERPC_SYSCALL, lev);
> >> + uint32_t lev = (ctx->opcode >> 5) & 0x1;
> >> +#ifdef CONFIG_USER_ONLY
> >> + gen_exception_err(ctx, POWERPC_EXCP_SYSCALL_USER, lev);
> >> +#else
> >> + gen_exception_err_nip(ctx, POWERPC_EXCP_SYSCALL, lev, ctx->base.pc_next);
> >> +#endif
> >
> > I think this is the nail in the coffin for this one. Let's shelve it.
>
> I really would like to get rid of all the +4s and long comments in
> excp_helper.c though so I won't let this go until we find a solution. I've
All the += 4 are just because the handlers are repeated so many times.
And with this you have to add the - 4 for other cases.
And you removed the comment but you didn't add one here. Comments aren't
really a problem.
> now found that linux-user/ppc/cpu_loop.c handles this case and that also
> has a +4 that I've missed before so with that removed this should work.
> I'll try again.
The invariant that nip always refers to the instruction that caused the
exception for synchronous exceptions is a good one, and the patch has
caused a bunch of problems, so I don't want to merge it.
Thanks,
Nick
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 02/33] target/ppc: Move patching nip from exception handler to helper_scv
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
2024-05-08 0:14 ` [PATCH v3 01/33] target/ppc: Fix gen_sc to use correct nip BALATON Zoltan
@ 2024-05-08 0:14 ` BALATON Zoltan
2024-05-08 0:14 ` [PATCH v3 03/33] target/ppc: Simplify syscall exception handlers BALATON Zoltan
` (30 subsequent siblings)
32 siblings, 0 replies; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:14 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
From: Nicholas Piggin <npiggin@gmail.com>
Unlike sc, for scv a facility unavailable interrupt must be generated
if FSCR[SCV]=0 so we can't raise the exception with nip set to next
instruction but we can move advancing nip if the FSCR check passes to
helper_scv so the exception handler does not need to change it.
[balaton: added commit message]
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
target/ppc/excp_helper.c | 2 +-
target/ppc/translate.c | 6 +++++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 92fe535815..5aa84bccd2 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -1415,7 +1415,6 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int excp)
case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception */
lev = env->error_code;
dump_syscall(env);
- env->nip += 4;
new_msr |= env->msr & ((target_ulong)1 << MSR_EE);
new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
@@ -2524,6 +2523,7 @@ void helper_ppc_maybe_interrupt(CPUPPCState *env)
void helper_scv(CPUPPCState *env, uint32_t lev)
{
if (env->spr[SPR_FSCR] & (1ull << FSCR_SCV)) {
+ env->nip += 4;
raise_exception_err(env, POWERPC_EXCP_SYSCALL_VECTORED, lev);
} else {
raise_exception_err(env, POWERPC_EXCP_FU, FSCR_IC_SCV);
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index e112c44a02..1d4e9f0679 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -4493,7 +4493,11 @@ static void gen_scv(DisasContext *ctx)
{
uint32_t lev = (ctx->opcode >> 5) & 0x7F;
- /* Set the PC back to the faulting instruction. */
+ /*
+ * Set the PC back to the scv instruction (unlike sc), because a facility
+ * unavailable interrupt must be generated if FSCR[SCV]=0. The helper
+ * advances nip if the FSCR check passes.
+ */
gen_update_nip(ctx, ctx->cia);
gen_helper_scv(tcg_env, tcg_constant_i32(lev));
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v3 03/33] target/ppc: Simplify syscall exception handlers
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
2024-05-08 0:14 ` [PATCH v3 01/33] target/ppc: Fix gen_sc to use correct nip BALATON Zoltan
2024-05-08 0:14 ` [PATCH v3 02/33] target/ppc: Move patching nip from exception handler to helper_scv BALATON Zoltan
@ 2024-05-08 0:14 ` BALATON Zoltan
2024-05-08 0:14 ` [PATCH v3 04/33] target/ppc: Remove unused helper BALATON Zoltan
` (29 subsequent siblings)
32 siblings, 0 replies; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:14 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
After previous changes the hypercall handling in 7xx and 74xx
exception handlers can be folded into one if statement to simplify
this code. Also add "unlikely" to mark the less frequently used branch
for the compiler.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
---
target/ppc/excp_helper.c | 22 ++++++----------------
1 file changed, 6 insertions(+), 16 deletions(-)
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 5aa84bccd2..d19212f772 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -762,26 +762,21 @@ static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp)
case POWERPC_EXCP_SYSCALL: /* System call exception */
{
int lev = env->error_code;
-
- if (lev == 1 && cpu->vhyp) {
- dump_hcall(env);
- } else {
- dump_syscall(env);
- }
/*
* The Virtual Open Firmware (VOF) relies on the 'sc 1'
* instruction to communicate with QEMU. The pegasos2 machine
* uses VOF and the 7xx CPUs, so although the 7xx don't have
* HV mode, we need to keep hypercall support.
*/
- if (lev == 1 && cpu->vhyp) {
+ if (unlikely(lev == 1 && cpu->vhyp)) {
PPCVirtualHypervisorClass *vhc =
PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
+ dump_hcall(env);
vhc->hypercall(cpu->vhyp, cpu);
powerpc_reset_excp_state(cpu);
return;
}
-
+ dump_syscall(env);
break;
}
case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
@@ -907,26 +902,21 @@ static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp)
case POWERPC_EXCP_SYSCALL: /* System call exception */
{
int lev = env->error_code;
-
- if (lev == 1 && cpu->vhyp) {
- dump_hcall(env);
- } else {
- dump_syscall(env);
- }
/*
* The Virtual Open Firmware (VOF) relies on the 'sc 1'
* instruction to communicate with QEMU. The pegasos2 machine
* uses VOF and the 74xx CPUs, so although the 74xx don't have
* HV mode, we need to keep hypercall support.
*/
- if (lev == 1 && cpu->vhyp) {
+ if (unlikely(lev == 1 && cpu->vhyp)) {
PPCVirtualHypervisorClass *vhc =
PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
+ dump_hcall(env);
vhc->hypercall(cpu->vhyp, cpu);
powerpc_reset_excp_state(cpu);
return;
}
-
+ dump_syscall(env);
break;
}
case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v3 04/33] target/ppc: Remove unused helper
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (2 preceding siblings ...)
2024-05-08 0:14 ` [PATCH v3 03/33] target/ppc: Simplify syscall exception handlers BALATON Zoltan
@ 2024-05-08 0:14 ` BALATON Zoltan
2024-05-08 0:14 ` [PATCH v3 05/33] target/ppc/mmu_common.c: Move calculation of a value closer to its usage BALATON Zoltan
` (28 subsequent siblings)
32 siblings, 0 replies; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:14 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
The helper_rac function is defined but not used, remove it.
Fixes: 005b69fdcc (target/ppc: Remove PowerPC 601 CPUs)
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviwed-by: Nicholas Piggin <npiggin@gmail.com>
---
target/ppc/helper.h | 2 --
target/ppc/mmu_helper.c | 24 ------------------------
2 files changed, 26 deletions(-)
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 86f97ee1e7..f769e01c3d 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -700,8 +700,6 @@ DEF_HELPER_2(book3s_msgclr, void, env, tl)
DEF_HELPER_4(dlmzb, tl, env, tl, tl, i32)
#if !defined(CONFIG_USER_ONLY)
-DEF_HELPER_2(rac, tl, env, tl)
-
DEF_HELPER_2(load_dcr, tl, env, tl)
DEF_HELPER_3(store_dcr, void, env, tl, tl)
#endif
diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
index b35a93c198..421e777ee6 100644
--- a/target/ppc/mmu_helper.c
+++ b/target/ppc/mmu_helper.c
@@ -596,30 +596,6 @@ void helper_6xx_tlbi(CPUPPCState *env, target_ulong EPN)
do_6xx_tlb(env, EPN, 1);
}
-/*****************************************************************************/
-/* PowerPC 601 specific instructions (POWER bridge) */
-
-target_ulong helper_rac(CPUPPCState *env, target_ulong addr)
-{
- mmu_ctx_t ctx;
- int nb_BATs;
- target_ulong ret = 0;
-
- /*
- * We don't have to generate many instances of this instruction,
- * as rac is supervisor only.
- *
- * XXX: FIX THIS: Pretend we have no BAT
- */
- nb_BATs = env->nb_BATs;
- env->nb_BATs = 0;
- if (get_physical_address_wtlb(env, &ctx, addr, 0, ACCESS_INT, 0) == 0) {
- ret = ctx.raddr;
- }
- env->nb_BATs = nb_BATs;
- return ret;
-}
-
static inline target_ulong booke_tlb_to_page_size(int size)
{
return 1024 << (2 * size);
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v3 05/33] target/ppc/mmu_common.c: Move calculation of a value closer to its usage
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (3 preceding siblings ...)
2024-05-08 0:14 ` [PATCH v3 04/33] target/ppc: Remove unused helper BALATON Zoltan
@ 2024-05-08 0:14 ` BALATON Zoltan
2024-05-08 0:14 ` [PATCH v3 06/33] target/ppc/mmu_common.c: Remove unneeded local variable BALATON Zoltan
` (27 subsequent siblings)
32 siblings, 0 replies; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:14 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
In mmubooke_check_tlb() and mmubooke206_check_tlb() prot2 is
calculated first but only used after an unrelated check that can
return before tha value is used. Move the calculation after the check,
closer to where it is used, to keep them together and avoid computing
it when not needed.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviwed-by: Nicholas Piggin <npiggin@gmail.com>
---
target/ppc/mmu_common.c | 36 +++++++++++++++++-------------------
1 file changed, 17 insertions(+), 19 deletions(-)
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index 4fde7fd3bf..f79e390306 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -635,12 +635,6 @@ static int mmubooke_check_tlb(CPUPPCState *env, ppcemb_tlb_t *tlb,
return -1;
}
- if (FIELD_EX64(env->msr, MSR, PR)) {
- prot2 = tlb->prot & 0xF;
- } else {
- prot2 = (tlb->prot >> 4) & 0xF;
- }
-
/* Check the address space */
if ((access_type == MMU_INST_FETCH ?
FIELD_EX64(env->msr, MSR, IR) :
@@ -649,6 +643,11 @@ static int mmubooke_check_tlb(CPUPPCState *env, ppcemb_tlb_t *tlb,
return -1;
}
+ if (FIELD_EX64(env->msr, MSR, PR)) {
+ prot2 = tlb->prot & 0xF;
+ } else {
+ prot2 = (tlb->prot >> 4) & 0xF;
+ }
*prot = prot2;
if (prot2 & prot_for_access_type(access_type)) {
qemu_log_mask(CPU_LOG_MMU, "%s: good TLB!\n", __func__);
@@ -830,6 +829,18 @@ static int mmubooke206_check_tlb(CPUPPCState *env, ppcmas_tlb_t *tlb,
found_tlb:
+ /* Check the address space and permissions */
+ if (access_type == MMU_INST_FETCH) {
+ /* There is no way to fetch code using epid load */
+ assert(!use_epid);
+ as = FIELD_EX64(env->msr, MSR, IR);
+ }
+
+ if (as != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) {
+ qemu_log_mask(CPU_LOG_MMU, "%s: AS doesn't match\n", __func__);
+ return -1;
+ }
+
if (pr) {
if (tlb->mas7_3 & MAS3_UR) {
prot2 |= PAGE_READ;
@@ -851,19 +862,6 @@ found_tlb:
prot2 |= PAGE_EXEC;
}
}
-
- /* Check the address space and permissions */
- if (access_type == MMU_INST_FETCH) {
- /* There is no way to fetch code using epid load */
- assert(!use_epid);
- as = FIELD_EX64(env->msr, MSR, IR);
- }
-
- if (as != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) {
- qemu_log_mask(CPU_LOG_MMU, "%s: AS doesn't match\n", __func__);
- return -1;
- }
-
*prot = prot2;
if (prot2 & prot_for_access_type(access_type)) {
qemu_log_mask(CPU_LOG_MMU, "%s: good TLB!\n", __func__);
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v3 06/33] target/ppc/mmu_common.c: Remove unneeded local variable
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (4 preceding siblings ...)
2024-05-08 0:14 ` [PATCH v3 05/33] target/ppc/mmu_common.c: Move calculation of a value closer to its usage BALATON Zoltan
@ 2024-05-08 0:14 ` BALATON Zoltan
2024-05-08 0:14 ` [PATCH v3 07/33] target/ppc/mmu_common.c: Simplify checking for real mode BALATON Zoltan
` (26 subsequent siblings)
32 siblings, 0 replies; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:14 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
In mmubooke_check_tlb() and mmubooke206_check_tlb() we can assign the
value directly the the destination, no need to have a separate local
variable for it.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
---
target/ppc/mmu_common.c | 30 +++++++++++++-----------------
1 file changed, 13 insertions(+), 17 deletions(-)
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index f79e390306..09cbeb0052 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -628,8 +628,6 @@ static int mmubooke_check_tlb(CPUPPCState *env, ppcemb_tlb_t *tlb,
hwaddr *raddr, int *prot, target_ulong address,
MMUAccessType access_type, int i)
{
- int prot2;
-
if (!mmubooke_check_pid(env, tlb, raddr, address, i)) {
qemu_log_mask(CPU_LOG_MMU, "%s: TLB entry not found\n", __func__);
return -1;
@@ -644,17 +642,16 @@ static int mmubooke_check_tlb(CPUPPCState *env, ppcemb_tlb_t *tlb,
}
if (FIELD_EX64(env->msr, MSR, PR)) {
- prot2 = tlb->prot & 0xF;
+ *prot = tlb->prot & 0xF;
} else {
- prot2 = (tlb->prot >> 4) & 0xF;
+ *prot = (tlb->prot >> 4) & 0xF;
}
- *prot = prot2;
- if (prot2 & prot_for_access_type(access_type)) {
+ if (*prot & prot_for_access_type(access_type)) {
qemu_log_mask(CPU_LOG_MMU, "%s: good TLB!\n", __func__);
return 0;
}
- qemu_log_mask(CPU_LOG_MMU, "%s: no prot match: %x\n", __func__, prot2);
+ qemu_log_mask(CPU_LOG_MMU, "%s: no prot match: %x\n", __func__, *prot);
return access_type == MMU_INST_FETCH ? -3 : -2;
}
@@ -795,7 +792,6 @@ static int mmubooke206_check_tlb(CPUPPCState *env, ppcmas_tlb_t *tlb,
target_ulong address,
MMUAccessType access_type, int mmu_idx)
{
- int prot2 = 0;
uint32_t epid;
bool as, pr;
bool use_epid = mmubooke206_get_as(env, mmu_idx, &epid, &as, &pr);
@@ -841,34 +837,34 @@ found_tlb:
return -1;
}
+ *prot = 0;
if (pr) {
if (tlb->mas7_3 & MAS3_UR) {
- prot2 |= PAGE_READ;
+ *prot |= PAGE_READ;
}
if (tlb->mas7_3 & MAS3_UW) {
- prot2 |= PAGE_WRITE;
+ *prot |= PAGE_WRITE;
}
if (tlb->mas7_3 & MAS3_UX) {
- prot2 |= PAGE_EXEC;
+ *prot |= PAGE_EXEC;
}
} else {
if (tlb->mas7_3 & MAS3_SR) {
- prot2 |= PAGE_READ;
+ *prot |= PAGE_READ;
}
if (tlb->mas7_3 & MAS3_SW) {
- prot2 |= PAGE_WRITE;
+ *prot |= PAGE_WRITE;
}
if (tlb->mas7_3 & MAS3_SX) {
- prot2 |= PAGE_EXEC;
+ *prot |= PAGE_EXEC;
}
}
- *prot = prot2;
- if (prot2 & prot_for_access_type(access_type)) {
+ if (*prot & prot_for_access_type(access_type)) {
qemu_log_mask(CPU_LOG_MMU, "%s: good TLB!\n", __func__);
return 0;
}
- qemu_log_mask(CPU_LOG_MMU, "%s: no prot match: %x\n", __func__, prot2);
+ qemu_log_mask(CPU_LOG_MMU, "%s: no prot match: %x\n", __func__, *prot);
return access_type == MMU_INST_FETCH ? -3 : -2;
}
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v3 07/33] target/ppc/mmu_common.c: Simplify checking for real mode
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (5 preceding siblings ...)
2024-05-08 0:14 ` [PATCH v3 06/33] target/ppc/mmu_common.c: Remove unneeded local variable BALATON Zoltan
@ 2024-05-08 0:14 ` BALATON Zoltan
2024-05-08 0:15 ` [PATCH v3 08/33] target/ppc/mmu_common.c: Drop cases for unimplemented MPC8xx MMU BALATON Zoltan
` (25 subsequent siblings)
32 siblings, 0 replies; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:14 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
In get_physical_address_wtlb() the real_mode flag depends on either
the MSR[IR] or MSR[DR] bit depending on access_type. Extract just the
needed bit in a more straight forward way instead of doing unnecessary
computation.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
---
target/ppc/mmu_common.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index 09cbeb0052..886fb6a657 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -1184,8 +1184,10 @@ int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
int mmu_idx)
{
int ret = -1;
- bool real_mode = (type == ACCESS_CODE && !FIELD_EX64(env->msr, MSR, IR)) ||
- (type != ACCESS_CODE && !FIELD_EX64(env->msr, MSR, DR));
+ bool real_mode;
+
+ real_mode = (type == ACCESS_CODE) ? !FIELD_EX64(env->msr, MSR, IR)
+ : !FIELD_EX64(env->msr, MSR, DR);
switch (env->mmu_model) {
case POWERPC_MMU_SOFT_6xx:
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v3 08/33] target/ppc/mmu_common.c: Drop cases for unimplemented MPC8xx MMU
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (6 preceding siblings ...)
2024-05-08 0:14 ` [PATCH v3 07/33] target/ppc/mmu_common.c: Simplify checking for real mode BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 0:15 ` [PATCH v3 09/33] target/ppc/mmu_common.c: Introduce mmu6xx_get_physical_address() BALATON Zoltan
` (24 subsequent siblings)
32 siblings, 0 replies; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
The default case will catch this and abort the same way and there is
still a warning about it in ppc_tlb_invalidate_all() so drop these
from mmu_common.c to simplify this code.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
---
target/ppc/mmu_common.c | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index 886fb6a657..aa137123a4 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -1219,10 +1219,6 @@ int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
ret = mmubooke206_get_physical_address(env, ctx, eaddr, access_type,
mmu_idx);
break;
- case POWERPC_MMU_MPC8xx:
- /* XXX: TODO */
- cpu_abort(env_cpu(env), "MPC8xx MMU model is not implemented\n");
- break;
case POWERPC_MMU_REAL:
if (real_mode) {
ret = check_physical(env, ctx, eaddr, access_type);
@@ -1353,8 +1349,6 @@ static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
env->spr[SPR_BOOKE_DEAR] = eaddr;
env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, MMU_DATA_LOAD);
break;
- case POWERPC_MMU_MPC8xx:
- cpu_abort(cs, "MPC8xx MMU model is not implemented\n");
case POWERPC_MMU_REAL:
cpu_abort(cs, "PowerPC in real mode should never raise "
"any MMU exceptions\n");
@@ -1427,9 +1421,6 @@ static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
env->spr[SPR_40x_ESR] = 0x00000000;
}
break;
- case POWERPC_MMU_MPC8xx:
- /* XXX: TODO */
- cpu_abort(cs, "MPC8xx MMU model is not implemented\n");
case POWERPC_MMU_BOOKE206:
booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
/* fall through */
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v3 09/33] target/ppc/mmu_common.c: Introduce mmu6xx_get_physical_address()
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (7 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 08/33] target/ppc/mmu_common.c: Drop cases for unimplemented MPC8xx MMU BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 12:40 ` Nicholas Piggin
2024-05-08 0:15 ` [PATCH v3 10/33] target/ppc/mmu_common.c: Move else branch to avoid large if block BALATON Zoltan
` (23 subsequent siblings)
32 siblings, 1 reply; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
Repurpose get_segment_6xx_tlb() to do the whole address translation
for POWERPC_MMU_SOFT_6xx MMU model by moving the BAT check there and
renaming it to match other similar functions. These are only called
once together so no need to keep these separate functions and
combining them simplifies the caller allowing further restructuring.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
target/ppc/mmu_common.c | 26 ++++++++++++--------------
1 file changed, 12 insertions(+), 14 deletions(-)
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index aa137123a4..181273579b 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -360,19 +360,23 @@ static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
return ret;
}
-/* Perform segment based translation */
-static int get_segment_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
- target_ulong eaddr, MMUAccessType access_type,
- int type)
+static int mmu6xx_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
+ target_ulong eaddr,
+ MMUAccessType access_type, int type)
{
PowerPCCPU *cpu = env_archcpu(env);
hwaddr hash;
- target_ulong vsid;
+ target_ulong vsid, sr, pgidx;
int ds, target_page_bits;
bool pr;
int ret;
- target_ulong sr, pgidx;
+ /* First try to find a BAT entry if there are any */
+ if (env->nb_BATs && get_bat_6xx_tlb(env, ctx, eaddr, access_type) == 0) {
+ return 0;
+ }
+
+ /* Perform segment based translation when no BATs matched */
pr = FIELD_EX64(env->msr, MSR, PR);
ctx->eaddr = eaddr;
@@ -1194,14 +1198,8 @@ int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
if (real_mode) {
ret = check_physical(env, ctx, eaddr, access_type);
} else {
- /* Try to find a BAT */
- if (env->nb_BATs != 0) {
- ret = get_bat_6xx_tlb(env, ctx, eaddr, access_type);
- }
- if (ret < 0) {
- /* We didn't match any BAT entry or don't have BATs */
- ret = get_segment_6xx_tlb(env, ctx, eaddr, access_type, type);
- }
+ ret = mmu6xx_get_physical_address(env, ctx, eaddr, access_type,
+ type);
}
break;
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* Re: [PATCH v3 09/33] target/ppc/mmu_common.c: Introduce mmu6xx_get_physical_address()
2024-05-08 0:15 ` [PATCH v3 09/33] target/ppc/mmu_common.c: Introduce mmu6xx_get_physical_address() BALATON Zoltan
@ 2024-05-08 12:40 ` Nicholas Piggin
0 siblings, 0 replies; 58+ messages in thread
From: Nicholas Piggin @ 2024-05-08 12:40 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel, qemu-ppc; +Cc: Daniel Henrique Barboza
On Wed May 8, 2024 at 10:15 AM AEST, BALATON Zoltan wrote:
> Repurpose get_segment_6xx_tlb() to do the whole address translation
> for POWERPC_MMU_SOFT_6xx MMU model by moving the BAT check there and
> renaming it to match other similar functions. These are only called
> once together so no need to keep these separate functions and
> combining them simplifies the caller allowing further restructuring.
>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> ---
> target/ppc/mmu_common.c | 26 ++++++++++++--------------
> 1 file changed, 12 insertions(+), 14 deletions(-)
>
> diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
> index aa137123a4..181273579b 100644
> --- a/target/ppc/mmu_common.c
> +++ b/target/ppc/mmu_common.c
> @@ -360,19 +360,23 @@ static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
> return ret;
> }
>
> -/* Perform segment based translation */
> -static int get_segment_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
> - target_ulong eaddr, MMUAccessType access_type,
> - int type)
> +static int mmu6xx_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
> + target_ulong eaddr,
> + MMUAccessType access_type, int type)
> {
> PowerPCCPU *cpu = env_archcpu(env);
> hwaddr hash;
> - target_ulong vsid;
> + target_ulong vsid, sr, pgidx;
> int ds, target_page_bits;
> bool pr;
> int ret;
> - target_ulong sr, pgidx;
>
> + /* First try to find a BAT entry if there are any */
> + if (env->nb_BATs && get_bat_6xx_tlb(env, ctx, eaddr, access_type) == 0) {
> + return 0;
> + }
> +
> + /* Perform segment based translation when no BATs matched */
> pr = FIELD_EX64(env->msr, MSR, PR);
> ctx->eaddr = eaddr;
>
> @@ -1194,14 +1198,8 @@ int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
> if (real_mode) {
> ret = check_physical(env, ctx, eaddr, access_type);
> } else {
> - /* Try to find a BAT */
> - if (env->nb_BATs != 0) {
> - ret = get_bat_6xx_tlb(env, ctx, eaddr, access_type);
> - }
> - if (ret < 0) {
> - /* We didn't match any BAT entry or don't have BATs */
> - ret = get_segment_6xx_tlb(env, ctx, eaddr, access_type, type);
> - }
> + ret = mmu6xx_get_physical_address(env, ctx, eaddr, access_type,
> + type);
> }
> break;
>
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 10/33] target/ppc/mmu_common.c: Move else branch to avoid large if block
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (8 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 09/33] target/ppc/mmu_common.c: Introduce mmu6xx_get_physical_address() BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 12:43 ` Nicholas Piggin
2024-05-08 0:15 ` [PATCH v3 11/33] target/ppc/mmu_common.c: Move some debug logging BALATON Zoltan
` (22 subsequent siblings)
32 siblings, 1 reply; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
In mmu6xx_get_physical_address() we have a large if block with a two
line else branch that effectively returns. Invert the condition and
move the else there to allow deindenting the large if block to make
the flow easier to follow.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
target/ppc/mmu_common.c | 71 ++++++++++++++++++++---------------------
1 file changed, 34 insertions(+), 37 deletions(-)
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index 181273579b..9d337a73ba 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -405,47 +405,44 @@ static int mmu6xx_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
ret = -1;
if (!ds) {
/* Check if instruction fetch is allowed, if needed */
- if (type != ACCESS_CODE || ctx->nx == 0) {
- /* Page address translation */
- qemu_log_mask(CPU_LOG_MMU, "htab_base " HWADDR_FMT_plx
- " htab_mask " HWADDR_FMT_plx
- " hash " HWADDR_FMT_plx "\n",
- ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu), hash);
- ctx->hash[0] = hash;
- ctx->hash[1] = ~hash;
-
- /* Initialize real address with an invalid value */
- ctx->raddr = (hwaddr)-1ULL;
- /* Software TLB search */
- ret = ppc6xx_tlb_check(env, ctx, eaddr, access_type);
+ if (type == ACCESS_CODE && ctx->nx) {
+ qemu_log_mask(CPU_LOG_MMU, "No access allowed\n");
+ return -3;
+ }
+ /* Page address translation */
+ qemu_log_mask(CPU_LOG_MMU, "htab_base " HWADDR_FMT_plx " htab_mask "
+ HWADDR_FMT_plx " hash " HWADDR_FMT_plx "\n",
+ ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu), hash);
+ ctx->hash[0] = hash;
+ ctx->hash[1] = ~hash;
+
+ /* Initialize real address with an invalid value */
+ ctx->raddr = (hwaddr)-1ULL;
+ /* Software TLB search */
+ ret = ppc6xx_tlb_check(env, ctx, eaddr, access_type);
#if defined(DUMP_PAGE_TABLES)
- if (qemu_loglevel_mask(CPU_LOG_MMU)) {
- CPUState *cs = env_cpu(env);
- hwaddr curaddr;
- uint32_t a0, a1, a2, a3;
-
- qemu_log("Page table: " HWADDR_FMT_plx " len " HWADDR_FMT_plx
- "\n", ppc_hash32_hpt_base(cpu),
- ppc_hash32_hpt_mask(cpu) + 0x80);
- for (curaddr = ppc_hash32_hpt_base(cpu);
- curaddr < (ppc_hash32_hpt_base(cpu)
- + ppc_hash32_hpt_mask(cpu) + 0x80);
- curaddr += 16) {
- a0 = ldl_phys(cs->as, curaddr);
- a1 = ldl_phys(cs->as, curaddr + 4);
- a2 = ldl_phys(cs->as, curaddr + 8);
- a3 = ldl_phys(cs->as, curaddr + 12);
- if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
- qemu_log(HWADDR_FMT_plx ": %08x %08x %08x %08x\n",
- curaddr, a0, a1, a2, a3);
- }
+ if (qemu_loglevel_mask(CPU_LOG_MMU)) {
+ CPUState *cs = env_cpu(env);
+ hwaddr curaddr;
+ uint32_t a0, a1, a2, a3;
+
+ qemu_log("Page table: " HWADDR_FMT_plx " len " HWADDR_FMT_plx "\n",
+ ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu) + 0x80);
+ for (curaddr = ppc_hash32_hpt_base(cpu);
+ curaddr < (ppc_hash32_hpt_base(cpu)
+ + ppc_hash32_hpt_mask(cpu) + 0x80);
+ curaddr += 16) {
+ a0 = ldl_phys(cs->as, curaddr);
+ a1 = ldl_phys(cs->as, curaddr + 4);
+ a2 = ldl_phys(cs->as, curaddr + 8);
+ a3 = ldl_phys(cs->as, curaddr + 12);
+ if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
+ qemu_log(HWADDR_FMT_plx ": %08x %08x %08x %08x\n",
+ curaddr, a0, a1, a2, a3);
}
}
-#endif
- } else {
- qemu_log_mask(CPU_LOG_MMU, "No access allowed\n");
- ret = -3;
}
+#endif
} else {
qemu_log_mask(CPU_LOG_MMU, "direct store...\n");
/* Direct-store segment : absolutely *BUGGY* for now */
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* Re: [PATCH v3 10/33] target/ppc/mmu_common.c: Move else branch to avoid large if block
2024-05-08 0:15 ` [PATCH v3 10/33] target/ppc/mmu_common.c: Move else branch to avoid large if block BALATON Zoltan
@ 2024-05-08 12:43 ` Nicholas Piggin
0 siblings, 0 replies; 58+ messages in thread
From: Nicholas Piggin @ 2024-05-08 12:43 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel, qemu-ppc; +Cc: Daniel Henrique Barboza
On Wed May 8, 2024 at 10:15 AM AEST, BALATON Zoltan wrote:
> In mmu6xx_get_physical_address() we have a large if block with a two
> line else branch that effectively returns. Invert the condition and
> move the else there to allow deindenting the large if block to make
> the flow easier to follow.
>
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> ---
> target/ppc/mmu_common.c | 71 ++++++++++++++++++++---------------------
> 1 file changed, 34 insertions(+), 37 deletions(-)
>
> diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
> index 181273579b..9d337a73ba 100644
> --- a/target/ppc/mmu_common.c
> +++ b/target/ppc/mmu_common.c
> @@ -405,47 +405,44 @@ static int mmu6xx_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
> ret = -1;
> if (!ds) {
> /* Check if instruction fetch is allowed, if needed */
> - if (type != ACCESS_CODE || ctx->nx == 0) {
> - /* Page address translation */
> - qemu_log_mask(CPU_LOG_MMU, "htab_base " HWADDR_FMT_plx
> - " htab_mask " HWADDR_FMT_plx
> - " hash " HWADDR_FMT_plx "\n",
> - ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu), hash);
> - ctx->hash[0] = hash;
> - ctx->hash[1] = ~hash;
> -
> - /* Initialize real address with an invalid value */
> - ctx->raddr = (hwaddr)-1ULL;
> - /* Software TLB search */
> - ret = ppc6xx_tlb_check(env, ctx, eaddr, access_type);
> + if (type == ACCESS_CODE && ctx->nx) {
> + qemu_log_mask(CPU_LOG_MMU, "No access allowed\n");
> + return -3;
> + }
Function is already inconsistent with assigning ret and falling
through to the return ret at the end vs returning immediately, so
okay since you're tidying it up.
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
> + /* Page address translation */
> + qemu_log_mask(CPU_LOG_MMU, "htab_base " HWADDR_FMT_plx " htab_mask "
> + HWADDR_FMT_plx " hash " HWADDR_FMT_plx "\n",
> + ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu), hash);
> + ctx->hash[0] = hash;
> + ctx->hash[1] = ~hash;
> +
> + /* Initialize real address with an invalid value */
> + ctx->raddr = (hwaddr)-1ULL;
> + /* Software TLB search */
> + ret = ppc6xx_tlb_check(env, ctx, eaddr, access_type);
> #if defined(DUMP_PAGE_TABLES)
> - if (qemu_loglevel_mask(CPU_LOG_MMU)) {
> - CPUState *cs = env_cpu(env);
> - hwaddr curaddr;
> - uint32_t a0, a1, a2, a3;
> -
> - qemu_log("Page table: " HWADDR_FMT_plx " len " HWADDR_FMT_plx
> - "\n", ppc_hash32_hpt_base(cpu),
> - ppc_hash32_hpt_mask(cpu) + 0x80);
> - for (curaddr = ppc_hash32_hpt_base(cpu);
> - curaddr < (ppc_hash32_hpt_base(cpu)
> - + ppc_hash32_hpt_mask(cpu) + 0x80);
> - curaddr += 16) {
> - a0 = ldl_phys(cs->as, curaddr);
> - a1 = ldl_phys(cs->as, curaddr + 4);
> - a2 = ldl_phys(cs->as, curaddr + 8);
> - a3 = ldl_phys(cs->as, curaddr + 12);
> - if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
> - qemu_log(HWADDR_FMT_plx ": %08x %08x %08x %08x\n",
> - curaddr, a0, a1, a2, a3);
> - }
> + if (qemu_loglevel_mask(CPU_LOG_MMU)) {
> + CPUState *cs = env_cpu(env);
> + hwaddr curaddr;
> + uint32_t a0, a1, a2, a3;
> +
> + qemu_log("Page table: " HWADDR_FMT_plx " len " HWADDR_FMT_plx "\n",
> + ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu) + 0x80);
> + for (curaddr = ppc_hash32_hpt_base(cpu);
> + curaddr < (ppc_hash32_hpt_base(cpu)
> + + ppc_hash32_hpt_mask(cpu) + 0x80);
> + curaddr += 16) {
> + a0 = ldl_phys(cs->as, curaddr);
> + a1 = ldl_phys(cs->as, curaddr + 4);
> + a2 = ldl_phys(cs->as, curaddr + 8);
> + a3 = ldl_phys(cs->as, curaddr + 12);
> + if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
> + qemu_log(HWADDR_FMT_plx ": %08x %08x %08x %08x\n",
> + curaddr, a0, a1, a2, a3);
> }
> }
> -#endif
> - } else {
> - qemu_log_mask(CPU_LOG_MMU, "No access allowed\n");
> - ret = -3;
> }
> +#endif
> } else {
> qemu_log_mask(CPU_LOG_MMU, "direct store...\n");
> /* Direct-store segment : absolutely *BUGGY* for now */
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 11/33] target/ppc/mmu_common.c: Move some debug logging
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (9 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 10/33] target/ppc/mmu_common.c: Move else branch to avoid large if block BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 12:47 ` Nicholas Piggin
2024-05-08 0:15 ` [PATCH v3 12/33] target/ppc/mmu_common.c: Eliminate ret from mmu6xx_get_physical_address() BALATON Zoltan
` (21 subsequent siblings)
32 siblings, 1 reply; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
Move the debug logging within ppc6xx_tlb_check() from after its only
call to simplify the caller.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
target/ppc/mmu_common.c | 55 +++++++++++++++++++----------------------
1 file changed, 26 insertions(+), 29 deletions(-)
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index 9d337a73ba..b2f2cee1a8 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -225,17 +225,14 @@ static int ppc6xx_tlb_check(CPUPPCState *env, mmu_ctx_t *ctx,
access_type == MMU_INST_FETCH ? 'I' : 'D');
switch (ppc6xx_tlb_pte_check(ctx, tlb->pte0, tlb->pte1,
0, access_type)) {
- case -3:
- /* TLB inconsistency */
- return -1;
case -2:
/* Access violation */
ret = -2;
best = nr;
break;
- case -1:
+ case -1: /* No match */
+ case -3: /* TLB inconsistency */
default:
- /* No match */
break;
case 0:
/* access granted */
@@ -251,14 +248,37 @@ static int ppc6xx_tlb_check(CPUPPCState *env, mmu_ctx_t *ctx,
}
}
if (best != -1) {
- done:
+done:
qemu_log_mask(CPU_LOG_MMU, "found TLB at addr " HWADDR_FMT_plx
" prot=%01x ret=%d\n",
ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret);
/* Update page flags */
pte_update_flags(ctx, &env->tlb.tlb6[best].pte1, ret, access_type);
}
+#if defined(DUMP_PAGE_TABLES)
+ if (qemu_loglevel_mask(CPU_LOG_MMU)) {
+ CPUState *cs = env_cpu(env);
+ PowerPCCPU *cpu = env_archcpu(env);
+ hwaddr curaddr;
+ uint32_t a0, a1, a2, a3;
+ qemu_log("Page table: " HWADDR_FMT_plx " len " HWADDR_FMT_plx "\n",
+ ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu) + 0x80);
+ for (curaddr = ppc_hash32_hpt_base(cpu);
+ curaddr < (ppc_hash32_hpt_base(cpu)
+ + ppc_hash32_hpt_mask(cpu) + 0x80);
+ curaddr += 16) {
+ a0 = ldl_phys(cs->as, curaddr);
+ a1 = ldl_phys(cs->as, curaddr + 4);
+ a2 = ldl_phys(cs->as, curaddr + 8);
+ a3 = ldl_phys(cs->as, curaddr + 12);
+ if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
+ qemu_log(HWADDR_FMT_plx ": %08x %08x %08x %08x\n",
+ curaddr, a0, a1, a2, a3);
+ }
+ }
+ }
+#endif
return ret;
}
@@ -420,29 +440,6 @@ static int mmu6xx_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
ctx->raddr = (hwaddr)-1ULL;
/* Software TLB search */
ret = ppc6xx_tlb_check(env, ctx, eaddr, access_type);
-#if defined(DUMP_PAGE_TABLES)
- if (qemu_loglevel_mask(CPU_LOG_MMU)) {
- CPUState *cs = env_cpu(env);
- hwaddr curaddr;
- uint32_t a0, a1, a2, a3;
-
- qemu_log("Page table: " HWADDR_FMT_plx " len " HWADDR_FMT_plx "\n",
- ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu) + 0x80);
- for (curaddr = ppc_hash32_hpt_base(cpu);
- curaddr < (ppc_hash32_hpt_base(cpu)
- + ppc_hash32_hpt_mask(cpu) + 0x80);
- curaddr += 16) {
- a0 = ldl_phys(cs->as, curaddr);
- a1 = ldl_phys(cs->as, curaddr + 4);
- a2 = ldl_phys(cs->as, curaddr + 8);
- a3 = ldl_phys(cs->as, curaddr + 12);
- if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
- qemu_log(HWADDR_FMT_plx ": %08x %08x %08x %08x\n",
- curaddr, a0, a1, a2, a3);
- }
- }
- }
-#endif
} else {
qemu_log_mask(CPU_LOG_MMU, "direct store...\n");
/* Direct-store segment : absolutely *BUGGY* for now */
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* Re: [PATCH v3 11/33] target/ppc/mmu_common.c: Move some debug logging
2024-05-08 0:15 ` [PATCH v3 11/33] target/ppc/mmu_common.c: Move some debug logging BALATON Zoltan
@ 2024-05-08 12:47 ` Nicholas Piggin
0 siblings, 0 replies; 58+ messages in thread
From: Nicholas Piggin @ 2024-05-08 12:47 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel, qemu-ppc; +Cc: Daniel Henrique Barboza
On Wed May 8, 2024 at 10:15 AM AEST, BALATON Zoltan wrote:
> Move the debug logging within ppc6xx_tlb_check() from after its only
> call to simplify the caller.
>
I *think* the logic looks right.
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> ---
> target/ppc/mmu_common.c | 55 +++++++++++++++++++----------------------
> 1 file changed, 26 insertions(+), 29 deletions(-)
>
> diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
> index 9d337a73ba..b2f2cee1a8 100644
> --- a/target/ppc/mmu_common.c
> +++ b/target/ppc/mmu_common.c
> @@ -225,17 +225,14 @@ static int ppc6xx_tlb_check(CPUPPCState *env, mmu_ctx_t *ctx,
> access_type == MMU_INST_FETCH ? 'I' : 'D');
> switch (ppc6xx_tlb_pte_check(ctx, tlb->pte0, tlb->pte1,
> 0, access_type)) {
> - case -3:
> - /* TLB inconsistency */
> - return -1;
> case -2:
> /* Access violation */
> ret = -2;
> best = nr;
> break;
> - case -1:
> + case -1: /* No match */
> + case -3: /* TLB inconsistency */
> default:
> - /* No match */
> break;
> case 0:
> /* access granted */
> @@ -251,14 +248,37 @@ static int ppc6xx_tlb_check(CPUPPCState *env, mmu_ctx_t *ctx,
> }
> }
> if (best != -1) {
> - done:
> +done:
> qemu_log_mask(CPU_LOG_MMU, "found TLB at addr " HWADDR_FMT_plx
> " prot=%01x ret=%d\n",
> ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret);
> /* Update page flags */
> pte_update_flags(ctx, &env->tlb.tlb6[best].pte1, ret, access_type);
> }
> +#if defined(DUMP_PAGE_TABLES)
> + if (qemu_loglevel_mask(CPU_LOG_MMU)) {
> + CPUState *cs = env_cpu(env);
> + PowerPCCPU *cpu = env_archcpu(env);
Do you need to de-indent this one level?
Otherwise,
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Thanks,
Nick
> + hwaddr curaddr;
> + uint32_t a0, a1, a2, a3;
>
> + qemu_log("Page table: " HWADDR_FMT_plx " len " HWADDR_FMT_plx "\n",
> + ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu) + 0x80);
> + for (curaddr = ppc_hash32_hpt_base(cpu);
> + curaddr < (ppc_hash32_hpt_base(cpu)
> + + ppc_hash32_hpt_mask(cpu) + 0x80);
> + curaddr += 16) {
> + a0 = ldl_phys(cs->as, curaddr);
> + a1 = ldl_phys(cs->as, curaddr + 4);
> + a2 = ldl_phys(cs->as, curaddr + 8);
> + a3 = ldl_phys(cs->as, curaddr + 12);
> + if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
> + qemu_log(HWADDR_FMT_plx ": %08x %08x %08x %08x\n",
> + curaddr, a0, a1, a2, a3);
> + }
> + }
> + }
> +#endif
> return ret;
> }
>
> @@ -420,29 +440,6 @@ static int mmu6xx_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
> ctx->raddr = (hwaddr)-1ULL;
> /* Software TLB search */
> ret = ppc6xx_tlb_check(env, ctx, eaddr, access_type);
> -#if defined(DUMP_PAGE_TABLES)
> - if (qemu_loglevel_mask(CPU_LOG_MMU)) {
> - CPUState *cs = env_cpu(env);
> - hwaddr curaddr;
> - uint32_t a0, a1, a2, a3;
> -
> - qemu_log("Page table: " HWADDR_FMT_plx " len " HWADDR_FMT_plx "\n",
> - ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu) + 0x80);
> - for (curaddr = ppc_hash32_hpt_base(cpu);
> - curaddr < (ppc_hash32_hpt_base(cpu)
> - + ppc_hash32_hpt_mask(cpu) + 0x80);
> - curaddr += 16) {
> - a0 = ldl_phys(cs->as, curaddr);
> - a1 = ldl_phys(cs->as, curaddr + 4);
> - a2 = ldl_phys(cs->as, curaddr + 8);
> - a3 = ldl_phys(cs->as, curaddr + 12);
> - if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
> - qemu_log(HWADDR_FMT_plx ": %08x %08x %08x %08x\n",
> - curaddr, a0, a1, a2, a3);
> - }
> - }
> - }
> -#endif
> } else {
> qemu_log_mask(CPU_LOG_MMU, "direct store...\n");
> /* Direct-store segment : absolutely *BUGGY* for now */
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 12/33] target/ppc/mmu_common.c: Eliminate ret from mmu6xx_get_physical_address()
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (10 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 11/33] target/ppc/mmu_common.c: Move some debug logging BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 12:48 ` Nicholas Piggin
2024-05-08 0:15 ` [PATCH v3 13/33] target/ppc/mmu_common.c: Split out BookE cases before checking real mode BALATON Zoltan
` (20 subsequent siblings)
32 siblings, 1 reply; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
Return directly, which is simpler than dragging a return value through
multpile if and else blocks.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
target/ppc/mmu_common.c | 84 +++++++++++++++++++----------------------
1 file changed, 39 insertions(+), 45 deletions(-)
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index b2f2cee1a8..2b6252f3f9 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -389,7 +389,6 @@ static int mmu6xx_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
target_ulong vsid, sr, pgidx;
int ds, target_page_bits;
bool pr;
- int ret;
/* First try to find a BAT entry if there are any */
if (env->nb_BATs && get_bat_6xx_tlb(env, ctx, eaddr, access_type) == 0) {
@@ -422,7 +421,6 @@ static int mmu6xx_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
qemu_log_mask(CPU_LOG_MMU,
"pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx "\n",
ctx->key, ds, ctx->nx, vsid);
- ret = -1;
if (!ds) {
/* Check if instruction fetch is allowed, if needed */
if (type == ACCESS_CODE && ctx->nx) {
@@ -439,51 +437,47 @@ static int mmu6xx_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
/* Initialize real address with an invalid value */
ctx->raddr = (hwaddr)-1ULL;
/* Software TLB search */
- ret = ppc6xx_tlb_check(env, ctx, eaddr, access_type);
- } else {
- qemu_log_mask(CPU_LOG_MMU, "direct store...\n");
- /* Direct-store segment : absolutely *BUGGY* for now */
-
- switch (type) {
- case ACCESS_INT:
- /* Integer load/store : only access allowed */
- break;
- case ACCESS_CODE:
- /* No code fetch is allowed in direct-store areas */
- return -4;
- case ACCESS_FLOAT:
- /* Floating point load/store */
- return -4;
- case ACCESS_RES:
- /* lwarx, ldarx or srwcx. */
- return -4;
- case ACCESS_CACHE:
- /*
- * dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi
- *
- * Should make the instruction do no-op. As it already do
- * no-op, it's quite easy :-)
- */
- ctx->raddr = eaddr;
- return 0;
- case ACCESS_EXT:
- /* eciwx or ecowx */
- return -4;
- default:
- qemu_log_mask(CPU_LOG_MMU, "ERROR: instruction should not need "
- "address translation\n");
- return -4;
- }
- if ((access_type == MMU_DATA_STORE || ctx->key != 1) &&
- (access_type == MMU_DATA_LOAD || ctx->key != 0)) {
- ctx->raddr = eaddr;
- ret = 2;
- } else {
- ret = -2;
- }
+ return ppc6xx_tlb_check(env, ctx, eaddr, access_type);
}
- return ret;
+ /* Direct-store segment : absolutely *BUGGY* for now */
+ qemu_log_mask(CPU_LOG_MMU, "direct store...\n");
+ switch (type) {
+ case ACCESS_INT:
+ /* Integer load/store : only access allowed */
+ break;
+ case ACCESS_CODE:
+ /* No code fetch is allowed in direct-store areas */
+ return -4;
+ case ACCESS_FLOAT:
+ /* Floating point load/store */
+ return -4;
+ case ACCESS_RES:
+ /* lwarx, ldarx or srwcx. */
+ return -4;
+ case ACCESS_CACHE:
+ /*
+ * dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi
+ *
+ * Should make the instruction do no-op. As it already do
+ * no-op, it's quite easy :-)
+ */
+ ctx->raddr = eaddr;
+ return 0;
+ case ACCESS_EXT:
+ /* eciwx or ecowx */
+ return -4;
+ default:
+ qemu_log_mask(CPU_LOG_MMU, "ERROR: instruction should not need address"
+ " translation\n");
+ return -4;
+ }
+ if ((access_type == MMU_DATA_STORE || ctx->key != 1) &&
+ (access_type == MMU_DATA_LOAD || ctx->key != 0)) {
+ ctx->raddr = eaddr;
+ return 2;
+ }
+ return -2;
}
/* Generic TLB check function for embedded PowerPC implementations */
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* Re: [PATCH v3 12/33] target/ppc/mmu_common.c: Eliminate ret from mmu6xx_get_physical_address()
2024-05-08 0:15 ` [PATCH v3 12/33] target/ppc/mmu_common.c: Eliminate ret from mmu6xx_get_physical_address() BALATON Zoltan
@ 2024-05-08 12:48 ` Nicholas Piggin
0 siblings, 0 replies; 58+ messages in thread
From: Nicholas Piggin @ 2024-05-08 12:48 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel, qemu-ppc; +Cc: Daniel Henrique Barboza
On Wed May 8, 2024 at 10:15 AM AEST, BALATON Zoltan wrote:
> Return directly, which is simpler than dragging a return value through
> multpile if and else blocks.
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
>
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> ---
> target/ppc/mmu_common.c | 84 +++++++++++++++++++----------------------
> 1 file changed, 39 insertions(+), 45 deletions(-)
>
> diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
> index b2f2cee1a8..2b6252f3f9 100644
> --- a/target/ppc/mmu_common.c
> +++ b/target/ppc/mmu_common.c
> @@ -389,7 +389,6 @@ static int mmu6xx_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
> target_ulong vsid, sr, pgidx;
> int ds, target_page_bits;
> bool pr;
> - int ret;
>
> /* First try to find a BAT entry if there are any */
> if (env->nb_BATs && get_bat_6xx_tlb(env, ctx, eaddr, access_type) == 0) {
> @@ -422,7 +421,6 @@ static int mmu6xx_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
> qemu_log_mask(CPU_LOG_MMU,
> "pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx "\n",
> ctx->key, ds, ctx->nx, vsid);
> - ret = -1;
> if (!ds) {
> /* Check if instruction fetch is allowed, if needed */
> if (type == ACCESS_CODE && ctx->nx) {
> @@ -439,51 +437,47 @@ static int mmu6xx_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
> /* Initialize real address with an invalid value */
> ctx->raddr = (hwaddr)-1ULL;
> /* Software TLB search */
> - ret = ppc6xx_tlb_check(env, ctx, eaddr, access_type);
> - } else {
> - qemu_log_mask(CPU_LOG_MMU, "direct store...\n");
> - /* Direct-store segment : absolutely *BUGGY* for now */
> -
> - switch (type) {
> - case ACCESS_INT:
> - /* Integer load/store : only access allowed */
> - break;
> - case ACCESS_CODE:
> - /* No code fetch is allowed in direct-store areas */
> - return -4;
> - case ACCESS_FLOAT:
> - /* Floating point load/store */
> - return -4;
> - case ACCESS_RES:
> - /* lwarx, ldarx or srwcx. */
> - return -4;
> - case ACCESS_CACHE:
> - /*
> - * dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi
> - *
> - * Should make the instruction do no-op. As it already do
> - * no-op, it's quite easy :-)
> - */
> - ctx->raddr = eaddr;
> - return 0;
> - case ACCESS_EXT:
> - /* eciwx or ecowx */
> - return -4;
> - default:
> - qemu_log_mask(CPU_LOG_MMU, "ERROR: instruction should not need "
> - "address translation\n");
> - return -4;
> - }
> - if ((access_type == MMU_DATA_STORE || ctx->key != 1) &&
> - (access_type == MMU_DATA_LOAD || ctx->key != 0)) {
> - ctx->raddr = eaddr;
> - ret = 2;
> - } else {
> - ret = -2;
> - }
> + return ppc6xx_tlb_check(env, ctx, eaddr, access_type);
> }
>
> - return ret;
> + /* Direct-store segment : absolutely *BUGGY* for now */
> + qemu_log_mask(CPU_LOG_MMU, "direct store...\n");
> + switch (type) {
> + case ACCESS_INT:
> + /* Integer load/store : only access allowed */
> + break;
> + case ACCESS_CODE:
> + /* No code fetch is allowed in direct-store areas */
> + return -4;
> + case ACCESS_FLOAT:
> + /* Floating point load/store */
> + return -4;
> + case ACCESS_RES:
> + /* lwarx, ldarx or srwcx. */
> + return -4;
> + case ACCESS_CACHE:
> + /*
> + * dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi
> + *
> + * Should make the instruction do no-op. As it already do
> + * no-op, it's quite easy :-)
> + */
> + ctx->raddr = eaddr;
> + return 0;
> + case ACCESS_EXT:
> + /* eciwx or ecowx */
> + return -4;
> + default:
> + qemu_log_mask(CPU_LOG_MMU, "ERROR: instruction should not need address"
> + " translation\n");
> + return -4;
> + }
> + if ((access_type == MMU_DATA_STORE || ctx->key != 1) &&
> + (access_type == MMU_DATA_LOAD || ctx->key != 0)) {
> + ctx->raddr = eaddr;
> + return 2;
> + }
> + return -2;
> }
>
> /* Generic TLB check function for embedded PowerPC implementations */
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 13/33] target/ppc/mmu_common.c: Split out BookE cases before checking real mode
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (11 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 12/33] target/ppc/mmu_common.c: Eliminate ret from mmu6xx_get_physical_address() BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 0:15 ` [PATCH v3 14/33] target/ppc/mmu_common.c: Split off real mode cases in get_physical_address_wtlb() BALATON Zoltan
` (19 subsequent siblings)
32 siblings, 0 replies; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
BookE does not have real mode so split off and handle it first in
get_physical_address_wtlb() before checking for real mode for other
MMU models.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
---
target/ppc/mmu_common.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index 2b6252f3f9..5a0df60ebc 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -1178,6 +1178,13 @@ int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
int ret = -1;
bool real_mode;
+ if (env->mmu_model == POWERPC_MMU_BOOKE) {
+ return mmubooke_get_physical_address(env, ctx, eaddr, access_type);
+ } else if (env->mmu_model == POWERPC_MMU_BOOKE206) {
+ return mmubooke206_get_physical_address(env, ctx, eaddr, access_type,
+ mmu_idx);
+ }
+
real_mode = (type == ACCESS_CODE) ? !FIELD_EX64(env->msr, MSR, IR)
: !FIELD_EX64(env->msr, MSR, DR);
@@ -1198,13 +1205,6 @@ int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
ret = mmu40x_get_physical_address(env, ctx, eaddr, access_type);
}
break;
- case POWERPC_MMU_BOOKE:
- ret = mmubooke_get_physical_address(env, ctx, eaddr, access_type);
- break;
- case POWERPC_MMU_BOOKE206:
- ret = mmubooke206_get_physical_address(env, ctx, eaddr, access_type,
- mmu_idx);
- break;
case POWERPC_MMU_REAL:
if (real_mode) {
ret = check_physical(env, ctx, eaddr, access_type);
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v3 14/33] target/ppc/mmu_common.c: Split off real mode cases in get_physical_address_wtlb()
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (12 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 13/33] target/ppc/mmu_common.c: Split out BookE cases before checking real mode BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 0:15 ` [PATCH v3 15/33] target/ppc/mmu_common.c: Inline and remove check_physical() BALATON Zoltan
` (18 subsequent siblings)
32 siblings, 0 replies; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
The real mode handling is identical in the remaining switch cases.
Split off these common real mode cases into a separate conditional to
leave only the else branches in the switch that are different.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
---
target/ppc/mmu_common.c | 34 +++++++++-------------------------
1 file changed, 9 insertions(+), 25 deletions(-)
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index 5a0df60ebc..e03a433f02 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -1175,7 +1175,6 @@ int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
MMUAccessType access_type, int type,
int mmu_idx)
{
- int ret = -1;
bool real_mode;
if (env->mmu_model == POWERPC_MMU_BOOKE) {
@@ -1187,38 +1186,23 @@ int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
real_mode = (type == ACCESS_CODE) ? !FIELD_EX64(env->msr, MSR, IR)
: !FIELD_EX64(env->msr, MSR, DR);
+ if (real_mode && (env->mmu_model == POWERPC_MMU_SOFT_6xx ||
+ env->mmu_model == POWERPC_MMU_SOFT_4xx ||
+ env->mmu_model == POWERPC_MMU_REAL)) {
+ return check_physical(env, ctx, eaddr, access_type);
+ }
switch (env->mmu_model) {
case POWERPC_MMU_SOFT_6xx:
- if (real_mode) {
- ret = check_physical(env, ctx, eaddr, access_type);
- } else {
- ret = mmu6xx_get_physical_address(env, ctx, eaddr, access_type,
- type);
- }
- break;
-
+ return mmu6xx_get_physical_address(env, ctx, eaddr, access_type, type);
case POWERPC_MMU_SOFT_4xx:
- if (real_mode) {
- ret = check_physical(env, ctx, eaddr, access_type);
- } else {
- ret = mmu40x_get_physical_address(env, ctx, eaddr, access_type);
- }
- break;
+ return mmu40x_get_physical_address(env, ctx, eaddr, access_type);
case POWERPC_MMU_REAL:
- if (real_mode) {
- ret = check_physical(env, ctx, eaddr, access_type);
- } else {
- cpu_abort(env_cpu(env),
- "PowerPC in real mode do not do any translation\n");
- }
- return -1;
+ cpu_abort(env_cpu(env),
+ "PowerPC in real mode do not do any translation\n");
default:
cpu_abort(env_cpu(env), "Unknown or invalid MMU model\n");
- return -1;
}
-
- return ret;
}
static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address,
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v3 15/33] target/ppc/mmu_common.c: Inline and remove check_physical()
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (13 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 14/33] target/ppc/mmu_common.c: Split off real mode cases in get_physical_address_wtlb() BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 0:15 ` [PATCH v3 16/33] target/ppc/mmu_common.c: Simplify mmubooke_get_physical_address() BALATON Zoltan
` (17 subsequent siblings)
32 siblings, 0 replies; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
This function just does two assignments and and unnecessary check that
is always true so inline it in the only caller left and remove it.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
---
target/ppc/mmu_common.c | 26 +++-----------------------
1 file changed, 3 insertions(+), 23 deletions(-)
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index e03a433f02..7283eafe27 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -1148,28 +1148,6 @@ void dump_mmu(CPUPPCState *env)
}
}
-static int check_physical(CPUPPCState *env, mmu_ctx_t *ctx, target_ulong eaddr,
- MMUAccessType access_type)
-{
- ctx->raddr = eaddr;
- ctx->prot = PAGE_READ | PAGE_EXEC;
-
- switch (env->mmu_model) {
- case POWERPC_MMU_SOFT_6xx:
- case POWERPC_MMU_SOFT_4xx:
- case POWERPC_MMU_REAL:
- case POWERPC_MMU_BOOKE:
- ctx->prot |= PAGE_WRITE;
- break;
-
- default:
- /* Caller's checks mean we should never get here for other models */
- g_assert_not_reached();
- }
-
- return 0;
-}
-
int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
target_ulong eaddr,
MMUAccessType access_type, int type,
@@ -1189,7 +1167,9 @@ int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
if (real_mode && (env->mmu_model == POWERPC_MMU_SOFT_6xx ||
env->mmu_model == POWERPC_MMU_SOFT_4xx ||
env->mmu_model == POWERPC_MMU_REAL)) {
- return check_physical(env, ctx, eaddr, access_type);
+ ctx->raddr = eaddr;
+ ctx->prot = PAGE_RWX;
+ return 0;
}
switch (env->mmu_model) {
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v3 16/33] target/ppc/mmu_common.c: Simplify mmubooke_get_physical_address()
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (14 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 15/33] target/ppc/mmu_common.c: Inline and remove check_physical() BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 0:15 ` [PATCH v3 17/33] target/ppc/mmu_common.c: Simplify mmubooke206_get_physical_address() BALATON Zoltan
` (16 subsequent siblings)
32 siblings, 0 replies; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
---
target/ppc/mmu_common.c | 25 +++++++++----------------
1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index 7283eafe27..9793e6d282 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -652,31 +652,24 @@ static int mmubooke_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
MMUAccessType access_type)
{
ppcemb_tlb_t *tlb;
- hwaddr raddr;
- int i, ret;
+ hwaddr raddr = (hwaddr)-1ULL;
+ int i, ret = -1;
- ret = -1;
- raddr = (hwaddr)-1ULL;
for (i = 0; i < env->nb_tlb; i++) {
tlb = &env->tlb.tlbe[i];
ret = mmubooke_check_tlb(env, tlb, &raddr, &ctx->prot, address,
access_type, i);
if (ret != -1) {
+ if (ret >= 0) {
+ ctx->raddr = raddr;
+ }
break;
}
}
-
- if (ret >= 0) {
- ctx->raddr = raddr;
- qemu_log_mask(CPU_LOG_MMU, "%s: access granted " TARGET_FMT_lx
- " => " HWADDR_FMT_plx " %d %d\n", __func__,
- address, ctx->raddr, ctx->prot, ret);
- } else {
- qemu_log_mask(CPU_LOG_MMU, "%s: access refused " TARGET_FMT_lx
- " => " HWADDR_FMT_plx " %d %d\n", __func__,
- address, raddr, ctx->prot, ret);
- }
-
+ qemu_log_mask(CPU_LOG_MMU,
+ "%s: access %s " TARGET_FMT_lx " => " HWADDR_FMT_plx
+ " %d %d\n", __func__, ret < 0 ? "refused" : "granted",
+ address, raddr, ctx->prot, ret);
return ret;
}
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v3 17/33] target/ppc/mmu_common.c: Simplify mmubooke206_get_physical_address()
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (15 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 16/33] target/ppc/mmu_common.c: Simplify mmubooke_get_physical_address() BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 0:15 ` [PATCH v3 18/33] target/ppc/mmu_common.c: Fix misindented qemu_log_mask() calls BALATON Zoltan
` (15 subsequent siblings)
32 siblings, 0 replies; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
This function is similar to mmubooke_get_physical_address() and can be
simplified the same way.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
---
target/ppc/mmu_common.c | 26 +++++++++-----------------
1 file changed, 9 insertions(+), 17 deletions(-)
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index 9793e6d282..a5bc747f40 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -859,15 +859,11 @@ static int mmubooke206_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
int mmu_idx)
{
ppcmas_tlb_t *tlb;
- hwaddr raddr;
- int i, j, ret;
-
- ret = -1;
- raddr = (hwaddr)-1ULL;
+ hwaddr raddr = (hwaddr)-1ULL;
+ int i, j, ret = -1;
for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
int ways = booke206_tlb_ways(env, i);
-
for (j = 0; j < ways; j++) {
tlb = booke206_get_tlbm(env, i, address, j);
if (!tlb) {
@@ -876,6 +872,9 @@ static int mmubooke206_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
ret = mmubooke206_check_tlb(env, tlb, &raddr, &ctx->prot, address,
access_type, mmu_idx);
if (ret != -1) {
+ if (ret >= 0) {
+ ctx->raddr = raddr;
+ }
goto found_tlb;
}
}
@@ -883,17 +882,10 @@ static int mmubooke206_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
found_tlb:
- if (ret >= 0) {
- ctx->raddr = raddr;
- qemu_log_mask(CPU_LOG_MMU, "%s: access granted " TARGET_FMT_lx
- " => " HWADDR_FMT_plx " %d %d\n", __func__, address,
- ctx->raddr, ctx->prot, ret);
- } else {
- qemu_log_mask(CPU_LOG_MMU, "%s: access refused " TARGET_FMT_lx
- " => " HWADDR_FMT_plx " %d %d\n", __func__, address,
- raddr, ctx->prot, ret);
- }
-
+ qemu_log_mask(CPU_LOG_MMU, "%s: access %s " TARGET_FMT_lx " => "
+ HWADDR_FMT_plx " %d %d\n", __func__,
+ ret < 0 ? "refused" : "granted", address, raddr,
+ ctx->prot, ret);
return ret;
}
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v3 18/33] target/ppc/mmu_common.c: Fix misindented qemu_log_mask() calls
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (16 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 17/33] target/ppc/mmu_common.c: Simplify mmubooke206_get_physical_address() BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 0:15 ` [PATCH v3 19/33] target/ppc/mmu_common.c: Deindent ppc_jumbo_xlate() BALATON Zoltan
` (14 subsequent siblings)
32 siblings, 0 replies; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
Fix several qemu_log_mask() calls that are misindented.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Acked-by: Nicholas Piggin <npiggin@gmail.com>
---
target/ppc/mmu_common.c | 42 ++++++++++++++++++++---------------------
1 file changed, 20 insertions(+), 22 deletions(-)
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index a5bc747f40..3f584f2655 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -318,8 +318,8 @@ static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
int ret = -1;
bool ifetch = access_type == MMU_INST_FETCH;
- qemu_log_mask(CPU_LOG_MMU, "%s: %cBAT v " TARGET_FMT_lx "\n", __func__,
- ifetch ? 'I' : 'D', virtual);
+ qemu_log_mask(CPU_LOG_MMU, "%s: %cBAT v " TARGET_FMT_lx "\n", __func__,
+ ifetch ? 'I' : 'D', virtual);
if (ifetch) {
BATlt = env->IBAT[1];
BATut = env->IBAT[0];
@@ -333,9 +333,9 @@ static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
BEPIu = *BATu & 0xF0000000;
BEPIl = *BATu & 0x0FFE0000;
bat_size_prot(env, &bl, &valid, &prot, BATu, BATl);
- qemu_log_mask(CPU_LOG_MMU, "%s: %cBAT%d v " TARGET_FMT_lx " BATu "
- TARGET_FMT_lx " BATl " TARGET_FMT_lx "\n", __func__,
- ifetch ? 'I' : 'D', i, virtual, *BATu, *BATl);
+ qemu_log_mask(CPU_LOG_MMU, "%s: %cBAT%d v " TARGET_FMT_lx " BATu "
+ TARGET_FMT_lx " BATl " TARGET_FMT_lx "\n", __func__,
+ ifetch ? 'I' : 'D', i, virtual, *BATu, *BATl);
if ((virtual & 0xF0000000) == BEPIu &&
((virtual & 0x0FFE0000) & ~bl) == BEPIl) {
/* BAT matches */
@@ -367,12 +367,11 @@ static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
BEPIu = *BATu & 0xF0000000;
BEPIl = *BATu & 0x0FFE0000;
bl = (*BATu & 0x00001FFC) << 15;
- qemu_log_mask(CPU_LOG_MMU, "%s: %cBAT%d v "
- TARGET_FMT_lx " BATu " TARGET_FMT_lx
- " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " "
- TARGET_FMT_lx " " TARGET_FMT_lx "\n",
- __func__, ifetch ? 'I' : 'D', i, virtual,
- *BATu, *BATl, BEPIu, BEPIl, bl);
+ qemu_log_mask(CPU_LOG_MMU, "%s: %cBAT%d v " TARGET_FMT_lx
+ " BATu " TARGET_FMT_lx " BATl " TARGET_FMT_lx
+ "\n\t" TARGET_FMT_lx " " TARGET_FMT_lx " "
+ TARGET_FMT_lx "\n", __func__, ifetch ? 'I' : 'D',
+ i, virtual, *BATu, *BATl, BEPIu, BEPIl, bl);
}
}
}
@@ -418,9 +417,8 @@ static int mmu6xx_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
hash = vsid ^ pgidx;
ctx->ptem = (vsid << 7) | (pgidx >> 10);
- qemu_log_mask(CPU_LOG_MMU,
- "pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx "\n",
- ctx->key, ds, ctx->nx, vsid);
+ qemu_log_mask(CPU_LOG_MMU, "pte segment: key=%d ds %d nx %d vsid "
+ TARGET_FMT_lx "\n", ctx->key, ds, ctx->nx, vsid);
if (!ds) {
/* Check if instruction fetch is allowed, if needed */
if (type == ACCESS_CODE && ctx->nx) {
@@ -586,9 +584,9 @@ static int mmu40x_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
return 0;
}
}
- qemu_log_mask(CPU_LOG_MMU, "%s: access refused " TARGET_FMT_lx
- " => " HWADDR_FMT_plx
- " %d %d\n", __func__, address, raddr, ctx->prot, ret);
+ qemu_log_mask(CPU_LOG_MMU, "%s: access refused " TARGET_FMT_lx
+ " => " HWADDR_FMT_plx " %d %d\n",
+ __func__, address, raddr, ctx->prot, ret);
return ret;
}
@@ -700,11 +698,11 @@ int ppcmas_tlb_check(CPUPPCState *env, ppcmas_tlb_t *tlb, hwaddr *raddrp,
}
mask = ~(booke206_tlb_to_page_size(env, tlb) - 1);
- qemu_log_mask(CPU_LOG_MMU, "%s: TLB ADDR=0x" TARGET_FMT_lx
- " PID=0x%x MAS1=0x%x MAS2=0x%" PRIx64 " mask=0x%"
- HWADDR_PRIx " MAS7_3=0x%" PRIx64 " MAS8=0x%" PRIx32 "\n",
- __func__, address, pid, tlb->mas1, tlb->mas2, mask,
- tlb->mas7_3, tlb->mas8);
+ qemu_log_mask(CPU_LOG_MMU, "%s: TLB ADDR=0x" TARGET_FMT_lx
+ " PID=0x%x MAS1=0x%x MAS2=0x%" PRIx64 " mask=0x%"
+ HWADDR_PRIx " MAS7_3=0x%" PRIx64 " MAS8=0x%" PRIx32 "\n",
+ __func__, address, pid, tlb->mas1, tlb->mas2, mask,
+ tlb->mas7_3, tlb->mas8);
/* Check PID */
tlb_pid = (tlb->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT;
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v3 19/33] target/ppc/mmu_common.c: Deindent ppc_jumbo_xlate()
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (17 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 18/33] target/ppc/mmu_common.c: Fix misindented qemu_log_mask() calls BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 0:15 ` [PATCH v3 20/33] target/ppc/mmu_common.c: Replace hard coded constants in ppc_jumbo_xlate() BALATON Zoltan
` (13 subsequent siblings)
32 siblings, 0 replies; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
Instead of putting a large block of code in an if, invert the
condition and return early to be able to deindent the code block.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Acked-by: Nicholas Piggin <npiggin@gmail.com>
---
target/ppc/mmu_common.c | 319 ++++++++++++++++++++--------------------
1 file changed, 159 insertions(+), 160 deletions(-)
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index 3f584f2655..b1b2d64b90 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -1252,187 +1252,186 @@ static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
*protp = ctx.prot;
*psizep = TARGET_PAGE_BITS;
return true;
+ } else if (!guest_visible) {
+ return false;
}
- if (guest_visible) {
- log_cpu_state_mask(CPU_LOG_MMU, cs, 0);
- if (type == ACCESS_CODE) {
- switch (ret) {
- case -1:
- /* No matches in page tables or TLB */
- switch (env->mmu_model) {
- case POWERPC_MMU_SOFT_6xx:
- cs->exception_index = POWERPC_EXCP_IFTLB;
- env->error_code = 1 << 18;
- env->spr[SPR_IMISS] = eaddr;
- env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
- goto tlb_miss;
- case POWERPC_MMU_SOFT_4xx:
- cs->exception_index = POWERPC_EXCP_ITLB;
- env->error_code = 0;
- env->spr[SPR_40x_DEAR] = eaddr;
- env->spr[SPR_40x_ESR] = 0x00000000;
- break;
- case POWERPC_MMU_BOOKE206:
- booke206_update_mas_tlb_miss(env, eaddr, 2, mmu_idx);
- /* fall through */
- case POWERPC_MMU_BOOKE:
- cs->exception_index = POWERPC_EXCP_ITLB;
- env->error_code = 0;
- env->spr[SPR_BOOKE_DEAR] = eaddr;
- env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, MMU_DATA_LOAD);
- break;
- case POWERPC_MMU_REAL:
- cpu_abort(cs, "PowerPC in real mode should never raise "
- "any MMU exceptions\n");
- default:
- cpu_abort(cs, "Unknown or invalid MMU model\n");
- }
+ log_cpu_state_mask(CPU_LOG_MMU, cs, 0);
+ if (type == ACCESS_CODE) {
+ switch (ret) {
+ case -1:
+ /* No matches in page tables or TLB */
+ switch (env->mmu_model) {
+ case POWERPC_MMU_SOFT_6xx:
+ cs->exception_index = POWERPC_EXCP_IFTLB;
+ env->error_code = 1 << 18;
+ env->spr[SPR_IMISS] = eaddr;
+ env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
+ goto tlb_miss;
+ case POWERPC_MMU_SOFT_4xx:
+ cs->exception_index = POWERPC_EXCP_ITLB;
+ env->error_code = 0;
+ env->spr[SPR_40x_DEAR] = eaddr;
+ env->spr[SPR_40x_ESR] = 0x00000000;
break;
- case -2:
- /* Access rights violation */
- cs->exception_index = POWERPC_EXCP_ISI;
- if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
- (env->mmu_model == POWERPC_MMU_BOOKE206)) {
- env->error_code = 0;
- } else {
- env->error_code = 0x08000000;
- }
+ case POWERPC_MMU_BOOKE206:
+ booke206_update_mas_tlb_miss(env, eaddr, 2, mmu_idx);
+ /* fall through */
+ case POWERPC_MMU_BOOKE:
+ cs->exception_index = POWERPC_EXCP_ITLB;
+ env->error_code = 0;
+ env->spr[SPR_BOOKE_DEAR] = eaddr;
+ env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, MMU_DATA_LOAD);
break;
- case -3:
- /* No execute protection violation */
- if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
- (env->mmu_model == POWERPC_MMU_BOOKE206)) {
- env->spr[SPR_BOOKE_ESR] = 0x00000000;
- env->error_code = 0;
+ case POWERPC_MMU_REAL:
+ cpu_abort(cs, "PowerPC in real mode should never raise "
+ "any MMU exceptions\n");
+ default:
+ cpu_abort(cs, "Unknown or invalid MMU model\n");
+ }
+ break;
+ case -2:
+ /* Access rights violation */
+ cs->exception_index = POWERPC_EXCP_ISI;
+ if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
+ (env->mmu_model == POWERPC_MMU_BOOKE206)) {
+ env->error_code = 0;
+ } else {
+ env->error_code = 0x08000000;
+ }
+ break;
+ case -3:
+ /* No execute protection violation */
+ if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
+ (env->mmu_model == POWERPC_MMU_BOOKE206)) {
+ env->spr[SPR_BOOKE_ESR] = 0x00000000;
+ env->error_code = 0;
+ } else {
+ env->error_code = 0x10000000;
+ }
+ cs->exception_index = POWERPC_EXCP_ISI;
+ break;
+ case -4:
+ /* Direct store exception */
+ /* No code fetch is allowed in direct-store areas */
+ cs->exception_index = POWERPC_EXCP_ISI;
+ if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
+ (env->mmu_model == POWERPC_MMU_BOOKE206)) {
+ env->error_code = 0;
+ } else {
+ env->error_code = 0x10000000;
+ }
+ break;
+ }
+ } else {
+ switch (ret) {
+ case -1:
+ /* No matches in page tables or TLB */
+ switch (env->mmu_model) {
+ case POWERPC_MMU_SOFT_6xx:
+ if (access_type == MMU_DATA_STORE) {
+ cs->exception_index = POWERPC_EXCP_DSTLB;
+ env->error_code = 1 << 16;
} else {
- env->error_code = 0x10000000;
+ cs->exception_index = POWERPC_EXCP_DLTLB;
+ env->error_code = 0;
}
- cs->exception_index = POWERPC_EXCP_ISI;
+ env->spr[SPR_DMISS] = eaddr;
+ env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem;
+ tlb_miss:
+ env->error_code |= ctx.key << 19;
+ env->spr[SPR_HASH1] = ppc_hash32_hpt_base(cpu) +
+ get_pteg_offset32(cpu, ctx.hash[0]);
+ env->spr[SPR_HASH2] = ppc_hash32_hpt_base(cpu) +
+ get_pteg_offset32(cpu, ctx.hash[1]);
break;
- case -4:
- /* Direct store exception */
- /* No code fetch is allowed in direct-store areas */
- cs->exception_index = POWERPC_EXCP_ISI;
- if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
- (env->mmu_model == POWERPC_MMU_BOOKE206)) {
- env->error_code = 0;
+ case POWERPC_MMU_SOFT_4xx:
+ cs->exception_index = POWERPC_EXCP_DTLB;
+ env->error_code = 0;
+ env->spr[SPR_40x_DEAR] = eaddr;
+ if (access_type == MMU_DATA_STORE) {
+ env->spr[SPR_40x_ESR] = 0x00800000;
} else {
- env->error_code = 0x10000000;
+ env->spr[SPR_40x_ESR] = 0x00000000;
}
break;
- }
- } else {
- switch (ret) {
- case -1:
- /* No matches in page tables or TLB */
- switch (env->mmu_model) {
- case POWERPC_MMU_SOFT_6xx:
- if (access_type == MMU_DATA_STORE) {
- cs->exception_index = POWERPC_EXCP_DSTLB;
- env->error_code = 1 << 16;
- } else {
- cs->exception_index = POWERPC_EXCP_DLTLB;
- env->error_code = 0;
- }
- env->spr[SPR_DMISS] = eaddr;
- env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem;
- tlb_miss:
- env->error_code |= ctx.key << 19;
- env->spr[SPR_HASH1] = ppc_hash32_hpt_base(cpu) +
- get_pteg_offset32(cpu, ctx.hash[0]);
- env->spr[SPR_HASH2] = ppc_hash32_hpt_base(cpu) +
- get_pteg_offset32(cpu, ctx.hash[1]);
- break;
- case POWERPC_MMU_SOFT_4xx:
- cs->exception_index = POWERPC_EXCP_DTLB;
- env->error_code = 0;
- env->spr[SPR_40x_DEAR] = eaddr;
- if (access_type == MMU_DATA_STORE) {
- env->spr[SPR_40x_ESR] = 0x00800000;
- } else {
- env->spr[SPR_40x_ESR] = 0x00000000;
- }
- break;
- case POWERPC_MMU_BOOKE206:
- booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
- /* fall through */
- case POWERPC_MMU_BOOKE:
- cs->exception_index = POWERPC_EXCP_DTLB;
- env->error_code = 0;
- env->spr[SPR_BOOKE_DEAR] = eaddr;
- env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
- break;
- case POWERPC_MMU_REAL:
- cpu_abort(cs, "PowerPC in real mode should never raise "
+ case POWERPC_MMU_BOOKE206:
+ booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
+ /* fall through */
+ case POWERPC_MMU_BOOKE:
+ cs->exception_index = POWERPC_EXCP_DTLB;
+ env->error_code = 0;
+ env->spr[SPR_BOOKE_DEAR] = eaddr;
+ env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
+ break;
+ case POWERPC_MMU_REAL:
+ cpu_abort(cs, "PowerPC in real mode should never raise "
"any MMU exceptions\n");
- default:
- cpu_abort(cs, "Unknown or invalid MMU model\n");
+ default:
+ cpu_abort(cs, "Unknown or invalid MMU model\n");
+ }
+ break;
+ case -2:
+ /* Access rights violation */
+ cs->exception_index = POWERPC_EXCP_DSI;
+ env->error_code = 0;
+ if (env->mmu_model == POWERPC_MMU_SOFT_4xx) {
+ env->spr[SPR_40x_DEAR] = eaddr;
+ if (access_type == MMU_DATA_STORE) {
+ env->spr[SPR_40x_ESR] |= 0x00800000;
+ }
+ } else if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
+ (env->mmu_model == POWERPC_MMU_BOOKE206)) {
+ env->spr[SPR_BOOKE_DEAR] = eaddr;
+ env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
+ } else {
+ env->spr[SPR_DAR] = eaddr;
+ if (access_type == MMU_DATA_STORE) {
+ env->spr[SPR_DSISR] = 0x0A000000;
+ } else {
+ env->spr[SPR_DSISR] = 0x08000000;
}
+ }
+ break;
+ case -4:
+ /* Direct store exception */
+ switch (type) {
+ case ACCESS_FLOAT:
+ /* Floating point load/store */
+ cs->exception_index = POWERPC_EXCP_ALIGN;
+ env->error_code = POWERPC_EXCP_ALIGN_FP;
+ env->spr[SPR_DAR] = eaddr;
break;
- case -2:
- /* Access rights violation */
+ case ACCESS_RES:
+ /* lwarx, ldarx or stwcx. */
cs->exception_index = POWERPC_EXCP_DSI;
env->error_code = 0;
- if (env->mmu_model == POWERPC_MMU_SOFT_4xx) {
- env->spr[SPR_40x_DEAR] = eaddr;
- if (access_type == MMU_DATA_STORE) {
- env->spr[SPR_40x_ESR] |= 0x00800000;
- }
- } else if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
- (env->mmu_model == POWERPC_MMU_BOOKE206)) {
- env->spr[SPR_BOOKE_DEAR] = eaddr;
- env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
+ env->spr[SPR_DAR] = eaddr;
+ if (access_type == MMU_DATA_STORE) {
+ env->spr[SPR_DSISR] = 0x06000000;
} else {
- env->spr[SPR_DAR] = eaddr;
- if (access_type == MMU_DATA_STORE) {
- env->spr[SPR_DSISR] = 0x0A000000;
- } else {
- env->spr[SPR_DSISR] = 0x08000000;
- }
+ env->spr[SPR_DSISR] = 0x04000000;
}
break;
- case -4:
- /* Direct store exception */
- switch (type) {
- case ACCESS_FLOAT:
- /* Floating point load/store */
- cs->exception_index = POWERPC_EXCP_ALIGN;
- env->error_code = POWERPC_EXCP_ALIGN_FP;
- env->spr[SPR_DAR] = eaddr;
- break;
- case ACCESS_RES:
- /* lwarx, ldarx or stwcx. */
- cs->exception_index = POWERPC_EXCP_DSI;
- env->error_code = 0;
- env->spr[SPR_DAR] = eaddr;
- if (access_type == MMU_DATA_STORE) {
- env->spr[SPR_DSISR] = 0x06000000;
- } else {
- env->spr[SPR_DSISR] = 0x04000000;
- }
- break;
- case ACCESS_EXT:
- /* eciwx or ecowx */
- cs->exception_index = POWERPC_EXCP_DSI;
- env->error_code = 0;
- env->spr[SPR_DAR] = eaddr;
- if (access_type == MMU_DATA_STORE) {
- env->spr[SPR_DSISR] = 0x06100000;
- } else {
- env->spr[SPR_DSISR] = 0x04100000;
- }
- break;
- default:
- printf("DSI: invalid exception (%d)\n", ret);
- cs->exception_index = POWERPC_EXCP_PROGRAM;
- env->error_code =
- POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL;
- env->spr[SPR_DAR] = eaddr;
- break;
+ case ACCESS_EXT:
+ /* eciwx or ecowx */
+ cs->exception_index = POWERPC_EXCP_DSI;
+ env->error_code = 0;
+ env->spr[SPR_DAR] = eaddr;
+ if (access_type == MMU_DATA_STORE) {
+ env->spr[SPR_DSISR] = 0x06100000;
+ } else {
+ env->spr[SPR_DSISR] = 0x04100000;
}
break;
+ default:
+ printf("DSI: invalid exception (%d)\n", ret);
+ cs->exception_index = POWERPC_EXCP_PROGRAM;
+ env->error_code = POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL;
+ env->spr[SPR_DAR] = eaddr;
+ break;
}
+ break;
}
}
return false;
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v3 20/33] target/ppc/mmu_common.c: Replace hard coded constants in ppc_jumbo_xlate()
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (18 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 19/33] target/ppc/mmu_common.c: Deindent ppc_jumbo_xlate() BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 0:15 ` [PATCH v3 21/33] target/ppc/mmu_common.c: Make get_physical_address_wtlb() static BALATON Zoltan
` (12 subsequent siblings)
32 siblings, 0 replies; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
The "2" in booke206_update_mas_tlb_miss() call corresponds to
MMU_INST_FETCH which is the value of access_type in this branch;
mmubooke206_esr() only checks for MMU_DATA_STORE and it's called from
code access so using MMU_DATA_LOAD here seems wrong so replace it with
access_type here as well that yields the same result. This also makes
these calls the same as the data access branch further down.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
---
target/ppc/mmu_common.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index b1b2d64b90..63b5fb98d1 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -1275,13 +1275,13 @@ static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
env->spr[SPR_40x_ESR] = 0x00000000;
break;
case POWERPC_MMU_BOOKE206:
- booke206_update_mas_tlb_miss(env, eaddr, 2, mmu_idx);
+ booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
/* fall through */
case POWERPC_MMU_BOOKE:
cs->exception_index = POWERPC_EXCP_ITLB;
env->error_code = 0;
env->spr[SPR_BOOKE_DEAR] = eaddr;
- env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, MMU_DATA_LOAD);
+ env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
break;
case POWERPC_MMU_REAL:
cpu_abort(cs, "PowerPC in real mode should never raise "
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v3 21/33] target/ppc/mmu_common.c: Make get_physical_address_wtlb() static
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (19 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 20/33] target/ppc/mmu_common.c: Replace hard coded constants in ppc_jumbo_xlate() BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 12:58 ` Nicholas Piggin
2024-05-08 0:15 ` [PATCH v3 22/33] target/ppc: Remove pp_check() and reuse ppc_hash32_pp_prot() BALATON Zoltan
` (11 subsequent siblings)
32 siblings, 1 reply; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
This function is not used from any other files so make it static and
fix the maybe used uninitialised warnings this has uncovered. Also
remove mmu_ctx_t definition from internal.h as this type is only used
within this file.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
target/ppc/internal.h | 17 +----------------
target/ppc/mmu_common.c | 18 +++++++++++++++---
2 files changed, 16 insertions(+), 19 deletions(-)
diff --git a/target/ppc/internal.h b/target/ppc/internal.h
index 98b41a970c..4a90dd2584 100644
--- a/target/ppc/internal.h
+++ b/target/ppc/internal.h
@@ -257,28 +257,13 @@ static inline int prot_for_access_type(MMUAccessType access_type)
/* PowerPC MMU emulation */
-typedef struct mmu_ctx_t mmu_ctx_t;
-
bool ppc_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
hwaddr *raddrp, int *psizep, int *protp,
int mmu_idx, bool guest_visible);
-int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
- target_ulong eaddr,
- MMUAccessType access_type, int type,
- int mmu_idx);
+
/* Software driven TLB helpers */
int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr,
int way, int is_code);
-/* Context used internally during MMU translations */
-struct mmu_ctx_t {
- hwaddr raddr; /* Real address */
- hwaddr eaddr; /* Effective address */
- int prot; /* Protection bits */
- hwaddr hash[2]; /* Pagetable hash values */
- target_ulong ptem; /* Virtual segment ID | API */
- int key; /* Access key */
- int nx; /* Non-execute area */
-};
#endif /* !CONFIG_USER_ONLY */
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index 63b5fb98d1..d92c9607b8 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -36,6 +36,17 @@
/* #define DUMP_PAGE_TABLES */
+/* Context used internally during MMU translations */
+typedef struct {
+ hwaddr raddr; /* Real address */
+ hwaddr eaddr; /* Effective address */
+ int prot; /* Protection bits */
+ hwaddr hash[2]; /* Pagetable hash values */
+ target_ulong ptem; /* Virtual segment ID | API */
+ int key; /* Access key */
+ int nx; /* Non-execute area */
+} mmu_ctx_t;
+
void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
{
PowerPCCPU *cpu = env_archcpu(env);
@@ -667,7 +678,7 @@ static int mmubooke_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
qemu_log_mask(CPU_LOG_MMU,
"%s: access %s " TARGET_FMT_lx " => " HWADDR_FMT_plx
" %d %d\n", __func__, ret < 0 ? "refused" : "granted",
- address, raddr, ctx->prot, ret);
+ address, raddr, ret == -1 ? 0 : ctx->prot, ret);
return ret;
}
@@ -883,7 +894,7 @@ found_tlb:
qemu_log_mask(CPU_LOG_MMU, "%s: access %s " TARGET_FMT_lx " => "
HWADDR_FMT_plx " %d %d\n", __func__,
ret < 0 ? "refused" : "granted", address, raddr,
- ctx->prot, ret);
+ ret == -1 ? 0 : ctx->prot, ret);
return ret;
}
@@ -1131,7 +1142,7 @@ void dump_mmu(CPUPPCState *env)
}
}
-int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
+static int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
target_ulong eaddr,
MMUAccessType access_type, int type,
int mmu_idx)
@@ -1150,6 +1161,7 @@ int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
if (real_mode && (env->mmu_model == POWERPC_MMU_SOFT_6xx ||
env->mmu_model == POWERPC_MMU_SOFT_4xx ||
env->mmu_model == POWERPC_MMU_REAL)) {
+ memset(ctx, 0, sizeof(*ctx));
ctx->raddr = eaddr;
ctx->prot = PAGE_RWX;
return 0;
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* Re: [PATCH v3 21/33] target/ppc/mmu_common.c: Make get_physical_address_wtlb() static
2024-05-08 0:15 ` [PATCH v3 21/33] target/ppc/mmu_common.c: Make get_physical_address_wtlb() static BALATON Zoltan
@ 2024-05-08 12:58 ` Nicholas Piggin
0 siblings, 0 replies; 58+ messages in thread
From: Nicholas Piggin @ 2024-05-08 12:58 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel, qemu-ppc; +Cc: Daniel Henrique Barboza
On Wed May 8, 2024 at 10:15 AM AEST, BALATON Zoltan wrote:
> This function is not used from any other files so make it static and
> fix the maybe used uninitialised warnings this has uncovered. Also
> remove mmu_ctx_t definition from internal.h as this type is only used
> within this file.
If you add a /* quiet used uninitialized warning */ or similar comment
on the memset then.
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
If you respin you could, put the prot fixes as their own patch but
pretty minor thing if you can't be bothered.
>
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> ---
> target/ppc/internal.h | 17 +----------------
> target/ppc/mmu_common.c | 18 +++++++++++++++---
> 2 files changed, 16 insertions(+), 19 deletions(-)
>
> diff --git a/target/ppc/internal.h b/target/ppc/internal.h
> index 98b41a970c..4a90dd2584 100644
> --- a/target/ppc/internal.h
> +++ b/target/ppc/internal.h
> @@ -257,28 +257,13 @@ static inline int prot_for_access_type(MMUAccessType access_type)
>
> /* PowerPC MMU emulation */
>
> -typedef struct mmu_ctx_t mmu_ctx_t;
> -
> bool ppc_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
> hwaddr *raddrp, int *psizep, int *protp,
> int mmu_idx, bool guest_visible);
> -int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
> - target_ulong eaddr,
> - MMUAccessType access_type, int type,
> - int mmu_idx);
> +
> /* Software driven TLB helpers */
> int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr,
> int way, int is_code);
> -/* Context used internally during MMU translations */
> -struct mmu_ctx_t {
> - hwaddr raddr; /* Real address */
> - hwaddr eaddr; /* Effective address */
> - int prot; /* Protection bits */
> - hwaddr hash[2]; /* Pagetable hash values */
> - target_ulong ptem; /* Virtual segment ID | API */
> - int key; /* Access key */
> - int nx; /* Non-execute area */
> -};
>
> #endif /* !CONFIG_USER_ONLY */
>
> diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
> index 63b5fb98d1..d92c9607b8 100644
> --- a/target/ppc/mmu_common.c
> +++ b/target/ppc/mmu_common.c
> @@ -36,6 +36,17 @@
>
> /* #define DUMP_PAGE_TABLES */
>
> +/* Context used internally during MMU translations */
> +typedef struct {
> + hwaddr raddr; /* Real address */
> + hwaddr eaddr; /* Effective address */
> + int prot; /* Protection bits */
> + hwaddr hash[2]; /* Pagetable hash values */
> + target_ulong ptem; /* Virtual segment ID | API */
> + int key; /* Access key */
> + int nx; /* Non-execute area */
> +} mmu_ctx_t;
> +
> void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
> {
> PowerPCCPU *cpu = env_archcpu(env);
> @@ -667,7 +678,7 @@ static int mmubooke_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
> qemu_log_mask(CPU_LOG_MMU,
> "%s: access %s " TARGET_FMT_lx " => " HWADDR_FMT_plx
> " %d %d\n", __func__, ret < 0 ? "refused" : "granted",
> - address, raddr, ctx->prot, ret);
> + address, raddr, ret == -1 ? 0 : ctx->prot, ret);
> return ret;
> }
>
> @@ -883,7 +894,7 @@ found_tlb:
> qemu_log_mask(CPU_LOG_MMU, "%s: access %s " TARGET_FMT_lx " => "
> HWADDR_FMT_plx " %d %d\n", __func__,
> ret < 0 ? "refused" : "granted", address, raddr,
> - ctx->prot, ret);
> + ret == -1 ? 0 : ctx->prot, ret);
> return ret;
> }
>
> @@ -1131,7 +1142,7 @@ void dump_mmu(CPUPPCState *env)
> }
> }
>
> -int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
> +static int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
> target_ulong eaddr,
> MMUAccessType access_type, int type,
> int mmu_idx)
> @@ -1150,6 +1161,7 @@ int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
> if (real_mode && (env->mmu_model == POWERPC_MMU_SOFT_6xx ||
> env->mmu_model == POWERPC_MMU_SOFT_4xx ||
> env->mmu_model == POWERPC_MMU_REAL)) {
> + memset(ctx, 0, sizeof(*ctx));
> ctx->raddr = eaddr;
> ctx->prot = PAGE_RWX;
> return 0;
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 22/33] target/ppc: Remove pp_check() and reuse ppc_hash32_pp_prot()
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (20 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 21/33] target/ppc/mmu_common.c: Make get_physical_address_wtlb() static BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 12:59 ` Nicholas Piggin
2024-05-08 0:15 ` [PATCH v3 23/33] target/ppc/mmu_common.c: Remove BookE from direct store handling BALATON Zoltan
` (10 subsequent siblings)
32 siblings, 1 reply; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
The ppc_hash32_pp_prot() function in mmu-hash32.c is the same as
pp_check() in mmu_common.c, merge these to remove duplicated code.
Define the common function in internal.h as static lnline otherwise
exporting the function from mmu-hash32.c would stop the compiler
inlining it which results in slightly lower performance.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
target/ppc/internal.h | 35 ++++++++++++++++++++++++++++++++
target/ppc/mmu-hash32.c | 45 -----------------------------------------
target/ppc/mmu_common.c | 44 ++--------------------------------------
3 files changed, 37 insertions(+), 87 deletions(-)
diff --git a/target/ppc/internal.h b/target/ppc/internal.h
index 4a90dd2584..46176c4711 100644
--- a/target/ppc/internal.h
+++ b/target/ppc/internal.h
@@ -256,6 +256,41 @@ static inline int prot_for_access_type(MMUAccessType access_type)
#ifndef CONFIG_USER_ONLY
/* PowerPC MMU emulation */
+static inline int ppc_hash32_pp_prot(int key, int pp, int nx)
+{
+ int prot;
+
+ if (key == 0) {
+ switch (pp) {
+ case 0x0:
+ case 0x1:
+ case 0x2:
+ prot = PAGE_READ | PAGE_WRITE;
+ break;
+ case 0x3:
+ prot = PAGE_READ;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ } else {
+ switch (pp) {
+ case 0x0:
+ prot = 0;
+ break;
+ case 0x1:
+ case 0x3:
+ prot = PAGE_READ;
+ break;
+ case 0x2:
+ prot = PAGE_READ | PAGE_WRITE;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ }
+ return nx ? prot : prot | PAGE_EXEC;
+}
bool ppc_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
hwaddr *raddrp, int *psizep, int *protp,
diff --git a/target/ppc/mmu-hash32.c b/target/ppc/mmu-hash32.c
index 6dfedab11d..960751a50e 100644
--- a/target/ppc/mmu-hash32.c
+++ b/target/ppc/mmu-hash32.c
@@ -43,51 +43,6 @@ struct mmu_ctx_hash32 {
int key; /* Access key */
};
-static int ppc_hash32_pp_prot(int key, int pp, int nx)
-{
- int prot;
-
- if (key == 0) {
- switch (pp) {
- case 0x0:
- case 0x1:
- case 0x2:
- prot = PAGE_READ | PAGE_WRITE;
- break;
-
- case 0x3:
- prot = PAGE_READ;
- break;
-
- default:
- abort();
- }
- } else {
- switch (pp) {
- case 0x0:
- prot = 0;
- break;
-
- case 0x1:
- case 0x3:
- prot = PAGE_READ;
- break;
-
- case 0x2:
- prot = PAGE_READ | PAGE_WRITE;
- break;
-
- default:
- abort();
- }
- }
- if (nx == 0) {
- prot |= PAGE_EXEC;
- }
-
- return prot;
-}
-
static int ppc_hash32_pte_prot(int mmu_idx,
target_ulong sr, ppc_hash_pte32_t pte)
{
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index d92c9607b8..87cac12d68 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -76,44 +76,6 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
/*****************************************************************************/
/* PowerPC MMU emulation */
-static int pp_check(int key, int pp, int nx)
-{
- int access;
-
- /* Compute access rights */
- access = 0;
- if (key == 0) {
- switch (pp) {
- case 0x0:
- case 0x1:
- case 0x2:
- access |= PAGE_WRITE;
- /* fall through */
- case 0x3:
- access |= PAGE_READ;
- break;
- }
- } else {
- switch (pp) {
- case 0x0:
- access = 0;
- break;
- case 0x1:
- case 0x3:
- access = PAGE_READ;
- break;
- case 0x2:
- access = PAGE_READ | PAGE_WRITE;
- break;
- }
- }
- if (nx == 0) {
- access |= PAGE_EXEC;
- }
-
- return access;
-}
-
static int check_prot(int prot, MMUAccessType access_type)
{
return prot & prot_for_access_type(access_type) ? 0 : -2;
@@ -141,7 +103,7 @@ static int ppc6xx_tlb_pte_check(mmu_ctx_t *ctx, target_ulong pte0,
MMUAccessType access_type)
{
target_ulong ptem, mmask;
- int access, ret, pteh, ptev, pp;
+ int ret, pteh, ptev, pp;
ret = -1;
/* Check validity and table match */
@@ -160,11 +122,9 @@ static int ppc6xx_tlb_pte_check(mmu_ctx_t *ctx, target_ulong pte0,
return -3;
}
}
- /* Compute access rights */
- access = pp_check(ctx->key, pp, ctx->nx);
/* Keep the matching PTE information */
ctx->raddr = pte1;
- ctx->prot = access;
+ ctx->prot = ppc_hash32_pp_prot(ctx->key, pp, ctx->nx);
ret = check_prot(ctx->prot, access_type);
if (ret == 0) {
/* Access granted */
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* Re: [PATCH v3 22/33] target/ppc: Remove pp_check() and reuse ppc_hash32_pp_prot()
2024-05-08 0:15 ` [PATCH v3 22/33] target/ppc: Remove pp_check() and reuse ppc_hash32_pp_prot() BALATON Zoltan
@ 2024-05-08 12:59 ` Nicholas Piggin
0 siblings, 0 replies; 58+ messages in thread
From: Nicholas Piggin @ 2024-05-08 12:59 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel, qemu-ppc; +Cc: Daniel Henrique Barboza
On Wed May 8, 2024 at 10:15 AM AEST, BALATON Zoltan wrote:
> The ppc_hash32_pp_prot() function in mmu-hash32.c is the same as
> pp_check() in mmu_common.c, merge these to remove duplicated code.
> Define the common function in internal.h as static lnline otherwise
> exporting the function from mmu-hash32.c would stop the compiler
> inlining it which results in slightly lower performance.
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
>
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> ---
> target/ppc/internal.h | 35 ++++++++++++++++++++++++++++++++
> target/ppc/mmu-hash32.c | 45 -----------------------------------------
> target/ppc/mmu_common.c | 44 ++--------------------------------------
> 3 files changed, 37 insertions(+), 87 deletions(-)
>
> diff --git a/target/ppc/internal.h b/target/ppc/internal.h
> index 4a90dd2584..46176c4711 100644
> --- a/target/ppc/internal.h
> +++ b/target/ppc/internal.h
> @@ -256,6 +256,41 @@ static inline int prot_for_access_type(MMUAccessType access_type)
> #ifndef CONFIG_USER_ONLY
>
> /* PowerPC MMU emulation */
> +static inline int ppc_hash32_pp_prot(int key, int pp, int nx)
> +{
> + int prot;
> +
> + if (key == 0) {
> + switch (pp) {
> + case 0x0:
> + case 0x1:
> + case 0x2:
> + prot = PAGE_READ | PAGE_WRITE;
> + break;
> + case 0x3:
> + prot = PAGE_READ;
> + break;
> + default:
> + g_assert_not_reached();
> + }
> + } else {
> + switch (pp) {
> + case 0x0:
> + prot = 0;
> + break;
> + case 0x1:
> + case 0x3:
> + prot = PAGE_READ;
> + break;
> + case 0x2:
> + prot = PAGE_READ | PAGE_WRITE;
> + break;
> + default:
> + g_assert_not_reached();
> + }
> + }
> + return nx ? prot : prot | PAGE_EXEC;
> +}
>
> bool ppc_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
> hwaddr *raddrp, int *psizep, int *protp,
> diff --git a/target/ppc/mmu-hash32.c b/target/ppc/mmu-hash32.c
> index 6dfedab11d..960751a50e 100644
> --- a/target/ppc/mmu-hash32.c
> +++ b/target/ppc/mmu-hash32.c
> @@ -43,51 +43,6 @@ struct mmu_ctx_hash32 {
> int key; /* Access key */
> };
>
> -static int ppc_hash32_pp_prot(int key, int pp, int nx)
> -{
> - int prot;
> -
> - if (key == 0) {
> - switch (pp) {
> - case 0x0:
> - case 0x1:
> - case 0x2:
> - prot = PAGE_READ | PAGE_WRITE;
> - break;
> -
> - case 0x3:
> - prot = PAGE_READ;
> - break;
> -
> - default:
> - abort();
> - }
> - } else {
> - switch (pp) {
> - case 0x0:
> - prot = 0;
> - break;
> -
> - case 0x1:
> - case 0x3:
> - prot = PAGE_READ;
> - break;
> -
> - case 0x2:
> - prot = PAGE_READ | PAGE_WRITE;
> - break;
> -
> - default:
> - abort();
> - }
> - }
> - if (nx == 0) {
> - prot |= PAGE_EXEC;
> - }
> -
> - return prot;
> -}
> -
> static int ppc_hash32_pte_prot(int mmu_idx,
> target_ulong sr, ppc_hash_pte32_t pte)
> {
> diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
> index d92c9607b8..87cac12d68 100644
> --- a/target/ppc/mmu_common.c
> +++ b/target/ppc/mmu_common.c
> @@ -76,44 +76,6 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
> /*****************************************************************************/
> /* PowerPC MMU emulation */
>
> -static int pp_check(int key, int pp, int nx)
> -{
> - int access;
> -
> - /* Compute access rights */
> - access = 0;
> - if (key == 0) {
> - switch (pp) {
> - case 0x0:
> - case 0x1:
> - case 0x2:
> - access |= PAGE_WRITE;
> - /* fall through */
> - case 0x3:
> - access |= PAGE_READ;
> - break;
> - }
> - } else {
> - switch (pp) {
> - case 0x0:
> - access = 0;
> - break;
> - case 0x1:
> - case 0x3:
> - access = PAGE_READ;
> - break;
> - case 0x2:
> - access = PAGE_READ | PAGE_WRITE;
> - break;
> - }
> - }
> - if (nx == 0) {
> - access |= PAGE_EXEC;
> - }
> -
> - return access;
> -}
> -
> static int check_prot(int prot, MMUAccessType access_type)
> {
> return prot & prot_for_access_type(access_type) ? 0 : -2;
> @@ -141,7 +103,7 @@ static int ppc6xx_tlb_pte_check(mmu_ctx_t *ctx, target_ulong pte0,
> MMUAccessType access_type)
> {
> target_ulong ptem, mmask;
> - int access, ret, pteh, ptev, pp;
> + int ret, pteh, ptev, pp;
>
> ret = -1;
> /* Check validity and table match */
> @@ -160,11 +122,9 @@ static int ppc6xx_tlb_pte_check(mmu_ctx_t *ctx, target_ulong pte0,
> return -3;
> }
> }
> - /* Compute access rights */
> - access = pp_check(ctx->key, pp, ctx->nx);
> /* Keep the matching PTE information */
> ctx->raddr = pte1;
> - ctx->prot = access;
> + ctx->prot = ppc_hash32_pp_prot(ctx->key, pp, ctx->nx);
> ret = check_prot(ctx->prot, access_type);
> if (ret == 0) {
> /* Access granted */
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 23/33] target/ppc/mmu_common.c: Remove BookE from direct store handling
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (21 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 22/33] target/ppc: Remove pp_check() and reuse ppc_hash32_pp_prot() BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 12:59 ` Nicholas Piggin
2024-05-08 0:15 ` [PATCH v3 24/33] target/ppc/mmu_common.c: Split off BookE handling from ppc_jumbo_xlate() BALATON Zoltan
` (9 subsequent siblings)
32 siblings, 1 reply; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
As BookE never returns -4 we can drop BookE from the direct store case
in ppc_jumbo_xlate().
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
target/ppc/mmu_common.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index 87cac12d68..03b834eb77 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -1287,12 +1287,7 @@ static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
/* Direct store exception */
/* No code fetch is allowed in direct-store areas */
cs->exception_index = POWERPC_EXCP_ISI;
- if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
- (env->mmu_model == POWERPC_MMU_BOOKE206)) {
- env->error_code = 0;
- } else {
- env->error_code = 0x10000000;
- }
+ env->error_code = 0x10000000;
break;
}
} else {
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* Re: [PATCH v3 23/33] target/ppc/mmu_common.c: Remove BookE from direct store handling
2024-05-08 0:15 ` [PATCH v3 23/33] target/ppc/mmu_common.c: Remove BookE from direct store handling BALATON Zoltan
@ 2024-05-08 12:59 ` Nicholas Piggin
0 siblings, 0 replies; 58+ messages in thread
From: Nicholas Piggin @ 2024-05-08 12:59 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel, qemu-ppc; +Cc: Daniel Henrique Barboza
On Wed May 8, 2024 at 10:15 AM AEST, BALATON Zoltan wrote:
> As BookE never returns -4 we can drop BookE from the direct store case
> in ppc_jumbo_xlate().
>
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
> ---
> target/ppc/mmu_common.c | 7 +------
> 1 file changed, 1 insertion(+), 6 deletions(-)
>
> diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
> index 87cac12d68..03b834eb77 100644
> --- a/target/ppc/mmu_common.c
> +++ b/target/ppc/mmu_common.c
> @@ -1287,12 +1287,7 @@ static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
> /* Direct store exception */
> /* No code fetch is allowed in direct-store areas */
> cs->exception_index = POWERPC_EXCP_ISI;
> - if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
> - (env->mmu_model == POWERPC_MMU_BOOKE206)) {
> - env->error_code = 0;
> - } else {
> - env->error_code = 0x10000000;
> - }
> + env->error_code = 0x10000000;
> break;
> }
> } else {
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 24/33] target/ppc/mmu_common.c: Split off BookE handling from ppc_jumbo_xlate()
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (22 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 23/33] target/ppc/mmu_common.c: Remove BookE from direct store handling BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 13:01 ` Nicholas Piggin
2024-05-08 0:15 ` [PATCH v3 25/33] target/ppc/mmu_common.c: Remove BookE handling from get_physical_address_wtlb() BALATON Zoltan
` (8 subsequent siblings)
32 siblings, 1 reply; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
Introduce ppc_booke_xlate() to handle BookE and BookE 2.06 cases to
reduce ppc_jumbo_xlate() further.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
target/ppc/mmu_common.c | 128 +++++++++++++++++++++++++++++-----------
1 file changed, 92 insertions(+), 36 deletions(-)
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index 03b834eb77..83dc041a77 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -1194,6 +1194,92 @@ static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address,
env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT;
}
+static bool ppc_booke_xlate(PowerPCCPU *cpu, vaddr eaddr,
+ MMUAccessType access_type,
+ hwaddr *raddrp, int *psizep, int *protp,
+ int mmu_idx, bool guest_visible)
+{
+ CPUState *cs = CPU(cpu);
+ CPUPPCState *env = &cpu->env;
+ mmu_ctx_t ctx;
+ int ret;
+
+ if (env->mmu_model == POWERPC_MMU_BOOKE206) {
+ ret = mmubooke206_get_physical_address(env, &ctx, eaddr, access_type,
+ mmu_idx);
+ } else {
+ ret = mmubooke_get_physical_address(env, &ctx, eaddr, access_type);
+ }
+ if (ret == 0) {
+ *raddrp = ctx.raddr;
+ *protp = ctx.prot;
+ *psizep = TARGET_PAGE_BITS;
+ return true;
+ } else if (!guest_visible) {
+ return false;
+ }
+
+ log_cpu_state_mask(CPU_LOG_MMU, cs, 0);
+ if (access_type == MMU_INST_FETCH) {
+ switch (ret) {
+ case -1:
+ /* No matches in page tables or TLB */
+ switch (env->mmu_model) {
+ case POWERPC_MMU_BOOKE206:
+ booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
+ /* fall through */
+ case POWERPC_MMU_BOOKE:
+ cs->exception_index = POWERPC_EXCP_ITLB;
+ env->error_code = 0;
+ env->spr[SPR_BOOKE_DEAR] = eaddr;
+ env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ break;
+ case -2:
+ /* Access rights violation */
+ cs->exception_index = POWERPC_EXCP_ISI;
+ env->error_code = 0;
+ break;
+ case -3:
+ /* No execute protection violation */
+ cs->exception_index = POWERPC_EXCP_ISI;
+ env->spr[SPR_BOOKE_ESR] = 0;
+ env->error_code = 0;
+ break;
+ }
+ } else {
+ switch (ret) {
+ case -1:
+ /* No matches in page tables or TLB */
+ switch (env->mmu_model) {
+ case POWERPC_MMU_BOOKE206:
+ booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
+ /* fall through */
+ case POWERPC_MMU_BOOKE:
+ cs->exception_index = POWERPC_EXCP_DTLB;
+ env->error_code = 0;
+ env->spr[SPR_BOOKE_DEAR] = eaddr;
+ env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ break;
+ case -2:
+ /* Access rights violation */
+ cs->exception_index = POWERPC_EXCP_DSI;
+ env->error_code = 0;
+ env->spr[SPR_BOOKE_DEAR] = eaddr;
+ env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
+ break;
+ }
+ }
+ return false;
+}
+
/* Perform address translation */
/* TODO: Split this by mmu_model. */
static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
@@ -1246,15 +1332,6 @@ static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
env->spr[SPR_40x_DEAR] = eaddr;
env->spr[SPR_40x_ESR] = 0x00000000;
break;
- case POWERPC_MMU_BOOKE206:
- booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
- /* fall through */
- case POWERPC_MMU_BOOKE:
- cs->exception_index = POWERPC_EXCP_ITLB;
- env->error_code = 0;
- env->spr[SPR_BOOKE_DEAR] = eaddr;
- env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
- break;
case POWERPC_MMU_REAL:
cpu_abort(cs, "PowerPC in real mode should never raise "
"any MMU exceptions\n");
@@ -1265,23 +1342,12 @@ static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
case -2:
/* Access rights violation */
cs->exception_index = POWERPC_EXCP_ISI;
- if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
- (env->mmu_model == POWERPC_MMU_BOOKE206)) {
- env->error_code = 0;
- } else {
- env->error_code = 0x08000000;
- }
+ env->error_code = 0x08000000;
break;
case -3:
/* No execute protection violation */
- if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
- (env->mmu_model == POWERPC_MMU_BOOKE206)) {
- env->spr[SPR_BOOKE_ESR] = 0x00000000;
- env->error_code = 0;
- } else {
- env->error_code = 0x10000000;
- }
cs->exception_index = POWERPC_EXCP_ISI;
+ env->error_code = 0x10000000;
break;
case -4:
/* Direct store exception */
@@ -1322,15 +1388,6 @@ static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
env->spr[SPR_40x_ESR] = 0x00000000;
}
break;
- case POWERPC_MMU_BOOKE206:
- booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
- /* fall through */
- case POWERPC_MMU_BOOKE:
- cs->exception_index = POWERPC_EXCP_DTLB;
- env->error_code = 0;
- env->spr[SPR_BOOKE_DEAR] = eaddr;
- env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
- break;
case POWERPC_MMU_REAL:
cpu_abort(cs, "PowerPC in real mode should never raise "
"any MMU exceptions\n");
@@ -1347,10 +1404,6 @@ static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
if (access_type == MMU_DATA_STORE) {
env->spr[SPR_40x_ESR] |= 0x00800000;
}
- } else if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
- (env->mmu_model == POWERPC_MMU_BOOKE206)) {
- env->spr[SPR_BOOKE_DEAR] = eaddr;
- env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
} else {
env->spr[SPR_DAR] = eaddr;
if (access_type == MMU_DATA_STORE) {
@@ -1429,7 +1482,10 @@ bool ppc_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
case POWERPC_MMU_32B:
return ppc_hash32_xlate(cpu, eaddr, access_type, raddrp,
psizep, protp, mmu_idx, guest_visible);
-
+ case POWERPC_MMU_BOOKE:
+ case POWERPC_MMU_BOOKE206:
+ return ppc_booke_xlate(cpu, eaddr, access_type, raddrp,
+ psizep, protp, mmu_idx, guest_visible);
default:
return ppc_jumbo_xlate(cpu, eaddr, access_type, raddrp,
psizep, protp, mmu_idx, guest_visible);
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* Re: [PATCH v3 24/33] target/ppc/mmu_common.c: Split off BookE handling from ppc_jumbo_xlate()
2024-05-08 0:15 ` [PATCH v3 24/33] target/ppc/mmu_common.c: Split off BookE handling from ppc_jumbo_xlate() BALATON Zoltan
@ 2024-05-08 13:01 ` Nicholas Piggin
0 siblings, 0 replies; 58+ messages in thread
From: Nicholas Piggin @ 2024-05-08 13:01 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel, qemu-ppc; +Cc: Daniel Henrique Barboza
On Wed May 8, 2024 at 10:15 AM AEST, BALATON Zoltan wrote:
> Introduce ppc_booke_xlate() to handle BookE and BookE 2.06 cases to
> reduce ppc_jumbo_xlate() further.
>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> ---
> target/ppc/mmu_common.c | 128 +++++++++++++++++++++++++++++-----------
> 1 file changed, 92 insertions(+), 36 deletions(-)
>
> diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
> index 03b834eb77..83dc041a77 100644
> --- a/target/ppc/mmu_common.c
> +++ b/target/ppc/mmu_common.c
> @@ -1194,6 +1194,92 @@ static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address,
> env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT;
> }
>
> +static bool ppc_booke_xlate(PowerPCCPU *cpu, vaddr eaddr,
> + MMUAccessType access_type,
> + hwaddr *raddrp, int *psizep, int *protp,
> + int mmu_idx, bool guest_visible)
> +{
> + CPUState *cs = CPU(cpu);
> + CPUPPCState *env = &cpu->env;
> + mmu_ctx_t ctx;
> + int ret;
> +
> + if (env->mmu_model == POWERPC_MMU_BOOKE206) {
> + ret = mmubooke206_get_physical_address(env, &ctx, eaddr, access_type,
> + mmu_idx);
> + } else {
> + ret = mmubooke_get_physical_address(env, &ctx, eaddr, access_type);
> + }
> + if (ret == 0) {
> + *raddrp = ctx.raddr;
> + *protp = ctx.prot;
> + *psizep = TARGET_PAGE_BITS;
> + return true;
> + } else if (!guest_visible) {
> + return false;
> + }
> +
> + log_cpu_state_mask(CPU_LOG_MMU, cs, 0);
> + if (access_type == MMU_INST_FETCH) {
> + switch (ret) {
> + case -1:
> + /* No matches in page tables or TLB */
> + switch (env->mmu_model) {
> + case POWERPC_MMU_BOOKE206:
> + booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
> + /* fall through */
> + case POWERPC_MMU_BOOKE:
> + cs->exception_index = POWERPC_EXCP_ITLB;
> + env->error_code = 0;
> + env->spr[SPR_BOOKE_DEAR] = eaddr;
> + env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
> + break;
> + default:
> + g_assert_not_reached();
> + }
> + break;
> + case -2:
> + /* Access rights violation */
> + cs->exception_index = POWERPC_EXCP_ISI;
> + env->error_code = 0;
> + break;
> + case -3:
> + /* No execute protection violation */
> + cs->exception_index = POWERPC_EXCP_ISI;
> + env->spr[SPR_BOOKE_ESR] = 0;
> + env->error_code = 0;
> + break;
> + }
> + } else {
> + switch (ret) {
> + case -1:
> + /* No matches in page tables or TLB */
> + switch (env->mmu_model) {
> + case POWERPC_MMU_BOOKE206:
> + booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
> + /* fall through */
> + case POWERPC_MMU_BOOKE:
> + cs->exception_index = POWERPC_EXCP_DTLB;
> + env->error_code = 0;
> + env->spr[SPR_BOOKE_DEAR] = eaddr;
> + env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
> + break;
> + default:
> + g_assert_not_reached();
> + }
> + break;
> + case -2:
> + /* Access rights violation */
> + cs->exception_index = POWERPC_EXCP_DSI;
> + env->error_code = 0;
> + env->spr[SPR_BOOKE_DEAR] = eaddr;
> + env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
> + break;
> + }
> + }
> + return false;
> +}
> +
> /* Perform address translation */
> /* TODO: Split this by mmu_model. */
> static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
> @@ -1246,15 +1332,6 @@ static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
> env->spr[SPR_40x_DEAR] = eaddr;
> env->spr[SPR_40x_ESR] = 0x00000000;
> break;
> - case POWERPC_MMU_BOOKE206:
> - booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
> - /* fall through */
> - case POWERPC_MMU_BOOKE:
> - cs->exception_index = POWERPC_EXCP_ITLB;
> - env->error_code = 0;
> - env->spr[SPR_BOOKE_DEAR] = eaddr;
> - env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
> - break;
> case POWERPC_MMU_REAL:
> cpu_abort(cs, "PowerPC in real mode should never raise "
> "any MMU exceptions\n");
> @@ -1265,23 +1342,12 @@ static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
> case -2:
> /* Access rights violation */
> cs->exception_index = POWERPC_EXCP_ISI;
> - if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
> - (env->mmu_model == POWERPC_MMU_BOOKE206)) {
> - env->error_code = 0;
> - } else {
> - env->error_code = 0x08000000;
> - }
> + env->error_code = 0x08000000;
> break;
> case -3:
> /* No execute protection violation */
> - if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
> - (env->mmu_model == POWERPC_MMU_BOOKE206)) {
> - env->spr[SPR_BOOKE_ESR] = 0x00000000;
> - env->error_code = 0;
> - } else {
> - env->error_code = 0x10000000;
> - }
> cs->exception_index = POWERPC_EXCP_ISI;
> + env->error_code = 0x10000000;
> break;
> case -4:
> /* Direct store exception */
> @@ -1322,15 +1388,6 @@ static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
> env->spr[SPR_40x_ESR] = 0x00000000;
> }
> break;
> - case POWERPC_MMU_BOOKE206:
> - booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
> - /* fall through */
> - case POWERPC_MMU_BOOKE:
> - cs->exception_index = POWERPC_EXCP_DTLB;
> - env->error_code = 0;
> - env->spr[SPR_BOOKE_DEAR] = eaddr;
> - env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
> - break;
> case POWERPC_MMU_REAL:
> cpu_abort(cs, "PowerPC in real mode should never raise "
> "any MMU exceptions\n");
> @@ -1347,10 +1404,6 @@ static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
> if (access_type == MMU_DATA_STORE) {
> env->spr[SPR_40x_ESR] |= 0x00800000;
> }
> - } else if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
> - (env->mmu_model == POWERPC_MMU_BOOKE206)) {
> - env->spr[SPR_BOOKE_DEAR] = eaddr;
> - env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
> } else {
> env->spr[SPR_DAR] = eaddr;
> if (access_type == MMU_DATA_STORE) {
> @@ -1429,7 +1482,10 @@ bool ppc_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
> case POWERPC_MMU_32B:
> return ppc_hash32_xlate(cpu, eaddr, access_type, raddrp,
> psizep, protp, mmu_idx, guest_visible);
> -
> + case POWERPC_MMU_BOOKE:
> + case POWERPC_MMU_BOOKE206:
> + return ppc_booke_xlate(cpu, eaddr, access_type, raddrp,
> + psizep, protp, mmu_idx, guest_visible);
> default:
> return ppc_jumbo_xlate(cpu, eaddr, access_type, raddrp,
> psizep, protp, mmu_idx, guest_visible);
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 25/33] target/ppc/mmu_common.c: Remove BookE handling from get_physical_address_wtlb()
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (23 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 24/33] target/ppc/mmu_common.c: Split off BookE handling from ppc_jumbo_xlate() BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 13:12 ` Nicholas Piggin
2024-05-08 0:15 ` [PATCH v3 26/33] target/ppc/mmu_common.c: Simplify ppc_booke_xlate() part 1 BALATON Zoltan
` (7 subsequent siblings)
32 siblings, 1 reply; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
This function is no longer called for BookE MMU model so remove parts
related to it. This has uncovered a few may be used uninitialised
warnings that are also fixed.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
target/ppc/mmu_common.c | 25 +++++--------------------
1 file changed, 5 insertions(+), 20 deletions(-)
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index 83dc041a77..788e2bebd5 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -629,12 +629,10 @@ static int mmubooke_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
ret = mmubooke_check_tlb(env, tlb, &raddr, &ctx->prot, address,
access_type, i);
if (ret != -1) {
- if (ret >= 0) {
- ctx->raddr = raddr;
- }
break;
}
}
+ ctx->raddr = raddr;
qemu_log_mask(CPU_LOG_MMU,
"%s: access %s " TARGET_FMT_lx " => " HWADDR_FMT_plx
" %d %d\n", __func__, ret < 0 ? "refused" : "granted",
@@ -841,9 +839,6 @@ static int mmubooke206_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
ret = mmubooke206_check_tlb(env, tlb, &raddr, &ctx->prot, address,
access_type, mmu_idx);
if (ret != -1) {
- if (ret >= 0) {
- ctx->raddr = raddr;
- }
goto found_tlb;
}
}
@@ -851,6 +846,7 @@ static int mmubooke206_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
found_tlb:
+ ctx->raddr = raddr;
qemu_log_mask(CPU_LOG_MMU, "%s: access %s " TARGET_FMT_lx " => "
HWADDR_FMT_plx " %d %d\n", __func__,
ret < 0 ? "refused" : "granted", address, raddr,
@@ -1107,20 +1103,9 @@ static int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
MMUAccessType access_type, int type,
int mmu_idx)
{
- bool real_mode;
-
- if (env->mmu_model == POWERPC_MMU_BOOKE) {
- return mmubooke_get_physical_address(env, ctx, eaddr, access_type);
- } else if (env->mmu_model == POWERPC_MMU_BOOKE206) {
- return mmubooke206_get_physical_address(env, ctx, eaddr, access_type,
- mmu_idx);
- }
-
- real_mode = (type == ACCESS_CODE) ? !FIELD_EX64(env->msr, MSR, IR)
- : !FIELD_EX64(env->msr, MSR, DR);
- if (real_mode && (env->mmu_model == POWERPC_MMU_SOFT_6xx ||
- env->mmu_model == POWERPC_MMU_SOFT_4xx ||
- env->mmu_model == POWERPC_MMU_REAL)) {
+ bool real_mode = (type == ACCESS_CODE) ? !FIELD_EX64(env->msr, MSR, IR)
+ : !FIELD_EX64(env->msr, MSR, DR);
+ if (real_mode) {
memset(ctx, 0, sizeof(*ctx));
ctx->raddr = eaddr;
ctx->prot = PAGE_RWX;
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* Re: [PATCH v3 25/33] target/ppc/mmu_common.c: Remove BookE handling from get_physical_address_wtlb()
2024-05-08 0:15 ` [PATCH v3 25/33] target/ppc/mmu_common.c: Remove BookE handling from get_physical_address_wtlb() BALATON Zoltan
@ 2024-05-08 13:12 ` Nicholas Piggin
0 siblings, 0 replies; 58+ messages in thread
From: Nicholas Piggin @ 2024-05-08 13:12 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel, qemu-ppc; +Cc: Daniel Henrique Barboza
On Wed May 8, 2024 at 10:15 AM AEST, BALATON Zoltan wrote:
> This function is no longer called for BookE MMU model so remove parts
> related to it. This has uncovered a few may be used uninitialised
> warnings that are also fixed.
>
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> ---
> target/ppc/mmu_common.c | 25 +++++--------------------
> 1 file changed, 5 insertions(+), 20 deletions(-)
>
> diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
> index 83dc041a77..788e2bebd5 100644
> --- a/target/ppc/mmu_common.c
> +++ b/target/ppc/mmu_common.c
> @@ -629,12 +629,10 @@ static int mmubooke_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
> ret = mmubooke_check_tlb(env, tlb, &raddr, &ctx->prot, address,
> access_type, i);
> if (ret != -1) {
> - if (ret >= 0) {
> - ctx->raddr = raddr;
> - }
> break;
> }
> }
> + ctx->raddr = raddr;
Not sure if this is quite the right thing to do or if it's just masking
used uninits.
> qemu_log_mask(CPU_LOG_MMU,
> "%s: access %s " TARGET_FMT_lx " => " HWADDR_FMT_plx
> " %d %d\n", __func__, ret < 0 ? "refused" : "granted",
> @@ -841,9 +839,6 @@ static int mmubooke206_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
> ret = mmubooke206_check_tlb(env, tlb, &raddr, &ctx->prot, address,
> access_type, mmu_idx);
> if (ret != -1) {
> - if (ret >= 0) {
> - ctx->raddr = raddr;
> - }
> goto found_tlb;
> }
> }
> @@ -851,6 +846,7 @@ static int mmubooke206_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
>
> found_tlb:
>
> + ctx->raddr = raddr;
> qemu_log_mask(CPU_LOG_MMU, "%s: access %s " TARGET_FMT_lx " => "
> HWADDR_FMT_plx " %d %d\n", __func__,
> ret < 0 ? "refused" : "granted", address, raddr,
> @@ -1107,20 +1103,9 @@ static int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
> MMUAccessType access_type, int type,
> int mmu_idx)
> {
> - bool real_mode;
> -
> - if (env->mmu_model == POWERPC_MMU_BOOKE) {
> - return mmubooke_get_physical_address(env, ctx, eaddr, access_type);
> - } else if (env->mmu_model == POWERPC_MMU_BOOKE206) {
> - return mmubooke206_get_physical_address(env, ctx, eaddr, access_type,
> - mmu_idx);
> - }
Also still don't like how this gets removed here rather than when it's
stopped being called. I know it's a tangle but it would be better to
try squash the would-be warnings first, then put this in the same as
the previous patch.
Add /* quiet used uninit */ warnings if they can't be fixed properly.
Thanks,
Nick
> -
> - real_mode = (type == ACCESS_CODE) ? !FIELD_EX64(env->msr, MSR, IR)
> - : !FIELD_EX64(env->msr, MSR, DR);
> - if (real_mode && (env->mmu_model == POWERPC_MMU_SOFT_6xx ||
> - env->mmu_model == POWERPC_MMU_SOFT_4xx ||
> - env->mmu_model == POWERPC_MMU_REAL)) {
> + bool real_mode = (type == ACCESS_CODE) ? !FIELD_EX64(env->msr, MSR, IR)
> + : !FIELD_EX64(env->msr, MSR, DR);
> + if (real_mode) {
> memset(ctx, 0, sizeof(*ctx));
> ctx->raddr = eaddr;
> ctx->prot = PAGE_RWX;
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 26/33] target/ppc/mmu_common.c: Simplify ppc_booke_xlate() part 1
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (24 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 25/33] target/ppc/mmu_common.c: Remove BookE handling from get_physical_address_wtlb() BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 13:17 ` Nicholas Piggin
2024-05-08 0:15 ` [PATCH v3 27/33] target/ppc/mmu_common.c: Simplify ppc_booke_xlate() part 2 BALATON Zoltan
` (6 subsequent siblings)
32 siblings, 1 reply; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
Move setting error_code that appears in every case out in front and
hoist the common fall through case for BOOKE206 as well which allows
removing the nested switches.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
target/ppc/mmu_common.c | 41 ++++++++++++-----------------------------
1 file changed, 12 insertions(+), 29 deletions(-)
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index 788e2bebd5..c725a7932f 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -1205,58 +1205,41 @@ static bool ppc_booke_xlate(PowerPCCPU *cpu, vaddr eaddr,
}
log_cpu_state_mask(CPU_LOG_MMU, cs, 0);
+ env->error_code = 0;
+ if (ret == -1) {
+ if (env->mmu_model == POWERPC_MMU_BOOKE206) {
+ booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
+ }
+ }
if (access_type == MMU_INST_FETCH) {
switch (ret) {
case -1:
/* No matches in page tables or TLB */
- switch (env->mmu_model) {
- case POWERPC_MMU_BOOKE206:
- booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
- /* fall through */
- case POWERPC_MMU_BOOKE:
- cs->exception_index = POWERPC_EXCP_ITLB;
- env->error_code = 0;
- env->spr[SPR_BOOKE_DEAR] = eaddr;
- env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
- break;
- default:
- g_assert_not_reached();
- }
+ cs->exception_index = POWERPC_EXCP_ITLB;
+ env->spr[SPR_BOOKE_DEAR] = eaddr;
+ env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
break;
case -2:
/* Access rights violation */
cs->exception_index = POWERPC_EXCP_ISI;
- env->error_code = 0;
break;
case -3:
/* No execute protection violation */
cs->exception_index = POWERPC_EXCP_ISI;
env->spr[SPR_BOOKE_ESR] = 0;
- env->error_code = 0;
break;
}
} else {
switch (ret) {
case -1:
/* No matches in page tables or TLB */
- switch (env->mmu_model) {
- case POWERPC_MMU_BOOKE206:
- booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
- /* fall through */
- case POWERPC_MMU_BOOKE:
- cs->exception_index = POWERPC_EXCP_DTLB;
- env->error_code = 0;
- env->spr[SPR_BOOKE_DEAR] = eaddr;
- env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
- break;
- default:
- g_assert_not_reached();
- }
+ cs->exception_index = POWERPC_EXCP_DTLB;
+ env->spr[SPR_BOOKE_DEAR] = eaddr;
+ env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
break;
case -2:
/* Access rights violation */
cs->exception_index = POWERPC_EXCP_DSI;
- env->error_code = 0;
env->spr[SPR_BOOKE_DEAR] = eaddr;
env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
break;
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* Re: [PATCH v3 26/33] target/ppc/mmu_common.c: Simplify ppc_booke_xlate() part 1
2024-05-08 0:15 ` [PATCH v3 26/33] target/ppc/mmu_common.c: Simplify ppc_booke_xlate() part 1 BALATON Zoltan
@ 2024-05-08 13:17 ` Nicholas Piggin
2024-05-08 15:25 ` BALATON Zoltan
0 siblings, 1 reply; 58+ messages in thread
From: Nicholas Piggin @ 2024-05-08 13:17 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel, qemu-ppc; +Cc: Daniel Henrique Barboza
On Wed May 8, 2024 at 10:15 AM AEST, BALATON Zoltan wrote:
> Move setting error_code that appears in every case out in front and
> hoist the common fall through case for BOOKE206 as well which allows
> removing the nested switches.
>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> ---
> target/ppc/mmu_common.c | 41 ++++++++++++-----------------------------
> 1 file changed, 12 insertions(+), 29 deletions(-)
>
> diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
> index 788e2bebd5..c725a7932f 100644
> --- a/target/ppc/mmu_common.c
> +++ b/target/ppc/mmu_common.c
> @@ -1205,58 +1205,41 @@ static bool ppc_booke_xlate(PowerPCCPU *cpu, vaddr eaddr,
> }
>
> log_cpu_state_mask(CPU_LOG_MMU, cs, 0);
> + env->error_code = 0;
> + if (ret == -1) {
> + if (env->mmu_model == POWERPC_MMU_BOOKE206) {
> + booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
> + }
> + }
> if (access_type == MMU_INST_FETCH) {
> switch (ret) {
> case -1:
> /* No matches in page tables or TLB */
> - switch (env->mmu_model) {
> - case POWERPC_MMU_BOOKE206:
> - booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
> - /* fall through */
> - case POWERPC_MMU_BOOKE:
> - cs->exception_index = POWERPC_EXCP_ITLB;
> - env->error_code = 0;
> - env->spr[SPR_BOOKE_DEAR] = eaddr;
> - env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
> - break;
> - default:
> - g_assert_not_reached();
> - }
> + cs->exception_index = POWERPC_EXCP_ITLB;
> + env->spr[SPR_BOOKE_DEAR] = eaddr;
> + env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
> break;
> case -2:
> /* Access rights violation */
> cs->exception_index = POWERPC_EXCP_ISI;
> - env->error_code = 0;
> break;
> case -3:
> /* No execute protection violation */
> cs->exception_index = POWERPC_EXCP_ISI;
> env->spr[SPR_BOOKE_ESR] = 0;
I don't know BookE well but AFAIKS it says ESR if not set explicitly
is generally cleared to 0 by interrupts which I guess is the case here.
I don't see why the same would not apply to the -2 case either. That
would reduce special cases.
Although that's a behaviour change. It's possible current beahviour is
deliberate or matches some particular CPU. Not something for this
series.
Thanks,
Nick
> - env->error_code = 0;
> break;
> }
> } else {
> switch (ret) {
> case -1:
> /* No matches in page tables or TLB */
> - switch (env->mmu_model) {
> - case POWERPC_MMU_BOOKE206:
> - booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
> - /* fall through */
> - case POWERPC_MMU_BOOKE:
> - cs->exception_index = POWERPC_EXCP_DTLB;
> - env->error_code = 0;
> - env->spr[SPR_BOOKE_DEAR] = eaddr;
> - env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
> - break;
> - default:
> - g_assert_not_reached();
> - }
> + cs->exception_index = POWERPC_EXCP_DTLB;
> + env->spr[SPR_BOOKE_DEAR] = eaddr;
> + env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
> break;
> case -2:
> /* Access rights violation */
> cs->exception_index = POWERPC_EXCP_DSI;
> - env->error_code = 0;
> env->spr[SPR_BOOKE_DEAR] = eaddr;
> env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
> break;
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH v3 26/33] target/ppc/mmu_common.c: Simplify ppc_booke_xlate() part 1
2024-05-08 13:17 ` Nicholas Piggin
@ 2024-05-08 15:25 ` BALATON Zoltan
2024-05-09 5:53 ` Nicholas Piggin
0 siblings, 1 reply; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 15:25 UTC (permalink / raw)
To: Nicholas Piggin; +Cc: qemu-devel, qemu-ppc, Daniel Henrique Barboza
On Wed, 8 May 2024, Nicholas Piggin wrote:
> On Wed May 8, 2024 at 10:15 AM AEST, BALATON Zoltan wrote:
>> Move setting error_code that appears in every case out in front and
>> hoist the common fall through case for BOOKE206 as well which allows
>> removing the nested switches.
>>
>
> Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
>
>> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
>> ---
>> target/ppc/mmu_common.c | 41 ++++++++++++-----------------------------
>> 1 file changed, 12 insertions(+), 29 deletions(-)
>>
>> diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
>> index 788e2bebd5..c725a7932f 100644
>> --- a/target/ppc/mmu_common.c
>> +++ b/target/ppc/mmu_common.c
>> @@ -1205,58 +1205,41 @@ static bool ppc_booke_xlate(PowerPCCPU *cpu, vaddr eaddr,
>> }
>>
>> log_cpu_state_mask(CPU_LOG_MMU, cs, 0);
>> + env->error_code = 0;
>> + if (ret == -1) {
>> + if (env->mmu_model == POWERPC_MMU_BOOKE206) {
>> + booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
>> + }
>> + }
>> if (access_type == MMU_INST_FETCH) {
>> switch (ret) {
>> case -1:
>> /* No matches in page tables or TLB */
>> - switch (env->mmu_model) {
>> - case POWERPC_MMU_BOOKE206:
>> - booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
>> - /* fall through */
>> - case POWERPC_MMU_BOOKE:
>> - cs->exception_index = POWERPC_EXCP_ITLB;
>> - env->error_code = 0;
>> - env->spr[SPR_BOOKE_DEAR] = eaddr;
>> - env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
>> - break;
>> - default:
>> - g_assert_not_reached();
>> - }
>> + cs->exception_index = POWERPC_EXCP_ITLB;
>> + env->spr[SPR_BOOKE_DEAR] = eaddr;
>> + env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
>> break;
>> case -2:
>> /* Access rights violation */
>> cs->exception_index = POWERPC_EXCP_ISI;
>> - env->error_code = 0;
>> break;
>> case -3:
>> /* No execute protection violation */
>> cs->exception_index = POWERPC_EXCP_ISI;
>> env->spr[SPR_BOOKE_ESR] = 0;
>
> I don't know BookE well but AFAIKS it says ESR if not set explicitly
> is generally cleared to 0 by interrupts which I guess is the case here.
> I don't see why the same would not apply to the -2 case either. That
> would reduce special cases.
>
> Although that's a behaviour change. It's possible current beahviour is
> deliberate or matches some particular CPU. Not something for this
> series.
I don't know what the correct behaviour should be so I just tried to keep
what was there. After this clean it should be simpler to find out and
correct this later.
Regards,
BALATON Zoltan
> Thanks,
> Nick
>
>> - env->error_code = 0;
>> break;
>> }
>> } else {
>> switch (ret) {
>> case -1:
>> /* No matches in page tables or TLB */
>> - switch (env->mmu_model) {
>> - case POWERPC_MMU_BOOKE206:
>> - booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
>> - /* fall through */
>> - case POWERPC_MMU_BOOKE:
>> - cs->exception_index = POWERPC_EXCP_DTLB;
>> - env->error_code = 0;
>> - env->spr[SPR_BOOKE_DEAR] = eaddr;
>> - env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
>> - break;
>> - default:
>> - g_assert_not_reached();
>> - }
>> + cs->exception_index = POWERPC_EXCP_DTLB;
>> + env->spr[SPR_BOOKE_DEAR] = eaddr;
>> + env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
>> break;
>> case -2:
>> /* Access rights violation */
>> cs->exception_index = POWERPC_EXCP_DSI;
>> - env->error_code = 0;
>> env->spr[SPR_BOOKE_DEAR] = eaddr;
>> env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
>> break;
>
>
>
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH v3 26/33] target/ppc/mmu_common.c: Simplify ppc_booke_xlate() part 1
2024-05-08 15:25 ` BALATON Zoltan
@ 2024-05-09 5:53 ` Nicholas Piggin
0 siblings, 0 replies; 58+ messages in thread
From: Nicholas Piggin @ 2024-05-09 5:53 UTC (permalink / raw)
To: BALATON Zoltan; +Cc: qemu-devel, qemu-ppc, Daniel Henrique Barboza
On Thu May 9, 2024 at 1:25 AM AEST, BALATON Zoltan wrote:
> On Wed, 8 May 2024, Nicholas Piggin wrote:
> > On Wed May 8, 2024 at 10:15 AM AEST, BALATON Zoltan wrote:
> >> Move setting error_code that appears in every case out in front and
> >> hoist the common fall through case for BOOKE206 as well which allows
> >> removing the nested switches.
> >>
> >
> > Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
> >
> >> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> >> ---
> >> target/ppc/mmu_common.c | 41 ++++++++++++-----------------------------
> >> 1 file changed, 12 insertions(+), 29 deletions(-)
> >>
> >> diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
> >> index 788e2bebd5..c725a7932f 100644
> >> --- a/target/ppc/mmu_common.c
> >> +++ b/target/ppc/mmu_common.c
> >> @@ -1205,58 +1205,41 @@ static bool ppc_booke_xlate(PowerPCCPU *cpu, vaddr eaddr,
> >> }
> >>
> >> log_cpu_state_mask(CPU_LOG_MMU, cs, 0);
> >> + env->error_code = 0;
> >> + if (ret == -1) {
> >> + if (env->mmu_model == POWERPC_MMU_BOOKE206) {
> >> + booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
> >> + }
> >> + }
> >> if (access_type == MMU_INST_FETCH) {
> >> switch (ret) {
> >> case -1:
> >> /* No matches in page tables or TLB */
> >> - switch (env->mmu_model) {
> >> - case POWERPC_MMU_BOOKE206:
> >> - booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
> >> - /* fall through */
> >> - case POWERPC_MMU_BOOKE:
> >> - cs->exception_index = POWERPC_EXCP_ITLB;
> >> - env->error_code = 0;
> >> - env->spr[SPR_BOOKE_DEAR] = eaddr;
> >> - env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
> >> - break;
> >> - default:
> >> - g_assert_not_reached();
> >> - }
> >> + cs->exception_index = POWERPC_EXCP_ITLB;
> >> + env->spr[SPR_BOOKE_DEAR] = eaddr;
> >> + env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
> >> break;
> >> case -2:
> >> /* Access rights violation */
> >> cs->exception_index = POWERPC_EXCP_ISI;
> >> - env->error_code = 0;
> >> break;
> >> case -3:
> >> /* No execute protection violation */
> >> cs->exception_index = POWERPC_EXCP_ISI;
> >> env->spr[SPR_BOOKE_ESR] = 0;
> >
> > I don't know BookE well but AFAIKS it says ESR if not set explicitly
> > is generally cleared to 0 by interrupts which I guess is the case here.
> > I don't see why the same would not apply to the -2 case either. That
> > would reduce special cases.
> >
> > Although that's a behaviour change. It's possible current beahviour is
> > deliberate or matches some particular CPU. Not something for this
> > series.
>
> I don't know what the correct behaviour should be so I just tried to keep
> what was there. After this clean it should be simpler to find out and
> correct this later.
Right. Keeping exact behaviour is the right thing to do for such a
series, so it's good you have been doing it. It was just an offhand
comment because the special case annoyed me :)
Thanks,
Nick
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 27/33] target/ppc/mmu_common.c: Simplify ppc_booke_xlate() part 2
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (25 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 26/33] target/ppc/mmu_common.c: Simplify ppc_booke_xlate() part 1 BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 13:21 ` Nicholas Piggin
2024-05-08 0:15 ` [PATCH v3 28/33] target/ppc/mmu_common.c: Move BookE MMU functions together BALATON Zoltan
` (5 subsequent siblings)
32 siblings, 1 reply; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
Merge the code fetch and data access cases in a common switch.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
target/ppc/mmu_common.c | 50 +++++++++++++++++------------------------
1 file changed, 20 insertions(+), 30 deletions(-)
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index c725a7932f..04e5ad661d 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -1206,45 +1206,35 @@ static bool ppc_booke_xlate(PowerPCCPU *cpu, vaddr eaddr,
log_cpu_state_mask(CPU_LOG_MMU, cs, 0);
env->error_code = 0;
- if (ret == -1) {
+ switch (ret) {
+ case -1:
+ /* No matches in page tables or TLB */
if (env->mmu_model == POWERPC_MMU_BOOKE206) {
booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
}
- }
- if (access_type == MMU_INST_FETCH) {
- switch (ret) {
- case -1:
- /* No matches in page tables or TLB */
- cs->exception_index = POWERPC_EXCP_ITLB;
+ cs->exception_index = (access_type == MMU_INST_FETCH) ?
+ POWERPC_EXCP_ITLB : POWERPC_EXCP_DTLB;
+ env->spr[SPR_BOOKE_DEAR] = eaddr;
+ env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
+ break;
+ case -2:
+ /* Access rights violation */
+ cs->exception_index = (access_type == MMU_INST_FETCH) ?
+ POWERPC_EXCP_ISI : POWERPC_EXCP_DSI;
+ if (access_type != MMU_INST_FETCH) {
env->spr[SPR_BOOKE_DEAR] = eaddr;
env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
- break;
- case -2:
- /* Access rights violation */
- cs->exception_index = POWERPC_EXCP_ISI;
- break;
- case -3:
- /* No execute protection violation */
+ }
+ break;
+ case -3:
+ /* No execute protection violation */
+ if (access_type == MMU_INST_FETCH) {
cs->exception_index = POWERPC_EXCP_ISI;
env->spr[SPR_BOOKE_ESR] = 0;
- break;
- }
- } else {
- switch (ret) {
- case -1:
- /* No matches in page tables or TLB */
- cs->exception_index = POWERPC_EXCP_DTLB;
- env->spr[SPR_BOOKE_DEAR] = eaddr;
- env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
- break;
- case -2:
- /* Access rights violation */
- cs->exception_index = POWERPC_EXCP_DSI;
- env->spr[SPR_BOOKE_DEAR] = eaddr;
- env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
- break;
}
+ break;
}
+
return false;
}
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* Re: [PATCH v3 27/33] target/ppc/mmu_common.c: Simplify ppc_booke_xlate() part 2
2024-05-08 0:15 ` [PATCH v3 27/33] target/ppc/mmu_common.c: Simplify ppc_booke_xlate() part 2 BALATON Zoltan
@ 2024-05-08 13:21 ` Nicholas Piggin
0 siblings, 0 replies; 58+ messages in thread
From: Nicholas Piggin @ 2024-05-08 13:21 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel, qemu-ppc; +Cc: Daniel Henrique Barboza
On Wed May 8, 2024 at 10:15 AM AEST, BALATON Zoltan wrote:
> Merge the code fetch and data access cases in a common switch.
>
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> ---
> target/ppc/mmu_common.c | 50 +++++++++++++++++------------------------
> 1 file changed, 20 insertions(+), 30 deletions(-)
>
> diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
> index c725a7932f..04e5ad661d 100644
> --- a/target/ppc/mmu_common.c
> +++ b/target/ppc/mmu_common.c
> @@ -1206,45 +1206,35 @@ static bool ppc_booke_xlate(PowerPCCPU *cpu, vaddr eaddr,
>
> log_cpu_state_mask(CPU_LOG_MMU, cs, 0);
> env->error_code = 0;
> - if (ret == -1) {
> + switch (ret) {
> + case -1:
> + /* No matches in page tables or TLB */
> if (env->mmu_model == POWERPC_MMU_BOOKE206) {
> booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
> }
> - }
> - if (access_type == MMU_INST_FETCH) {
> - switch (ret) {
> - case -1:
> - /* No matches in page tables or TLB */
> - cs->exception_index = POWERPC_EXCP_ITLB;
> + cs->exception_index = (access_type == MMU_INST_FETCH) ?
> + POWERPC_EXCP_ITLB : POWERPC_EXCP_DTLB;
> + env->spr[SPR_BOOKE_DEAR] = eaddr;
> + env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
> + break;
> + case -2:
> + /* Access rights violation */
> + cs->exception_index = (access_type == MMU_INST_FETCH) ?
> + POWERPC_EXCP_ISI : POWERPC_EXCP_DSI;
> + if (access_type != MMU_INST_FETCH) {
> env->spr[SPR_BOOKE_DEAR] = eaddr;
> env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
> - break;
> - case -2:
> - /* Access rights violation */
> - cs->exception_index = POWERPC_EXCP_ISI;
> - break;
> - case -3:
> - /* No execute protection violation */
> + }
> + break;
> + case -3:
> + /* No execute protection violation */
> + if (access_type == MMU_INST_FETCH) {
-3 can't be a data access I think, so if is not required.
Thanks,
Nick
> cs->exception_index = POWERPC_EXCP_ISI;
> env->spr[SPR_BOOKE_ESR] = 0;
> - break;
> - }
> - } else {
> - switch (ret) {
> - case -1:
> - /* No matches in page tables or TLB */
> - cs->exception_index = POWERPC_EXCP_DTLB;
> - env->spr[SPR_BOOKE_DEAR] = eaddr;
> - env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
> - break;
> - case -2:
> - /* Access rights violation */
> - cs->exception_index = POWERPC_EXCP_DSI;
> - env->spr[SPR_BOOKE_DEAR] = eaddr;
> - env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
> - break;
> }
> + break;
> }
> +
> return false;
> }
>
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 28/33] target/ppc/mmu_common.c: Move BookE MMU functions together
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (26 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 27/33] target/ppc/mmu_common.c: Simplify ppc_booke_xlate() part 2 BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 13:21 ` Nicholas Piggin
2024-05-08 0:15 ` [PATCH v3 29/33] target/ppc: Remove id_tlbs flag from CPU env BALATON Zoltan
` (4 subsequent siblings)
32 siblings, 1 reply; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
target/ppc/mmu_common.c | 226 ++++++++++++++++++++--------------------
1 file changed, 113 insertions(+), 113 deletions(-)
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index 04e5ad661d..a6e7b64049 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -854,6 +854,119 @@ found_tlb:
return ret;
}
+static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address,
+ MMUAccessType access_type, int mmu_idx)
+{
+ uint32_t epid;
+ bool as, pr;
+ uint32_t missed_tid = 0;
+ bool use_epid = mmubooke206_get_as(env, mmu_idx, &epid, &as, &pr);
+
+ if (access_type == MMU_INST_FETCH) {
+ as = FIELD_EX64(env->msr, MSR, IR);
+ }
+ env->spr[SPR_BOOKE_MAS0] = env->spr[SPR_BOOKE_MAS4] & MAS4_TLBSELD_MASK;
+ env->spr[SPR_BOOKE_MAS1] = env->spr[SPR_BOOKE_MAS4] & MAS4_TSIZED_MASK;
+ env->spr[SPR_BOOKE_MAS2] = env->spr[SPR_BOOKE_MAS4] & MAS4_WIMGED_MASK;
+ env->spr[SPR_BOOKE_MAS3] = 0;
+ env->spr[SPR_BOOKE_MAS6] = 0;
+ env->spr[SPR_BOOKE_MAS7] = 0;
+
+ /* AS */
+ if (as) {
+ env->spr[SPR_BOOKE_MAS1] |= MAS1_TS;
+ env->spr[SPR_BOOKE_MAS6] |= MAS6_SAS;
+ }
+
+ env->spr[SPR_BOOKE_MAS1] |= MAS1_VALID;
+ env->spr[SPR_BOOKE_MAS2] |= address & MAS2_EPN_MASK;
+
+ if (!use_epid) {
+ switch (env->spr[SPR_BOOKE_MAS4] & MAS4_TIDSELD_PIDZ) {
+ case MAS4_TIDSELD_PID0:
+ missed_tid = env->spr[SPR_BOOKE_PID];
+ break;
+ case MAS4_TIDSELD_PID1:
+ missed_tid = env->spr[SPR_BOOKE_PID1];
+ break;
+ case MAS4_TIDSELD_PID2:
+ missed_tid = env->spr[SPR_BOOKE_PID2];
+ break;
+ }
+ env->spr[SPR_BOOKE_MAS6] |= env->spr[SPR_BOOKE_PID] << 16;
+ } else {
+ missed_tid = epid;
+ env->spr[SPR_BOOKE_MAS6] |= missed_tid << 16;
+ }
+ env->spr[SPR_BOOKE_MAS1] |= (missed_tid << MAS1_TID_SHIFT);
+
+
+ /* next victim logic */
+ env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_ESEL_SHIFT;
+ env->last_way++;
+ env->last_way &= booke206_tlb_ways(env, 0) - 1;
+ env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT;
+}
+
+static bool ppc_booke_xlate(PowerPCCPU *cpu, vaddr eaddr,
+ MMUAccessType access_type,
+ hwaddr *raddrp, int *psizep, int *protp,
+ int mmu_idx, bool guest_visible)
+{
+ CPUState *cs = CPU(cpu);
+ CPUPPCState *env = &cpu->env;
+ mmu_ctx_t ctx;
+ int ret;
+
+ if (env->mmu_model == POWERPC_MMU_BOOKE206) {
+ ret = mmubooke206_get_physical_address(env, &ctx, eaddr, access_type,
+ mmu_idx);
+ } else {
+ ret = mmubooke_get_physical_address(env, &ctx, eaddr, access_type);
+ }
+ if (ret == 0) {
+ *raddrp = ctx.raddr;
+ *protp = ctx.prot;
+ *psizep = TARGET_PAGE_BITS;
+ return true;
+ } else if (!guest_visible) {
+ return false;
+ }
+
+ log_cpu_state_mask(CPU_LOG_MMU, cs, 0);
+ env->error_code = 0;
+ switch (ret) {
+ case -1:
+ /* No matches in page tables or TLB */
+ if (env->mmu_model == POWERPC_MMU_BOOKE206) {
+ booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
+ }
+ cs->exception_index = (access_type == MMU_INST_FETCH) ?
+ POWERPC_EXCP_ITLB : POWERPC_EXCP_DTLB;
+ env->spr[SPR_BOOKE_DEAR] = eaddr;
+ env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
+ break;
+ case -2:
+ /* Access rights violation */
+ cs->exception_index = (access_type == MMU_INST_FETCH) ?
+ POWERPC_EXCP_ISI : POWERPC_EXCP_DSI;
+ if (access_type != MMU_INST_FETCH) {
+ env->spr[SPR_BOOKE_DEAR] = eaddr;
+ env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
+ }
+ break;
+ case -3:
+ /* No execute protection violation */
+ if (access_type == MMU_INST_FETCH) {
+ cs->exception_index = POWERPC_EXCP_ISI;
+ env->spr[SPR_BOOKE_ESR] = 0;
+ }
+ break;
+ }
+
+ return false;
+}
+
static const char *book3e_tsize_to_str[32] = {
"1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K",
"1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M",
@@ -1125,119 +1238,6 @@ static int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
}
}
-static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address,
- MMUAccessType access_type, int mmu_idx)
-{
- uint32_t epid;
- bool as, pr;
- uint32_t missed_tid = 0;
- bool use_epid = mmubooke206_get_as(env, mmu_idx, &epid, &as, &pr);
-
- if (access_type == MMU_INST_FETCH) {
- as = FIELD_EX64(env->msr, MSR, IR);
- }
- env->spr[SPR_BOOKE_MAS0] = env->spr[SPR_BOOKE_MAS4] & MAS4_TLBSELD_MASK;
- env->spr[SPR_BOOKE_MAS1] = env->spr[SPR_BOOKE_MAS4] & MAS4_TSIZED_MASK;
- env->spr[SPR_BOOKE_MAS2] = env->spr[SPR_BOOKE_MAS4] & MAS4_WIMGED_MASK;
- env->spr[SPR_BOOKE_MAS3] = 0;
- env->spr[SPR_BOOKE_MAS6] = 0;
- env->spr[SPR_BOOKE_MAS7] = 0;
-
- /* AS */
- if (as) {
- env->spr[SPR_BOOKE_MAS1] |= MAS1_TS;
- env->spr[SPR_BOOKE_MAS6] |= MAS6_SAS;
- }
-
- env->spr[SPR_BOOKE_MAS1] |= MAS1_VALID;
- env->spr[SPR_BOOKE_MAS2] |= address & MAS2_EPN_MASK;
-
- if (!use_epid) {
- switch (env->spr[SPR_BOOKE_MAS4] & MAS4_TIDSELD_PIDZ) {
- case MAS4_TIDSELD_PID0:
- missed_tid = env->spr[SPR_BOOKE_PID];
- break;
- case MAS4_TIDSELD_PID1:
- missed_tid = env->spr[SPR_BOOKE_PID1];
- break;
- case MAS4_TIDSELD_PID2:
- missed_tid = env->spr[SPR_BOOKE_PID2];
- break;
- }
- env->spr[SPR_BOOKE_MAS6] |= env->spr[SPR_BOOKE_PID] << 16;
- } else {
- missed_tid = epid;
- env->spr[SPR_BOOKE_MAS6] |= missed_tid << 16;
- }
- env->spr[SPR_BOOKE_MAS1] |= (missed_tid << MAS1_TID_SHIFT);
-
-
- /* next victim logic */
- env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_ESEL_SHIFT;
- env->last_way++;
- env->last_way &= booke206_tlb_ways(env, 0) - 1;
- env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT;
-}
-
-static bool ppc_booke_xlate(PowerPCCPU *cpu, vaddr eaddr,
- MMUAccessType access_type,
- hwaddr *raddrp, int *psizep, int *protp,
- int mmu_idx, bool guest_visible)
-{
- CPUState *cs = CPU(cpu);
- CPUPPCState *env = &cpu->env;
- mmu_ctx_t ctx;
- int ret;
-
- if (env->mmu_model == POWERPC_MMU_BOOKE206) {
- ret = mmubooke206_get_physical_address(env, &ctx, eaddr, access_type,
- mmu_idx);
- } else {
- ret = mmubooke_get_physical_address(env, &ctx, eaddr, access_type);
- }
- if (ret == 0) {
- *raddrp = ctx.raddr;
- *protp = ctx.prot;
- *psizep = TARGET_PAGE_BITS;
- return true;
- } else if (!guest_visible) {
- return false;
- }
-
- log_cpu_state_mask(CPU_LOG_MMU, cs, 0);
- env->error_code = 0;
- switch (ret) {
- case -1:
- /* No matches in page tables or TLB */
- if (env->mmu_model == POWERPC_MMU_BOOKE206) {
- booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
- }
- cs->exception_index = (access_type == MMU_INST_FETCH) ?
- POWERPC_EXCP_ITLB : POWERPC_EXCP_DTLB;
- env->spr[SPR_BOOKE_DEAR] = eaddr;
- env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
- break;
- case -2:
- /* Access rights violation */
- cs->exception_index = (access_type == MMU_INST_FETCH) ?
- POWERPC_EXCP_ISI : POWERPC_EXCP_DSI;
- if (access_type != MMU_INST_FETCH) {
- env->spr[SPR_BOOKE_DEAR] = eaddr;
- env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
- }
- break;
- case -3:
- /* No execute protection violation */
- if (access_type == MMU_INST_FETCH) {
- cs->exception_index = POWERPC_EXCP_ISI;
- env->spr[SPR_BOOKE_ESR] = 0;
- }
- break;
- }
-
- return false;
-}
-
/* Perform address translation */
/* TODO: Split this by mmu_model. */
static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* Re: [PATCH v3 28/33] target/ppc/mmu_common.c: Move BookE MMU functions together
2024-05-08 0:15 ` [PATCH v3 28/33] target/ppc/mmu_common.c: Move BookE MMU functions together BALATON Zoltan
@ 2024-05-08 13:21 ` Nicholas Piggin
0 siblings, 0 replies; 58+ messages in thread
From: Nicholas Piggin @ 2024-05-08 13:21 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel, qemu-ppc; +Cc: Daniel Henrique Barboza
On Wed May 8, 2024 at 10:15 AM AEST, BALATON Zoltan wrote:
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Okay for now but we should split into a new file soon.
Acked-by: Nicholas Piggin <npiggin@gmail.com>
> ---
> target/ppc/mmu_common.c | 226 ++++++++++++++++++++--------------------
> 1 file changed, 113 insertions(+), 113 deletions(-)
>
> diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
> index 04e5ad661d..a6e7b64049 100644
> --- a/target/ppc/mmu_common.c
> +++ b/target/ppc/mmu_common.c
> @@ -854,6 +854,119 @@ found_tlb:
> return ret;
> }
>
> +static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address,
> + MMUAccessType access_type, int mmu_idx)
> +{
> + uint32_t epid;
> + bool as, pr;
> + uint32_t missed_tid = 0;
> + bool use_epid = mmubooke206_get_as(env, mmu_idx, &epid, &as, &pr);
> +
> + if (access_type == MMU_INST_FETCH) {
> + as = FIELD_EX64(env->msr, MSR, IR);
> + }
> + env->spr[SPR_BOOKE_MAS0] = env->spr[SPR_BOOKE_MAS4] & MAS4_TLBSELD_MASK;
> + env->spr[SPR_BOOKE_MAS1] = env->spr[SPR_BOOKE_MAS4] & MAS4_TSIZED_MASK;
> + env->spr[SPR_BOOKE_MAS2] = env->spr[SPR_BOOKE_MAS4] & MAS4_WIMGED_MASK;
> + env->spr[SPR_BOOKE_MAS3] = 0;
> + env->spr[SPR_BOOKE_MAS6] = 0;
> + env->spr[SPR_BOOKE_MAS7] = 0;
> +
> + /* AS */
> + if (as) {
> + env->spr[SPR_BOOKE_MAS1] |= MAS1_TS;
> + env->spr[SPR_BOOKE_MAS6] |= MAS6_SAS;
> + }
> +
> + env->spr[SPR_BOOKE_MAS1] |= MAS1_VALID;
> + env->spr[SPR_BOOKE_MAS2] |= address & MAS2_EPN_MASK;
> +
> + if (!use_epid) {
> + switch (env->spr[SPR_BOOKE_MAS4] & MAS4_TIDSELD_PIDZ) {
> + case MAS4_TIDSELD_PID0:
> + missed_tid = env->spr[SPR_BOOKE_PID];
> + break;
> + case MAS4_TIDSELD_PID1:
> + missed_tid = env->spr[SPR_BOOKE_PID1];
> + break;
> + case MAS4_TIDSELD_PID2:
> + missed_tid = env->spr[SPR_BOOKE_PID2];
> + break;
> + }
> + env->spr[SPR_BOOKE_MAS6] |= env->spr[SPR_BOOKE_PID] << 16;
> + } else {
> + missed_tid = epid;
> + env->spr[SPR_BOOKE_MAS6] |= missed_tid << 16;
> + }
> + env->spr[SPR_BOOKE_MAS1] |= (missed_tid << MAS1_TID_SHIFT);
> +
> +
> + /* next victim logic */
> + env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_ESEL_SHIFT;
> + env->last_way++;
> + env->last_way &= booke206_tlb_ways(env, 0) - 1;
> + env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT;
> +}
> +
> +static bool ppc_booke_xlate(PowerPCCPU *cpu, vaddr eaddr,
> + MMUAccessType access_type,
> + hwaddr *raddrp, int *psizep, int *protp,
> + int mmu_idx, bool guest_visible)
> +{
> + CPUState *cs = CPU(cpu);
> + CPUPPCState *env = &cpu->env;
> + mmu_ctx_t ctx;
> + int ret;
> +
> + if (env->mmu_model == POWERPC_MMU_BOOKE206) {
> + ret = mmubooke206_get_physical_address(env, &ctx, eaddr, access_type,
> + mmu_idx);
> + } else {
> + ret = mmubooke_get_physical_address(env, &ctx, eaddr, access_type);
> + }
> + if (ret == 0) {
> + *raddrp = ctx.raddr;
> + *protp = ctx.prot;
> + *psizep = TARGET_PAGE_BITS;
> + return true;
> + } else if (!guest_visible) {
> + return false;
> + }
> +
> + log_cpu_state_mask(CPU_LOG_MMU, cs, 0);
> + env->error_code = 0;
> + switch (ret) {
> + case -1:
> + /* No matches in page tables or TLB */
> + if (env->mmu_model == POWERPC_MMU_BOOKE206) {
> + booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
> + }
> + cs->exception_index = (access_type == MMU_INST_FETCH) ?
> + POWERPC_EXCP_ITLB : POWERPC_EXCP_DTLB;
> + env->spr[SPR_BOOKE_DEAR] = eaddr;
> + env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
> + break;
> + case -2:
> + /* Access rights violation */
> + cs->exception_index = (access_type == MMU_INST_FETCH) ?
> + POWERPC_EXCP_ISI : POWERPC_EXCP_DSI;
> + if (access_type != MMU_INST_FETCH) {
> + env->spr[SPR_BOOKE_DEAR] = eaddr;
> + env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
> + }
> + break;
> + case -3:
> + /* No execute protection violation */
> + if (access_type == MMU_INST_FETCH) {
> + cs->exception_index = POWERPC_EXCP_ISI;
> + env->spr[SPR_BOOKE_ESR] = 0;
> + }
> + break;
> + }
> +
> + return false;
> +}
> +
> static const char *book3e_tsize_to_str[32] = {
> "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K",
> "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M",
> @@ -1125,119 +1238,6 @@ static int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
> }
> }
>
> -static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address,
> - MMUAccessType access_type, int mmu_idx)
> -{
> - uint32_t epid;
> - bool as, pr;
> - uint32_t missed_tid = 0;
> - bool use_epid = mmubooke206_get_as(env, mmu_idx, &epid, &as, &pr);
> -
> - if (access_type == MMU_INST_FETCH) {
> - as = FIELD_EX64(env->msr, MSR, IR);
> - }
> - env->spr[SPR_BOOKE_MAS0] = env->spr[SPR_BOOKE_MAS4] & MAS4_TLBSELD_MASK;
> - env->spr[SPR_BOOKE_MAS1] = env->spr[SPR_BOOKE_MAS4] & MAS4_TSIZED_MASK;
> - env->spr[SPR_BOOKE_MAS2] = env->spr[SPR_BOOKE_MAS4] & MAS4_WIMGED_MASK;
> - env->spr[SPR_BOOKE_MAS3] = 0;
> - env->spr[SPR_BOOKE_MAS6] = 0;
> - env->spr[SPR_BOOKE_MAS7] = 0;
> -
> - /* AS */
> - if (as) {
> - env->spr[SPR_BOOKE_MAS1] |= MAS1_TS;
> - env->spr[SPR_BOOKE_MAS6] |= MAS6_SAS;
> - }
> -
> - env->spr[SPR_BOOKE_MAS1] |= MAS1_VALID;
> - env->spr[SPR_BOOKE_MAS2] |= address & MAS2_EPN_MASK;
> -
> - if (!use_epid) {
> - switch (env->spr[SPR_BOOKE_MAS4] & MAS4_TIDSELD_PIDZ) {
> - case MAS4_TIDSELD_PID0:
> - missed_tid = env->spr[SPR_BOOKE_PID];
> - break;
> - case MAS4_TIDSELD_PID1:
> - missed_tid = env->spr[SPR_BOOKE_PID1];
> - break;
> - case MAS4_TIDSELD_PID2:
> - missed_tid = env->spr[SPR_BOOKE_PID2];
> - break;
> - }
> - env->spr[SPR_BOOKE_MAS6] |= env->spr[SPR_BOOKE_PID] << 16;
> - } else {
> - missed_tid = epid;
> - env->spr[SPR_BOOKE_MAS6] |= missed_tid << 16;
> - }
> - env->spr[SPR_BOOKE_MAS1] |= (missed_tid << MAS1_TID_SHIFT);
> -
> -
> - /* next victim logic */
> - env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_ESEL_SHIFT;
> - env->last_way++;
> - env->last_way &= booke206_tlb_ways(env, 0) - 1;
> - env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT;
> -}
> -
> -static bool ppc_booke_xlate(PowerPCCPU *cpu, vaddr eaddr,
> - MMUAccessType access_type,
> - hwaddr *raddrp, int *psizep, int *protp,
> - int mmu_idx, bool guest_visible)
> -{
> - CPUState *cs = CPU(cpu);
> - CPUPPCState *env = &cpu->env;
> - mmu_ctx_t ctx;
> - int ret;
> -
> - if (env->mmu_model == POWERPC_MMU_BOOKE206) {
> - ret = mmubooke206_get_physical_address(env, &ctx, eaddr, access_type,
> - mmu_idx);
> - } else {
> - ret = mmubooke_get_physical_address(env, &ctx, eaddr, access_type);
> - }
> - if (ret == 0) {
> - *raddrp = ctx.raddr;
> - *protp = ctx.prot;
> - *psizep = TARGET_PAGE_BITS;
> - return true;
> - } else if (!guest_visible) {
> - return false;
> - }
> -
> - log_cpu_state_mask(CPU_LOG_MMU, cs, 0);
> - env->error_code = 0;
> - switch (ret) {
> - case -1:
> - /* No matches in page tables or TLB */
> - if (env->mmu_model == POWERPC_MMU_BOOKE206) {
> - booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
> - }
> - cs->exception_index = (access_type == MMU_INST_FETCH) ?
> - POWERPC_EXCP_ITLB : POWERPC_EXCP_DTLB;
> - env->spr[SPR_BOOKE_DEAR] = eaddr;
> - env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
> - break;
> - case -2:
> - /* Access rights violation */
> - cs->exception_index = (access_type == MMU_INST_FETCH) ?
> - POWERPC_EXCP_ISI : POWERPC_EXCP_DSI;
> - if (access_type != MMU_INST_FETCH) {
> - env->spr[SPR_BOOKE_DEAR] = eaddr;
> - env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
> - }
> - break;
> - case -3:
> - /* No execute protection violation */
> - if (access_type == MMU_INST_FETCH) {
> - cs->exception_index = POWERPC_EXCP_ISI;
> - env->spr[SPR_BOOKE_ESR] = 0;
> - }
> - break;
> - }
> -
> - return false;
> -}
> -
> /* Perform address translation */
> /* TODO: Split this by mmu_model. */
> static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 29/33] target/ppc: Remove id_tlbs flag from CPU env
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (27 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 28/33] target/ppc/mmu_common.c: Move BookE MMU functions together BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 0:15 ` [PATCH v3 30/33] target/ppc: Split off common embedded TLB init BALATON Zoltan
` (3 subsequent siblings)
32 siblings, 0 replies; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
This flag for split instruction/data TLBs is only set for 6xx soft TLB
MMU model and not used otherwise so no need to have a separate flag
for that.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
---
hw/ppc/pegasos2.c | 2 +-
target/ppc/cpu.h | 1 -
target/ppc/cpu_init.c | 19 +++++--------------
target/ppc/helper_regs.c | 1 -
target/ppc/mmu_common.c | 10 ++--------
target/ppc/mmu_helper.c | 12 ++----------
6 files changed, 10 insertions(+), 35 deletions(-)
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 04d6decb2b..dfc6fab180 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -984,7 +984,7 @@ static void *build_fdt(MachineState *machine, int *fdt_size)
cpu->env.icache_line_size);
qemu_fdt_setprop_cell(fdt, cp, "i-cache-line-size",
cpu->env.icache_line_size);
- if (cpu->env.id_tlbs) {
+ if (cpu->env.tlb_type == TLB_6XX) {
qemu_fdt_setprop_cell(fdt, cp, "i-tlb-sets", cpu->env.nb_ways);
qemu_fdt_setprop_cell(fdt, cp, "i-tlb-size", cpu->env.tlb_per_way);
qemu_fdt_setprop_cell(fdt, cp, "d-tlb-sets", cpu->env.nb_ways);
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 0ac55d6b25..21e12a4f0d 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1260,7 +1260,6 @@ struct CPUArchState {
int tlb_per_way; /* Speed-up helper: used to avoid divisions at run time */
int nb_ways; /* Number of ways in the TLB set */
int last_way; /* Last used way used to allocate TLB in a LRU way */
- int id_tlbs; /* If 1, MMU has separated TLBs for instructions & data */
int nb_pids; /* Number of available PID registers */
int tlb_type; /* Type of TLB we're dealing with */
ppc_tlb_t tlb; /* TLB is optional. Allocate them only if needed */
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index c11a69fd90..07ad788e54 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -2117,7 +2117,6 @@ static void init_proc_405(CPUPPCState *env)
#if !defined(CONFIG_USER_ONLY)
env->nb_tlb = 64;
env->nb_ways = 1;
- env->id_tlbs = 0;
env->tlb_type = TLB_EMB;
#endif
init_excp_4xx(env);
@@ -2190,7 +2189,6 @@ static void init_proc_440EP(CPUPPCState *env)
#if !defined(CONFIG_USER_ONLY)
env->nb_tlb = 64;
env->nb_ways = 1;
- env->id_tlbs = 0;
env->tlb_type = TLB_EMB;
#endif
init_excp_BookE(env);
@@ -2288,7 +2286,6 @@ static void init_proc_440GP(CPUPPCState *env)
#if !defined(CONFIG_USER_ONLY)
env->nb_tlb = 64;
env->nb_ways = 1;
- env->id_tlbs = 0;
env->tlb_type = TLB_EMB;
#endif
init_excp_BookE(env);
@@ -2362,7 +2359,6 @@ static void init_proc_440x5(CPUPPCState *env)
#if !defined(CONFIG_USER_ONLY)
env->nb_tlb = 64;
env->nb_ways = 1;
- env->id_tlbs = 0;
env->tlb_type = TLB_EMB;
#endif
init_excp_BookE(env);
@@ -2724,7 +2720,6 @@ static void init_proc_e200(CPUPPCState *env)
#if !defined(CONFIG_USER_ONLY)
env->nb_tlb = 64;
env->nb_ways = 1;
- env->id_tlbs = 0;
env->tlb_type = TLB_EMB;
#endif
init_excp_e200(env, 0xFFFF0000UL);
@@ -2843,7 +2838,6 @@ static void init_proc_e500(CPUPPCState *env, int version)
/* Memory management */
env->nb_pids = 3;
env->nb_ways = 2;
- env->id_tlbs = 0;
switch (version) {
case fsl_e500v1:
tlbncfg[0] = register_tlbncfg(2, 1, 1, 0, 256);
@@ -6800,20 +6794,17 @@ static void init_ppc_proc(PowerPCCPU *cpu)
}
/* Allocate TLBs buffer when needed */
#if !defined(CONFIG_USER_ONLY)
- if (env->nb_tlb != 0) {
- int nb_tlb = env->nb_tlb;
- if (env->id_tlbs != 0) {
- nb_tlb *= 2;
- }
+ if (env->nb_tlb) {
switch (env->tlb_type) {
case TLB_6XX:
- env->tlb.tlb6 = g_new0(ppc6xx_tlb_t, nb_tlb);
+ /* 6xx has separate TLBs for instructions and data hence times 2 */
+ env->tlb.tlb6 = g_new0(ppc6xx_tlb_t, 2 * env->nb_tlb);
break;
case TLB_EMB:
- env->tlb.tlbe = g_new0(ppcemb_tlb_t, nb_tlb);
+ env->tlb.tlbe = g_new0(ppcemb_tlb_t, env->nb_tlb);
break;
case TLB_MAS:
- env->tlb.tlbm = g_new0(ppcmas_tlb_t, nb_tlb);
+ env->tlb.tlbm = g_new0(ppcmas_tlb_t, env->nb_tlb);
break;
}
/* Pre-compute some useful values */
diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c
index 25258986e3..ed583fe9b3 100644
--- a/target/ppc/helper_regs.c
+++ b/target/ppc/helper_regs.c
@@ -693,7 +693,6 @@ void register_6xx_7xx_soft_tlb(CPUPPCState *env, int nb_tlbs, int nb_ways)
#if !defined(CONFIG_USER_ONLY)
env->nb_tlb = nb_tlbs;
env->nb_ways = nb_ways;
- env->id_tlbs = 1;
env->tlb_type = TLB_6XX;
spr_register(env, SPR_DMISS, "DMISS",
SPR_NOACCESS, SPR_NOACCESS,
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index a6e7b64049..eff015066d 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -90,8 +90,8 @@ int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr,
nr = (eaddr >> TARGET_PAGE_BITS) & (env->tlb_per_way - 1);
/* Select TLB way */
nr += env->tlb_per_way * way;
- /* 6xx have separate TLBs for instructions and data */
- if (is_code && env->id_tlbs == 1) {
+ /* 6xx has separate TLBs for instructions and data */
+ if (is_code) {
nr += env->nb_tlb;
}
@@ -1153,13 +1153,7 @@ static void mmu6xx_dump_mmu(CPUPPCState *env)
mmu6xx_dump_BATs(env, ACCESS_INT);
mmu6xx_dump_BATs(env, ACCESS_CODE);
- if (env->id_tlbs != 1) {
- qemu_printf("ERROR: 6xx MMU should have separated TLB"
- " for code and data\n");
- }
-
qemu_printf("\nTLBs [EPN EPN + SIZE]\n");
-
for (type = 0; type < 2; type++) {
for (way = 0; way < env->nb_ways; way++) {
for (entry = env->nb_tlb * type + env->tlb_per_way * way;
diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
index 421e777ee6..680ca0b618 100644
--- a/target/ppc/mmu_helper.c
+++ b/target/ppc/mmu_helper.c
@@ -45,14 +45,8 @@
static inline void ppc6xx_tlb_invalidate_all(CPUPPCState *env)
{
ppc6xx_tlb_t *tlb;
- int nr, max;
+ int nr, max = 2 * env->nb_tlb;
- /* LOG_SWTLB("Invalidate all TLBs\n"); */
- /* Invalidate all defined software TLB */
- max = env->nb_tlb;
- if (env->id_tlbs == 1) {
- max *= 2;
- }
for (nr = 0; nr < max; nr++) {
tlb = &env->tlb.tlb6[nr];
pte_invalidate(&tlb->pte0);
@@ -308,9 +302,7 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr)
switch (env->mmu_model) {
case POWERPC_MMU_SOFT_6xx:
ppc6xx_tlb_invalidate_virt(env, addr, 0);
- if (env->id_tlbs == 1) {
- ppc6xx_tlb_invalidate_virt(env, addr, 1);
- }
+ ppc6xx_tlb_invalidate_virt(env, addr, 1);
break;
case POWERPC_MMU_32B:
/*
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v3 30/33] target/ppc: Split off common embedded TLB init
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (28 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 29/33] target/ppc: Remove id_tlbs flag from CPU env BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 0:15 ` [PATCH v3 31/33] target/ppc/mmu-hash32.c: Drop a local variable BALATON Zoltan
` (2 subsequent siblings)
32 siblings, 0 replies; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
Several 4xx CPUs and e200 share the same TLB settings enclosed in an
ifdef. Split it off in a common function to reduce code duplication
and the number of ifdefs.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
---
target/ppc/cpu_init.c | 46 ++++++++++++++++---------------------------
1 file changed, 17 insertions(+), 29 deletions(-)
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 07ad788e54..92c71b2a09 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -2107,18 +2107,22 @@ static int check_pow_hid0_74xx(CPUPPCState *env)
return 0;
}
+static void init_tlbs_emb(CPUPPCState *env)
+{
+#ifndef CONFIG_USER_ONLY
+ env->nb_tlb = 64;
+ env->nb_ways = 1;
+ env->tlb_type = TLB_EMB;
+#endif
+}
+
static void init_proc_405(CPUPPCState *env)
{
register_40x_sprs(env);
register_405_sprs(env);
register_usprgh_sprs(env);
- /* Memory management */
-#if !defined(CONFIG_USER_ONLY)
- env->nb_tlb = 64;
- env->nb_ways = 1;
- env->tlb_type = TLB_EMB;
-#endif
+ init_tlbs_emb(env);
init_excp_4xx(env);
env->dcache_line_size = 32;
env->icache_line_size = 32;
@@ -2185,12 +2189,8 @@ static void init_proc_440EP(CPUPPCState *env)
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
- /* Memory management */
-#if !defined(CONFIG_USER_ONLY)
- env->nb_tlb = 64;
- env->nb_ways = 1;
- env->tlb_type = TLB_EMB;
-#endif
+
+ init_tlbs_emb(env);
init_excp_BookE(env);
env->dcache_line_size = 32;
env->icache_line_size = 32;
@@ -2282,12 +2282,7 @@ static void init_proc_440GP(CPUPPCState *env)
register_440_sprs(env);
register_usprgh_sprs(env);
- /* Memory management */
-#if !defined(CONFIG_USER_ONLY)
- env->nb_tlb = 64;
- env->nb_ways = 1;
- env->tlb_type = TLB_EMB;
-#endif
+ init_tlbs_emb(env);
init_excp_BookE(env);
env->dcache_line_size = 32;
env->icache_line_size = 32;
@@ -2355,12 +2350,8 @@ static void init_proc_440x5(CPUPPCState *env)
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
- /* Memory management */
-#if !defined(CONFIG_USER_ONLY)
- env->nb_tlb = 64;
- env->nb_ways = 1;
- env->tlb_type = TLB_EMB;
-#endif
+
+ init_tlbs_emb(env);
init_excp_BookE(env);
env->dcache_line_size = 32;
env->icache_line_size = 32;
@@ -2717,11 +2708,8 @@ static void init_proc_e200(CPUPPCState *env)
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
-#if !defined(CONFIG_USER_ONLY)
- env->nb_tlb = 64;
- env->nb_ways = 1;
- env->tlb_type = TLB_EMB;
-#endif
+
+ init_tlbs_emb(env);
init_excp_e200(env, 0xFFFF0000UL);
env->dcache_line_size = 32;
env->icache_line_size = 32;
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v3 31/33] target/ppc/mmu-hash32.c: Drop a local variable
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (29 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 30/33] target/ppc: Split off common embedded TLB init BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 13:22 ` Nicholas Piggin
2024-05-08 0:15 ` [PATCH v3 32/33] target/ppc/mmu-radix64.c: " BALATON Zoltan
2024-05-08 0:15 ` [PATCH v3 33/33] target/ppc: Add a macro to check for page protection bit BALATON Zoltan
32 siblings, 1 reply; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
In ppc_hash32_xlate() the value of need_prop is checked in two places
but precalculating it does not help because when we reach the first
check we always return and not reach the second place so the value
will only be used once. We can drop the local variable and calculate
it when needed, which makes these checks using it similar to other
places with such checks.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
target/ppc/mmu-hash32.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/target/ppc/mmu-hash32.c b/target/ppc/mmu-hash32.c
index 960751a50e..b5d7aeed4e 100644
--- a/target/ppc/mmu-hash32.c
+++ b/target/ppc/mmu-hash32.c
@@ -347,7 +347,6 @@ bool ppc_hash32_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
hwaddr pte_offset;
ppc_hash_pte32_t pte;
int prot;
- int need_prot;
hwaddr raddr;
/* There are no hash32 large pages. */
@@ -361,13 +360,11 @@ bool ppc_hash32_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
return true;
}
- need_prot = prot_for_access_type(access_type);
-
/* 2. Check Block Address Translation entries (BATs) */
if (env->nb_BATs != 0) {
raddr = ppc_hash32_bat_lookup(cpu, eaddr, access_type, protp, mmu_idx);
if (raddr != -1) {
- if (need_prot & ~*protp) {
+ if (prot_for_access_type(access_type) & ~*protp) {
if (guest_visible) {
if (access_type == MMU_INST_FETCH) {
cs->exception_index = POWERPC_EXCP_ISI;
@@ -435,7 +432,7 @@ bool ppc_hash32_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
prot = ppc_hash32_pte_prot(mmu_idx, sr, pte);
- if (need_prot & ~prot) {
+ if (prot_for_access_type(access_type) & ~prot) {
/* Access right violation */
qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
if (guest_visible) {
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* Re: [PATCH v3 31/33] target/ppc/mmu-hash32.c: Drop a local variable
2024-05-08 0:15 ` [PATCH v3 31/33] target/ppc/mmu-hash32.c: Drop a local variable BALATON Zoltan
@ 2024-05-08 13:22 ` Nicholas Piggin
0 siblings, 0 replies; 58+ messages in thread
From: Nicholas Piggin @ 2024-05-08 13:22 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel, qemu-ppc; +Cc: Daniel Henrique Barboza
On Wed May 8, 2024 at 10:15 AM AEST, BALATON Zoltan wrote:
> In ppc_hash32_xlate() the value of need_prop is checked in two places
> but precalculating it does not help because when we reach the first
> check we always return and not reach the second place so the value
> will only be used once. We can drop the local variable and calculate
> it when needed, which makes these checks using it similar to other
> places with such checks.
Sure, why not.
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
>
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> ---
> target/ppc/mmu-hash32.c | 7 ++-----
> 1 file changed, 2 insertions(+), 5 deletions(-)
>
> diff --git a/target/ppc/mmu-hash32.c b/target/ppc/mmu-hash32.c
> index 960751a50e..b5d7aeed4e 100644
> --- a/target/ppc/mmu-hash32.c
> +++ b/target/ppc/mmu-hash32.c
> @@ -347,7 +347,6 @@ bool ppc_hash32_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
> hwaddr pte_offset;
> ppc_hash_pte32_t pte;
> int prot;
> - int need_prot;
> hwaddr raddr;
>
> /* There are no hash32 large pages. */
> @@ -361,13 +360,11 @@ bool ppc_hash32_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
> return true;
> }
>
> - need_prot = prot_for_access_type(access_type);
> -
> /* 2. Check Block Address Translation entries (BATs) */
> if (env->nb_BATs != 0) {
> raddr = ppc_hash32_bat_lookup(cpu, eaddr, access_type, protp, mmu_idx);
> if (raddr != -1) {
> - if (need_prot & ~*protp) {
> + if (prot_for_access_type(access_type) & ~*protp) {
> if (guest_visible) {
> if (access_type == MMU_INST_FETCH) {
> cs->exception_index = POWERPC_EXCP_ISI;
> @@ -435,7 +432,7 @@ bool ppc_hash32_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
>
> prot = ppc_hash32_pte_prot(mmu_idx, sr, pte);
>
> - if (need_prot & ~prot) {
> + if (prot_for_access_type(access_type) & ~prot) {
> /* Access right violation */
> qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
> if (guest_visible) {
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 32/33] target/ppc/mmu-radix64.c: Drop a local variable
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (30 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 31/33] target/ppc/mmu-hash32.c: Drop a local variable BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 13:22 ` Nicholas Piggin
2024-05-08 0:15 ` [PATCH v3 33/33] target/ppc: Add a macro to check for page protection bit BALATON Zoltan
32 siblings, 1 reply; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
The value is only used once so no need to introduce a local variable
for it.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
target/ppc/mmu-radix64.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
index 8daf71d2db..395ce3b782 100644
--- a/target/ppc/mmu-radix64.c
+++ b/target/ppc/mmu-radix64.c
@@ -185,7 +185,6 @@ static bool ppc_radix64_check_prot(PowerPCCPU *cpu, MMUAccessType access_type,
int mmu_idx, bool partition_scoped)
{
CPUPPCState *env = &cpu->env;
- int need_prot;
/* Check Page Attributes (pte58:59) */
if ((pte & R_PTE_ATT) == R_PTE_ATT_NI_IO && access_type == MMU_INST_FETCH) {
@@ -210,8 +209,8 @@ static bool ppc_radix64_check_prot(PowerPCCPU *cpu, MMUAccessType access_type,
}
/* Check if requested access type is allowed */
- need_prot = prot_for_access_type(access_type);
- if (need_prot & ~*prot) { /* Page Protected for that Access */
+ if (prot_for_access_type(access_type) & ~*prot) {
+ /* Page Protected for that Access */
*fault_cause |= access_type == MMU_INST_FETCH ? SRR1_NOEXEC_GUARD :
DSISR_PROTFAULT;
return true;
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* Re: [PATCH v3 32/33] target/ppc/mmu-radix64.c: Drop a local variable
2024-05-08 0:15 ` [PATCH v3 32/33] target/ppc/mmu-radix64.c: " BALATON Zoltan
@ 2024-05-08 13:22 ` Nicholas Piggin
0 siblings, 0 replies; 58+ messages in thread
From: Nicholas Piggin @ 2024-05-08 13:22 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel, qemu-ppc; +Cc: Daniel Henrique Barboza
On Wed May 8, 2024 at 10:15 AM AEST, BALATON Zoltan wrote:
> The value is only used once so no need to introduce a local variable
> for it.
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
>
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> ---
> target/ppc/mmu-radix64.c | 5 ++---
> 1 file changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
> index 8daf71d2db..395ce3b782 100644
> --- a/target/ppc/mmu-radix64.c
> +++ b/target/ppc/mmu-radix64.c
> @@ -185,7 +185,6 @@ static bool ppc_radix64_check_prot(PowerPCCPU *cpu, MMUAccessType access_type,
> int mmu_idx, bool partition_scoped)
> {
> CPUPPCState *env = &cpu->env;
> - int need_prot;
>
> /* Check Page Attributes (pte58:59) */
> if ((pte & R_PTE_ATT) == R_PTE_ATT_NI_IO && access_type == MMU_INST_FETCH) {
> @@ -210,8 +209,8 @@ static bool ppc_radix64_check_prot(PowerPCCPU *cpu, MMUAccessType access_type,
> }
>
> /* Check if requested access type is allowed */
> - need_prot = prot_for_access_type(access_type);
> - if (need_prot & ~*prot) { /* Page Protected for that Access */
> + if (prot_for_access_type(access_type) & ~*prot) {
> + /* Page Protected for that Access */
> *fault_cause |= access_type == MMU_INST_FETCH ? SRR1_NOEXEC_GUARD :
> DSISR_PROTFAULT;
> return true;
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 33/33] target/ppc: Add a macro to check for page protection bit
2024-05-08 0:14 [PATCH v3 00/33] Misc PPC exception and BookE MMU clean ups BALATON Zoltan
` (31 preceding siblings ...)
2024-05-08 0:15 ` [PATCH v3 32/33] target/ppc/mmu-radix64.c: " BALATON Zoltan
@ 2024-05-08 0:15 ` BALATON Zoltan
2024-05-08 13:29 ` Nicholas Piggin
32 siblings, 1 reply; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 0:15 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Daniel Henrique Barboza
Checking if a page protection bit is set for a given access type is a
common operation. Add a macro to avoid repeating the same check at
multiple places and also avoid a function call. As this relies on
access type and page protection bit values having certain relation
also add an assert to ensure that this assumption holds.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
target/ppc/cpu_init.c | 4 ++++
target/ppc/internal.h | 20 ++------------------
target/ppc/mmu-hash32.c | 6 +++---
target/ppc/mmu-hash64.c | 2 +-
target/ppc/mmu-radix64.c | 2 +-
target/ppc/mmu_common.c | 26 +++++++++++++-------------
6 files changed, 24 insertions(+), 36 deletions(-)
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 92c71b2a09..6639235544 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -7377,6 +7377,10 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
resettable_class_set_parent_phases(rc, NULL, ppc_cpu_reset_hold, NULL,
&pcc->parent_phases);
+ /* CHECK_PROT_ACCESS relies on this MMU access and PAGE bits relation */
+ assert(MMU_DATA_LOAD == 0 && MMU_DATA_STORE == 1 && MMU_INST_FETCH == 2 &&
+ PAGE_READ == 1 && PAGE_WRITE == 2 && PAGE_EXEC == 4);
+
cc->class_by_name = ppc_cpu_class_by_name;
cc->has_work = ppc_cpu_has_work;
cc->mmu_index = ppc_cpu_mmu_index;
diff --git a/target/ppc/internal.h b/target/ppc/internal.h
index 46176c4711..9880422ce3 100644
--- a/target/ppc/internal.h
+++ b/target/ppc/internal.h
@@ -234,24 +234,8 @@ void destroy_ppc_opcodes(PowerPCCPU *cpu);
void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *ppc);
const gchar *ppc_gdb_arch_name(CPUState *cs);
-/**
- * prot_for_access_type:
- * @access_type: Access type
- *
- * Return the protection bit required for the given access type.
- */
-static inline int prot_for_access_type(MMUAccessType access_type)
-{
- switch (access_type) {
- case MMU_INST_FETCH:
- return PAGE_EXEC;
- case MMU_DATA_LOAD:
- return PAGE_READ;
- case MMU_DATA_STORE:
- return PAGE_WRITE;
- }
- g_assert_not_reached();
-}
+/* Check if permission bit required for the access_type is set in prot */
+#define CHECK_PROT_ACCESS(prot, access_type) ((prot) & (1 << (access_type)))
#ifndef CONFIG_USER_ONLY
diff --git a/target/ppc/mmu-hash32.c b/target/ppc/mmu-hash32.c
index b5d7aeed4e..fa4a4ced6d 100644
--- a/target/ppc/mmu-hash32.c
+++ b/target/ppc/mmu-hash32.c
@@ -213,7 +213,7 @@ static bool ppc_hash32_direct_store(PowerPCCPU *cpu, target_ulong sr,
}
*prot = key ? PAGE_READ | PAGE_WRITE : PAGE_READ;
- if (*prot & prot_for_access_type(access_type)) {
+ if (CHECK_PROT_ACCESS(*prot, access_type)) {
*raddr = eaddr;
return true;
}
@@ -364,7 +364,7 @@ bool ppc_hash32_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
if (env->nb_BATs != 0) {
raddr = ppc_hash32_bat_lookup(cpu, eaddr, access_type, protp, mmu_idx);
if (raddr != -1) {
- if (prot_for_access_type(access_type) & ~*protp) {
+ if (!CHECK_PROT_ACCESS(*protp, access_type)) {
if (guest_visible) {
if (access_type == MMU_INST_FETCH) {
cs->exception_index = POWERPC_EXCP_ISI;
@@ -432,7 +432,7 @@ bool ppc_hash32_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
prot = ppc_hash32_pte_prot(mmu_idx, sr, pte);
- if (prot_for_access_type(access_type) & ~prot) {
+ if (!CHECK_PROT_ACCESS(prot, access_type)) {
/* Access right violation */
qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
if (guest_visible) {
diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
index 5a0d80feda..14c2116ae7 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -1097,7 +1097,7 @@ bool ppc_hash64_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
amr_prot = ppc_hash64_amr_prot(cpu, pte);
prot = exec_prot & pp_prot & amr_prot;
- need_prot = prot_for_access_type(access_type);
+ need_prot = CHECK_PROT_ACCESS(PAGE_RWX, access_type);
if (need_prot & ~prot) {
/* Access right violation */
qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
index 395ce3b782..a72cd927c4 100644
--- a/target/ppc/mmu-radix64.c
+++ b/target/ppc/mmu-radix64.c
@@ -209,7 +209,7 @@ static bool ppc_radix64_check_prot(PowerPCCPU *cpu, MMUAccessType access_type,
}
/* Check if requested access type is allowed */
- if (prot_for_access_type(access_type) & ~*prot) {
+ if (!CHECK_PROT_ACCESS(*prot, access_type)) {
/* Page Protected for that Access */
*fault_cause |= access_type == MMU_INST_FETCH ? SRR1_NOEXEC_GUARD :
DSISR_PROTFAULT;
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index eff015066d..24d68926b4 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -76,11 +76,6 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
/*****************************************************************************/
/* PowerPC MMU emulation */
-static int check_prot(int prot, MMUAccessType access_type)
-{
- return prot & prot_for_access_type(access_type) ? 0 : -2;
-}
-
int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr,
int way, int is_code)
{
@@ -125,13 +120,14 @@ static int ppc6xx_tlb_pte_check(mmu_ctx_t *ctx, target_ulong pte0,
/* Keep the matching PTE information */
ctx->raddr = pte1;
ctx->prot = ppc_hash32_pp_prot(ctx->key, pp, ctx->nx);
- ret = check_prot(ctx->prot, access_type);
- if (ret == 0) {
+ if (CHECK_PROT_ACCESS(ctx->prot, access_type)) {
/* Access granted */
qemu_log_mask(CPU_LOG_MMU, "PTE access granted !\n");
+ ret = 0;
} else {
/* Access right violation */
qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
+ ret = -2;
}
}
}
@@ -317,12 +313,14 @@ static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
(virtual & 0x0001F000);
/* Compute access rights */
ctx->prot = prot;
- ret = check_prot(ctx->prot, access_type);
- if (ret == 0) {
+ if (CHECK_PROT_ACCESS(ctx->prot, access_type)) {
qemu_log_mask(CPU_LOG_MMU, "BAT %d match: r " HWADDR_FMT_plx
" prot=%c%c\n", i, ctx->raddr,
ctx->prot & PAGE_READ ? 'R' : '-',
ctx->prot & PAGE_WRITE ? 'W' : '-');
+ ret = 0;
+ } else {
+ ret = -2;
}
break;
}
@@ -540,9 +538,11 @@ static int mmu40x_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
check_perms:
/* Check from TLB entry */
ctx->prot = tlb->prot;
- ret = check_prot(ctx->prot, access_type);
- if (ret == -2) {
+ if (CHECK_PROT_ACCESS(ctx->prot, access_type)) {
+ ret = 0;
+ } else {
env->spr[SPR_40x_ESR] = 0;
+ ret = -2;
}
break;
}
@@ -607,7 +607,7 @@ static int mmubooke_check_tlb(CPUPPCState *env, ppcemb_tlb_t *tlb,
} else {
*prot = (tlb->prot >> 4) & 0xF;
}
- if (*prot & prot_for_access_type(access_type)) {
+ if (CHECK_PROT_ACCESS(*prot, access_type)) {
qemu_log_mask(CPU_LOG_MMU, "%s: good TLB!\n", __func__);
return 0;
}
@@ -811,7 +811,7 @@ found_tlb:
*prot |= PAGE_EXEC;
}
}
- if (*prot & prot_for_access_type(access_type)) {
+ if (CHECK_PROT_ACCESS(*prot, access_type)) {
qemu_log_mask(CPU_LOG_MMU, "%s: good TLB!\n", __func__);
return 0;
}
--
2.30.9
^ permalink raw reply related [flat|nested] 58+ messages in thread
* Re: [PATCH v3 33/33] target/ppc: Add a macro to check for page protection bit
2024-05-08 0:15 ` [PATCH v3 33/33] target/ppc: Add a macro to check for page protection bit BALATON Zoltan
@ 2024-05-08 13:29 ` Nicholas Piggin
2024-05-08 15:23 ` BALATON Zoltan
2024-05-08 23:35 ` BALATON Zoltan
0 siblings, 2 replies; 58+ messages in thread
From: Nicholas Piggin @ 2024-05-08 13:29 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel, qemu-ppc; +Cc: Daniel Henrique Barboza
On Wed May 8, 2024 at 10:15 AM AEST, BALATON Zoltan wrote:
> Checking if a page protection bit is set for a given access type is a
> common operation. Add a macro to avoid repeating the same check at
> multiple places and also avoid a function call. As this relies on
> access type and page protection bit values having certain relation
> also add an assert to ensure that this assumption holds.
>
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> ---
> target/ppc/cpu_init.c | 4 ++++
> target/ppc/internal.h | 20 ++------------------
> target/ppc/mmu-hash32.c | 6 +++---
> target/ppc/mmu-hash64.c | 2 +-
> target/ppc/mmu-radix64.c | 2 +-
> target/ppc/mmu_common.c | 26 +++++++++++++-------------
> 6 files changed, 24 insertions(+), 36 deletions(-)
>
> diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
> index 92c71b2a09..6639235544 100644
> --- a/target/ppc/cpu_init.c
> +++ b/target/ppc/cpu_init.c
> @@ -7377,6 +7377,10 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
> resettable_class_set_parent_phases(rc, NULL, ppc_cpu_reset_hold, NULL,
> &pcc->parent_phases);
>
> + /* CHECK_PROT_ACCESS relies on this MMU access and PAGE bits relation */
> + assert(MMU_DATA_LOAD == 0 && MMU_DATA_STORE == 1 && MMU_INST_FETCH == 2 &&
> + PAGE_READ == 1 && PAGE_WRITE == 2 && PAGE_EXEC == 4);
> +
Can you use qemu_build_assert() for this?
> cc->class_by_name = ppc_cpu_class_by_name;
> cc->has_work = ppc_cpu_has_work;
> cc->mmu_index = ppc_cpu_mmu_index;
> diff --git a/target/ppc/internal.h b/target/ppc/internal.h
> index 46176c4711..9880422ce3 100644
> --- a/target/ppc/internal.h
> +++ b/target/ppc/internal.h
> @@ -234,24 +234,8 @@ void destroy_ppc_opcodes(PowerPCCPU *cpu);
> void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *ppc);
> const gchar *ppc_gdb_arch_name(CPUState *cs);
>
> -/**
> - * prot_for_access_type:
> - * @access_type: Access type
> - *
> - * Return the protection bit required for the given access type.
> - */
> -static inline int prot_for_access_type(MMUAccessType access_type)
> -{
> - switch (access_type) {
> - case MMU_INST_FETCH:
> - return PAGE_EXEC;
> - case MMU_DATA_LOAD:
> - return PAGE_READ;
> - case MMU_DATA_STORE:
> - return PAGE_WRITE;
> - }
> - g_assert_not_reached();
> -}
> +/* Check if permission bit required for the access_type is set in prot */
> +#define CHECK_PROT_ACCESS(prot, access_type) ((prot) & (1 << (access_type)))
We don't want to use a macro when an inline function will work.
Does the compiler not see the pattern and transform the existing
code into a shift? If it does then I would leave it. If not, then
just keep prot_for_access_type but make it a shift and maybe
comment the logic.
I would call the new function check_prot_for_access_type().
>
> #ifndef CONFIG_USER_ONLY
>
> diff --git a/target/ppc/mmu-hash32.c b/target/ppc/mmu-hash32.c
> index b5d7aeed4e..fa4a4ced6d 100644
> --- a/target/ppc/mmu-hash32.c
> +++ b/target/ppc/mmu-hash32.c
> @@ -213,7 +213,7 @@ static bool ppc_hash32_direct_store(PowerPCCPU *cpu, target_ulong sr,
> }
>
> *prot = key ? PAGE_READ | PAGE_WRITE : PAGE_READ;
> - if (*prot & prot_for_access_type(access_type)) {
> + if (CHECK_PROT_ACCESS(*prot, access_type)) {
> *raddr = eaddr;
> return true;
> }
This does read better, and better than the check_prot() below
that it replaces too, so I like the cleanup.
Thanks,
Nick
> @@ -364,7 +364,7 @@ bool ppc_hash32_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
> if (env->nb_BATs != 0) {
> raddr = ppc_hash32_bat_lookup(cpu, eaddr, access_type, protp, mmu_idx);
> if (raddr != -1) {
> - if (prot_for_access_type(access_type) & ~*protp) {
> + if (!CHECK_PROT_ACCESS(*protp, access_type)) {
> if (guest_visible) {
> if (access_type == MMU_INST_FETCH) {
> cs->exception_index = POWERPC_EXCP_ISI;
> @@ -432,7 +432,7 @@ bool ppc_hash32_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
>
> prot = ppc_hash32_pte_prot(mmu_idx, sr, pte);
>
> - if (prot_for_access_type(access_type) & ~prot) {
> + if (!CHECK_PROT_ACCESS(prot, access_type)) {
> /* Access right violation */
> qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
> if (guest_visible) {
> diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
> index 5a0d80feda..14c2116ae7 100644
> --- a/target/ppc/mmu-hash64.c
> +++ b/target/ppc/mmu-hash64.c
> @@ -1097,7 +1097,7 @@ bool ppc_hash64_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
> amr_prot = ppc_hash64_amr_prot(cpu, pte);
> prot = exec_prot & pp_prot & amr_prot;
>
> - need_prot = prot_for_access_type(access_type);
> + need_prot = CHECK_PROT_ACCESS(PAGE_RWX, access_type);
> if (need_prot & ~prot) {
> /* Access right violation */
> qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
> diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
> index 395ce3b782..a72cd927c4 100644
> --- a/target/ppc/mmu-radix64.c
> +++ b/target/ppc/mmu-radix64.c
> @@ -209,7 +209,7 @@ static bool ppc_radix64_check_prot(PowerPCCPU *cpu, MMUAccessType access_type,
> }
>
> /* Check if requested access type is allowed */
> - if (prot_for_access_type(access_type) & ~*prot) {
> + if (!CHECK_PROT_ACCESS(*prot, access_type)) {
> /* Page Protected for that Access */
> *fault_cause |= access_type == MMU_INST_FETCH ? SRR1_NOEXEC_GUARD :
> DSISR_PROTFAULT;
> diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
> index eff015066d..24d68926b4 100644
> --- a/target/ppc/mmu_common.c
> +++ b/target/ppc/mmu_common.c
> @@ -76,11 +76,6 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
> /*****************************************************************************/
> /* PowerPC MMU emulation */
>
> -static int check_prot(int prot, MMUAccessType access_type)
> -{
> - return prot & prot_for_access_type(access_type) ? 0 : -2;
> -}
> -
> int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr,
> int way, int is_code)
> {
> @@ -125,13 +120,14 @@ static int ppc6xx_tlb_pte_check(mmu_ctx_t *ctx, target_ulong pte0,
> /* Keep the matching PTE information */
> ctx->raddr = pte1;
> ctx->prot = ppc_hash32_pp_prot(ctx->key, pp, ctx->nx);
> - ret = check_prot(ctx->prot, access_type);
> - if (ret == 0) {
> + if (CHECK_PROT_ACCESS(ctx->prot, access_type)) {
> /* Access granted */
> qemu_log_mask(CPU_LOG_MMU, "PTE access granted !\n");
> + ret = 0;
> } else {
> /* Access right violation */
> qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
> + ret = -2;
> }
> }
> }
> @@ -317,12 +313,14 @@ static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
> (virtual & 0x0001F000);
> /* Compute access rights */
> ctx->prot = prot;
> - ret = check_prot(ctx->prot, access_type);
> - if (ret == 0) {
> + if (CHECK_PROT_ACCESS(ctx->prot, access_type)) {
> qemu_log_mask(CPU_LOG_MMU, "BAT %d match: r " HWADDR_FMT_plx
> " prot=%c%c\n", i, ctx->raddr,
> ctx->prot & PAGE_READ ? 'R' : '-',
> ctx->prot & PAGE_WRITE ? 'W' : '-');
> + ret = 0;
> + } else {
> + ret = -2;
> }
> break;
> }
> @@ -540,9 +538,11 @@ static int mmu40x_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
> check_perms:
> /* Check from TLB entry */
> ctx->prot = tlb->prot;
> - ret = check_prot(ctx->prot, access_type);
> - if (ret == -2) {
> + if (CHECK_PROT_ACCESS(ctx->prot, access_type)) {
> + ret = 0;
> + } else {
> env->spr[SPR_40x_ESR] = 0;
> + ret = -2;
> }
> break;
> }
> @@ -607,7 +607,7 @@ static int mmubooke_check_tlb(CPUPPCState *env, ppcemb_tlb_t *tlb,
> } else {
> *prot = (tlb->prot >> 4) & 0xF;
> }
> - if (*prot & prot_for_access_type(access_type)) {
> + if (CHECK_PROT_ACCESS(*prot, access_type)) {
> qemu_log_mask(CPU_LOG_MMU, "%s: good TLB!\n", __func__);
> return 0;
> }
> @@ -811,7 +811,7 @@ found_tlb:
> *prot |= PAGE_EXEC;
> }
> }
> - if (*prot & prot_for_access_type(access_type)) {
> + if (CHECK_PROT_ACCESS(*prot, access_type)) {
> qemu_log_mask(CPU_LOG_MMU, "%s: good TLB!\n", __func__);
> return 0;
> }
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH v3 33/33] target/ppc: Add a macro to check for page protection bit
2024-05-08 13:29 ` Nicholas Piggin
@ 2024-05-08 15:23 ` BALATON Zoltan
2024-05-09 5:52 ` Nicholas Piggin
2024-05-08 23:35 ` BALATON Zoltan
1 sibling, 1 reply; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 15:23 UTC (permalink / raw)
To: Nicholas Piggin; +Cc: qemu-devel, qemu-ppc, Daniel Henrique Barboza
On Wed, 8 May 2024, Nicholas Piggin wrote:
> On Wed May 8, 2024 at 10:15 AM AEST, BALATON Zoltan wrote:
>> Checking if a page protection bit is set for a given access type is a
>> common operation. Add a macro to avoid repeating the same check at
>> multiple places and also avoid a function call. As this relies on
>> access type and page protection bit values having certain relation
>> also add an assert to ensure that this assumption holds.
>>
>> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
>> ---
>> target/ppc/cpu_init.c | 4 ++++
>> target/ppc/internal.h | 20 ++------------------
>> target/ppc/mmu-hash32.c | 6 +++---
>> target/ppc/mmu-hash64.c | 2 +-
>> target/ppc/mmu-radix64.c | 2 +-
>> target/ppc/mmu_common.c | 26 +++++++++++++-------------
>> 6 files changed, 24 insertions(+), 36 deletions(-)
>>
>> diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
>> index 92c71b2a09..6639235544 100644
>> --- a/target/ppc/cpu_init.c
>> +++ b/target/ppc/cpu_init.c
>> @@ -7377,6 +7377,10 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
>> resettable_class_set_parent_phases(rc, NULL, ppc_cpu_reset_hold, NULL,
>> &pcc->parent_phases);
>>
>> + /* CHECK_PROT_ACCESS relies on this MMU access and PAGE bits relation */
>> + assert(MMU_DATA_LOAD == 0 && MMU_DATA_STORE == 1 && MMU_INST_FETCH == 2 &&
>> + PAGE_READ == 1 && PAGE_WRITE == 2 && PAGE_EXEC == 4);
>> +
>
> Can you use qemu_build_assert() for this?
First I've try #if and #error but seems access_type is an enum and the
preprocessor does not see those. If qemu_build_assert is a wrapper around
the same then it might not work but I'll check.
>> cc->class_by_name = ppc_cpu_class_by_name;
>> cc->has_work = ppc_cpu_has_work;
>> cc->mmu_index = ppc_cpu_mmu_index;
>> diff --git a/target/ppc/internal.h b/target/ppc/internal.h
>> index 46176c4711..9880422ce3 100644
>> --- a/target/ppc/internal.h
>> +++ b/target/ppc/internal.h
>> @@ -234,24 +234,8 @@ void destroy_ppc_opcodes(PowerPCCPU *cpu);
>> void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *ppc);
>> const gchar *ppc_gdb_arch_name(CPUState *cs);
>>
>> -/**
>> - * prot_for_access_type:
>> - * @access_type: Access type
>> - *
>> - * Return the protection bit required for the given access type.
>> - */
>> -static inline int prot_for_access_type(MMUAccessType access_type)
>> -{
>> - switch (access_type) {
>> - case MMU_INST_FETCH:
>> - return PAGE_EXEC;
>> - case MMU_DATA_LOAD:
>> - return PAGE_READ;
>> - case MMU_DATA_STORE:
>> - return PAGE_WRITE;
>> - }
>> - g_assert_not_reached();
>> -}
>> +/* Check if permission bit required for the access_type is set in prot */
>> +#define CHECK_PROT_ACCESS(prot, access_type) ((prot) & (1 << (access_type)))
>
> We don't want to use a macro when an inline function will work.
What's wrong with a macro? This has no local variables or any complex
operation that would warant a function IMO it's just a conditional named
for convenience so we don't have to type it everywhere and easier to see
what is it for. A macro is just right for that.
> Does the compiler not see the pattern and transform the existing
> code into a shift? If it does then I would leave it. If not, then
> just keep prot_for_access_type but make it a shift and maybe
> comment the logic.
I don't know but prot_for_access_type is not even needed because this will
work for that too passing PAGE_RWX for prot as done below at one place so
no need for another function for that.
> I would call the new function check_prot_for_access_type().
I can rename it and could make it static inline but I like a macro for
this better.
Regards,
BALATON Zoltan
>>
>> #ifndef CONFIG_USER_ONLY
>>
>> diff --git a/target/ppc/mmu-hash32.c b/target/ppc/mmu-hash32.c
>> index b5d7aeed4e..fa4a4ced6d 100644
>> --- a/target/ppc/mmu-hash32.c
>> +++ b/target/ppc/mmu-hash32.c
>> @@ -213,7 +213,7 @@ static bool ppc_hash32_direct_store(PowerPCCPU *cpu, target_ulong sr,
>> }
>>
>> *prot = key ? PAGE_READ | PAGE_WRITE : PAGE_READ;
>> - if (*prot & prot_for_access_type(access_type)) {
>> + if (CHECK_PROT_ACCESS(*prot, access_type)) {
>> *raddr = eaddr;
>> return true;
>> }
>
> This does read better, and better than the check_prot() below
> that it replaces too, so I like the cleanup.
>
> Thanks,
> Nick
>
>> @@ -364,7 +364,7 @@ bool ppc_hash32_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
>> if (env->nb_BATs != 0) {
>> raddr = ppc_hash32_bat_lookup(cpu, eaddr, access_type, protp, mmu_idx);
>> if (raddr != -1) {
>> - if (prot_for_access_type(access_type) & ~*protp) {
>> + if (!CHECK_PROT_ACCESS(*protp, access_type)) {
>> if (guest_visible) {
>> if (access_type == MMU_INST_FETCH) {
>> cs->exception_index = POWERPC_EXCP_ISI;
>> @@ -432,7 +432,7 @@ bool ppc_hash32_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
>>
>> prot = ppc_hash32_pte_prot(mmu_idx, sr, pte);
>>
>> - if (prot_for_access_type(access_type) & ~prot) {
>> + if (!CHECK_PROT_ACCESS(prot, access_type)) {
>> /* Access right violation */
>> qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
>> if (guest_visible) {
>> diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
>> index 5a0d80feda..14c2116ae7 100644
>> --- a/target/ppc/mmu-hash64.c
>> +++ b/target/ppc/mmu-hash64.c
>> @@ -1097,7 +1097,7 @@ bool ppc_hash64_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
>> amr_prot = ppc_hash64_amr_prot(cpu, pte);
>> prot = exec_prot & pp_prot & amr_prot;
>>
>> - need_prot = prot_for_access_type(access_type);
>> + need_prot = CHECK_PROT_ACCESS(PAGE_RWX, access_type);
>> if (need_prot & ~prot) {
>> /* Access right violation */
>> qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
>> diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
>> index 395ce3b782..a72cd927c4 100644
>> --- a/target/ppc/mmu-radix64.c
>> +++ b/target/ppc/mmu-radix64.c
>> @@ -209,7 +209,7 @@ static bool ppc_radix64_check_prot(PowerPCCPU *cpu, MMUAccessType access_type,
>> }
>>
>> /* Check if requested access type is allowed */
>> - if (prot_for_access_type(access_type) & ~*prot) {
>> + if (!CHECK_PROT_ACCESS(*prot, access_type)) {
>> /* Page Protected for that Access */
>> *fault_cause |= access_type == MMU_INST_FETCH ? SRR1_NOEXEC_GUARD :
>> DSISR_PROTFAULT;
>> diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
>> index eff015066d..24d68926b4 100644
>> --- a/target/ppc/mmu_common.c
>> +++ b/target/ppc/mmu_common.c
>> @@ -76,11 +76,6 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
>> /*****************************************************************************/
>> /* PowerPC MMU emulation */
>>
>> -static int check_prot(int prot, MMUAccessType access_type)
>> -{
>> - return prot & prot_for_access_type(access_type) ? 0 : -2;
>> -}
>> -
>> int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr,
>> int way, int is_code)
>> {
>> @@ -125,13 +120,14 @@ static int ppc6xx_tlb_pte_check(mmu_ctx_t *ctx, target_ulong pte0,
>> /* Keep the matching PTE information */
>> ctx->raddr = pte1;
>> ctx->prot = ppc_hash32_pp_prot(ctx->key, pp, ctx->nx);
>> - ret = check_prot(ctx->prot, access_type);
>> - if (ret == 0) {
>> + if (CHECK_PROT_ACCESS(ctx->prot, access_type)) {
>> /* Access granted */
>> qemu_log_mask(CPU_LOG_MMU, "PTE access granted !\n");
>> + ret = 0;
>> } else {
>> /* Access right violation */
>> qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
>> + ret = -2;
>> }
>> }
>> }
>> @@ -317,12 +313,14 @@ static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
>> (virtual & 0x0001F000);
>> /* Compute access rights */
>> ctx->prot = prot;
>> - ret = check_prot(ctx->prot, access_type);
>> - if (ret == 0) {
>> + if (CHECK_PROT_ACCESS(ctx->prot, access_type)) {
>> qemu_log_mask(CPU_LOG_MMU, "BAT %d match: r " HWADDR_FMT_plx
>> " prot=%c%c\n", i, ctx->raddr,
>> ctx->prot & PAGE_READ ? 'R' : '-',
>> ctx->prot & PAGE_WRITE ? 'W' : '-');
>> + ret = 0;
>> + } else {
>> + ret = -2;
>> }
>> break;
>> }
>> @@ -540,9 +538,11 @@ static int mmu40x_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
>> check_perms:
>> /* Check from TLB entry */
>> ctx->prot = tlb->prot;
>> - ret = check_prot(ctx->prot, access_type);
>> - if (ret == -2) {
>> + if (CHECK_PROT_ACCESS(ctx->prot, access_type)) {
>> + ret = 0;
>> + } else {
>> env->spr[SPR_40x_ESR] = 0;
>> + ret = -2;
>> }
>> break;
>> }
>> @@ -607,7 +607,7 @@ static int mmubooke_check_tlb(CPUPPCState *env, ppcemb_tlb_t *tlb,
>> } else {
>> *prot = (tlb->prot >> 4) & 0xF;
>> }
>> - if (*prot & prot_for_access_type(access_type)) {
>> + if (CHECK_PROT_ACCESS(*prot, access_type)) {
>> qemu_log_mask(CPU_LOG_MMU, "%s: good TLB!\n", __func__);
>> return 0;
>> }
>> @@ -811,7 +811,7 @@ found_tlb:
>> *prot |= PAGE_EXEC;
>> }
>> }
>> - if (*prot & prot_for_access_type(access_type)) {
>> + if (CHECK_PROT_ACCESS(*prot, access_type)) {
>> qemu_log_mask(CPU_LOG_MMU, "%s: good TLB!\n", __func__);
>> return 0;
>> }
>
>
>
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH v3 33/33] target/ppc: Add a macro to check for page protection bit
2024-05-08 15:23 ` BALATON Zoltan
@ 2024-05-09 5:52 ` Nicholas Piggin
0 siblings, 0 replies; 58+ messages in thread
From: Nicholas Piggin @ 2024-05-09 5:52 UTC (permalink / raw)
To: BALATON Zoltan; +Cc: qemu-devel, qemu-ppc, Daniel Henrique Barboza
On Thu May 9, 2024 at 1:23 AM AEST, BALATON Zoltan wrote:
> On Wed, 8 May 2024, Nicholas Piggin wrote:
> > On Wed May 8, 2024 at 10:15 AM AEST, BALATON Zoltan wrote:
> >> Checking if a page protection bit is set for a given access type is a
> >> common operation. Add a macro to avoid repeating the same check at
> >> multiple places and also avoid a function call. As this relies on
> >> access type and page protection bit values having certain relation
> >> also add an assert to ensure that this assumption holds.
> >>
> >> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> >> ---
> >> target/ppc/cpu_init.c | 4 ++++
> >> target/ppc/internal.h | 20 ++------------------
> >> target/ppc/mmu-hash32.c | 6 +++---
> >> target/ppc/mmu-hash64.c | 2 +-
> >> target/ppc/mmu-radix64.c | 2 +-
> >> target/ppc/mmu_common.c | 26 +++++++++++++-------------
> >> 6 files changed, 24 insertions(+), 36 deletions(-)
> >>
> >> diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
> >> index 92c71b2a09..6639235544 100644
> >> --- a/target/ppc/cpu_init.c
> >> +++ b/target/ppc/cpu_init.c
> >> @@ -7377,6 +7377,10 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
> >> resettable_class_set_parent_phases(rc, NULL, ppc_cpu_reset_hold, NULL,
> >> &pcc->parent_phases);
> >>
> >> + /* CHECK_PROT_ACCESS relies on this MMU access and PAGE bits relation */
> >> + assert(MMU_DATA_LOAD == 0 && MMU_DATA_STORE == 1 && MMU_INST_FETCH == 2 &&
> >> + PAGE_READ == 1 && PAGE_WRITE == 2 && PAGE_EXEC == 4);
> >> +
> >
> > Can you use qemu_build_assert() for this?
>
> First I've try #if and #error but seems access_type is an enum and the
> preprocessor does not see those. If qemu_build_assert is a wrapper around
> the same then it might not work but I'll check.
>
> >> cc->class_by_name = ppc_cpu_class_by_name;
> >> cc->has_work = ppc_cpu_has_work;
> >> cc->mmu_index = ppc_cpu_mmu_index;
> >> diff --git a/target/ppc/internal.h b/target/ppc/internal.h
> >> index 46176c4711..9880422ce3 100644
> >> --- a/target/ppc/internal.h
> >> +++ b/target/ppc/internal.h
> >> @@ -234,24 +234,8 @@ void destroy_ppc_opcodes(PowerPCCPU *cpu);
> >> void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *ppc);
> >> const gchar *ppc_gdb_arch_name(CPUState *cs);
> >>
> >> -/**
> >> - * prot_for_access_type:
> >> - * @access_type: Access type
> >> - *
> >> - * Return the protection bit required for the given access type.
> >> - */
> >> -static inline int prot_for_access_type(MMUAccessType access_type)
> >> -{
> >> - switch (access_type) {
> >> - case MMU_INST_FETCH:
> >> - return PAGE_EXEC;
> >> - case MMU_DATA_LOAD:
> >> - return PAGE_READ;
> >> - case MMU_DATA_STORE:
> >> - return PAGE_WRITE;
> >> - }
> >> - g_assert_not_reached();
> >> -}
> >> +/* Check if permission bit required for the access_type is set in prot */
> >> +#define CHECK_PROT_ACCESS(prot, access_type) ((prot) & (1 << (access_type)))
> >
> > We don't want to use a macro when an inline function will work.
>
> What's wrong with a macro? This has no local variables or any complex
> operation that would warant a function IMO it's just a conditional named
> for convenience so we don't have to type it everywhere and easier to see
> what is it for. A macro is just right for that.
Macro does not get parameter or return type check, and has a bunch of
other potential issues
https://gcc.gnu.org/onlinedocs/cpp/macros/macro-pitfalls.html
Macro should not be used unless you can not do it with inline function.
There is no benefit to macro here.
>
> > Does the compiler not see the pattern and transform the existing
> > code into a shift? If it does then I would leave it. If not, then
> > just keep prot_for_access_type but make it a shift and maybe
> > comment the logic.
>
> I don't know but prot_for_access_type is not even needed because this will
> work for that too passing PAGE_RWX for prot as done below at one place so
> no need for another function for that.
>
> > I would call the new function check_prot_for_access_type().
>
> I can rename it and could make it static inline but I like a macro for
> this better.
Thanks,
Nick
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH v3 33/33] target/ppc: Add a macro to check for page protection bit
2024-05-08 13:29 ` Nicholas Piggin
2024-05-08 15:23 ` BALATON Zoltan
@ 2024-05-08 23:35 ` BALATON Zoltan
2024-05-09 5:58 ` Nicholas Piggin
1 sibling, 1 reply; 58+ messages in thread
From: BALATON Zoltan @ 2024-05-08 23:35 UTC (permalink / raw)
To: Nicholas Piggin; +Cc: qemu-devel, qemu-ppc, Daniel Henrique Barboza
On Wed, 8 May 2024, Nicholas Piggin wrote:
> On Wed May 8, 2024 at 10:15 AM AEST, BALATON Zoltan wrote:
>> Checking if a page protection bit is set for a given access type is a
>> common operation. Add a macro to avoid repeating the same check at
>> multiple places and also avoid a function call. As this relies on
>> access type and page protection bit values having certain relation
>> also add an assert to ensure that this assumption holds.
>>
>> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
>> ---
>> target/ppc/cpu_init.c | 4 ++++
>> target/ppc/internal.h | 20 ++------------------
>> target/ppc/mmu-hash32.c | 6 +++---
>> target/ppc/mmu-hash64.c | 2 +-
>> target/ppc/mmu-radix64.c | 2 +-
>> target/ppc/mmu_common.c | 26 +++++++++++++-------------
>> 6 files changed, 24 insertions(+), 36 deletions(-)
>>
>> diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
>> index 92c71b2a09..6639235544 100644
>> --- a/target/ppc/cpu_init.c
>> +++ b/target/ppc/cpu_init.c
>> @@ -7377,6 +7377,10 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
>> resettable_class_set_parent_phases(rc, NULL, ppc_cpu_reset_hold, NULL,
>> &pcc->parent_phases);
>>
>> + /* CHECK_PROT_ACCESS relies on this MMU access and PAGE bits relation */
>> + assert(MMU_DATA_LOAD == 0 && MMU_DATA_STORE == 1 && MMU_INST_FETCH == 2 &&
>> + PAGE_READ == 1 && PAGE_WRITE == 2 && PAGE_EXEC == 4);
>> +
>
> Can you use qemu_build_assert() for this?
I've changed it to qemu_build_assert and seems to work.
>> cc->class_by_name = ppc_cpu_class_by_name;
>> cc->has_work = ppc_cpu_has_work;
>> cc->mmu_index = ppc_cpu_mmu_index;
>> diff --git a/target/ppc/internal.h b/target/ppc/internal.h
>> index 46176c4711..9880422ce3 100644
>> --- a/target/ppc/internal.h
>> +++ b/target/ppc/internal.h
>> @@ -234,24 +234,8 @@ void destroy_ppc_opcodes(PowerPCCPU *cpu);
>> void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *ppc);
>> const gchar *ppc_gdb_arch_name(CPUState *cs);
>>
>> -/**
>> - * prot_for_access_type:
>> - * @access_type: Access type
>> - *
>> - * Return the protection bit required for the given access type.
>> - */
>> -static inline int prot_for_access_type(MMUAccessType access_type)
>> -{
>> - switch (access_type) {
>> - case MMU_INST_FETCH:
>> - return PAGE_EXEC;
>> - case MMU_DATA_LOAD:
>> - return PAGE_READ;
>> - case MMU_DATA_STORE:
>> - return PAGE_WRITE;
>> - }
>> - g_assert_not_reached();
>> -}
>> +/* Check if permission bit required for the access_type is set in prot */
>> +#define CHECK_PROT_ACCESS(prot, access_type) ((prot) & (1 << (access_type)))
>
> We don't want to use a macro when an inline function will work.
>
> Does the compiler not see the pattern and transform the existing
> code into a shift? If it does then I would leave it. If not, then
> just keep prot_for_access_type but make it a shift and maybe
> comment the logic.
>
> I would call the new function check_prot_for_access_type().
That would be too long and does not fit on one line. Long names with
underscore and 80 char line limit does not go well together. I've left
this unchanged for now and wait for your reply on this.
Regards,
BALATON Zoltan
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH v3 33/33] target/ppc: Add a macro to check for page protection bit
2024-05-08 23:35 ` BALATON Zoltan
@ 2024-05-09 5:58 ` Nicholas Piggin
0 siblings, 0 replies; 58+ messages in thread
From: Nicholas Piggin @ 2024-05-09 5:58 UTC (permalink / raw)
To: BALATON Zoltan; +Cc: qemu-devel, qemu-ppc, Daniel Henrique Barboza
On Thu May 9, 2024 at 9:35 AM AEST, BALATON Zoltan wrote:
> On Wed, 8 May 2024, Nicholas Piggin wrote:
> > On Wed May 8, 2024 at 10:15 AM AEST, BALATON Zoltan wrote:
> >> Checking if a page protection bit is set for a given access type is a
> >> common operation. Add a macro to avoid repeating the same check at
> >> multiple places and also avoid a function call. As this relies on
> >> access type and page protection bit values having certain relation
> >> also add an assert to ensure that this assumption holds.
> >>
> >> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> >> ---
> >> target/ppc/cpu_init.c | 4 ++++
> >> target/ppc/internal.h | 20 ++------------------
> >> target/ppc/mmu-hash32.c | 6 +++---
> >> target/ppc/mmu-hash64.c | 2 +-
> >> target/ppc/mmu-radix64.c | 2 +-
> >> target/ppc/mmu_common.c | 26 +++++++++++++-------------
> >> 6 files changed, 24 insertions(+), 36 deletions(-)
> >>
> >> diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
> >> index 92c71b2a09..6639235544 100644
> >> --- a/target/ppc/cpu_init.c
> >> +++ b/target/ppc/cpu_init.c
> >> @@ -7377,6 +7377,10 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
> >> resettable_class_set_parent_phases(rc, NULL, ppc_cpu_reset_hold, NULL,
> >> &pcc->parent_phases);
> >>
> >> + /* CHECK_PROT_ACCESS relies on this MMU access and PAGE bits relation */
> >> + assert(MMU_DATA_LOAD == 0 && MMU_DATA_STORE == 1 && MMU_INST_FETCH == 2 &&
> >> + PAGE_READ == 1 && PAGE_WRITE == 2 && PAGE_EXEC == 4);
> >> +
> >
> > Can you use qemu_build_assert() for this?
>
> I've changed it to qemu_build_assert and seems to work.
>
> >> cc->class_by_name = ppc_cpu_class_by_name;
> >> cc->has_work = ppc_cpu_has_work;
> >> cc->mmu_index = ppc_cpu_mmu_index;
> >> diff --git a/target/ppc/internal.h b/target/ppc/internal.h
> >> index 46176c4711..9880422ce3 100644
> >> --- a/target/ppc/internal.h
> >> +++ b/target/ppc/internal.h
> >> @@ -234,24 +234,8 @@ void destroy_ppc_opcodes(PowerPCCPU *cpu);
> >> void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *ppc);
> >> const gchar *ppc_gdb_arch_name(CPUState *cs);
> >>
> >> -/**
> >> - * prot_for_access_type:
> >> - * @access_type: Access type
> >> - *
> >> - * Return the protection bit required for the given access type.
> >> - */
> >> -static inline int prot_for_access_type(MMUAccessType access_type)
> >> -{
> >> - switch (access_type) {
> >> - case MMU_INST_FETCH:
> >> - return PAGE_EXEC;
> >> - case MMU_DATA_LOAD:
> >> - return PAGE_READ;
> >> - case MMU_DATA_STORE:
> >> - return PAGE_WRITE;
> >> - }
> >> - g_assert_not_reached();
> >> -}
> >> +/* Check if permission bit required for the access_type is set in prot */
> >> +#define CHECK_PROT_ACCESS(prot, access_type) ((prot) & (1 << (access_type)))
> >
> > We don't want to use a macro when an inline function will work.
> >
> > Does the compiler not see the pattern and transform the existing
> > code into a shift? If it does then I would leave it. If not, then
> > just keep prot_for_access_type but make it a shift and maybe
> > comment the logic.
> >
> > I would call the new function check_prot_for_access_type().
>
> That would be too long and does not fit on one line. Long names with
> underscore and 80 char line limit does not go well together. I've left
> this unchanged for now and wait for your reply on this.
Just split the line at the second argument. Better name is more
important than minimising line count.
Thanks,
Nick
^ permalink raw reply [flat|nested] 58+ messages in thread