target/loongarch: Add some CPUCFG bits with host CPU model
Some CPUCFG capability bits depend on KVM host hypervsior and they are detected on QEMU. However some CPUCFG bits are irrelative with hypervsior, here these bits are checked from host machine and set for VM with host CPU model. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Song Gao <gaosong@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn>
Bibo Mao committed
Feb 25, 2026 at 09:41 UTC
45e3ef638e73799815a07a31041afe162d856dc3
2 files changed
+43
-1
target/loongarch/cpu.c
+35
-1
@@ -532,7 +532,7 @@ static uint32_t get_host_cpucfg(int number)
532
533
static void loongarch_host_initfn(Object *obj)
534
{
535
- uint32_t data;
535
+ uint32_t data, cpucfg, field;
536
uint64_t cpuid;
537
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
538
@@ -542,6 +542,40 @@ static void loongarch_host_initfn(Object *obj)
542
cpu->env.cpucfg[0] = data;
543
}
544
545
+ /*
546
+ * There is no exception in KVM hypervisor when these intructions are
547
+ * executed if HW support, KVM hypervisor cannot control this.
548
+ *
549
+ * Set cpucfg bits which cannot be controlled by KVM hypervisor.
550
+ */
551
+ data = get_host_cpucfg(2);
552
+ cpucfg = cpu->env.cpucfg[2];
553
+ field = FIELD_EX32(data, CPUCFG2, FRECIPE);
554
+ cpucfg = FIELD_DP32(cpucfg, CPUCFG2, FRECIPE, field);
555
+ field = FIELD_EX32(data, CPUCFG2, DIV32);
556
+ cpucfg = FIELD_DP32(cpucfg, CPUCFG2, DIV32, field);
557
+ field = FIELD_EX32(data, CPUCFG2, LAM_BH);
558
+ cpucfg = FIELD_DP32(cpucfg, CPUCFG2, LAM_BH, field);
559
+ field = FIELD_EX32(data, CPUCFG2, LAMCAS);
560
+ cpucfg = FIELD_DP32(cpucfg, CPUCFG2, LAMCAS, field);
561
+ field = FIELD_EX32(data, CPUCFG2, LLACQ_SCREL);
562
+ cpucfg = FIELD_DP32(cpucfg, CPUCFG2, LLACQ_SCREL, field);
563
+ field = FIELD_EX32(data, CPUCFG2, SCQ);
564
+ cpucfg = FIELD_DP32(cpucfg, CPUCFG2, SCQ, field);
565
+ cpu->env.cpucfg[2] = cpucfg;
566
+
567
+ data = get_host_cpucfg(3);
568
+ cpucfg = cpu->env.cpucfg[3];
569
+ field = FIELD_EX32(data, CPUCFG3, DBAR_HINTS);
570
+ cpucfg = FIELD_DP32(cpucfg, CPUCFG3, DBAR_HINTS, field);
571
+ field = FIELD_EX32(data, CPUCFG3, ALDORDER_STA);
572
+ cpucfg = FIELD_DP32(cpucfg, CPUCFG3, ALDORDER_STA, field);
573
+ field = FIELD_EX32(data, CPUCFG3, ASTORDER_STA);
574
+ cpucfg = FIELD_DP32(cpucfg, CPUCFG3, ASTORDER_STA, field);
575
+ field = FIELD_EX32(data, CPUCFG3, SLDORDER_STA);
576
+ cpucfg = FIELD_DP32(cpucfg, CPUCFG3, SLDORDER_STA, field);
577
+ cpu->env.cpucfg[3] = cpucfg;
578
+
579
cpuid = get_host_cpu_model();
580
if (cpuid) {
581
cpu->env.cpu_id = cpuid;
target/loongarch/cpu.h
+8
@@ -147,6 +147,7 @@ FIELD(CPUCFG2, LSPW, 21, 1)
147
FIELD(CPUCFG2, LAM, 22, 1)
148
FIELD(CPUCFG2, HPTW, 24, 1)
149
FIELD(CPUCFG2, FRECIPE, 25, 1)
150
+FIELD(CPUCFG2, DIV32, 26, 1)
151
FIELD(CPUCFG2, LAM_BH, 27, 1)
152
FIELD(CPUCFG2, LAMCAS, 28, 1)
153
FIELD(CPUCFG2, LLACQ_SCREL, 29, 1)
@@ -165,6 +166,13 @@ FIELD(CPUCFG3, SPW_LVL, 8, 3)
166
FIELD(CPUCFG3, SPW_HP_HF, 11, 1)
167
FIELD(CPUCFG3, RVA, 12, 1)
168
FIELD(CPUCFG3, RVAMAX, 13, 4)
169
+FIELD(CPUCFG3, DBAR_HINTS, 17, 1)
170
+FIELD(CPUCFG3, ALDORDER_CAP, 18, 1)
171
+FIELD(CPUCFG3, ASTORDER_CAP, 19, 1)
172
+FIELD(CPUCFG3, ALDORDER_STA, 20, 1)
173
+FIELD(CPUCFG3, ASTORDER_STA, 21, 1)
174
+FIELD(CPUCFG3, SLDORDER_CAP, 22, 1)
175
+FIELD(CPUCFG3, SLDORDER_STA, 23, 1)
176
177
/* cpucfg[4] bits */
178
FIELD(CPUCFG4, CC_FREQ, 0, 32)