From patchwork Wed Oct 26 20:16:36 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Juan Quintela X-Patchwork-Id: 121995 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id CD9221007D2 for ; Thu, 27 Oct 2011 07:32:45 +1100 (EST) Received: from localhost ([::1]:52281 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RJA9T-0004ig-E4 for incoming@patchwork.ozlabs.org; Wed, 26 Oct 2011 16:32:43 -0400 Received: from eggs.gnu.org ([140.186.70.92]:60353) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RJA9M-0004hN-LM for qemu-devel@nongnu.org; Wed, 26 Oct 2011 16:32:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RJA9J-0003Gr-8o for qemu-devel@nongnu.org; Wed, 26 Oct 2011 16:32:36 -0400 Received: from mx1.redhat.com ([209.132.183.28]:2164) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RJA9I-0003GX-Pv for qemu-devel@nongnu.org; Wed, 26 Oct 2011 16:32:33 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p9QKWFq3026478 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 26 Oct 2011 16:32:15 -0400 Received: from neno.neno (ovpn-116-28.ams2.redhat.com [10.36.116.28]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p9QKHulk018327; Wed, 26 Oct 2011 16:31:43 -0400 From: Juan Quintela To: qemu-devel@nongnu.org Date: Wed, 26 Oct 2011 22:16:36 +0200 Message-Id: <2496465c30a7fdcb4630be859494183af4152dd3.1319658750.git.quintela@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 209.132.183.28 Cc: Huacai Chen , Peter Maydell , Alexander Graf , Blue Swirl , Max Filippov , Michael Walle , Paul Brook , "Edgar E. Iglesias" , Aurelien Jarno , Richard Henderson Subject: [Qemu-devel] [PATCH 22/28] vmstate: port mips cpu X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Signed-off-by: Juan Quintela --- target-mips/cpu.h | 5 +- target-mips/machine.c | 465 +++++++++++++++++++------------------------------ 2 files changed, 182 insertions(+), 288 deletions(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 7810924..af9c384 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -37,6 +37,9 @@ struct r4k_tlb_t { uint_fast16_t D0:1; uint_fast16_t D1:1; target_ulong PFN[2]; + /* Fields needed as intermediate for vmstate */ + uint8_t asid_vmstate; + uint16_t flags_vmstate; }; #if !defined(CONFIG_USER_ONLY) @@ -507,8 +510,6 @@ void mips_cpu_list (FILE *f, fprintf_function cpu_fprintf); #define cpu_signal_handler cpu_mips_signal_handler #define cpu_list mips_cpu_list -#define CPU_SAVE_VERSION 4 - /* 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 134dbd5..988a5c9 100644 --- a/target-mips/machine.c +++ b/target-mips/machine.c @@ -3,304 +3,197 @@ #include "cpu.h" -static void save_tc(QEMUFile *f, TCState *tc) -{ - 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); -} - -static void save_fpu(QEMUFile *f, CPUMIPSFPUContext *fpu) -{ - 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); -} - -void cpu_save(QEMUFile *f, void *opaque) -{ - CPUState *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].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]); +static const VMStateDescription vmstate_tc = { + .name = "tc", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + 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_END_OF_LIST() } +}; + +static const VMStateDescription vmstate_fpu_reg = { + .name = "fpu_reg", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT64(d, fpr_t), + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription vmstate_fpu_context = { + .name = "fpu_context", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_STRUCT_ARRAY(fpr, CPUMIPSFPUContext, 32, 0, + vmstate_fpu_reg, fpr_t), + 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() + } +}; - /* 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); - qemu_put_betls(f, &env->bcond); - - /* 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_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); - - /* 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]); -} - -static void load_tc(QEMUFile *f, TCState *tc) +static void tlb_pre_save(void *opaque) { - 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); + r4k_tlb_t *tlb = opaque; + + tlb->asid_vmstate = tlb->ASID; + tlb->flags_vmstate = ((tlb->G << 10) | + (tlb->C0 << 7) | + (tlb->C1 << 4) | + (tlb->V0 << 3) | + (tlb->V1 << 2) | + (tlb->D0 << 1) | + (tlb->D1 << 0)); } -static void load_fpu(QEMUFile *f, CPUMIPSFPUContext *fpu) +static int tlb_post_load(void *opaque, int version_id) { - 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 *tlb = opaque; + + tlb->ASID = tlb->asid_vmstate; + tlb->G = (tlb->flags_vmstate >> 10) & 1; + tlb->C0 = (tlb->flags_vmstate >> 7) & 3; + tlb->C1 = (tlb->flags_vmstate >> 4) & 3; + tlb->V0 = (tlb->flags_vmstate >> 3) & 1; + tlb->V1 = (tlb->flags_vmstate >> 2) & 1; + tlb->D0 = (tlb->flags_vmstate >> 1) & 1; + tlb->D1 = (tlb->flags_vmstate >> 0) & 1; + return 0; } -int cpu_load(QEMUFile *f, void *opaque, int version_id) -{ - CPUState *env = opaque; - int i; - - if (version_id != 4) { - return -EINVAL; - } - /* Load active TC */ - load_tc(f, &env->active_tc); - - /* 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; - qemu_get_betls(f, &env->tlb.mmu.r4k.tlb[i].PFN[0]); - qemu_get_betls(f, &env->tlb.mmu.r4k.tlb[i].PFN[1]); +static const VMStateDescription vmstate_tlb = { + .name = "tlb", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .pre_save = tlb_pre_save, + .post_load = tlb_post_load, + .fields = (VMStateField[]) { + VMSTATE_UINTTL(VPN, r4k_tlb_t), + VMSTATE_UINT32(PageMask, r4k_tlb_t), + VMSTATE_UINT8(asid_vmstate, r4k_tlb_t), + VMSTATE_UINT16(flags_vmstate, r4k_tlb_t), + VMSTATE_UINTTL_ARRAY(PFN, r4k_tlb_t, 2), + VMSTATE_END_OF_LIST() } +}; - /* 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_betls(f, &env->bcond); - - /* 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); - 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); - - /* Load inactive TC state */ - for (i = 0; i < MIPS_SHADOW_SET_MAX; i++) - load_tc(f, &env->tcs[i]); - for (i = 0; i < MIPS_FPU_MAX; i++) - load_fpu(f, &env->fpus[i]); +static int cpu_post_load(void *opaque, int version_id) +{ + CPUState *env = opaque; /* XXX: ensure compatiblity for halted bit ? */ tlb_flush(env, 1); return 0; } + +const VMStateDescription vmstate_cpu = { + .name = "cpu", + .version_id = 4, + .minimum_version_id = 4, + .minimum_version_id_old = 4, + .post_load = cpu_post_load, + .fields = (VMStateField[]) { + VMSTATE_STRUCT(active_tc, CPUState, 0, vmstate_tc, TCState), + VMSTATE_STRUCT(active_fpu, CPUState, 0, vmstate_fpu_context, + CPUMIPSFPUContext), + /* Save MVP */ + VMSTATE_INT32(mvp.CP0_MVPControl, CPUState), + VMSTATE_INT32(mvp.CP0_MVPConf0, CPUState), + VMSTATE_INT32(mvp.CP0_MVPConf1, CPUState), + /* Save TLB */ + VMSTATE_UINT32(tlb.nb_tlb, CPUState), + VMSTATE_UINT32(tlb.tlb_in_use, CPUState), + VMSTATE_STRUCT_ARRAY(tlb.mmu.r4k.tlb, CPUState, MIPS_TLB_MAX, 0, + vmstate_tlb, r4k_tlb_t), + /* Save CPU metastate */ + VMSTATE_UINT32(current_tc, CPUState), + VMSTATE_UINT32(current_fpu, CPUState), + VMSTATE_INT32(error_code, CPUState), + VMSTATE_UINT32(hflags, CPUState), + VMSTATE_UINTTL(btarget, CPUState), + VMSTATE_UINTTL(bcond, CPUState), + /* Save remaining CP1 registers */ + VMSTATE_INT32(CP0_Index, CPUState), + VMSTATE_INT32(CP0_Random, CPUState), + VMSTATE_INT32(CP0_VPEControl, CPUState), + VMSTATE_INT32(CP0_VPEConf0, CPUState), + VMSTATE_INT32(CP0_VPEConf1, CPUState), + VMSTATE_UINTTL(CP0_YQMask, CPUState), + VMSTATE_UINTTL(CP0_VPESchedule, CPUState), + VMSTATE_UINTTL(CP0_VPEScheFBack, CPUState), + VMSTATE_INT32(CP0_VPEOpt, CPUState), + VMSTATE_UINTTL(CP0_EntryLo0, CPUState), + VMSTATE_UINTTL(CP0_EntryLo1, CPUState), + VMSTATE_UINTTL(CP0_Context, CPUState), + VMSTATE_INT32(CP0_PageMask, CPUState), + VMSTATE_INT32(CP0_PageGrain, CPUState), + VMSTATE_INT32(CP0_Wired, CPUState), + VMSTATE_INT32(CP0_SRSConf0, CPUState), + VMSTATE_INT32(CP0_SRSConf1, CPUState), + VMSTATE_INT32(CP0_SRSConf2, CPUState), + VMSTATE_INT32(CP0_SRSConf3, CPUState), + VMSTATE_INT32(CP0_SRSConf4, CPUState), + VMSTATE_INT32(CP0_HWREna, CPUState), + VMSTATE_UINTTL(CP0_BadVAddr, CPUState), + VMSTATE_INT32(CP0_Count, CPUState), + VMSTATE_UINTTL(CP0_EntryHi, CPUState), + VMSTATE_INT32(CP0_Compare, CPUState), + VMSTATE_INT32(CP0_Status, CPUState), + VMSTATE_INT32(CP0_IntCtl, CPUState), + VMSTATE_INT32(CP0_SRSCtl, CPUState), + VMSTATE_INT32(CP0_SRSMap, CPUState), + VMSTATE_INT32(CP0_Cause, CPUState), + VMSTATE_UINTTL(CP0_EPC, CPUState), + VMSTATE_INT32(CP0_PRid, CPUState), + VMSTATE_INT32(CP0_EBase, CPUState), + VMSTATE_INT32(CP0_Config0, CPUState), + VMSTATE_INT32(CP0_Config1, CPUState), + VMSTATE_INT32(CP0_Config2, CPUState), + VMSTATE_INT32(CP0_Config3, CPUState), + VMSTATE_INT32(CP0_Config6, CPUState), + VMSTATE_INT32(CP0_Config7, CPUState), + VMSTATE_UINTTL(lladdr, CPUState), + VMSTATE_UINTTL_ARRAY(CP0_WatchLo, CPUState, 8), + VMSTATE_INT32_ARRAY(CP0_WatchHi, CPUState, 8), + VMSTATE_UINTTL(CP0_XContext, CPUState), + VMSTATE_INT32(CP0_Framemask, CPUState), + VMSTATE_INT32(CP0_Debug, CPUState), + VMSTATE_UINTTL(CP0_DEPC, CPUState), + VMSTATE_INT32(CP0_Performance0, CPUState), + VMSTATE_INT32(CP0_TagLo, CPUState), + VMSTATE_INT32(CP0_DataLo, CPUState), + VMSTATE_INT32(CP0_TagHi, CPUState), + VMSTATE_INT32(CP0_DataHi, CPUState), + VMSTATE_UINTTL(CP0_ErrorEPC, CPUState), + VMSTATE_INT32(CP0_DESAVE, CPUState), + /* Save inactive TC state */ + VMSTATE_STRUCT_ARRAY(tcs, CPUState, MIPS_SHADOW_SET_MAX, 0, + vmstate_tc, TCState), + VMSTATE_STRUCT_ARRAY(fpus, CPUState, MIPS_FPU_MAX, 0, + vmstate_fpu_context, CPUMIPSFPUContext), + VMSTATE_END_OF_LIST() + }, +};