On 11/14/24 08:01, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/sparc/cpu.h | 8 ++++---
> target/sparc/cpu.c | 2 +-
> target/sparc/mmu_helper.c | 44 +++++++++++++++++++++++++--------------
> 3 files changed, 34 insertions(+), 20 deletions(-)
>
> diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
> index f517e5a383..4c8927e9fa 100644
> --- a/target/sparc/cpu.h
> +++ b/target/sparc/cpu.h
> @@ -4,6 +4,7 @@
> #include "qemu/bswap.h"
> #include "cpu-qom.h"
> #include "exec/cpu-defs.h"
> +#include "exec/memop.h"
> #include "qemu/cpu-float.h"
>
> #if !defined(TARGET_SPARC64)
> @@ -596,9 +597,10 @@ G_NORETURN void cpu_raise_exception_ra(CPUSPARCState *, int, uintptr_t);
> void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu);
> void sparc_cpu_list(void);
> /* mmu_helper.c */
> -bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
> - MMUAccessType access_type, int mmu_idx,
> - bool probe, uintptr_t retaddr);
> +bool sparc_cpu_tlb_fill_align(CPUState *cs, CPUTLBEntryFull *out,
> + vaddr addr, MMUAccessType access_type,
> + int mmu_idx, MemOp memop, int size,
> + bool probe, uintptr_t retaddr);
> target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev);
> void dump_mmu(CPUSPARCState *env);
>
> diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
> index dd7af86de7..57ae53bd71 100644
> --- a/target/sparc/cpu.c
> +++ b/target/sparc/cpu.c
> @@ -932,7 +932,7 @@ static const TCGCPUOps sparc_tcg_ops = {
> .restore_state_to_opc = sparc_restore_state_to_opc,
>
> #ifndef CONFIG_USER_ONLY
> - .tlb_fill = sparc_cpu_tlb_fill,
> + .tlb_fill_align = sparc_cpu_tlb_fill_align,
> .cpu_exec_interrupt = sparc_cpu_exec_interrupt,
> .cpu_exec_halt = sparc_cpu_has_work,
> .do_interrupt = sparc_cpu_do_interrupt,
> diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c
> index 9ff06026b8..32766a37d6 100644
> --- a/target/sparc/mmu_helper.c
> +++ b/target/sparc/mmu_helper.c
> @@ -203,12 +203,12 @@ static int get_physical_address(CPUSPARCState *env, CPUTLBEntryFull *full,
> }
>
> /* Perform address translation */
> -bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
> - MMUAccessType access_type, int mmu_idx,
> - bool probe, uintptr_t retaddr)
> +bool sparc_cpu_tlb_fill_align(CPUState *cs, CPUTLBEntryFull *out,
> + vaddr address, MMUAccessType access_type,
> + int mmu_idx, MemOp memop, int size,
> + bool probe, uintptr_t retaddr)
> {
> CPUSPARCState *env = cpu_env(cs);
> - CPUTLBEntryFull full = {};
> target_ulong vaddr;
> int error_code = 0, access_index;
>
> @@ -220,16 +220,21 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
> */
> assert(!probe);
>
> + if (address & ((1 << memop_alignment_bits(memop)) - 1)) {
> + sparc_cpu_do_unaligned_access(cs, address, access_type,
> + mmu_idx, retaddr);
> + }
> +
> + memset(out, 0, sizeof(*out));
> address &= TARGET_PAGE_MASK;
> - error_code = get_physical_address(env, &full, &access_index,
> + error_code = get_physical_address(env, out, &access_index,
> address, access_type, mmu_idx);
> vaddr = address;
> if (likely(error_code == 0)) {
> qemu_log_mask(CPU_LOG_MMU,
> "Translate at %" VADDR_PRIx " -> "
> HWADDR_FMT_plx ", vaddr " TARGET_FMT_lx "\n",
> - address, full.phys_addr, vaddr);
> - tlb_set_page_full(cs, mmu_idx, vaddr, &full);
> + address, out->phys_addr, vaddr);
> return true;
> }
>
> @@ -244,8 +249,7 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
> permissions. If no mapping is available, redirect accesses to
> neverland. Fake/overridden mappings will be flushed when
> switching to normal mode. */
> - full.prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
> - tlb_set_page_full(cs, mmu_idx, vaddr, &full);
> + out->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
> return true;
> } else {
> if (access_type == MMU_INST_FETCH) {
> @@ -754,22 +758,30 @@ static int get_physical_address(CPUSPARCState *env, CPUTLBEntryFull *full,
> }
>
> /* Perform address translation */
> -bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
> - MMUAccessType access_type, int mmu_idx,
> - bool probe, uintptr_t retaddr)
> +bool sparc_cpu_tlb_fill_align(CPUState *cs, CPUTLBEntryFull *out,
> + vaddr address, MMUAccessType access_type,
> + int mmu_idx, MemOp memop, int size,
> + bool probe, uintptr_t retaddr)
> {
> CPUSPARCState *env = cpu_env(cs);
> - CPUTLBEntryFull full = {};
> int error_code = 0, access_index;
>
> + if (address & ((1 << memop_alignment_bits(memop)) - 1)) {
> + if (probe) {
> + return false;
> + }
> + sparc_cpu_do_unaligned_access(cs, address, access_type,
> + mmu_idx, retaddr);
> + }
> +
> + memset(out, 0, sizeof(*out));
> address &= TARGET_PAGE_MASK;
> - error_code = get_physical_address(env, &full, &access_index,
> + error_code = get_physical_address(env, out, &access_index,
> address, access_type, mmu_idx);
> if (likely(error_code == 0)) {
> - trace_mmu_helper_mmu_fault(address, full.phys_addr, mmu_idx, env->tl,
> + trace_mmu_helper_mmu_fault(address, out->phys_addr, mmu_idx, env->tl,
> env->dmmu.mmu_primary_context,
> env->dmmu.mmu_secondary_context);
> - tlb_set_page_full(cs, mmu_idx, address, &full);
> return true;
> }
> if (probe) {
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>