[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] target/mips: Only update MVPControl.EVP bit if executed on a mas
From: |
Philippe Mathieu-Daudé |
Subject: |
[PATCH] target/mips: Only update MVPControl.EVP bit if executed on a master VPE |
Date: |
Tue, 27 Apr 2021 12:35:55 +0200 |
According to the 'MIPS MT Application-Specific Extension' manual:
If the VPE executing the instruction is not a Master VPE,
with the MVP bit of the VPEConf0 register set, the EVP bit
is unchanged by the instruction.
Add the VPEConf0.MVP bit and modify the DVPE/EVPE opcodes to only
update the MVPControl.EVP bit if executed on a master VPE.
Reported-by: Hansni Bu
Buglink: https://bugs.launchpad.net/qemu/+bug/1926277
Fixes: f249412c749 ("mips: Add MT halting and waking of VPEs")
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
target/mips/cpu.h | 1 +
target/mips/cp0_helper.c | 32 ++++++++++++++++++--------------
2 files changed, 19 insertions(+), 14 deletions(-)
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 075c24abdad..bd22fac6959 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -114,6 +114,7 @@ struct CPUMIPSMVPContext {
#define CP0MVPC0_PTLBE 16
#define CP0MVPC0_TCA 15
#define CP0MVPC0_PVPE 10
+#define CP0MVPC0_MVP 1
#define CP0MVPC0_PTC 0
int32_t CP0_MVPConf1;
#define CP0MVPC1_CIM 31
diff --git a/target/mips/cp0_helper.c b/target/mips/cp0_helper.c
index aae2af6eccc..1e39e28808a 100644
--- a/target/mips/cp0_helper.c
+++ b/target/mips/cp0_helper.c
@@ -1635,12 +1635,14 @@ target_ulong helper_dvpe(CPUMIPSState *env)
CPUState *other_cs = first_cpu;
target_ulong prev = env->mvp->CP0_MVPControl;
- CPU_FOREACH(other_cs) {
- MIPSCPU *other_cpu = MIPS_CPU(other_cs);
- /* Turn off all VPEs except the one executing the dvpe. */
- if (&other_cpu->env != env) {
- other_cpu->env.mvp->CP0_MVPControl &= ~(1 << CP0MVPCo_EVP);
- mips_vpe_sleep(other_cpu);
+ if (env->mvp->CP0_MVPConf0 & (1 << CP0MVPC0_MVP)) {
+ CPU_FOREACH(other_cs) {
+ MIPSCPU *other_cpu = MIPS_CPU(other_cs);
+ /* Turn off all VPEs except the one executing the dvpe. */
+ if (&other_cpu->env != env) {
+ other_cpu->env.mvp->CP0_MVPControl &= ~(1 << CP0MVPCo_EVP);
+ mips_vpe_sleep(other_cpu);
+ }
}
}
return prev;
@@ -1651,15 +1653,17 @@ target_ulong helper_evpe(CPUMIPSState *env)
CPUState *other_cs = first_cpu;
target_ulong prev = env->mvp->CP0_MVPControl;
- CPU_FOREACH(other_cs) {
- MIPSCPU *other_cpu = MIPS_CPU(other_cs);
+ if (env->mvp->CP0_MVPConf0 & (1 << CP0MVPC0_MVP)) {
+ CPU_FOREACH(other_cs) {
+ MIPSCPU *other_cpu = MIPS_CPU(other_cs);
- if (&other_cpu->env != env
- /* If the VPE is WFI, don't disturb its sleep. */
- && !mips_vpe_is_wfi(other_cpu)) {
- /* Enable the VPE. */
- other_cpu->env.mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
- mips_vpe_wake(other_cpu); /* And wake it up. */
+ if (&other_cpu->env != env
+ /* If the VPE is WFI, don't disturb its sleep. */
+ && !mips_vpe_is_wfi(other_cpu)) {
+ /* Enable the VPE. */
+ other_cpu->env.mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
+ mips_vpe_wake(other_cpu); /* And wake it up. */
+ }
}
}
return prev;
--
2.26.3
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH] target/mips: Only update MVPControl.EVP bit if executed on a master VPE,
Philippe Mathieu-Daudé <=