* [Qemu-devel] [PATCH v2 0/2] target-mips: port MIPS CPU to VMState
@ 2015-02-20 13:07 Leon Alrae
2015-02-20 13:07 ` [Qemu-devel] [PATCH v2 1/2] target-mips: replace cpu_save/cpu_load with VMStateDescription Leon Alrae
2015-02-20 13:07 ` [Qemu-devel] [PATCH v2 2/2] target-mips: add missing MSACSR and restore fp_status and hflags Leon Alrae
0 siblings, 2 replies; 4+ messages in thread
From: Leon Alrae @ 2015-02-20 13:07 UTC (permalink / raw)
To: qemu-devel; +Cc: quintela, rth7680, macro, amit.shah, afaerber, aurelien
Hi,
This small patchset converts MIPS CPU to use VMStateDescription:
[1/2]: ports all the MIPS CPU fields to new VMStateDescription structure
[2/2]: adds MSACSR and uses post_load() to restore *fp_status from *CSR
registers. These changes include ported Maciej's updates made for old
cpu_load/cpu_save sent some time ago.
I tested them by just checking whether the restored guest system still works
after savevm/loadvm and migrate commands.
This series applies on top of the pending mips-next pull request:
http://patchwork.ozlabs.org/patch/439769/
Comments and suggestions are welcome.
Thanks,
Leon
v2:
* use cc->vmsd rather than dc->vmsd (Andreas Faerber)
* avoid saving TCG-related state (Richard Henderson)
Leon Alrae (2):
target-mips: replace cpu_save/cpu_load with VMStateDescription
target-mips: add missing MSACSR and restore fp_status and hflags
target-mips/cpu-qom.h | 4 +
target-mips/cpu.c | 1 +
target-mips/cpu.h | 19 +-
target-mips/machine.c | 571 ++++++++++++++++++++-----------------------
target-mips/msa_helper.c | 12 +-
target-mips/translate_init.c | 10 +-
6 files changed, 288 insertions(+), 329 deletions(-)
--
2.1.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH v2 1/2] target-mips: replace cpu_save/cpu_load with VMStateDescription
2015-02-20 13:07 [Qemu-devel] [PATCH v2 0/2] target-mips: port MIPS CPU to VMState Leon Alrae
@ 2015-02-20 13:07 ` Leon Alrae
2015-02-20 13:07 ` [Qemu-devel] [PATCH v2 2/2] target-mips: add missing MSACSR and restore fp_status and hflags Leon Alrae
1 sibling, 0 replies; 4+ messages in thread
From: Leon Alrae @ 2015-02-20 13:07 UTC (permalink / raw)
To: qemu-devel; +Cc: quintela, rth7680, macro, amit.shah, afaerber, aurelien
Create VMStateDescription for MIPS CPU. The new structure contains exactly the
same fields as before, therefore leaving existing version_id.
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
---
target-mips/cpu-qom.h | 4 +
target-mips/cpu.c | 1 +
target-mips/cpu.h | 2 -
target-mips/machine.c | 567 ++++++++++++++++++++++----------------------------
4 files changed, 257 insertions(+), 317 deletions(-)
diff --git a/target-mips/cpu-qom.h b/target-mips/cpu-qom.h
index 2ffc1bf..4d6f9de 100644
--- a/target-mips/cpu-qom.h
+++ b/target-mips/cpu-qom.h
@@ -74,6 +74,10 @@ static inline MIPSCPU *mips_env_get_cpu(CPUMIPSState *env)
#define ENV_OFFSET offsetof(MIPSCPU, env)
+#ifndef CONFIG_USER_ONLY
+extern const struct VMStateDescription vmstate_mips_cpu;
+#endif
+
void mips_cpu_do_interrupt(CPUState *cpu);
bool mips_cpu_exec_interrupt(CPUState *cpu, int int_req);
void mips_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index 98dc94e..958c999 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -148,6 +148,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
cc->do_unassigned_access = mips_cpu_unassigned_access;
cc->do_unaligned_access = mips_cpu_do_unaligned_access;
cc->get_phys_page_debug = mips_cpu_get_phys_page_debug;
+ cc->vmsd = &vmstate_mips_cpu;
#endif
cc->gdb_num_core_regs = 73;
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 5ea61bc..59a2373 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -614,8 +614,6 @@ void mips_cpu_list (FILE *f, fprintf_function cpu_fprintf);
extern void cpu_wrdsp(uint32_t rs, uint32_t mask_num, CPUMIPSState *env);
extern uint32_t cpu_rddsp(uint32_t mask_num, CPUMIPSState *env);
-#define CPU_SAVE_VERSION 5
-
/* MMU modes definitions. We carefully match the indices with our
hflags layout. */
#define MMU_MODE0_SUFFIX _kernel
diff --git a/target-mips/machine.c b/target-mips/machine.c
index 6c76dfb..7fc4839 100644
--- a/target-mips/machine.c
+++ b/target-mips/machine.c
@@ -1,341 +1,278 @@
#include "hw/hw.h"
-#include "hw/boards.h"
#include "cpu.h"
-static void save_tc(QEMUFile *f, TCState *tc)
+/* FPU state */
+
+static int get_fpr(QEMUFile *f, void *pv, size_t size)
{
- int i;
-
- /* Save active TC */
- for(i = 0; i < 32; i++)
- qemu_put_betls(f, &tc->gpr[i]);
- qemu_put_betls(f, &tc->PC);
- for(i = 0; i < MIPS_DSP_ACC; i++)
- qemu_put_betls(f, &tc->HI[i]);
- for(i = 0; i < MIPS_DSP_ACC; i++)
- qemu_put_betls(f, &tc->LO[i]);
- for(i = 0; i < MIPS_DSP_ACC; i++)
- qemu_put_betls(f, &tc->ACX[i]);
- qemu_put_betls(f, &tc->DSPControl);
- qemu_put_sbe32s(f, &tc->CP0_TCStatus);
- qemu_put_sbe32s(f, &tc->CP0_TCBind);
- qemu_put_betls(f, &tc->CP0_TCHalt);
- qemu_put_betls(f, &tc->CP0_TCContext);
- qemu_put_betls(f, &tc->CP0_TCSchedule);
- qemu_put_betls(f, &tc->CP0_TCScheFBack);
- qemu_put_sbe32s(f, &tc->CP0_Debug_tcstatus);
- qemu_put_betls(f, &tc->CP0_UserLocal);
+ fpr_t *v = pv;
+ qemu_get_be64s(f, &v->d);
+ return 0;
}
-static void save_fpu(QEMUFile *f, CPUMIPSFPUContext *fpu)
+static void put_fpr(QEMUFile *f, void *pv, size_t size)
{
- int i;
-
- for(i = 0; i < 32; i++)
- qemu_put_be64s(f, &fpu->fpr[i].d);
- qemu_put_s8s(f, &fpu->fp_status.float_detect_tininess);
- qemu_put_s8s(f, &fpu->fp_status.float_rounding_mode);
- qemu_put_s8s(f, &fpu->fp_status.float_exception_flags);
- qemu_put_be32s(f, &fpu->fcr0);
- qemu_put_be32s(f, &fpu->fcr31);
+ fpr_t *v = pv;
+ qemu_put_be64s(f, &v->d);
}
-void cpu_save(QEMUFile *f, void *opaque)
-{
- CPUMIPSState *env = opaque;
- int i;
-
- /* Save active TC */
- save_tc(f, &env->active_tc);
-
- /* Save active FPU */
- save_fpu(f, &env->active_fpu);
-
- /* Save MVP */
- qemu_put_sbe32s(f, &env->mvp->CP0_MVPControl);
- qemu_put_sbe32s(f, &env->mvp->CP0_MVPConf0);
- qemu_put_sbe32s(f, &env->mvp->CP0_MVPConf1);
-
- /* Save TLB */
- qemu_put_be32s(f, &env->tlb->nb_tlb);
- qemu_put_be32s(f, &env->tlb->tlb_in_use);
- for(i = 0; i < MIPS_TLB_MAX; i++) {
- uint16_t flags = ((env->tlb->mmu.r4k.tlb[i].EHINV << 15) |
- (env->tlb->mmu.r4k.tlb[i].RI1 << 14) |
- (env->tlb->mmu.r4k.tlb[i].RI0 << 13) |
- (env->tlb->mmu.r4k.tlb[i].XI1 << 12) |
- (env->tlb->mmu.r4k.tlb[i].XI0 << 11) |
- (env->tlb->mmu.r4k.tlb[i].G << 10) |
- (env->tlb->mmu.r4k.tlb[i].C0 << 7) |
- (env->tlb->mmu.r4k.tlb[i].C1 << 4) |
- (env->tlb->mmu.r4k.tlb[i].V0 << 3) |
- (env->tlb->mmu.r4k.tlb[i].V1 << 2) |
- (env->tlb->mmu.r4k.tlb[i].D0 << 1) |
- (env->tlb->mmu.r4k.tlb[i].D1 << 0));
- uint8_t asid;
-
- qemu_put_betls(f, &env->tlb->mmu.r4k.tlb[i].VPN);
- qemu_put_be32s(f, &env->tlb->mmu.r4k.tlb[i].PageMask);
- asid = env->tlb->mmu.r4k.tlb[i].ASID;
- qemu_put_8s(f, &asid);
- qemu_put_be16s(f, &flags);
- qemu_put_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[0]);
- qemu_put_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[1]);
- }
+const VMStateInfo vmstate_info_fpr = {
+ .name = "fpr",
+ .get = get_fpr,
+ .put = put_fpr,
+};
+
+#define VMSTATE_FPR_ARRAY_V(_f, _s, _n, _v) \
+ VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_fpr, fpr_t)
+
+#define VMSTATE_FPR_ARRAY(_f, _s, _n) \
+ VMSTATE_FPR_ARRAY_V(_f, _s, _n, 0)
+
+static VMStateField vmstate_fpu_fields[] = {
+ VMSTATE_FPR_ARRAY(fpr, CPUMIPSFPUContext, 32),
+ VMSTATE_INT8(fp_status.float_detect_tininess, CPUMIPSFPUContext),
+ VMSTATE_INT8(fp_status.float_rounding_mode, CPUMIPSFPUContext),
+ VMSTATE_INT8(fp_status.float_exception_flags, CPUMIPSFPUContext),
+ VMSTATE_UINT32(fcr0, CPUMIPSFPUContext),
+ VMSTATE_UINT32(fcr31, CPUMIPSFPUContext),
+ VMSTATE_END_OF_LIST()
+};
+
+const VMStateDescription vmstate_fpu = {
+ .name = "cpu/fpu",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = vmstate_fpu_fields
+};
+
+const VMStateDescription vmstate_inactive_fpu = {
+ .name = "cpu/inactive_fpu",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = vmstate_fpu_fields
+};
- /* Save CPU metastate */
- qemu_put_be32s(f, &env->current_tc);
- qemu_put_be32s(f, &env->current_fpu);
- qemu_put_sbe32s(f, &env->error_code);
- qemu_put_be32s(f, &env->hflags);
- qemu_put_betls(f, &env->btarget);
- i = env->bcond;
- qemu_put_sbe32s(f, &i);
-
- /* Save remaining CP1 registers */
- qemu_put_sbe32s(f, &env->CP0_Index);
- qemu_put_sbe32s(f, &env->CP0_Random);
- qemu_put_sbe32s(f, &env->CP0_VPEControl);
- qemu_put_sbe32s(f, &env->CP0_VPEConf0);
- qemu_put_sbe32s(f, &env->CP0_VPEConf1);
- qemu_put_betls(f, &env->CP0_YQMask);
- qemu_put_betls(f, &env->CP0_VPESchedule);
- qemu_put_betls(f, &env->CP0_VPEScheFBack);
- qemu_put_sbe32s(f, &env->CP0_VPEOpt);
- qemu_put_betls(f, &env->CP0_EntryLo0);
- qemu_put_betls(f, &env->CP0_EntryLo1);
- qemu_put_betls(f, &env->CP0_Context);
- qemu_put_sbe32s(f, &env->CP0_PageMask);
- qemu_put_sbe32s(f, &env->CP0_PageGrain);
- qemu_put_sbe32s(f, &env->CP0_Wired);
- qemu_put_sbe32s(f, &env->CP0_SRSConf0);
- qemu_put_sbe32s(f, &env->CP0_SRSConf1);
- qemu_put_sbe32s(f, &env->CP0_SRSConf2);
- qemu_put_sbe32s(f, &env->CP0_SRSConf3);
- qemu_put_sbe32s(f, &env->CP0_SRSConf4);
- qemu_put_sbe32s(f, &env->CP0_HWREna);
- qemu_put_betls(f, &env->CP0_BadVAddr);
- qemu_put_be32s(f, &env->CP0_BadInstr);
- qemu_put_be32s(f, &env->CP0_BadInstrP);
- qemu_put_sbe32s(f, &env->CP0_Count);
- qemu_put_betls(f, &env->CP0_EntryHi);
- qemu_put_sbe32s(f, &env->CP0_Compare);
- qemu_put_sbe32s(f, &env->CP0_Status);
- qemu_put_sbe32s(f, &env->CP0_IntCtl);
- qemu_put_sbe32s(f, &env->CP0_SRSCtl);
- qemu_put_sbe32s(f, &env->CP0_SRSMap);
- qemu_put_sbe32s(f, &env->CP0_Cause);
- qemu_put_betls(f, &env->CP0_EPC);
- qemu_put_sbe32s(f, &env->CP0_PRid);
- qemu_put_sbe32s(f, &env->CP0_EBase);
- qemu_put_sbe32s(f, &env->CP0_Config0);
- qemu_put_sbe32s(f, &env->CP0_Config1);
- qemu_put_sbe32s(f, &env->CP0_Config2);
- qemu_put_sbe32s(f, &env->CP0_Config3);
- qemu_put_sbe32s(f, &env->CP0_Config6);
- qemu_put_sbe32s(f, &env->CP0_Config7);
- qemu_put_betls(f, &env->lladdr);
- for(i = 0; i < 8; i++)
- qemu_put_betls(f, &env->CP0_WatchLo[i]);
- for(i = 0; i < 8; i++)
- qemu_put_sbe32s(f, &env->CP0_WatchHi[i]);
- qemu_put_betls(f, &env->CP0_XContext);
- qemu_put_sbe32s(f, &env->CP0_Framemask);
- qemu_put_sbe32s(f, &env->CP0_Debug);
- qemu_put_betls(f, &env->CP0_DEPC);
- qemu_put_sbe32s(f, &env->CP0_Performance0);
- qemu_put_sbe32s(f, &env->CP0_TagLo);
- qemu_put_sbe32s(f, &env->CP0_DataLo);
- qemu_put_sbe32s(f, &env->CP0_TagHi);
- qemu_put_sbe32s(f, &env->CP0_DataHi);
- qemu_put_betls(f, &env->CP0_ErrorEPC);
- qemu_put_sbe32s(f, &env->CP0_DESAVE);
- for (i = 0; i < MIPS_KSCRATCH_NUM; i++) {
- qemu_put_betls(f, &env->CP0_KScratch[i]);
+/* TC state */
+
+static VMStateField vmstate_tc_fields[] = {
+ VMSTATE_UINTTL_ARRAY(gpr, TCState, 32),
+ VMSTATE_UINTTL(PC, TCState),
+ VMSTATE_UINTTL_ARRAY(HI, TCState, MIPS_DSP_ACC),
+ VMSTATE_UINTTL_ARRAY(LO, TCState, MIPS_DSP_ACC),
+ VMSTATE_UINTTL_ARRAY(ACX, TCState, MIPS_DSP_ACC),
+ VMSTATE_UINTTL(DSPControl, TCState),
+ VMSTATE_INT32(CP0_TCStatus, TCState),
+ VMSTATE_INT32(CP0_TCBind, TCState),
+ VMSTATE_UINTTL(CP0_TCHalt, TCState),
+ VMSTATE_UINTTL(CP0_TCContext, TCState),
+ VMSTATE_UINTTL(CP0_TCSchedule, TCState),
+ VMSTATE_UINTTL(CP0_TCScheFBack, TCState),
+ VMSTATE_INT32(CP0_Debug_tcstatus, TCState),
+ VMSTATE_UINTTL(CP0_UserLocal, TCState),
+ VMSTATE_END_OF_LIST()
+};
+
+const VMStateDescription vmstate_tc = {
+ .name = "cpu/tc",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = vmstate_tc_fields
+};
+
+const VMStateDescription vmstate_inactive_tc = {
+ .name = "cpu/inactive_tc",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = vmstate_tc_fields
+};
+
+/* MVP state */
+
+const VMStateDescription vmstate_mvp = {
+ .name = "cpu/mvp",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_INT32(CP0_MVPControl, CPUMIPSMVPContext),
+ VMSTATE_INT32(CP0_MVPConf0, CPUMIPSMVPContext),
+ VMSTATE_INT32(CP0_MVPConf1, CPUMIPSMVPContext),
+ VMSTATE_END_OF_LIST()
}
+};
- /* Save inactive TC state */
- for (i = 0; i < MIPS_SHADOW_SET_MAX; i++)
- save_tc(f, &env->tcs[i]);
- for (i = 0; i < MIPS_FPU_MAX; i++)
- save_fpu(f, &env->fpus[i]);
-}
+/* TLB state */
-static void load_tc(QEMUFile *f, TCState *tc, int version_id)
+static int get_tlb(QEMUFile *f, void *pv, size_t size)
{
- int i;
-
- /* Save active TC */
- for(i = 0; i < 32; i++)
- qemu_get_betls(f, &tc->gpr[i]);
- qemu_get_betls(f, &tc->PC);
- for(i = 0; i < MIPS_DSP_ACC; i++)
- qemu_get_betls(f, &tc->HI[i]);
- for(i = 0; i < MIPS_DSP_ACC; i++)
- qemu_get_betls(f, &tc->LO[i]);
- for(i = 0; i < MIPS_DSP_ACC; i++)
- qemu_get_betls(f, &tc->ACX[i]);
- qemu_get_betls(f, &tc->DSPControl);
- qemu_get_sbe32s(f, &tc->CP0_TCStatus);
- qemu_get_sbe32s(f, &tc->CP0_TCBind);
- qemu_get_betls(f, &tc->CP0_TCHalt);
- qemu_get_betls(f, &tc->CP0_TCContext);
- qemu_get_betls(f, &tc->CP0_TCSchedule);
- qemu_get_betls(f, &tc->CP0_TCScheFBack);
- qemu_get_sbe32s(f, &tc->CP0_Debug_tcstatus);
- if (version_id >= 4) {
- qemu_get_betls(f, &tc->CP0_UserLocal);
- }
+ r4k_tlb_t *v = pv;
+ uint16_t flags;
+
+ qemu_get_betls(f, &v->VPN);
+ qemu_get_be32s(f, &v->PageMask);
+ qemu_get_8s(f, &v->ASID);
+ qemu_get_be16s(f, &flags);
+ v->G = (flags >> 10) & 1;
+ v->C0 = (flags >> 7) & 3;
+ v->C1 = (flags >> 4) & 3;
+ v->V0 = (flags >> 3) & 1;
+ v->V1 = (flags >> 2) & 1;
+ v->D0 = (flags >> 1) & 1;
+ v->D1 = (flags >> 0) & 1;
+ v->EHINV = (flags >> 15) & 1;
+ v->RI1 = (flags >> 14) & 1;
+ v->RI0 = (flags >> 13) & 1;
+ v->XI1 = (flags >> 12) & 1;
+ v->XI0 = (flags >> 11) & 1;
+ qemu_get_betls(f, &v->PFN[0]);
+ qemu_get_betls(f, &v->PFN[1]);
+
+ return 0;
}
-static void load_fpu(QEMUFile *f, CPUMIPSFPUContext *fpu)
+static void put_tlb(QEMUFile *f, void *pv, size_t size)
{
- int i;
-
- for(i = 0; i < 32; i++)
- qemu_get_be64s(f, &fpu->fpr[i].d);
- qemu_get_s8s(f, &fpu->fp_status.float_detect_tininess);
- qemu_get_s8s(f, &fpu->fp_status.float_rounding_mode);
- qemu_get_s8s(f, &fpu->fp_status.float_exception_flags);
- qemu_get_be32s(f, &fpu->fcr0);
- qemu_get_be32s(f, &fpu->fcr31);
+ r4k_tlb_t *v = pv;
+
+ uint16_t flags = ((v->EHINV << 15) |
+ (v->RI1 << 14) |
+ (v->RI0 << 13) |
+ (v->XI1 << 12) |
+ (v->XI0 << 11) |
+ (v->G << 10) |
+ (v->C0 << 7) |
+ (v->C1 << 4) |
+ (v->V0 << 3) |
+ (v->V1 << 2) |
+ (v->D0 << 1) |
+ (v->D1 << 0));
+
+ qemu_put_betls(f, &v->VPN);
+ qemu_put_be32s(f, &v->PageMask);
+ qemu_put_8s(f, &v->ASID);
+ qemu_put_be16s(f, &flags);
+ qemu_put_betls(f, &v->PFN[0]);
+ qemu_put_betls(f, &v->PFN[1]);
}
-int cpu_load(QEMUFile *f, void *opaque, int version_id)
-{
- CPUMIPSState *env = opaque;
- MIPSCPU *cpu = mips_env_get_cpu(env);
- int i;
+const VMStateInfo vmstate_info_tlb = {
+ .name = "tlb_entry",
+ .get = get_tlb,
+ .put = put_tlb,
+};
- if (version_id < 3) {
- return -EINVAL;
- }
+#define VMSTATE_TLB_ARRAY_V(_f, _s, _n, _v) \
+ VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_tlb, r4k_tlb_t)
- /* Load active TC */
- load_tc(f, &env->active_tc, version_id);
-
- /* Load active FPU */
- load_fpu(f, &env->active_fpu);
-
- /* Load MVP */
- qemu_get_sbe32s(f, &env->mvp->CP0_MVPControl);
- qemu_get_sbe32s(f, &env->mvp->CP0_MVPConf0);
- qemu_get_sbe32s(f, &env->mvp->CP0_MVPConf1);
-
- /* Load TLB */
- qemu_get_be32s(f, &env->tlb->nb_tlb);
- qemu_get_be32s(f, &env->tlb->tlb_in_use);
- for(i = 0; i < MIPS_TLB_MAX; i++) {
- uint16_t flags;
- uint8_t asid;
-
- qemu_get_betls(f, &env->tlb->mmu.r4k.tlb[i].VPN);
- qemu_get_be32s(f, &env->tlb->mmu.r4k.tlb[i].PageMask);
- qemu_get_8s(f, &asid);
- env->tlb->mmu.r4k.tlb[i].ASID = asid;
- qemu_get_be16s(f, &flags);
- env->tlb->mmu.r4k.tlb[i].G = (flags >> 10) & 1;
- env->tlb->mmu.r4k.tlb[i].C0 = (flags >> 7) & 3;
- env->tlb->mmu.r4k.tlb[i].C1 = (flags >> 4) & 3;
- env->tlb->mmu.r4k.tlb[i].V0 = (flags >> 3) & 1;
- env->tlb->mmu.r4k.tlb[i].V1 = (flags >> 2) & 1;
- env->tlb->mmu.r4k.tlb[i].D0 = (flags >> 1) & 1;
- env->tlb->mmu.r4k.tlb[i].D1 = (flags >> 0) & 1;
- if (version_id >= 5) {
- env->tlb->mmu.r4k.tlb[i].EHINV = (flags >> 15) & 1;
- env->tlb->mmu.r4k.tlb[i].RI1 = (flags >> 14) & 1;
- env->tlb->mmu.r4k.tlb[i].RI0 = (flags >> 13) & 1;
- env->tlb->mmu.r4k.tlb[i].XI1 = (flags >> 12) & 1;
- env->tlb->mmu.r4k.tlb[i].XI0 = (flags >> 11) & 1;
- }
- qemu_get_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[0]);
- qemu_get_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[1]);
- }
+#define VMSTATE_TLB_ARRAY(_f, _s, _n) \
+ VMSTATE_TLB_ARRAY_V(_f, _s, _n, 0)
- /* Load CPU metastate */
- qemu_get_be32s(f, &env->current_tc);
- qemu_get_be32s(f, &env->current_fpu);
- qemu_get_sbe32s(f, &env->error_code);
- qemu_get_be32s(f, &env->hflags);
- qemu_get_betls(f, &env->btarget);
- qemu_get_sbe32s(f, &i);
- env->bcond = i;
-
- /* Load remaining CP1 registers */
- qemu_get_sbe32s(f, &env->CP0_Index);
- qemu_get_sbe32s(f, &env->CP0_Random);
- qemu_get_sbe32s(f, &env->CP0_VPEControl);
- qemu_get_sbe32s(f, &env->CP0_VPEConf0);
- qemu_get_sbe32s(f, &env->CP0_VPEConf1);
- qemu_get_betls(f, &env->CP0_YQMask);
- qemu_get_betls(f, &env->CP0_VPESchedule);
- qemu_get_betls(f, &env->CP0_VPEScheFBack);
- qemu_get_sbe32s(f, &env->CP0_VPEOpt);
- qemu_get_betls(f, &env->CP0_EntryLo0);
- qemu_get_betls(f, &env->CP0_EntryLo1);
- qemu_get_betls(f, &env->CP0_Context);
- qemu_get_sbe32s(f, &env->CP0_PageMask);
- qemu_get_sbe32s(f, &env->CP0_PageGrain);
- qemu_get_sbe32s(f, &env->CP0_Wired);
- qemu_get_sbe32s(f, &env->CP0_SRSConf0);
- qemu_get_sbe32s(f, &env->CP0_SRSConf1);
- qemu_get_sbe32s(f, &env->CP0_SRSConf2);
- qemu_get_sbe32s(f, &env->CP0_SRSConf3);
- qemu_get_sbe32s(f, &env->CP0_SRSConf4);
- qemu_get_sbe32s(f, &env->CP0_HWREna);
- qemu_get_betls(f, &env->CP0_BadVAddr);
- if (version_id >= 5) {
- qemu_get_be32s(f, &env->CP0_BadInstr);
- qemu_get_be32s(f, &env->CP0_BadInstrP);
- }
- qemu_get_sbe32s(f, &env->CP0_Count);
- qemu_get_betls(f, &env->CP0_EntryHi);
- qemu_get_sbe32s(f, &env->CP0_Compare);
- qemu_get_sbe32s(f, &env->CP0_Status);
- qemu_get_sbe32s(f, &env->CP0_IntCtl);
- qemu_get_sbe32s(f, &env->CP0_SRSCtl);
- qemu_get_sbe32s(f, &env->CP0_SRSMap);
- qemu_get_sbe32s(f, &env->CP0_Cause);
- qemu_get_betls(f, &env->CP0_EPC);
- qemu_get_sbe32s(f, &env->CP0_PRid);
- qemu_get_sbe32s(f, &env->CP0_EBase);
- qemu_get_sbe32s(f, &env->CP0_Config0);
- qemu_get_sbe32s(f, &env->CP0_Config1);
- qemu_get_sbe32s(f, &env->CP0_Config2);
- qemu_get_sbe32s(f, &env->CP0_Config3);
- qemu_get_sbe32s(f, &env->CP0_Config6);
- qemu_get_sbe32s(f, &env->CP0_Config7);
- qemu_get_betls(f, &env->lladdr);
- for(i = 0; i < 8; i++)
- qemu_get_betls(f, &env->CP0_WatchLo[i]);
- for(i = 0; i < 8; i++)
- qemu_get_sbe32s(f, &env->CP0_WatchHi[i]);
- qemu_get_betls(f, &env->CP0_XContext);
- qemu_get_sbe32s(f, &env->CP0_Framemask);
- qemu_get_sbe32s(f, &env->CP0_Debug);
- qemu_get_betls(f, &env->CP0_DEPC);
- qemu_get_sbe32s(f, &env->CP0_Performance0);
- qemu_get_sbe32s(f, &env->CP0_TagLo);
- qemu_get_sbe32s(f, &env->CP0_DataLo);
- qemu_get_sbe32s(f, &env->CP0_TagHi);
- qemu_get_sbe32s(f, &env->CP0_DataHi);
- qemu_get_betls(f, &env->CP0_ErrorEPC);
- qemu_get_sbe32s(f, &env->CP0_DESAVE);
- if (version_id >= 5) {
- for (i = 0; i < MIPS_KSCRATCH_NUM; i++) {
- qemu_get_betls(f, &env->CP0_KScratch[i]);
- }
+const VMStateDescription vmstate_tlb = {
+ .name = "cpu/tlb",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(nb_tlb, CPUMIPSTLBContext),
+ VMSTATE_UINT32(tlb_in_use, CPUMIPSTLBContext),
+ VMSTATE_TLB_ARRAY(mmu.r4k.tlb, CPUMIPSTLBContext, MIPS_TLB_MAX),
+ VMSTATE_END_OF_LIST()
}
+};
- /* Load inactive TC state */
- for (i = 0; i < MIPS_SHADOW_SET_MAX; i++) {
- load_tc(f, &env->tcs[i], version_id);
- }
- for (i = 0; i < MIPS_FPU_MAX; i++)
- load_fpu(f, &env->fpus[i]);
+/* MIPS CPU state */
- /* XXX: ensure compatibility for halted bit ? */
- tlb_flush(CPU(cpu), 1);
- return 0;
-}
+const VMStateDescription vmstate_mips_cpu = {
+ .name = "cpu",
+ .version_id = 5,
+ .minimum_version_id = 5,
+ .fields = (VMStateField[]) {
+ /* Active TC */
+ VMSTATE_STRUCT(env.active_tc, MIPSCPU, 1, vmstate_tc, TCState),
+
+ /* Active FPU */
+ VMSTATE_STRUCT(env.active_fpu, MIPSCPU, 1, vmstate_fpu,
+ CPUMIPSFPUContext),
+
+ /* MVP */
+ VMSTATE_STRUCT_POINTER(env.mvp, MIPSCPU, vmstate_mvp,
+ CPUMIPSMVPContext),
+
+ /* TLB */
+ VMSTATE_STRUCT_POINTER(env.tlb, MIPSCPU, vmstate_tlb,
+ CPUMIPSTLBContext),
+
+ /* CPU metastate */
+ VMSTATE_UINT32(env.current_tc, MIPSCPU),
+ VMSTATE_UINT32(env.current_fpu, MIPSCPU),
+ VMSTATE_INT32(env.error_code, MIPSCPU),
+ VMSTATE_UINT32(env.hflags, MIPSCPU),
+ VMSTATE_UINTTL(env.btarget, MIPSCPU),
+ VMSTATE_UINTTL(env.bcond, MIPSCPU),
+
+ /* Remaining CP0 registers */
+ VMSTATE_INT32(env.CP0_Index, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Random, MIPSCPU),
+ VMSTATE_INT32(env.CP0_VPEControl, MIPSCPU),
+ VMSTATE_INT32(env.CP0_VPEConf0, MIPSCPU),
+ VMSTATE_INT32(env.CP0_VPEConf1, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_YQMask, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_VPESchedule, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_VPEScheFBack, MIPSCPU),
+ VMSTATE_INT32(env.CP0_VPEOpt, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_EntryLo0, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_EntryLo1, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_Context, MIPSCPU),
+ VMSTATE_INT32(env.CP0_PageMask, MIPSCPU),
+ VMSTATE_INT32(env.CP0_PageGrain, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Wired, MIPSCPU),
+ VMSTATE_INT32(env.CP0_SRSConf0, MIPSCPU),
+ VMSTATE_INT32(env.CP0_SRSConf1, MIPSCPU),
+ VMSTATE_INT32(env.CP0_SRSConf2, MIPSCPU),
+ VMSTATE_INT32(env.CP0_SRSConf3, MIPSCPU),
+ VMSTATE_INT32(env.CP0_SRSConf4, MIPSCPU),
+ VMSTATE_INT32(env.CP0_HWREna, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_BadVAddr, MIPSCPU),
+ VMSTATE_UINT32(env.CP0_BadInstr, MIPSCPU),
+ VMSTATE_UINT32(env.CP0_BadInstrP, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Count, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_EntryHi, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Compare, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Status, MIPSCPU),
+ VMSTATE_INT32(env.CP0_IntCtl, MIPSCPU),
+ VMSTATE_INT32(env.CP0_SRSCtl, MIPSCPU),
+ VMSTATE_INT32(env.CP0_SRSMap, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Cause, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_EPC, MIPSCPU),
+ VMSTATE_INT32(env.CP0_PRid, MIPSCPU),
+ VMSTATE_INT32(env.CP0_EBase, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Config0, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Config1, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Config2, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Config3, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Config6, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Config7, MIPSCPU),
+ VMSTATE_UINTTL(env.lladdr, MIPSCPU),
+ VMSTATE_UINTTL_ARRAY(env.CP0_WatchLo, MIPSCPU, 8),
+ VMSTATE_INT32_ARRAY(env.CP0_WatchHi, MIPSCPU, 8),
+ VMSTATE_UINTTL(env.CP0_XContext, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Framemask, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Debug, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_DEPC, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Performance0, MIPSCPU),
+ VMSTATE_INT32(env.CP0_TagLo, MIPSCPU),
+ VMSTATE_INT32(env.CP0_DataLo, MIPSCPU),
+ VMSTATE_INT32(env.CP0_TagHi, MIPSCPU),
+ VMSTATE_INT32(env.CP0_DataHi, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_ErrorEPC, MIPSCPU),
+ VMSTATE_INT32(env.CP0_DESAVE, MIPSCPU),
+ VMSTATE_UINTTL_ARRAY(env.CP0_KScratch, MIPSCPU, MIPS_KSCRATCH_NUM),
+
+ /* Inactive TC */
+ VMSTATE_STRUCT_ARRAY(env.tcs, MIPSCPU, MIPS_SHADOW_SET_MAX, 1,
+ vmstate_inactive_tc, TCState),
+ VMSTATE_STRUCT_ARRAY(env.fpus, MIPSCPU, MIPS_FPU_MAX, 1,
+ vmstate_inactive_fpu, CPUMIPSFPUContext),
+
+ VMSTATE_END_OF_LIST()
+ },
+};
--
2.1.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH v2 2/2] target-mips: add missing MSACSR and restore fp_status and hflags
2015-02-20 13:07 [Qemu-devel] [PATCH v2 0/2] target-mips: port MIPS CPU to VMState Leon Alrae
2015-02-20 13:07 ` [Qemu-devel] [PATCH v2 1/2] target-mips: replace cpu_save/cpu_load with VMStateDescription Leon Alrae
@ 2015-02-20 13:07 ` Leon Alrae
2015-02-20 15:38 ` Richard Henderson
1 sibling, 1 reply; 4+ messages in thread
From: Leon Alrae @ 2015-02-20 13:07 UTC (permalink / raw)
To: qemu-devel; +Cc: quintela, rth7680, macro, amit.shah, afaerber, aurelien
Save MSACSR state. Also remove fp_status, msa_fp_status, hflags and restore
them in post_load() from the architectural registers.
Float exception flags are not present in vmstate. Information they carry
is used only by softfloat caller who translates them into MIPS FCSR.Cause,
FCSR.Flags and then they are cleared. Therefore there is no need for saving
them in vmstate.
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
---
The introduced restore_fp_status() function is used only in the machine.c at
the moment, but there are many more places where this could be applied
instead of calling restore_rounding_mode() and restore_flush_mode() separately.
However I don't see this cleanup fitting into this patchset -- I'm leaving it
focused on vmstate rather than on a global cleanup which can come later.
---
target-mips/cpu.h | 17 +++++++++++++++++
target-mips/machine.c | 34 ++++++++++++++++++++++++++--------
target-mips/msa_helper.c | 12 +-----------
target-mips/translate_init.c | 10 ++--------
4 files changed, 46 insertions(+), 27 deletions(-)
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 59a2373..283a546 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -786,6 +786,23 @@ static inline void restore_flush_mode(CPUMIPSState *env)
&env->active_fpu.fp_status);
}
+static inline void restore_fp_status(CPUMIPSState *env)
+{
+ restore_rounding_mode(env);
+ restore_flush_mode(env);
+}
+
+static inline void restore_msa_fp_status(CPUMIPSState *env)
+{
+ float_status *status = &env->active_tc.msa_fp_status;
+ int rounding_mode = (env->active_tc.msacsr & MSACSR_RM_MASK) >> MSACSR_RM;
+ bool flush_to_zero = (env->active_tc.msacsr & MSACSR_FS_MASK) != 0;
+
+ set_float_rounding_mode(ieee_rm[rounding_mode], status);
+ set_flush_to_zero(flush_to_zero, status);
+ set_flush_inputs_to_zero(flush_to_zero, status);
+}
+
static inline void cpu_get_tb_cpu_state(CPUMIPSState *env, target_ulong *pc,
target_ulong *cs_base, int *flags)
{
diff --git a/target-mips/machine.c b/target-mips/machine.c
index 7fc4839..7d1fa32 100644
--- a/target-mips/machine.c
+++ b/target-mips/machine.c
@@ -2,19 +2,39 @@
#include "cpu.h"
+static int cpu_post_load(void *opaque, int version_id)
+{
+ MIPSCPU *cpu = opaque;
+ CPUMIPSState *env = &cpu->env;
+
+ restore_fp_status(env);
+ restore_msa_fp_status(env);
+ compute_hflags(env);
+
+ return 0;
+}
+
/* FPU state */
static int get_fpr(QEMUFile *f, void *pv, size_t size)
{
+ int i;
fpr_t *v = pv;
- qemu_get_be64s(f, &v->d);
+ /* Restore entire MSA vector register */
+ for (i = 0; i < MSA_WRLEN/64; i++) {
+ qemu_get_sbe64s(f, &v->wr.d[i]);
+ }
return 0;
}
static void put_fpr(QEMUFile *f, void *pv, size_t size)
{
+ int i;
fpr_t *v = pv;
- qemu_put_be64s(f, &v->d);
+ /* Save entire MSA vector register */
+ for (i = 0; i < MSA_WRLEN/64; i++) {
+ qemu_put_sbe64s(f, &v->wr.d[i]);
+ }
}
const VMStateInfo vmstate_info_fpr = {
@@ -31,9 +51,6 @@ const VMStateInfo vmstate_info_fpr = {
static VMStateField vmstate_fpu_fields[] = {
VMSTATE_FPR_ARRAY(fpr, CPUMIPSFPUContext, 32),
- VMSTATE_INT8(fp_status.float_detect_tininess, CPUMIPSFPUContext),
- VMSTATE_INT8(fp_status.float_rounding_mode, CPUMIPSFPUContext),
- VMSTATE_INT8(fp_status.float_exception_flags, CPUMIPSFPUContext),
VMSTATE_UINT32(fcr0, CPUMIPSFPUContext),
VMSTATE_UINT32(fcr31, CPUMIPSFPUContext),
VMSTATE_END_OF_LIST()
@@ -70,6 +87,7 @@ static VMStateField vmstate_tc_fields[] = {
VMSTATE_UINTTL(CP0_TCScheFBack, TCState),
VMSTATE_INT32(CP0_Debug_tcstatus, TCState),
VMSTATE_UINTTL(CP0_UserLocal, TCState),
+ VMSTATE_INT32(msacsr, TCState),
VMSTATE_END_OF_LIST()
};
@@ -183,8 +201,9 @@ const VMStateDescription vmstate_tlb = {
const VMStateDescription vmstate_mips_cpu = {
.name = "cpu",
- .version_id = 5,
- .minimum_version_id = 5,
+ .version_id = 6,
+ .minimum_version_id = 6,
+ .post_load = cpu_post_load,
.fields = (VMStateField[]) {
/* Active TC */
VMSTATE_STRUCT(env.active_tc, MIPSCPU, 1, vmstate_tc, TCState),
@@ -205,7 +224,6 @@ const VMStateDescription vmstate_mips_cpu = {
VMSTATE_UINT32(env.current_tc, MIPSCPU),
VMSTATE_UINT32(env.current_fpu, MIPSCPU),
VMSTATE_INT32(env.error_code, MIPSCPU),
- VMSTATE_UINT32(env.hflags, MIPSCPU),
VMSTATE_UINTTL(env.btarget, MIPSCPU),
VMSTATE_UINTTL(env.bcond, MIPSCPU),
diff --git a/target-mips/msa_helper.c b/target-mips/msa_helper.c
index c2160a6..26ffdc7 100644
--- a/target-mips/msa_helper.c
+++ b/target-mips/msa_helper.c
@@ -1348,17 +1348,7 @@ void helper_msa_ctcmsa(CPUMIPSState *env, target_ulong elm, uint32_t cd)
break;
case 1:
env->active_tc.msacsr = (int32_t)elm & MSACSR_MASK;
- /* set float_status rounding mode */
- set_float_rounding_mode(
- ieee_rm[(env->active_tc.msacsr & MSACSR_RM_MASK) >> MSACSR_RM],
- &env->active_tc.msa_fp_status);
- /* set float_status flush modes */
- set_flush_to_zero(
- (env->active_tc.msacsr & MSACSR_FS_MASK) != 0 ? 1 : 0,
- &env->active_tc.msa_fp_status);
- set_flush_inputs_to_zero(
- (env->active_tc.msacsr & MSACSR_FS_MASK) != 0 ? 1 : 0,
- &env->active_tc.msa_fp_status);
+ restore_msa_fp_status(env);
/* check exception */
if ((GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED)
& GET_FP_CAUSE(env->active_tc.msacsr)) {
diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index 9e8433a..85a65e7 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -835,6 +835,8 @@ static void msa_reset(CPUMIPSState *env)
- round to nearest / ties to even (RM bits are 0) */
env->active_tc.msacsr = 0;
+ restore_msa_fp_status(env);
+
/* tininess detected after rounding.*/
set_float_detect_tininess(float_tininess_after_rounding,
&env->active_tc.msa_fp_status);
@@ -842,14 +844,6 @@ static void msa_reset(CPUMIPSState *env)
/* clear float_status exception flags */
set_float_exception_flags(0, &env->active_tc.msa_fp_status);
- /* set float_status rounding mode */
- set_float_rounding_mode(float_round_nearest_even,
- &env->active_tc.msa_fp_status);
-
- /* set float_status flush modes */
- set_flush_to_zero(0, &env->active_tc.msa_fp_status);
- set_flush_inputs_to_zero(0, &env->active_tc.msa_fp_status);
-
/* clear float_status nan mode */
set_default_nan_mode(0, &env->active_tc.msa_fp_status);
}
--
2.1.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH v2 2/2] target-mips: add missing MSACSR and restore fp_status and hflags
2015-02-20 13:07 ` [Qemu-devel] [PATCH v2 2/2] target-mips: add missing MSACSR and restore fp_status and hflags Leon Alrae
@ 2015-02-20 15:38 ` Richard Henderson
0 siblings, 0 replies; 4+ messages in thread
From: Richard Henderson @ 2015-02-20 15:38 UTC (permalink / raw)
To: Leon Alrae, qemu-devel; +Cc: amit.shah, aurelien, afaerber, macro, quintela
On 02/20/2015 05:07 AM, Leon Alrae wrote:
> Save MSACSR state. Also remove fp_status, msa_fp_status, hflags and restore
> them in post_load() from the architectural registers.
> Float exception flags are not present in vmstate. Information they carry
> is used only by softfloat caller who translates them into MIPS FCSR.Cause,
> FCSR.Flags and then they are cleared. Therefore there is no need for saving
> them in vmstate.
>
> Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
r~
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2015-02-20 15:39 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-02-20 13:07 [Qemu-devel] [PATCH v2 0/2] target-mips: port MIPS CPU to VMState Leon Alrae
2015-02-20 13:07 ` [Qemu-devel] [PATCH v2 1/2] target-mips: replace cpu_save/cpu_load with VMStateDescription Leon Alrae
2015-02-20 13:07 ` [Qemu-devel] [PATCH v2 2/2] target-mips: add missing MSACSR and restore fp_status and hflags Leon Alrae
2015-02-20 15:38 ` Richard Henderson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).