Use virt-manager to start a virtual machine, and then use the following
command to manually trigger the crash of the virtual machine:
echo c > /proc/sysrq-trigger
After the VM is abnormal, the ESTAT register has a certain probability of
remaining interrupted. Then the VM is forced to restart and the VM is
suspended in the interrupt handling function during startup.
In order to clear the remaining interrupt information in the ESTAT
register, we carried out the operation and checked the status of other
registers during the reset process:
Set the CSR_CRMD, CSR_ESTAT, CSR_MSGIS and CSR_PERFCTRL registers to the
reset state when the CPU is reset.
Signed-off-by: Xianglai Li <[email protected]>
---
Cc: Alex Bennée <[email protected]>
Cc: Bibo Mao <[email protected]>
Cc: Song Gao <[email protected]>
changelog:
V1->V2:
1.Add a description of the issues related to this patch
2.Replace the macro definition MAX_PERF_EVENTS with the variable
perf_event_num as the condition for the for loop.
3.Rebase against the latest codebase.
4.Refer to the usage of end_reset_fields on ARM and other architectures,
and modify the current implementation accordingly.
Signed-off-by: Xianglai Li <[email protected]>
---
target/loongarch/cpu-csr.h | 7 +++++++
target/loongarch/cpu.c | 41 +++++++++++++++++---------------------
target/loongarch/cpu.h | 22 +++++++++++---------
3 files changed, 38 insertions(+), 32 deletions(-)
diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
index d860417af2..d936af8e57 100644
--- a/target/loongarch/cpu-csr.h
+++ b/target/loongarch/cpu-csr.h
@@ -211,6 +211,13 @@ FIELD(CSR_DMW_64, VSEG, 60, 4)
#define LOONGARCH_CSR_PERFCTRL(N) (0x200 + 2 * N)
#define LOONGARCH_CSR_PERFCNTR(N) (0x201 + 2 * N)
+FIELD(CSR_PERFCTRL, EV, 0, 10)
+FIELD(CSR_PERFCTRL, PLV0, 16, 1)
+FIELD(CSR_PERFCTRL, PLV1, 17, 1)
+FIELD(CSR_PERFCTRL, PLV2, 18, 1)
+FIELD(CSR_PERFCTRL, PLV3, 19, 1)
+FIELD(CSR_PERFCTRL, PMIE, 20, 1)
+
/* Debug CSRs */
#define LOONGARCH_CSR_DBG 0x500 /* debug config */
FIELD(CSR_DBG, DST, 0, 1)
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index fb03424ffa..aa6ecd9da2 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -623,44 +623,39 @@ static void loongarch_cpu_reset_hold(Object *obj,
ResetType type)
env->fcsr0 = 0x0;
int n;
- /* Set csr registers value after reset, see the manual 6.4. */
- sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, PLV, 0);
- sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, IE, 0);
- sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, DA, 1);
- sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, PG, 0);
- sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, DATF, 0);
- sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, DATM, 0);
- sys->CSR_EUEN = FIELD_DP64(sys->CSR_EUEN, CSR_EUEN, FPE, 0);
- sys->CSR_EUEN = FIELD_DP64(sys->CSR_EUEN, CSR_EUEN, SXE, 0);
- sys->CSR_EUEN = FIELD_DP64(sys->CSR_EUEN, CSR_EUEN, ASXE, 0);
- sys->CSR_EUEN = FIELD_DP64(sys->CSR_EUEN, CSR_EUEN, BTE, 0);
+ memset(sys, 0, offsetof(CPUSysState, end_reset_fields));
- sys->CSR_MISC = 0;
-
- sys->CSR_ECFG = FIELD_DP64(sys->CSR_ECFG, CSR_ECFG, VS, 0);
- sys->CSR_ECFG = FIELD_DP64(sys->CSR_ECFG, CSR_ECFG, LIE, 0);
+ /* Set csr registers value after reset, see the manual 6.4. */
+ sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, DA, 1);
- sys->CSR_ESTAT = sys->CSR_ESTAT & (~MAKE_64BIT_MASK(0, 2));
- sys->CSR_RVACFG = FIELD_DP64(sys->CSR_RVACFG, CSR_RVACFG, RBITS, 0);
sys->CSR_CPUID = cs->cpu_index;
sys->CSR_TCFG = FIELD_DP64(sys->CSR_TCFG, CSR_TCFG, EN, 0);
sys->CSR_LLBCTL = FIELD_DP64(sys->CSR_LLBCTL, CSR_LLBCTL, KLO, 0);
sys->CSR_TLBRERA = FIELD_DP64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 0);
sys->CSR_MERRCTL = FIELD_DP64(sys->CSR_MERRCTL, CSR_MERRCTL, ISMERR, 0);
sys->CSR_TID = cs->cpu_index;
+
+ sys->CSR_DBG = FIELD_DP64(sys->CSR_DBG, CSR_DBG, DST, 0);
+ for (n = 0; n < env->perf_event_num; n++) {
+ sys->CSR_PERFCTRL[n] = FIELD_DP64(sys->CSR_PERFCTRL[n], CSR_PERFCTRL,
+ PLV0, 0);
+ sys->CSR_PERFCTRL[n] = FIELD_DP64(sys->CSR_PERFCTRL[n], CSR_PERFCTRL,
+ PLV1, 0);
+ sys->CSR_PERFCTRL[n] = FIELD_DP64(sys->CSR_PERFCTRL[n], CSR_PERFCTRL,
+ PLV2, 0);
+ sys->CSR_PERFCTRL[n] = FIELD_DP64(sys->CSR_PERFCTRL[n], CSR_PERFCTRL,
+ PLV3, 0);
+ sys->CSR_PERFCTRL[n] = FIELD_DP64(sys->CSR_PERFCTRL[n], CSR_PERFCTRL,
+ PMIE, 0);
+ }
+
/*
* Workaround for edk2-stable202408, CSR PGD register is set only if
* its value is equal to zero for boot cpu, it causes reboot issue.