diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2016-02-26 12:54:22 +0000 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2016-02-26 12:54:22 +0000 |
| commit | 4d1e324b2241017c92d816ec3af51a14685dbf62 (patch) | |
| tree | a6a049570bd94df09d5a18bbbdef20ee9883963b /target-mips/op_helper.c | |
| parent | a88a5cd2e8b917e76b171e5859bdd2c569fa87ff (diff) | |
| parent | 01bc435b44b8802cc4697faa07d908684afbce4e (diff) | |
| download | focaccia-qemu-4d1e324b2241017c92d816ec3af51a14685dbf62.tar.gz focaccia-qemu-4d1e324b2241017c92d816ec3af51a14685dbf62.zip | |
Merge remote-tracking branch 'remotes/lalrae/tags/mips-20160226' into staging
MIPS patches 2016-02-26 Changes: * support for FPU and MSA in KVM guest * support for R6 Virtual Processors # gpg: Signature made Fri 26 Feb 2016 11:07:37 GMT using RSA key ID 0B29DA6B # gpg: Good signature from "Leon Alrae <leon.alrae@imgtec.com>" * remotes/lalrae/tags/mips-20160226: target-mips: implement R6 multi-threading mips/kvm: Support MSA in MIPS KVM guests mips/kvm: Support FPU in MIPS KVM guests mips/kvm: Support signed 64-bit KVM registers mips/kvm: Support unsigned KVM registers mips/kvm: Implement Config CP0 registers mips/kvm: Implement PRid CP0 register mips/kvm: Remove a couple of noisy DPRINTFs Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target-mips/op_helper.c')
| -rw-r--r-- | target-mips/op_helper.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 684ec92c12..7c5669cc96 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -571,6 +571,14 @@ static bool mips_vpe_is_wfi(MIPSCPU *c) return cpu->halted && mips_vpe_active(env); } +static bool mips_vp_is_wfi(MIPSCPU *c) +{ + CPUState *cpu = CPU(c); + CPUMIPSState *env = &c->env; + + return cpu->halted && mips_vp_active(env); +} + static inline void mips_vpe_wake(MIPSCPU *c) { /* Dont set ->halted = 0 directly, let it be done via cpu_has_work @@ -1840,6 +1848,46 @@ target_ulong helper_yield(CPUMIPSState *env, target_ulong arg) return env->CP0_YQMask; } +/* R6 Multi-threading */ +#ifndef CONFIG_USER_ONLY +target_ulong helper_dvp(CPUMIPSState *env) +{ + CPUState *other_cs = first_cpu; + target_ulong prev = env->CP0_VPControl; + + if (!((env->CP0_VPControl >> CP0VPCtl_DIS) & 1)) { + CPU_FOREACH(other_cs) { + MIPSCPU *other_cpu = MIPS_CPU(other_cs); + /* Turn off all VPs except the one executing the dvp. */ + if (&other_cpu->env != env) { + mips_vpe_sleep(other_cpu); + } + } + env->CP0_VPControl |= (1 << CP0VPCtl_DIS); + } + return prev; +} + +target_ulong helper_evp(CPUMIPSState *env) +{ + CPUState *other_cs = first_cpu; + target_ulong prev = env->CP0_VPControl; + + if ((env->CP0_VPControl >> CP0VPCtl_DIS) & 1) { + CPU_FOREACH(other_cs) { + MIPSCPU *other_cpu = MIPS_CPU(other_cs); + if ((&other_cpu->env != env) && !mips_vp_is_wfi(other_cpu)) { + /* If the VP is WFI, don't disturb its sleep. + * Otherwise, wake it up. */ + mips_vpe_wake(other_cpu); + } + } + env->CP0_VPControl &= ~(1 << CP0VPCtl_DIS); + } + return prev; +} +#endif /* !CONFIG_USER_ONLY */ + #ifndef CONFIG_USER_ONLY /* TLB management */ static void r4k_mips_tlb_flush_extra (CPUMIPSState *env, int first) |