Add LVZ property and AVAIL_LVZ macro based on cpucfg.
Signed-off-by: SignKirigami <[email protected]>
Signed-off-by: Hengyu Yu <[email protected]>
---
target/loongarch/cpu.c | 33 +++++++++++++++++++++++++++++++--
target/loongarch/cpu.h | 6 ++++++
target/loongarch/translate.h | 1 +
3 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index e1245235be..664763137d 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -267,11 +267,33 @@ static void loongarch_set_ptw(Object *obj, bool value,
Error **errp)
cpu->env.cpucfg[2] = FIELD_DP32(cpu->env.cpucfg[2], CPUCFG2, HPTW, value);
}
+static bool loongarch_get_lvz(Object *obj, Error **errp)
+{
+ return LOONGARCH_CPU(obj)->lvz != ON_OFF_AUTO_OFF;
+}
+
+static void loongarch_set_lvz(Object *obj, bool value, Error **errp)
+{
+ LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+
+ cpu->lvz = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
+
+ if (kvm_enabled()) {
+ /* lvz can not be only enabled in kvm mode currently */
+ return;
+ }
+
+ cpu->env.cpucfg[2] = FIELD_DP32(cpu->env.cpucfg[2], CPUCFG2, LVZ, value);
+ cpu->env.cpucfg[2] = FIELD_DP32(cpu->env.cpucfg[2], CPUCFG2, LVZ_VER,
+ value ? 1 : 0);
+}
+
static void loongarch_cpu_post_init(Object *obj)
{
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
cpu->lbt = ON_OFF_AUTO_OFF;
+ cpu->lvz = ON_OFF_AUTO_AUTO;
cpu->pmu = ON_OFF_AUTO_OFF;
cpu->lsx = ON_OFF_AUTO_AUTO;
cpu->lasx = ON_OFF_AUTO_AUTO;
@@ -283,6 +305,9 @@ static void loongarch_cpu_post_init(Object *obj)
loongarch_set_msgint);
object_property_add_bool(obj, "ptw", loongarch_get_ptw,
loongarch_set_ptw);
+ object_property_add_bool(obj, "lvz", loongarch_get_lvz,
+ loongarch_set_lvz);
+
/* lbt is enabled only in kvm mode, not supported in tcg mode */
if (kvm_enabled()) {
@@ -336,8 +361,12 @@ static void loongarch_la464_initfn(Object *obj)
data = FIELD_DP32(data, CPUCFG2, FP_SP, 1);
data = FIELD_DP32(data, CPUCFG2, FP_DP, 1);
data = FIELD_DP32(data, CPUCFG2, FP_VER, 1);
- data = FIELD_DP32(data, CPUCFG2, LSX, 1),
- data = FIELD_DP32(data, CPUCFG2, LASX, 1),
+ data = FIELD_DP32(data, CPUCFG2, LSX, 1);
+ data = FIELD_DP32(data, CPUCFG2, LASX, 1);
+ if (tcg_enabled()) {
+ data = FIELD_DP32(data, CPUCFG2, LVZ, 1);
+ data = FIELD_DP32(data, CPUCFG2, LVZ_VER, 1);
+ }
data = FIELD_DP32(data, CPUCFG2, LLFTP, 1);
data = FIELD_DP32(data, CPUCFG2, LLFTP_VER, 1);
data = FIELD_DP32(data, CPUCFG2, LSPW, 1);
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index c0edcc9065..918378ee9a 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -460,6 +460,7 @@ struct ArchCPU {
CPULoongArchState env;
uint32_t phy_id;
OnOffAuto lbt;
+ OnOffAuto lvz;
OnOffAuto pmu;
OnOffAuto ptw;
OnOffAuto lsx;
@@ -520,6 +521,11 @@ static inline CPUSysState *get_sys(CPULoongArchState *env,
int vm_level)
return &env->sys_states[vm_level];
}
+static inline bool cpu_has_lvz(CPULoongArchState *env)
+{
+ return FIELD_EX32(env->cpucfg[2], CPUCFG2, LVZ);
+}
+
static inline CPUTimerState *env_timer(CPULoongArchState *env)
{
return &env->sys_states[0].timer_state;
diff --git a/target/loongarch/translate.h b/target/loongarch/translate.h
index 8aa8325dc6..a7c165982c 100644
--- a/target/loongarch/translate.h
+++ b/target/loongarch/translate.h
@@ -24,6 +24,7 @@
#define avail_FP(C) (FIELD_EX32((C)->cpucfg2, CPUCFG2, FP))
#define avail_FP_SP(C) (FIELD_EX32((C)->cpucfg2, CPUCFG2, FP_SP))
#define avail_FP_DP(C) (FIELD_EX32((C)->cpucfg2, CPUCFG2, FP_DP))
+#define avail_LVZ(C) (FIELD_EX32((C)->cpucfg2, CPUCFG2, LVZ))
#define avail_LSPW(C) (FIELD_EX32((C)->cpucfg2, CPUCFG2, LSPW))
#define avail_LAM(C) (FIELD_EX32((C)->cpucfg2, CPUCFG2, LAM))
#define avail_LAM_BH(C) (FIELD_EX32((C)->cpucfg2, CPUCFG2, LAM_BH))
--
2.55.0