aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorBibo Mao <maobibo@loongson.cn>2024-08-27 11:58:07 +0800
committerSong Gao <gaosong@loongson.cn>2024-09-12 20:51:18 +0800
commita840d70ee474c514b939f6f16fd51396c73d01c7 (patch)
treea4016a107823ba4b8f4bd25a734590266eb08fc4 /target
parent4b7ea33074450bc6148c8e1545d78f179e64adb4 (diff)
downloadqemu-a840d70ee474c514b939f6f16fd51396c73d01c7.zip
qemu-a840d70ee474c514b939f6f16fd51396c73d01c7.tar.gz
qemu-a840d70ee474c514b939f6f16fd51396c73d01c7.tar.bz2
target/loongarch: Add compatible support about VM reboot
With edk2-stable202408 LoongArch UEFI bios, CSR PGD register is set only if its value is equal to zero for boot cpu, it causes reboot issue. Since CSR PGD register is changed with linux kernel, UEFI BIOS cannot use it. Add workaround to clear CSR registers relative with TLB in function loongarch_cpu_reset_hold(), so that VM can reboot with edk2-stable202408 UEFI bios. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Song Gao <gaosong@loongson.cn> Message-Id: <20240827035807.3326293-1-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn>
Diffstat (limited to 'target')
-rw-r--r--target/loongarch/cpu.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 5e85b9d..1159221 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -549,6 +549,20 @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType type)
env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 0);
env->CSR_MERRCTL = FIELD_DP64(env->CSR_MERRCTL, CSR_MERRCTL, ISMERR, 0);
env->CSR_TID = cs->cpu_index;
+ /*
+ * Workaround for edk2-stable202408, CSR PGD register is set only if
+ * its value is equal to zero for boot cpu, it causes reboot issue.
+ *
+ * Here clear CSR registers relative with TLB.
+ */
+ env->CSR_PGDH = 0;
+ env->CSR_PGDL = 0;
+ env->CSR_PWCL = 0;
+ env->CSR_PWCH = 0;
+ env->CSR_STLBPS = 0;
+ env->CSR_EENTRY = 0;
+ env->CSR_TLBRENTRY = 0;
+ env->CSR_MERRENTRY = 0;
for (n = 0; n < 4; n++) {
env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV0, 0);