/* * OpenRISC Machine * * Copyright (c) 2011-2012 Jia Liu * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . */ #include "qemu/osdep.h" #include "cpu.h" #include "migration/cpu.h" static const VMStateDescription vmstate_tlb_entry = { .name = "tlb_entry", .version_id = 1, .minimum_version_id = 1, .minimum_version_id_old = 1, .fields = (VMStateField[]) { VMSTATE_UINTTL(mr, OpenRISCTLBEntry), VMSTATE_UINTTL(tr, OpenRISCTLBEntry), VMSTATE_END_OF_LIST() } }; static const VMStateDescription vmstate_cpu_tlb = { .name = "cpu_tlb", .version_id = 2, .minimum_version_id = 2, .fields = (VMStateField[]) { VMSTATE_STRUCT_ARRAY(itlb, CPUOpenRISCTLBContext, TLB_SIZE, 0, vmstate_tlb_entry, OpenRISCTLBEntry), VMSTATE_STRUCT_ARRAY(dtlb, CPUOpenRISCTLBContext, TLB_SIZE, 0, vmstate_tlb_entry, OpenRISCTLBEntry), VMSTATE_END_OF_LIST() } }; static int get_sr(QEMUFile *f, void *opaque, size_t size, const VMStateField *field) { CPUOpenRISCState *env = opaque; cpu_set_sr(env, qemu_get_be32(f)); return 0; } static int put_sr(QEMUFile *f, void *opaque, size_t size, const VMStateField *field, QJSON *vmdesc) { CPUOpenRISCState *env = opaque; qemu_put_be32(f, cpu_get_sr(env)); return 0; } static const VMStateInfo vmstate_sr = { .name = "sr", .get = get_sr, .put = put_sr, }; static const VMStateDescription vmstate_env = { .name = "env", .version_id = 6, .minimum_version_id = 6, .fields = (VMStateField[]) { VMSTATE_UINTTL_2DARRAY(shadow_gpr, CPUOpenRISCState, 16, 32), VMSTATE_UINTTL(pc, CPUOpenRISCState), VMSTATE_UINTTL(ppc, CPUOpenRISCState), VMSTATE_UINTTL(jmp_pc, CPUOpenRISCState), VMSTATE_UINTTL(lock_addr, CPUOpenRISCState), VMSTATE_UINTTL(lock_value, CPUOpenRISCState), VMSTATE_UINTTL(epcr, CPUOpenRISCState), VMSTATE_UINTTL(eear, CPUOpenRISCState), /* Save the architecture value of the SR, not the internally expanded version. Since this architecture value does not exist in memory to be stored, this requires a but of hoop jumping. We want OFFSET=0 so that we effectively pass ENV to the helper functions, and we need to fill in the name by hand since there's no field of that name. */ { .name = "sr", .version_id = 0, .size = sizeof(uint32_t), .info = &vmstate_sr, .flags = VMS_SINGLE, .offset = 0 }, VMSTATE_UINT32(vr, CPUOpenRISCState), VMSTATE_UINT32(upr, CPUOpenRISCState), VMSTATE_UINT32(cpucfgr, CPUOpenRISCState), VMSTATE_UINT32(dmmucfgr, CPUOpenRISCState), VMSTATE_UINT32(immucfgr, CPUOpenRISCState), VMSTATE_UINT32(evbar, CPUOpenRISCState), VMSTATE_UINT32(pmr, CPUOpenRISCState), VMSTATE_UINT32(esr, CPUOpenRISCState), VMSTATE_UINT32(fpcsr, CPUOpenRISCState), VMSTATE_UINT64(mac, CPUOpenRISCState), VMSTATE_STRUCT(tlb, CPUOpenRISCState, 1, vmstate_cpu_tlb, CPUOpenRISCTLBContext), VMSTATE_TIMER_PTR(timer, CPUOpenRISCState), VMSTATE_UINT32(ttmr, CPUOpenRISCState), VMSTATE_UINT32(picmr, CPUOpenRISCState), VMSTATE_UINT32(picsr, CPUOpenRISCState), VMSTATE_END_OF_LIST() } }; static int cpu_post_load(void *opaque, int version_id) { OpenRISCCPU *cpu = opaque; CPUOpenRISCState *env = &cpu->env; /* Update env->fp_status to match env->fpcsr. */ cpu_set_fpcsr(env, env->fpcsr); return 0; } const VMStateDescription vmstate_openrisc_cpu = { .name = "cpu", .version_id = 1, .minimum_version_id = 1, .post_load = cpu_post_load, .fields = (VMStateField[]) { VMSTATE_CPU(), VMSTATE_STRUCT(env, OpenRISCCPU, 1, vmstate_env, CPUOpenRISCState), VMSTATE_END_OF_LIST() } };