From: Philippe Mathieu-Daudé Date: Tue, 13 Apr 2021 08:31:44 +0000 (+0200) Subject: target/mips: Move sysemu specific files under sysemu/ subfolder X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=85d8da3fea0c4ff38bbe759febfc2d2299b33ccd;p=qemu.git target/mips: Move sysemu specific files under sysemu/ subfolder Move sysemu-specific files under the new sysemu/ subfolder and adapt the Meson machinery. Update the KVM MIPS entry in MAINTAINERS. Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20210428170410.479308-17-f4bug@amsat.org> --- diff --git a/MAINTAINERS b/MAINTAINERS index 4c05ff8bba..8e4e329810 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -404,7 +404,8 @@ F: target/arm/kvm.c MIPS KVM CPUs M: Huacai Chen S: Odd Fixes -F: target/mips/kvm.c +F: target/mips/kvm* +F: target/mips/sysemu/ PPC KVM CPUs M: David Gibson diff --git a/target/mips/addr.c b/target/mips/addr.c deleted file mode 100644 index 86f1c129c9..0000000000 --- a/target/mips/addr.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * QEMU MIPS address translation support - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "qemu/osdep.h" -#include "cpu.h" - -static int mips_um_ksegs; - -uint64_t cpu_mips_kseg0_to_phys(void *opaque, uint64_t addr) -{ - return addr & 0x1fffffffll; -} - -uint64_t cpu_mips_phys_to_kseg0(void *opaque, uint64_t addr) -{ - return addr | ~0x7fffffffll; -} - -uint64_t cpu_mips_kvm_um_phys_to_kseg0(void *opaque, uint64_t addr) -{ - return addr | 0x40000000ll; -} - -uint64_t cpu_mips_kseg1_to_phys(void *opaque, uint64_t addr) -{ - return addr & 0x1fffffffll; -} - -uint64_t cpu_mips_phys_to_kseg1(void *opaque, uint64_t addr) -{ - return (addr & 0x1fffffffll) | 0xffffffffa0000000ll; -} - -bool mips_um_ksegs_enabled(void) -{ - return mips_um_ksegs; -} - -void mips_um_ksegs_enable(void) -{ - mips_um_ksegs = 1; -} diff --git a/target/mips/cp0_timer.c b/target/mips/cp0_timer.c deleted file mode 100644 index 70de95d338..0000000000 --- a/target/mips/cp0_timer.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * QEMU MIPS timer support - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "qemu/osdep.h" -#include "hw/irq.h" -#include "hw/mips/cpudevs.h" -#include "qemu/timer.h" -#include "sysemu/kvm.h" -#include "internal.h" - -/* MIPS R4K timer */ -static void cpu_mips_timer_update(CPUMIPSState *env) -{ - uint64_t now_ns, next_ns; - uint32_t wait; - - now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - wait = env->CP0_Compare - env->CP0_Count - - (uint32_t)(now_ns / env->cp0_count_ns); - next_ns = now_ns + (uint64_t)wait * env->cp0_count_ns; - timer_mod(env->timer, next_ns); -} - -/* Expire the timer. */ -static void cpu_mips_timer_expire(CPUMIPSState *env) -{ - cpu_mips_timer_update(env); - if (env->insn_flags & ISA_MIPS_R2) { - env->CP0_Cause |= 1 << CP0Ca_TI; - } - qemu_irq_raise(env->irq[(env->CP0_IntCtl >> CP0IntCtl_IPTI) & 0x7]); -} - -uint32_t cpu_mips_get_count(CPUMIPSState *env) -{ - if (env->CP0_Cause & (1 << CP0Ca_DC)) { - return env->CP0_Count; - } else { - uint64_t now_ns; - - now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - if (timer_pending(env->timer) - && timer_expired(env->timer, now_ns)) { - /* The timer has already expired. */ - cpu_mips_timer_expire(env); - } - - return env->CP0_Count + (uint32_t)(now_ns / env->cp0_count_ns); - } -} - -void cpu_mips_store_count(CPUMIPSState *env, uint32_t count) -{ - /* - * This gets called from cpu_state_reset(), potentially before timer init. - * So env->timer may be NULL, which is also the case with KVM enabled so - * treat timer as disabled in that case. - */ - if (env->CP0_Cause & (1 << CP0Ca_DC) || !env->timer) { - env->CP0_Count = count; - } else { - /* Store new count register */ - env->CP0_Count = count - - (uint32_t)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / - env->cp0_count_ns); - /* Update timer timer */ - cpu_mips_timer_update(env); - } -} - -void cpu_mips_store_compare(CPUMIPSState *env, uint32_t value) -{ - env->CP0_Compare = value; - if (!(env->CP0_Cause & (1 << CP0Ca_DC))) { - cpu_mips_timer_update(env); - } - if (env->insn_flags & ISA_MIPS_R2) { - env->CP0_Cause &= ~(1 << CP0Ca_TI); - } - qemu_irq_lower(env->irq[(env->CP0_IntCtl >> CP0IntCtl_IPTI) & 0x7]); -} - -void cpu_mips_start_count(CPUMIPSState *env) -{ - cpu_mips_store_count(env, env->CP0_Count); -} - -void cpu_mips_stop_count(CPUMIPSState *env) -{ - /* Store the current value */ - env->CP0_Count += (uint32_t)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / - env->cp0_count_ns); -} - -static void mips_timer_cb(void *opaque) -{ - CPUMIPSState *env; - - env = opaque; - - if (env->CP0_Cause & (1 << CP0Ca_DC)) { - return; - } - - /* - * ??? This callback should occur when the counter is exactly equal to - * the comparator value. Offset the count by one to avoid immediately - * retriggering the callback before any virtual time has passed. - */ - env->CP0_Count++; - cpu_mips_timer_expire(env); - env->CP0_Count--; -} - -void cpu_mips_clock_init(MIPSCPU *cpu) -{ - CPUMIPSState *env = &cpu->env; - - /* - * If we're in KVM mode, don't create the periodic timer, that is handled in - * kernel. - */ - if (!kvm_enabled()) { - env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &mips_timer_cb, env); - } -} diff --git a/target/mips/machine.c b/target/mips/machine.c deleted file mode 100644 index 80d37f9c2f..0000000000 --- a/target/mips/machine.c +++ /dev/null @@ -1,333 +0,0 @@ -#include "qemu/osdep.h" -#include "cpu.h" -#include "internal.h" -#include "migration/cpu.h" -#include "fpu_helper.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); - restore_pamask(env); - - return 0; -} - -/* FPU state */ - -static int get_fpr(QEMUFile *f, void *pv, size_t size, - const VMStateField *field) -{ - int i; - fpr_t *v = pv; - /* Restore entire MSA vector register */ - for (i = 0; i < MSA_WRLEN / 64; i++) { - qemu_get_sbe64s(f, &v->wr.d[i]); - } - return 0; -} - -static int put_fpr(QEMUFile *f, void *pv, size_t size, - const VMStateField *field, JSONWriter *vmdesc) -{ - int i; - fpr_t *v = pv; - /* Save entire MSA vector register */ - for (i = 0; i < MSA_WRLEN / 64; i++) { - qemu_put_sbe64s(f, &v->wr.d[i]); - } - - return 0; -} - -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_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 -}; - -/* TC state */ - -static VMStateField vmstate_tc_fields[] = { - VMSTATE_UINTTL_ARRAY(gpr, TCState, 32), -#if defined(TARGET_MIPS64) - VMSTATE_UINT64_ARRAY(gpr_hi, TCState, 32), -#endif /* TARGET_MIPS64 */ - 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_INT32(msacsr, TCState), - VMSTATE_UINTTL_ARRAY(mxu_gpr, TCState, NUMBER_OF_MXU_REGISTERS - 1), - VMSTATE_UINTTL(mxu_cr, TCState), - VMSTATE_END_OF_LIST() -}; - -const VMStateDescription vmstate_tc = { - .name = "cpu/tc", - .version_id = 2, - .minimum_version_id = 2, - .fields = vmstate_tc_fields -}; - -const VMStateDescription vmstate_inactive_tc = { - .name = "cpu/inactive_tc", - .version_id = 2, - .minimum_version_id = 2, - .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() - } -}; - -/* TLB state */ - -static int get_tlb(QEMUFile *f, void *pv, size_t size, - const VMStateField *field) -{ - r4k_tlb_t *v = pv; - uint16_t flags; - - qemu_get_betls(f, &v->VPN); - qemu_get_be32s(f, &v->PageMask); - qemu_get_be16s(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_be64s(f, &v->PFN[0]); - qemu_get_be64s(f, &v->PFN[1]); - - return 0; -} - -static int put_tlb(QEMUFile *f, void *pv, size_t size, - const VMStateField *field, JSONWriter *vmdesc) -{ - r4k_tlb_t *v = pv; - - uint16_t asid = v->ASID; - 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_be16s(f, &asid); - qemu_put_be16s(f, &flags); - qemu_put_be64s(f, &v->PFN[0]); - qemu_put_be64s(f, &v->PFN[1]); - - return 0; -} - -const VMStateInfo vmstate_info_tlb = { - .name = "tlb_entry", - .get = get_tlb, - .put = put_tlb, -}; - -#define VMSTATE_TLB_ARRAY_V(_f, _s, _n, _v) \ - VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_tlb, r4k_tlb_t) - -#define VMSTATE_TLB_ARRAY(_f, _s, _n) \ - VMSTATE_TLB_ARRAY_V(_f, _s, _n, 0) - -const VMStateDescription vmstate_tlb = { - .name = "cpu/tlb", - .version_id = 2, - .minimum_version_id = 2, - .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() - } -}; - -/* MIPS CPU state */ - -const VMStateDescription vmstate_mips_cpu = { - .name = "cpu", - .version_id = 21, - .minimum_version_id = 21, - .post_load = cpu_post_load, - .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_UINTTL(env.btarget, MIPSCPU), - VMSTATE_UINTTL(env.bcond, MIPSCPU), - - /* Remaining CP0 registers */ - VMSTATE_INT32(env.CP0_Index, MIPSCPU), - VMSTATE_INT32(env.CP0_VPControl, 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_UINT64(env.CP0_EntryLo0, MIPSCPU), - VMSTATE_UINT64(env.CP0_EntryLo1, MIPSCPU), - VMSTATE_INT32(env.CP0_GlobalNumber, MIPSCPU), - VMSTATE_UINTTL(env.CP0_Context, MIPSCPU), - VMSTATE_INT32(env.CP0_MemoryMapID, MIPSCPU), - VMSTATE_INT32(env.CP0_PageMask, MIPSCPU), - VMSTATE_INT32(env.CP0_PageGrain, MIPSCPU), - VMSTATE_UINTTL(env.CP0_SegCtl0, MIPSCPU), - VMSTATE_UINTTL(env.CP0_SegCtl1, MIPSCPU), - VMSTATE_UINTTL(env.CP0_SegCtl2, MIPSCPU), - VMSTATE_UINTTL(env.CP0_PWBase, MIPSCPU), - VMSTATE_UINTTL(env.CP0_PWField, MIPSCPU), - VMSTATE_UINTTL(env.CP0_PWSize, MIPSCPU), - VMSTATE_INT32(env.CP0_Wired, MIPSCPU), - VMSTATE_INT32(env.CP0_PWCtl, 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_UINT32(env.CP0_BadInstrX, MIPSCPU), - VMSTATE_INT32(env.CP0_Count, MIPSCPU), - VMSTATE_UINT32(env.CP0_SAARI, MIPSCPU), - VMSTATE_UINT64_ARRAY(env.CP0_SAAR, MIPSCPU, 2), - 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_UINTTL(env.CP0_EBase, MIPSCPU), - VMSTATE_UINTTL(env.CP0_CMGCRBase, 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_Config4, MIPSCPU), - VMSTATE_INT32(env.CP0_Config5, MIPSCPU), - VMSTATE_INT32(env.CP0_Config6, MIPSCPU), - VMSTATE_INT32(env.CP0_Config7, MIPSCPU), - VMSTATE_UINT64(env.CP0_LLAddr, MIPSCPU), - VMSTATE_UINT64_ARRAY(env.CP0_MAAR, MIPSCPU, MIPS_MAAR_MAX), - VMSTATE_INT32(env.CP0_MAARI, MIPSCPU), - VMSTATE_UINTTL(env.lladdr, MIPSCPU), - VMSTATE_UINTTL_ARRAY(env.CP0_WatchLo, MIPSCPU, 8), - VMSTATE_UINT64_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_ErrCtl, MIPSCPU), - VMSTATE_UINT64(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() - }, -}; diff --git a/target/mips/meson.build b/target/mips/meson.build index ca3cc62cf7..9a507937ec 100644 --- a/target/mips/meson.build +++ b/target/mips/meson.build @@ -7,6 +7,7 @@ gen = [ ] mips_user_ss = ss.source_set() +mips_softmmu_ss = ss.source_set() mips_ss = ss.source_set() mips_ss.add(files( 'cpu.c', @@ -14,6 +15,11 @@ mips_ss.add(files( 'gdbstub.c', 'msa.c', )) + +if have_system + subdir('sysemu') +endif + mips_tcg_ss = ss.source_set() mips_tcg_ss.add(gen) mips_tcg_ss.add(files( @@ -41,12 +47,6 @@ endif mips_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c')) -mips_softmmu_ss = ss.source_set() -mips_softmmu_ss.add(files( - 'addr.c', - 'cp0_timer.c', - 'machine.c', -)) mips_softmmu_ss.add(when: 'CONFIG_TCG', if_true: files( 'cp0_helper.c', 'mips-semi.c', diff --git a/target/mips/sysemu/addr.c b/target/mips/sysemu/addr.c new file mode 100644 index 0000000000..86f1c129c9 --- /dev/null +++ b/target/mips/sysemu/addr.c @@ -0,0 +1,61 @@ +/* + * QEMU MIPS address translation support + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" +#include "cpu.h" + +static int mips_um_ksegs; + +uint64_t cpu_mips_kseg0_to_phys(void *opaque, uint64_t addr) +{ + return addr & 0x1fffffffll; +} + +uint64_t cpu_mips_phys_to_kseg0(void *opaque, uint64_t addr) +{ + return addr | ~0x7fffffffll; +} + +uint64_t cpu_mips_kvm_um_phys_to_kseg0(void *opaque, uint64_t addr) +{ + return addr | 0x40000000ll; +} + +uint64_t cpu_mips_kseg1_to_phys(void *opaque, uint64_t addr) +{ + return addr & 0x1fffffffll; +} + +uint64_t cpu_mips_phys_to_kseg1(void *opaque, uint64_t addr) +{ + return (addr & 0x1fffffffll) | 0xffffffffa0000000ll; +} + +bool mips_um_ksegs_enabled(void) +{ + return mips_um_ksegs; +} + +void mips_um_ksegs_enable(void) +{ + mips_um_ksegs = 1; +} diff --git a/target/mips/sysemu/cp0_timer.c b/target/mips/sysemu/cp0_timer.c new file mode 100644 index 0000000000..70de95d338 --- /dev/null +++ b/target/mips/sysemu/cp0_timer.c @@ -0,0 +1,145 @@ +/* + * QEMU MIPS timer support + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" +#include "hw/irq.h" +#include "hw/mips/cpudevs.h" +#include "qemu/timer.h" +#include "sysemu/kvm.h" +#include "internal.h" + +/* MIPS R4K timer */ +static void cpu_mips_timer_update(CPUMIPSState *env) +{ + uint64_t now_ns, next_ns; + uint32_t wait; + + now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + wait = env->CP0_Compare - env->CP0_Count - + (uint32_t)(now_ns / env->cp0_count_ns); + next_ns = now_ns + (uint64_t)wait * env->cp0_count_ns; + timer_mod(env->timer, next_ns); +} + +/* Expire the timer. */ +static void cpu_mips_timer_expire(CPUMIPSState *env) +{ + cpu_mips_timer_update(env); + if (env->insn_flags & ISA_MIPS_R2) { + env->CP0_Cause |= 1 << CP0Ca_TI; + } + qemu_irq_raise(env->irq[(env->CP0_IntCtl >> CP0IntCtl_IPTI) & 0x7]); +} + +uint32_t cpu_mips_get_count(CPUMIPSState *env) +{ + if (env->CP0_Cause & (1 << CP0Ca_DC)) { + return env->CP0_Count; + } else { + uint64_t now_ns; + + now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + if (timer_pending(env->timer) + && timer_expired(env->timer, now_ns)) { + /* The timer has already expired. */ + cpu_mips_timer_expire(env); + } + + return env->CP0_Count + (uint32_t)(now_ns / env->cp0_count_ns); + } +} + +void cpu_mips_store_count(CPUMIPSState *env, uint32_t count) +{ + /* + * This gets called from cpu_state_reset(), potentially before timer init. + * So env->timer may be NULL, which is also the case with KVM enabled so + * treat timer as disabled in that case. + */ + if (env->CP0_Cause & (1 << CP0Ca_DC) || !env->timer) { + env->CP0_Count = count; + } else { + /* Store new count register */ + env->CP0_Count = count - + (uint32_t)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / + env->cp0_count_ns); + /* Update timer timer */ + cpu_mips_timer_update(env); + } +} + +void cpu_mips_store_compare(CPUMIPSState *env, uint32_t value) +{ + env->CP0_Compare = value; + if (!(env->CP0_Cause & (1 << CP0Ca_DC))) { + cpu_mips_timer_update(env); + } + if (env->insn_flags & ISA_MIPS_R2) { + env->CP0_Cause &= ~(1 << CP0Ca_TI); + } + qemu_irq_lower(env->irq[(env->CP0_IntCtl >> CP0IntCtl_IPTI) & 0x7]); +} + +void cpu_mips_start_count(CPUMIPSState *env) +{ + cpu_mips_store_count(env, env->CP0_Count); +} + +void cpu_mips_stop_count(CPUMIPSState *env) +{ + /* Store the current value */ + env->CP0_Count += (uint32_t)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / + env->cp0_count_ns); +} + +static void mips_timer_cb(void *opaque) +{ + CPUMIPSState *env; + + env = opaque; + + if (env->CP0_Cause & (1 << CP0Ca_DC)) { + return; + } + + /* + * ??? This callback should occur when the counter is exactly equal to + * the comparator value. Offset the count by one to avoid immediately + * retriggering the callback before any virtual time has passed. + */ + env->CP0_Count++; + cpu_mips_timer_expire(env); + env->CP0_Count--; +} + +void cpu_mips_clock_init(MIPSCPU *cpu) +{ + CPUMIPSState *env = &cpu->env; + + /* + * If we're in KVM mode, don't create the periodic timer, that is handled in + * kernel. + */ + if (!kvm_enabled()) { + env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &mips_timer_cb, env); + } +} diff --git a/target/mips/sysemu/machine.c b/target/mips/sysemu/machine.c new file mode 100644 index 0000000000..80d37f9c2f --- /dev/null +++ b/target/mips/sysemu/machine.c @@ -0,0 +1,333 @@ +#include "qemu/osdep.h" +#include "cpu.h" +#include "internal.h" +#include "migration/cpu.h" +#include "fpu_helper.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); + restore_pamask(env); + + return 0; +} + +/* FPU state */ + +static int get_fpr(QEMUFile *f, void *pv, size_t size, + const VMStateField *field) +{ + int i; + fpr_t *v = pv; + /* Restore entire MSA vector register */ + for (i = 0; i < MSA_WRLEN / 64; i++) { + qemu_get_sbe64s(f, &v->wr.d[i]); + } + return 0; +} + +static int put_fpr(QEMUFile *f, void *pv, size_t size, + const VMStateField *field, JSONWriter *vmdesc) +{ + int i; + fpr_t *v = pv; + /* Save entire MSA vector register */ + for (i = 0; i < MSA_WRLEN / 64; i++) { + qemu_put_sbe64s(f, &v->wr.d[i]); + } + + return 0; +} + +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_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 +}; + +/* TC state */ + +static VMStateField vmstate_tc_fields[] = { + VMSTATE_UINTTL_ARRAY(gpr, TCState, 32), +#if defined(TARGET_MIPS64) + VMSTATE_UINT64_ARRAY(gpr_hi, TCState, 32), +#endif /* TARGET_MIPS64 */ + 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_INT32(msacsr, TCState), + VMSTATE_UINTTL_ARRAY(mxu_gpr, TCState, NUMBER_OF_MXU_REGISTERS - 1), + VMSTATE_UINTTL(mxu_cr, TCState), + VMSTATE_END_OF_LIST() +}; + +const VMStateDescription vmstate_tc = { + .name = "cpu/tc", + .version_id = 2, + .minimum_version_id = 2, + .fields = vmstate_tc_fields +}; + +const VMStateDescription vmstate_inactive_tc = { + .name = "cpu/inactive_tc", + .version_id = 2, + .minimum_version_id = 2, + .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() + } +}; + +/* TLB state */ + +static int get_tlb(QEMUFile *f, void *pv, size_t size, + const VMStateField *field) +{ + r4k_tlb_t *v = pv; + uint16_t flags; + + qemu_get_betls(f, &v->VPN); + qemu_get_be32s(f, &v->PageMask); + qemu_get_be16s(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_be64s(f, &v->PFN[0]); + qemu_get_be64s(f, &v->PFN[1]); + + return 0; +} + +static int put_tlb(QEMUFile *f, void *pv, size_t size, + const VMStateField *field, JSONWriter *vmdesc) +{ + r4k_tlb_t *v = pv; + + uint16_t asid = v->ASID; + 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_be16s(f, &asid); + qemu_put_be16s(f, &flags); + qemu_put_be64s(f, &v->PFN[0]); + qemu_put_be64s(f, &v->PFN[1]); + + return 0; +} + +const VMStateInfo vmstate_info_tlb = { + .name = "tlb_entry", + .get = get_tlb, + .put = put_tlb, +}; + +#define VMSTATE_TLB_ARRAY_V(_f, _s, _n, _v) \ + VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_tlb, r4k_tlb_t) + +#define VMSTATE_TLB_ARRAY(_f, _s, _n) \ + VMSTATE_TLB_ARRAY_V(_f, _s, _n, 0) + +const VMStateDescription vmstate_tlb = { + .name = "cpu/tlb", + .version_id = 2, + .minimum_version_id = 2, + .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() + } +}; + +/* MIPS CPU state */ + +const VMStateDescription vmstate_mips_cpu = { + .name = "cpu", + .version_id = 21, + .minimum_version_id = 21, + .post_load = cpu_post_load, + .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_UINTTL(env.btarget, MIPSCPU), + VMSTATE_UINTTL(env.bcond, MIPSCPU), + + /* Remaining CP0 registers */ + VMSTATE_INT32(env.CP0_Index, MIPSCPU), + VMSTATE_INT32(env.CP0_VPControl, 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_UINT64(env.CP0_EntryLo0, MIPSCPU), + VMSTATE_UINT64(env.CP0_EntryLo1, MIPSCPU), + VMSTATE_INT32(env.CP0_GlobalNumber, MIPSCPU), + VMSTATE_UINTTL(env.CP0_Context, MIPSCPU), + VMSTATE_INT32(env.CP0_MemoryMapID, MIPSCPU), + VMSTATE_INT32(env.CP0_PageMask, MIPSCPU), + VMSTATE_INT32(env.CP0_PageGrain, MIPSCPU), + VMSTATE_UINTTL(env.CP0_SegCtl0, MIPSCPU), + VMSTATE_UINTTL(env.CP0_SegCtl1, MIPSCPU), + VMSTATE_UINTTL(env.CP0_SegCtl2, MIPSCPU), + VMSTATE_UINTTL(env.CP0_PWBase, MIPSCPU), + VMSTATE_UINTTL(env.CP0_PWField, MIPSCPU), + VMSTATE_UINTTL(env.CP0_PWSize, MIPSCPU), + VMSTATE_INT32(env.CP0_Wired, MIPSCPU), + VMSTATE_INT32(env.CP0_PWCtl, 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_UINT32(env.CP0_BadInstrX, MIPSCPU), + VMSTATE_INT32(env.CP0_Count, MIPSCPU), + VMSTATE_UINT32(env.CP0_SAARI, MIPSCPU), + VMSTATE_UINT64_ARRAY(env.CP0_SAAR, MIPSCPU, 2), + 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_UINTTL(env.CP0_EBase, MIPSCPU), + VMSTATE_UINTTL(env.CP0_CMGCRBase, 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_Config4, MIPSCPU), + VMSTATE_INT32(env.CP0_Config5, MIPSCPU), + VMSTATE_INT32(env.CP0_Config6, MIPSCPU), + VMSTATE_INT32(env.CP0_Config7, MIPSCPU), + VMSTATE_UINT64(env.CP0_LLAddr, MIPSCPU), + VMSTATE_UINT64_ARRAY(env.CP0_MAAR, MIPSCPU, MIPS_MAAR_MAX), + VMSTATE_INT32(env.CP0_MAARI, MIPSCPU), + VMSTATE_UINTTL(env.lladdr, MIPSCPU), + VMSTATE_UINTTL_ARRAY(env.CP0_WatchLo, MIPSCPU, 8), + VMSTATE_UINT64_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_ErrCtl, MIPSCPU), + VMSTATE_UINT64(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() + }, +}; diff --git a/target/mips/sysemu/meson.build b/target/mips/sysemu/meson.build new file mode 100644 index 0000000000..f2a1ff4608 --- /dev/null +++ b/target/mips/sysemu/meson.build @@ -0,0 +1,5 @@ +mips_softmmu_ss.add(files( + 'addr.c', + 'cp0_timer.c', + 'machine.c', +))