[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [v4 PATCH] target-mips: implement UserLocal Register
From: |
Andreas Färber |
Subject: |
Re: [Qemu-devel] [v4 PATCH] target-mips: implement UserLocal Register |
Date: |
Wed, 18 Jun 2014 17:21:13 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.5.0 |
Am 29.05.2014 19:36, schrieb Petar Jovanovic:
> From: Petar Jovanovic <address@hidden>
>
> From MIPS documentation (Volume III):
>
> UserLocal Register (CP0 Register 4, Select 2)
> Compliance Level: Recommended.
>
> The UserLocal register is a read-write register that is not interpreted by
> the hardware and conditionally readable via the RDHWR instruction.
>
> This register only exists if the Config3-ULRI register field is set.
>
> Privileged software may write this register with arbitrary information and
> make it accessible to unprivileged software via register 29 (ULR) of the
> RDHWR instruction. To do so, bit 29 of the HWREna register must be set to a
> 1 to enable unprivileged access to the register.
>
> Signed-off-by: Petar Jovanovic <address@hidden>
> ---
> v4:
> - removed MIPS_HFLAG_CP0UL, DisasContext now has a field ulri that is used
> for the same purpose;
>
> v3:
> - new hflag MIPS_HFLAG_HWRENA_ULR introduced, it is set when ULR bit
> from HWREna is set
> - helper rdhwr_ul removed, now the checks for rdhwr are done at
> translation time
> - CPU_SAVE_VERSION switched to 4, load_tc supports both (3 and 4)
> version ids
>
> v2:
> - Defined MIPS_HFLAG_CP0UL flag, checks are now based on hflags
> - CP0_UserLocal moved to struct TCState
> - Added tc->CP0_UserLocal in save_tc/load_tc in target-mips/machine.c
> - Reused CP0_UserLocal field for user-mode purpose
>
> linux-user/mips/target_cpu.h | 2 +-
> linux-user/syscall.c | 2 +-
> target-mips/cpu.h | 11 +++++----
> target-mips/machine.c | 13 ++++++----
> target-mips/op_helper.c | 14 ++++++++++-
> target-mips/translate.c | 54
> +++++++++++++++++++++++++++++++++++++++---
> 6 files changed, 82 insertions(+), 14 deletions(-)
>
> diff --git a/linux-user/mips/target_cpu.h b/linux-user/mips/target_cpu.h
> index ba8e9eb..19b8855 100644
> --- a/linux-user/mips/target_cpu.h
> +++ b/linux-user/mips/target_cpu.h
> @@ -30,7 +30,7 @@ static inline void cpu_clone_regs(CPUMIPSState *env,
> target_ulong newsp)
>
> static inline void cpu_set_tls(CPUMIPSState *env, target_ulong newtls)
> {
> - env->tls_value = newtls;
> + env->active_tc.CP0_UserLocal = newtls;
> }
>
> #endif
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 6efeeff..fda8dd6 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -8686,7 +8686,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long
> arg1,
> #ifdef TARGET_NR_set_thread_area
> case TARGET_NR_set_thread_area:
> #if defined(TARGET_MIPS)
> - ((CPUMIPSState *) cpu_env)->tls_value = arg1;
> + ((CPUMIPSState *) cpu_env)->active_tc.CP0_UserLocal = arg1;
> ret = 0;
> break;
> #elif defined(TARGET_CRIS)
> diff --git a/target-mips/cpu.h b/target-mips/cpu.h
> index 6c2014e..833e592 100644
> --- a/target-mips/cpu.h
> +++ b/target-mips/cpu.h
> @@ -167,6 +167,7 @@ struct TCState {
> target_ulong CP0_TCSchedule;
> target_ulong CP0_TCScheFBack;
> int32_t CP0_Debug_tcstatus;
> + target_ulong CP0_UserLocal;
> };
>
> typedef struct CPUMIPSState CPUMIPSState;
> @@ -361,6 +362,7 @@ struct CPUMIPSState {
> int32_t CP0_Config3;
> #define CP0C3_M 31
> #define CP0C3_ISA_ON_EXC 16
> +#define CP0C3_ULRI 13
> #define CP0C3_DSPP 10
> #define CP0C3_LPA 7
> #define CP0C3_VEIC 6
> @@ -469,6 +471,8 @@ struct CPUMIPSState {
> /* MIPS DSP resources access. */
> #define MIPS_HFLAG_DSP 0x40000 /* Enable access to MIPS DSP resources. */
> #define MIPS_HFLAG_DSPR2 0x80000 /* Enable access to MIPS DSPR2 resources.
> */
> + /* Extra flag about HWREna register. */
> +#define MIPS_HFLAG_HWRENA_ULR 0x100000 /* ULR bit from HWREna is set. */
> target_ulong btarget; /* Jump / branch target */
> target_ulong bcond; /* Branch condition (if needed) */
>
> @@ -478,8 +482,6 @@ struct CPUMIPSState {
> uint32_t CP0_TCStatus_rw_bitmask; /* Read/write bits in CP0_TCStatus */
> int insn_flags; /* Supported instruction set */
>
> - target_ulong tls_value; /* For usermode emulation */
> -
> CPU_COMMON
>
> /* Fields from here on are preserved across CPU reset. */
> @@ -522,7 +524,7 @@ void mips_cpu_list (FILE *f, fprintf_function
> cpu_fprintf);
> extern void cpu_wrdsp(uint32_t rs, uint32_t mask_num, CPUMIPSState *env);
> extern uint32_t cpu_rddsp(uint32_t mask_num, CPUMIPSState *env);
>
> -#define CPU_SAVE_VERSION 3
> +#define CPU_SAVE_VERSION 4
>
> /* MMU modes definitions. We carefully match the indices with our
> hflags layout. */
> @@ -681,7 +683,8 @@ static inline void cpu_get_tb_cpu_state(CPUMIPSState
> *env, target_ulong *pc,
> {
> *pc = env->active_tc.PC;
> *cs_base = 0;
> - *flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
> + *flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK |
> + MIPS_HFLAG_HWRENA_ULR);
> }
>
> static inline int mips_vpe_active(CPUMIPSState *env)
> diff --git a/target-mips/machine.c b/target-mips/machine.c
> index 0a07db8..0f36c9e 100644
> --- a/target-mips/machine.c
> +++ b/target-mips/machine.c
> @@ -25,6 +25,7 @@ static void save_tc(QEMUFile *f, TCState *tc)
> qemu_put_betls(f, &tc->CP0_TCSchedule);
> qemu_put_betls(f, &tc->CP0_TCScheFBack);
> qemu_put_sbe32s(f, &tc->CP0_Debug_tcstatus);
> + qemu_put_betls(f, &tc->CP0_UserLocal);
> }
>
> static void save_fpu(QEMUFile *f, CPUMIPSFPUContext *fpu)
> @@ -151,7 +152,7 @@ void cpu_save(QEMUFile *f, void *opaque)
> save_fpu(f, &env->fpus[i]);
> }
>
> -static void load_tc(QEMUFile *f, TCState *tc)
> +static void load_tc(QEMUFile *f, TCState *tc, int version_id)
> {
> int i;
>
> @@ -173,6 +174,9 @@ static void load_tc(QEMUFile *f, TCState *tc)
> qemu_get_betls(f, &tc->CP0_TCSchedule);
> qemu_get_betls(f, &tc->CP0_TCScheFBack);
> qemu_get_sbe32s(f, &tc->CP0_Debug_tcstatus);
> + if (version_id >= 4) {
> + qemu_get_betls(f, &tc->CP0_UserLocal);
> + }
> }
>
> static void load_fpu(QEMUFile *f, CPUMIPSFPUContext *fpu)
> @@ -194,11 +198,12 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
> MIPSCPU *cpu = mips_env_get_cpu(env);
> int i;
>
> - if (version_id != 3)
> + if (version_id < 3) {
> return -EINVAL;
> + }
>
> /* Load active TC */
> - load_tc(f, &env->active_tc);
> + load_tc(f, &env->active_tc, version_id);
>
> /* Load active FPU */
> load_fpu(f, &env->active_fpu);
> @@ -299,7 +304,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
>
> /* Load inactive TC state */
> for (i = 0; i < MIPS_SHADOW_SET_MAX; i++)
> - load_tc(f, &env->tcs[i]);
> + load_tc(f, &env->tcs[i], version_id);
Since Leon spotted an issue, can you please add braces for this loop
while at it?
> for (i = 0; i < MIPS_FPU_MAX; i++)
> load_fpu(f, &env->fpus[i]);
>
[snip]
Load/save and translation code looks good now.
Thanks,
Andreas
--
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg