summary refs log tree commit diff stats
path: root/target-mips/op_helper.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-02-26 12:54:22 +0000
committerPeter Maydell <peter.maydell@linaro.org>2016-02-26 12:54:22 +0000
commit4d1e324b2241017c92d816ec3af51a14685dbf62 (patch)
treea6a049570bd94df09d5a18bbbdef20ee9883963b /target-mips/op_helper.c
parenta88a5cd2e8b917e76b171e5859bdd2c569fa87ff (diff)
parent01bc435b44b8802cc4697faa07d908684afbce4e (diff)
downloadfocaccia-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.c48
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)