mirror of https://github.com/proxmox/mirror_qemu
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 <edgar.iglesias@xilinx.com> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>master
parent
e269b4bdf2
commit
19f27b6c24
|
@ -8,9 +8,24 @@
|
||||||
#ifndef MICROBLAZE_CPU_PARAM_H
|
#ifndef MICROBLAZE_CPU_PARAM_H
|
||||||
#define MICROBLAZE_CPU_PARAM_H 1
|
#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_LONG_BITS 64
|
||||||
#define TARGET_PHYS_ADDR_SPACE_BITS 64
|
#define TARGET_PHYS_ADDR_SPACE_BITS 64
|
||||||
#define TARGET_VIRT_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. */
|
/* FIXME: MB uses variable pages down to 1K but linux only uses 4k. */
|
||||||
#define TARGET_PAGE_BITS 12
|
#define TARGET_PAGE_BITS 12
|
||||||
#define NB_MMU_MODES 3
|
#define NB_MMU_MODES 3
|
||||||
|
|
|
@ -242,7 +242,7 @@ struct CPUMBState {
|
||||||
uint32_t pc;
|
uint32_t pc;
|
||||||
uint32_t msr; /* All bits of MSR except MSR[C] and MSR[CC] */
|
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 */
|
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 esr;
|
||||||
uint32_t fsr;
|
uint32_t fsr;
|
||||||
uint32_t btr;
|
uint32_t btr;
|
||||||
|
|
|
@ -303,8 +303,8 @@ void mb_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
|
||||||
iflags = cpu->env.iflags;
|
iflags = cpu->env.iflags;
|
||||||
|
|
||||||
qemu_log_mask(CPU_LOG_INT,
|
qemu_log_mask(CPU_LOG_INT,
|
||||||
"Unaligned access addr=" TARGET_FMT_lx
|
"Unaligned access addr=" TARGET_FMT_lx " pc=%x iflags=%x\n",
|
||||||
" pc=%x iflags=%x\n", addr, cpu->env.pc, iflags);
|
(target_ulong)addr, cpu->env.pc, iflags);
|
||||||
|
|
||||||
esr = ESR_EC_UNALIGNED_DATA;
|
esr = ESR_EC_UNALIGNED_DATA;
|
||||||
if (likely(iflags & ESR_ESS_FLAG)) {
|
if (likely(iflags & ESR_ESS_FLAG)) {
|
||||||
|
|
|
@ -687,6 +687,7 @@ static TCGv compute_ldst_addr_typeb(DisasContext *dc, int ra, int imm)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
static TCGv compute_ldst_addr_ea(DisasContext *dc, int ra, int rb)
|
static TCGv compute_ldst_addr_ea(DisasContext *dc, int ra, int rb)
|
||||||
{
|
{
|
||||||
int addr_size = dc->cpu->cfg.addr_size;
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void record_unaligned_ess(DisasContext *dc, int rd,
|
static void record_unaligned_ess(DisasContext *dc, int rd,
|
||||||
MemOp size, bool store)
|
MemOp size, bool store)
|
||||||
|
@ -776,8 +778,12 @@ static bool trans_lbuea(DisasContext *dc, arg_typea *arg)
|
||||||
if (trap_userspace(dc, true)) {
|
if (trap_userspace(dc, true)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_USER_ONLY
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
|
TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
|
||||||
return do_load(dc, arg->rd, addr, MO_UB, MMU_NOMMU_IDX, false);
|
return do_load(dc, arg->rd, addr, MO_UB, MMU_NOMMU_IDX, false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool trans_lbui(DisasContext *dc, arg_typeb *arg)
|
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)) {
|
if (trap_userspace(dc, true)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_USER_ONLY
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
|
TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
|
||||||
return do_load(dc, arg->rd, addr, MO_TEUW, MMU_NOMMU_IDX, false);
|
return do_load(dc, arg->rd, addr, MO_TEUW, MMU_NOMMU_IDX, false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool trans_lhui(DisasContext *dc, arg_typeb *arg)
|
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)) {
|
if (trap_userspace(dc, true)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_USER_ONLY
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
|
TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
|
||||||
return do_load(dc, arg->rd, addr, MO_TEUL, MMU_NOMMU_IDX, false);
|
return do_load(dc, arg->rd, addr, MO_TEUL, MMU_NOMMU_IDX, false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool trans_lwi(DisasContext *dc, arg_typeb *arg)
|
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)) {
|
if (trap_userspace(dc, true)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_USER_ONLY
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
|
TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
|
||||||
return do_store(dc, arg->rd, addr, MO_UB, MMU_NOMMU_IDX, false);
|
return do_store(dc, arg->rd, addr, MO_UB, MMU_NOMMU_IDX, false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool trans_sbi(DisasContext *dc, arg_typeb *arg)
|
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)) {
|
if (trap_userspace(dc, true)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_USER_ONLY
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
|
TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
|
||||||
return do_store(dc, arg->rd, addr, MO_TEUW, MMU_NOMMU_IDX, false);
|
return do_store(dc, arg->rd, addr, MO_TEUW, MMU_NOMMU_IDX, false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool trans_shi(DisasContext *dc, arg_typeb *arg)
|
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)) {
|
if (trap_userspace(dc, true)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_USER_ONLY
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
|
TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
|
||||||
return do_store(dc, arg->rd, addr, MO_TEUL, MMU_NOMMU_IDX, false);
|
return do_store(dc, arg->rd, addr, MO_TEUL, MMU_NOMMU_IDX, false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool trans_swi(DisasContext *dc, arg_typeb *arg)
|
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"
|
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->esr, env->fsr, env->btr, env->edr,
|
||||||
env->ear, env->slr, env->shr);
|
env->ear, env->slr, env->shr);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue