From 19f27b6c2493472fe2790cf08d7b0140d57bdad5 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 25 Aug 2020 12:37:12 -0700 Subject: [PATCH] target/microblaze: Reduce linux-user address space to 32-bit User-space programs cannot use the 64-bit lwea/swea instructions. We can improve code generation and runtime by restricting the user-only address space to 32-bit. Tested-by: Edgar E. Iglesias Reviewed-by: Edgar E. Iglesias Signed-off-by: Richard Henderson --- target/microblaze/cpu-param.h | 15 +++++++++++++++ target/microblaze/cpu.h | 2 +- target/microblaze/helper.c | 4 ++-- target/microblaze/translate.c | 28 +++++++++++++++++++++++++++- 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/target/microblaze/cpu-param.h b/target/microblaze/cpu-param.h index 4abbc62d50..4d8297fa94 100644 --- a/target/microblaze/cpu-param.h +++ b/target/microblaze/cpu-param.h @@ -8,9 +8,24 @@ #ifndef MICROBLAZE_CPU_PARAM_H #define MICROBLAZE_CPU_PARAM_H 1 +/* + * While system mode can address up to 64 bits of address space, + * this is done via the lea/sea instructions, which are system-only + * (as they also bypass the mmu). + * + * We can improve the user-only experience by only exposing 32 bits + * of address space. + */ +#ifdef CONFIG_USER_ONLY +#define TARGET_LONG_BITS 32 +#define TARGET_PHYS_ADDR_SPACE_BITS 32 +#define TARGET_VIRT_ADDR_SPACE_BITS 32 +#else #define TARGET_LONG_BITS 64 #define TARGET_PHYS_ADDR_SPACE_BITS 64 #define TARGET_VIRT_ADDR_SPACE_BITS 64 +#endif + /* FIXME: MB uses variable pages down to 1K but linux only uses 4k. */ #define TARGET_PAGE_BITS 12 #define NB_MMU_MODES 3 diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h index 4298f242a6..d11b6fa995 100644 --- a/target/microblaze/cpu.h +++ b/target/microblaze/cpu.h @@ -242,7 +242,7 @@ struct CPUMBState { uint32_t pc; uint32_t msr; /* All bits of MSR except MSR[C] and MSR[CC] */ uint32_t msr_c; /* MSR[C], in low bit; other bits must be 0 */ - uint64_t ear; + target_ulong ear; uint32_t esr; uint32_t fsr; uint32_t btr; diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c index 1667822fb7..48547385b0 100644 --- a/target/microblaze/helper.c +++ b/target/microblaze/helper.c @@ -303,8 +303,8 @@ void mb_cpu_do_unaligned_access(CPUState *cs, vaddr addr, iflags = cpu->env.iflags; qemu_log_mask(CPU_LOG_INT, - "Unaligned access addr=" TARGET_FMT_lx - " pc=%x iflags=%x\n", addr, cpu->env.pc, iflags); + "Unaligned access addr=" TARGET_FMT_lx " pc=%x iflags=%x\n", + (target_ulong)addr, cpu->env.pc, iflags); esr = ESR_EC_UNALIGNED_DATA; if (likely(iflags & ESR_ESS_FLAG)) { diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c index 8c287457a9..a377818b5e 100644 --- a/target/microblaze/translate.c +++ b/target/microblaze/translate.c @@ -687,6 +687,7 @@ static TCGv compute_ldst_addr_typeb(DisasContext *dc, int ra, int imm) return ret; } +#ifndef CONFIG_USER_ONLY static TCGv compute_ldst_addr_ea(DisasContext *dc, int ra, int rb) { int addr_size = dc->cpu->cfg.addr_size; @@ -712,6 +713,7 @@ static TCGv compute_ldst_addr_ea(DisasContext *dc, int ra, int rb) } return ret; } +#endif static void record_unaligned_ess(DisasContext *dc, int rd, MemOp size, bool store) @@ -776,8 +778,12 @@ static bool trans_lbuea(DisasContext *dc, arg_typea *arg) if (trap_userspace(dc, true)) { return true; } +#ifdef CONFIG_USER_ONLY + return true; +#else TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb); return do_load(dc, arg->rd, addr, MO_UB, MMU_NOMMU_IDX, false); +#endif } static bool trans_lbui(DisasContext *dc, arg_typeb *arg) @@ -803,8 +809,12 @@ static bool trans_lhuea(DisasContext *dc, arg_typea *arg) if (trap_userspace(dc, true)) { return true; } +#ifdef CONFIG_USER_ONLY + return true; +#else TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb); return do_load(dc, arg->rd, addr, MO_TEUW, MMU_NOMMU_IDX, false); +#endif } static bool trans_lhui(DisasContext *dc, arg_typeb *arg) @@ -830,8 +840,12 @@ static bool trans_lwea(DisasContext *dc, arg_typea *arg) if (trap_userspace(dc, true)) { return true; } +#ifdef CONFIG_USER_ONLY + return true; +#else TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb); return do_load(dc, arg->rd, addr, MO_TEUL, MMU_NOMMU_IDX, false); +#endif } static bool trans_lwi(DisasContext *dc, arg_typeb *arg) @@ -910,8 +924,12 @@ static bool trans_sbea(DisasContext *dc, arg_typea *arg) if (trap_userspace(dc, true)) { return true; } +#ifdef CONFIG_USER_ONLY + return true; +#else TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb); return do_store(dc, arg->rd, addr, MO_UB, MMU_NOMMU_IDX, false); +#endif } static bool trans_sbi(DisasContext *dc, arg_typeb *arg) @@ -937,8 +955,12 @@ static bool trans_shea(DisasContext *dc, arg_typea *arg) if (trap_userspace(dc, true)) { return true; } +#ifdef CONFIG_USER_ONLY + return true; +#else TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb); return do_store(dc, arg->rd, addr, MO_TEUW, MMU_NOMMU_IDX, false); +#endif } static bool trans_shi(DisasContext *dc, arg_typeb *arg) @@ -964,8 +986,12 @@ static bool trans_swea(DisasContext *dc, arg_typea *arg) if (trap_userspace(dc, true)) { return true; } +#ifdef CONFIG_USER_ONLY + return true; +#else TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb); return do_store(dc, arg->rd, addr, MO_TEUL, MMU_NOMMU_IDX, false); +#endif } static bool trans_swi(DisasContext *dc, arg_typeb *arg) @@ -1818,7 +1844,7 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags) } qemu_fprintf(f, "\nesr=0x%04x fsr=0x%02x btr=0x%08x edr=0x%x\n" - "ear=0x%016" PRIx64 " slr=0x%x shr=0x%x\n", + "ear=0x" TARGET_FMT_lx " slr=0x%x shr=0x%x\n", env->esr, env->fsr, env->btr, env->edr, env->ear, env->slr, env->shr);