remove target ifdefs from vl.c

(Glauber Costa)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4327 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
aurel32 2008-05-04 13:11:44 +00:00
parent 91834991f6
commit 8dd3dca351
11 changed files with 650 additions and 620 deletions

View File

@ -311,6 +311,9 @@ gen-op.h: op.o $(DYNGEN)
op.o: op.c op.o: op.c
$(CC) $(OP_CFLAGS) $(CPPFLAGS) -c -o $@ $< $(CC) $(OP_CFLAGS) $(CPPFLAGS) -c -o $@ $<
machine.o: machine.c
$(CC) $(OP_CFLAGS) $(CPPFLAGS) -c -o $@ $<
# HELPER_CFLAGS is used for all the code compiled with static register # HELPER_CFLAGS is used for all the code compiled with static register
# variables # variables
ifeq ($(TARGET_BASE_ARCH), i386) ifeq ($(TARGET_BASE_ARCH), i386)
@ -490,7 +493,7 @@ endif #CONFIG_DARWIN_USER
# System emulator target # System emulator target
ifndef CONFIG_USER_ONLY ifndef CONFIG_USER_ONLY
OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o machine.o
ifdef CONFIG_WIN32 ifdef CONFIG_WIN32
OBJS+=block-raw-win32.o OBJS+=block-raw-win32.o
else else

View File

@ -20,6 +20,7 @@ typedef struct QEMUMachine {
} QEMUMachine; } QEMUMachine;
int qemu_register_machine(QEMUMachine *m); int qemu_register_machine(QEMUMachine *m);
void register_machines(void);
/* Axis ETRAX. */ /* Axis ETRAX. */
extern QEMUMachine bareetraxfs_machine; extern QEMUMachine bareetraxfs_machine;

213
target-arm/machine.c Normal file
View File

@ -0,0 +1,213 @@
#include "hw/hw.h"
#include "hw/boards.h"
void register_machines(void)
{
qemu_register_machine(&integratorcp_machine);
qemu_register_machine(&versatilepb_machine);
qemu_register_machine(&versatileab_machine);
qemu_register_machine(&realview_machine);
qemu_register_machine(&akitapda_machine);
qemu_register_machine(&spitzpda_machine);
qemu_register_machine(&borzoipda_machine);
qemu_register_machine(&terrierpda_machine);
qemu_register_machine(&palmte_machine);
qemu_register_machine(&n800_machine);
qemu_register_machine(&lm3s811evb_machine);
qemu_register_machine(&lm3s6965evb_machine);
qemu_register_machine(&connex_machine);
qemu_register_machine(&verdex_machine);
qemu_register_machine(&mainstone2_machine);
qemu_register_machine(&musicpal_machine);
}
void cpu_save(QEMUFile *f, void *opaque)
{
int i;
CPUARMState *env = (CPUARMState *)opaque;
for (i = 0; i < 16; i++) {
qemu_put_be32(f, env->regs[i]);
}
qemu_put_be32(f, cpsr_read(env));
qemu_put_be32(f, env->spsr);
for (i = 0; i < 6; i++) {
qemu_put_be32(f, env->banked_spsr[i]);
qemu_put_be32(f, env->banked_r13[i]);
qemu_put_be32(f, env->banked_r14[i]);
}
for (i = 0; i < 5; i++) {
qemu_put_be32(f, env->usr_regs[i]);
qemu_put_be32(f, env->fiq_regs[i]);
}
qemu_put_be32(f, env->cp15.c0_cpuid);
qemu_put_be32(f, env->cp15.c0_cachetype);
qemu_put_be32(f, env->cp15.c1_sys);
qemu_put_be32(f, env->cp15.c1_coproc);
qemu_put_be32(f, env->cp15.c1_xscaleauxcr);
qemu_put_be32(f, env->cp15.c2_base0);
qemu_put_be32(f, env->cp15.c2_base1);
qemu_put_be32(f, env->cp15.c2_mask);
qemu_put_be32(f, env->cp15.c2_data);
qemu_put_be32(f, env->cp15.c2_insn);
qemu_put_be32(f, env->cp15.c3);
qemu_put_be32(f, env->cp15.c5_insn);
qemu_put_be32(f, env->cp15.c5_data);
for (i = 0; i < 8; i++) {
qemu_put_be32(f, env->cp15.c6_region[i]);
}
qemu_put_be32(f, env->cp15.c6_insn);
qemu_put_be32(f, env->cp15.c6_data);
qemu_put_be32(f, env->cp15.c9_insn);
qemu_put_be32(f, env->cp15.c9_data);
qemu_put_be32(f, env->cp15.c13_fcse);
qemu_put_be32(f, env->cp15.c13_context);
qemu_put_be32(f, env->cp15.c13_tls1);
qemu_put_be32(f, env->cp15.c13_tls2);
qemu_put_be32(f, env->cp15.c13_tls3);
qemu_put_be32(f, env->cp15.c15_cpar);
qemu_put_be32(f, env->features);
if (arm_feature(env, ARM_FEATURE_VFP)) {
for (i = 0; i < 16; i++) {
CPU_DoubleU u;
u.d = env->vfp.regs[i];
qemu_put_be32(f, u.l.upper);
qemu_put_be32(f, u.l.lower);
}
for (i = 0; i < 16; i++) {
qemu_put_be32(f, env->vfp.xregs[i]);
}
/* TODO: Should use proper FPSCR access functions. */
qemu_put_be32(f, env->vfp.vec_len);
qemu_put_be32(f, env->vfp.vec_stride);
if (arm_feature(env, ARM_FEATURE_VFP3)) {
for (i = 16; i < 32; i++) {
CPU_DoubleU u;
u.d = env->vfp.regs[i];
qemu_put_be32(f, u.l.upper);
qemu_put_be32(f, u.l.lower);
}
}
}
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
for (i = 0; i < 16; i++) {
qemu_put_be64(f, env->iwmmxt.regs[i]);
}
for (i = 0; i < 16; i++) {
qemu_put_be32(f, env->iwmmxt.cregs[i]);
}
}
if (arm_feature(env, ARM_FEATURE_M)) {
qemu_put_be32(f, env->v7m.other_sp);
qemu_put_be32(f, env->v7m.vecbase);
qemu_put_be32(f, env->v7m.basepri);
qemu_put_be32(f, env->v7m.control);
qemu_put_be32(f, env->v7m.current_sp);
qemu_put_be32(f, env->v7m.exception);
}
}
int cpu_load(QEMUFile *f, void *opaque, int version_id)
{
CPUARMState *env = (CPUARMState *)opaque;
int i;
if (version_id != ARM_CPU_SAVE_VERSION)
return -EINVAL;
for (i = 0; i < 16; i++) {
env->regs[i] = qemu_get_be32(f);
}
cpsr_write(env, qemu_get_be32(f), 0xffffffff);
env->spsr = qemu_get_be32(f);
for (i = 0; i < 6; i++) {
env->banked_spsr[i] = qemu_get_be32(f);
env->banked_r13[i] = qemu_get_be32(f);
env->banked_r14[i] = qemu_get_be32(f);
}
for (i = 0; i < 5; i++) {
env->usr_regs[i] = qemu_get_be32(f);
env->fiq_regs[i] = qemu_get_be32(f);
}
env->cp15.c0_cpuid = qemu_get_be32(f);
env->cp15.c0_cachetype = qemu_get_be32(f);
env->cp15.c1_sys = qemu_get_be32(f);
env->cp15.c1_coproc = qemu_get_be32(f);
env->cp15.c1_xscaleauxcr = qemu_get_be32(f);
env->cp15.c2_base0 = qemu_get_be32(f);
env->cp15.c2_base1 = qemu_get_be32(f);
env->cp15.c2_mask = qemu_get_be32(f);
env->cp15.c2_data = qemu_get_be32(f);
env->cp15.c2_insn = qemu_get_be32(f);
env->cp15.c3 = qemu_get_be32(f);
env->cp15.c5_insn = qemu_get_be32(f);
env->cp15.c5_data = qemu_get_be32(f);
for (i = 0; i < 8; i++) {
env->cp15.c6_region[i] = qemu_get_be32(f);
}
env->cp15.c6_insn = qemu_get_be32(f);
env->cp15.c6_data = qemu_get_be32(f);
env->cp15.c9_insn = qemu_get_be32(f);
env->cp15.c9_data = qemu_get_be32(f);
env->cp15.c13_fcse = qemu_get_be32(f);
env->cp15.c13_context = qemu_get_be32(f);
env->cp15.c13_tls1 = qemu_get_be32(f);
env->cp15.c13_tls2 = qemu_get_be32(f);
env->cp15.c13_tls3 = qemu_get_be32(f);
env->cp15.c15_cpar = qemu_get_be32(f);
env->features = qemu_get_be32(f);
if (arm_feature(env, ARM_FEATURE_VFP)) {
for (i = 0; i < 16; i++) {
CPU_DoubleU u;
u.l.upper = qemu_get_be32(f);
u.l.lower = qemu_get_be32(f);
env->vfp.regs[i] = u.d;
}
for (i = 0; i < 16; i++) {
env->vfp.xregs[i] = qemu_get_be32(f);
}
/* TODO: Should use proper FPSCR access functions. */
env->vfp.vec_len = qemu_get_be32(f);
env->vfp.vec_stride = qemu_get_be32(f);
if (arm_feature(env, ARM_FEATURE_VFP3)) {
for (i = 0; i < 16; i++) {
CPU_DoubleU u;
u.l.upper = qemu_get_be32(f);
u.l.lower = qemu_get_be32(f);
env->vfp.regs[i] = u.d;
}
}
}
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
for (i = 0; i < 16; i++) {
env->iwmmxt.regs[i] = qemu_get_be64(f);
}
for (i = 0; i < 16; i++) {
env->iwmmxt.cregs[i] = qemu_get_be32(f);
}
}
if (arm_feature(env, ARM_FEATURE_M)) {
env->v7m.other_sp = qemu_get_be32(f);
env->v7m.vecbase = qemu_get_be32(f);
env->v7m.basepri = qemu_get_be32(f);
env->v7m.control = qemu_get_be32(f);
env->v7m.current_sp = qemu_get_be32(f);
env->v7m.exception = qemu_get_be32(f);
}
return 0;
}

7
target-cris/machine.c Normal file
View File

@ -0,0 +1,7 @@
#include "hw/hw.h"
#include "hw/boards.h"
void register_machines(void)
{
qemu_register_machine(&bareetraxfs_machine);
}

264
target-i386/machine.c Normal file
View File

@ -0,0 +1,264 @@
#include "hw/hw.h"
#include "hw/boards.h"
#include "hw/pc.h"
#include "hw/isa.h"
#include "exec-all.h"
void register_machines(void)
{
qemu_register_machine(&pc_machine);
qemu_register_machine(&isapc_machine);
}
static void cpu_put_seg(QEMUFile *f, SegmentCache *dt)
{
qemu_put_be32(f, dt->selector);
qemu_put_betl(f, dt->base);
qemu_put_be32(f, dt->limit);
qemu_put_be32(f, dt->flags);
}
static void cpu_get_seg(QEMUFile *f, SegmentCache *dt)
{
dt->selector = qemu_get_be32(f);
dt->base = qemu_get_betl(f);
dt->limit = qemu_get_be32(f);
dt->flags = qemu_get_be32(f);
}
void cpu_save(QEMUFile *f, void *opaque)
{
CPUState *env = opaque;
uint16_t fptag, fpus, fpuc, fpregs_format;
uint32_t hflags;
int i;
for(i = 0; i < CPU_NB_REGS; i++)
qemu_put_betls(f, &env->regs[i]);
qemu_put_betls(f, &env->eip);
qemu_put_betls(f, &env->eflags);
hflags = env->hflags; /* XXX: suppress most of the redundant hflags */
qemu_put_be32s(f, &hflags);
/* FPU */
fpuc = env->fpuc;
fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
fptag = 0;
for(i = 0; i < 8; i++) {
fptag |= ((!env->fptags[i]) << i);
}
qemu_put_be16s(f, &fpuc);
qemu_put_be16s(f, &fpus);
qemu_put_be16s(f, &fptag);
#ifdef USE_X86LDOUBLE
fpregs_format = 0;
#else
fpregs_format = 1;
#endif
qemu_put_be16s(f, &fpregs_format);
for(i = 0; i < 8; i++) {
#ifdef USE_X86LDOUBLE
{
uint64_t mant;
uint16_t exp;
/* we save the real CPU data (in case of MMX usage only 'mant'
contains the MMX register */
cpu_get_fp80(&mant, &exp, env->fpregs[i].d);
qemu_put_be64(f, mant);
qemu_put_be16(f, exp);
}
#else
/* if we use doubles for float emulation, we save the doubles to
avoid losing information in case of MMX usage. It can give
problems if the image is restored on a CPU where long
doubles are used instead. */
qemu_put_be64(f, env->fpregs[i].mmx.MMX_Q(0));
#endif
}
for(i = 0; i < 6; i++)
cpu_put_seg(f, &env->segs[i]);
cpu_put_seg(f, &env->ldt);
cpu_put_seg(f, &env->tr);
cpu_put_seg(f, &env->gdt);
cpu_put_seg(f, &env->idt);
qemu_put_be32s(f, &env->sysenter_cs);
qemu_put_be32s(f, &env->sysenter_esp);
qemu_put_be32s(f, &env->sysenter_eip);
qemu_put_betls(f, &env->cr[0]);
qemu_put_betls(f, &env->cr[2]);
qemu_put_betls(f, &env->cr[3]);
qemu_put_betls(f, &env->cr[4]);
for(i = 0; i < 8; i++)
qemu_put_betls(f, &env->dr[i]);
/* MMU */
qemu_put_be32s(f, &env->a20_mask);
/* XMM */
qemu_put_be32s(f, &env->mxcsr);
for(i = 0; i < CPU_NB_REGS; i++) {
qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(0));
qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(1));
}
#ifdef TARGET_X86_64
qemu_put_be64s(f, &env->efer);
qemu_put_be64s(f, &env->star);
qemu_put_be64s(f, &env->lstar);
qemu_put_be64s(f, &env->cstar);
qemu_put_be64s(f, &env->fmask);
qemu_put_be64s(f, &env->kernelgsbase);
#endif
qemu_put_be32s(f, &env->smbase);
}
#ifdef USE_X86LDOUBLE
/* XXX: add that in a FPU generic layer */
union x86_longdouble {
uint64_t mant;
uint16_t exp;
};
#define MANTD1(fp) (fp & ((1LL << 52) - 1))
#define EXPBIAS1 1023
#define EXPD1(fp) ((fp >> 52) & 0x7FF)
#define SIGND1(fp) ((fp >> 32) & 0x80000000)
static void fp64_to_fp80(union x86_longdouble *p, uint64_t temp)
{
int e;
/* mantissa */
p->mant = (MANTD1(temp) << 11) | (1LL << 63);
/* exponent + sign */
e = EXPD1(temp) - EXPBIAS1 + 16383;
e |= SIGND1(temp) >> 16;
p->exp = e;
}
#endif
int cpu_load(QEMUFile *f, void *opaque, int version_id)
{
CPUState *env = opaque;
int i, guess_mmx;
uint32_t hflags;
uint16_t fpus, fpuc, fptag, fpregs_format;
if (version_id != 3 && version_id != 4)
return -EINVAL;
for(i = 0; i < CPU_NB_REGS; i++)
qemu_get_betls(f, &env->regs[i]);
qemu_get_betls(f, &env->eip);
qemu_get_betls(f, &env->eflags);
qemu_get_be32s(f, &hflags);
qemu_get_be16s(f, &fpuc);
qemu_get_be16s(f, &fpus);
qemu_get_be16s(f, &fptag);
qemu_get_be16s(f, &fpregs_format);
/* NOTE: we cannot always restore the FPU state if the image come
from a host with a different 'USE_X86LDOUBLE' define. We guess
if we are in an MMX state to restore correctly in that case. */
guess_mmx = ((fptag == 0xff) && (fpus & 0x3800) == 0);
for(i = 0; i < 8; i++) {
uint64_t mant;
uint16_t exp;
switch(fpregs_format) {
case 0:
mant = qemu_get_be64(f);
exp = qemu_get_be16(f);
#ifdef USE_X86LDOUBLE
env->fpregs[i].d = cpu_set_fp80(mant, exp);
#else
/* difficult case */
if (guess_mmx)
env->fpregs[i].mmx.MMX_Q(0) = mant;
else
env->fpregs[i].d = cpu_set_fp80(mant, exp);
#endif
break;
case 1:
mant = qemu_get_be64(f);
#ifdef USE_X86LDOUBLE
{
union x86_longdouble *p;
/* difficult case */
p = (void *)&env->fpregs[i];
if (guess_mmx) {
p->mant = mant;
p->exp = 0xffff;
} else {
fp64_to_fp80(p, mant);
}
}
#else
env->fpregs[i].mmx.MMX_Q(0) = mant;
#endif
break;
default:
return -EINVAL;
}
}
env->fpuc = fpuc;
/* XXX: restore FPU round state */
env->fpstt = (fpus >> 11) & 7;
env->fpus = fpus & ~0x3800;
fptag ^= 0xff;
for(i = 0; i < 8; i++) {
env->fptags[i] = (fptag >> i) & 1;
}
for(i = 0; i < 6; i++)
cpu_get_seg(f, &env->segs[i]);
cpu_get_seg(f, &env->ldt);
cpu_get_seg(f, &env->tr);
cpu_get_seg(f, &env->gdt);
cpu_get_seg(f, &env->idt);
qemu_get_be32s(f, &env->sysenter_cs);
qemu_get_be32s(f, &env->sysenter_esp);
qemu_get_be32s(f, &env->sysenter_eip);
qemu_get_betls(f, &env->cr[0]);
qemu_get_betls(f, &env->cr[2]);
qemu_get_betls(f, &env->cr[3]);
qemu_get_betls(f, &env->cr[4]);
for(i = 0; i < 8; i++)
qemu_get_betls(f, &env->dr[i]);
/* MMU */
qemu_get_be32s(f, &env->a20_mask);
qemu_get_be32s(f, &env->mxcsr);
for(i = 0; i < CPU_NB_REGS; i++) {
qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(0));
qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(1));
}
#ifdef TARGET_X86_64
qemu_get_be64s(f, &env->efer);
qemu_get_be64s(f, &env->star);
qemu_get_be64s(f, &env->lstar);
qemu_get_be64s(f, &env->cstar);
qemu_get_be64s(f, &env->fmask);
qemu_get_be64s(f, &env->kernelgsbase);
#endif
if (version_id >= 4)
qemu_get_be32s(f, &env->smbase);
/* XXX: compute hflags from scratch, except for CPL and IIF */
env->hflags = hflags;
tlb_flush(env, 1);
return 0;
}

9
target-m68k/machine.c Normal file
View File

@ -0,0 +1,9 @@
#include "hw/hw.h"
#include "hw/boards.h"
void register_machines(void)
{
qemu_register_machine(&mcf5208evb_machine);
qemu_register_machine(&an5206_machine);
qemu_register_machine(&dummy_m68k_machine);
}

22
target-mips/machine.c Normal file
View File

@ -0,0 +1,22 @@
#include "hw/hw.h"
#include "hw/boards.h"
void register_machines(void)
{
qemu_register_machine(&mips_machine);
qemu_register_machine(&mips_magnum_machine);
qemu_register_machine(&mips_malta_machine);
qemu_register_machine(&mips_pica61_machine);
qemu_register_machine(&mips_mipssim_machine);
}
void cpu_save(QEMUFile *f, void *opaque)
{
}
int cpu_load(QEMUFile *f, void *opaque, int version_id)
{
return 0;
}

20
target-ppc/machine.c Normal file
View File

@ -0,0 +1,20 @@
#include "hw/hw.h"
#include "hw/boards.h"
void register_machines(void)
{
qemu_register_machine(&heathrow_machine);
qemu_register_machine(&core99_machine);
qemu_register_machine(&prep_machine);
qemu_register_machine(&ref405ep_machine);
qemu_register_machine(&taihu_machine);
}
void cpu_save(QEMUFile *f, void *opaque)
{
}
int cpu_load(QEMUFile *f, void *opaque, int version_id)
{
return 0;
}

8
target-sh4/machine.c Normal file
View File

@ -0,0 +1,8 @@
#include "hw/hw.h"
#include "hw/boards.h"
void register_machines(void)
{
qemu_register_machine(&shix_machine);
qemu_register_machine(&r2d_machine);
}

102
target-sparc/machine.c Normal file
View File

@ -0,0 +1,102 @@
#include "hw/hw.h"
#include "hw/boards.h"
#include "exec-all.h"
void register_machines(void)
{
#ifdef TARGET_SPARC64
qemu_register_machine(&sun4u_machine);
#else
qemu_register_machine(&ss5_machine);
qemu_register_machine(&ss10_machine);
qemu_register_machine(&ss600mp_machine);
qemu_register_machine(&ss20_machine);
qemu_register_machine(&ss2_machine);
qemu_register_machine(&voyager_machine);
qemu_register_machine(&ss_lx_machine);
qemu_register_machine(&ss4_machine);
qemu_register_machine(&scls_machine);
qemu_register_machine(&sbook_machine);
qemu_register_machine(&ss1000_machine);
qemu_register_machine(&ss2000_machine);
#endif
}
void cpu_save(QEMUFile *f, void *opaque)
{
CPUState *env = opaque;
int i;
uint32_t tmp;
for(i = 0; i < 8; i++)
qemu_put_betls(f, &env->gregs[i]);
for(i = 0; i < NWINDOWS * 16; i++)
qemu_put_betls(f, &env->regbase[i]);
/* FPU */
for(i = 0; i < TARGET_FPREGS; i++) {
union {
float32 f;
uint32_t i;
} u;
u.f = env->fpr[i];
qemu_put_be32(f, u.i);
}
qemu_put_betls(f, &env->pc);
qemu_put_betls(f, &env->npc);
qemu_put_betls(f, &env->y);
tmp = GET_PSR(env);
qemu_put_be32(f, tmp);
qemu_put_betls(f, &env->fsr);
qemu_put_betls(f, &env->tbr);
#ifndef TARGET_SPARC64
qemu_put_be32s(f, &env->wim);
/* MMU */
for(i = 0; i < 16; i++)
qemu_put_be32s(f, &env->mmuregs[i]);
#endif
}
int cpu_load(QEMUFile *f, void *opaque, int version_id)
{
CPUState *env = opaque;
int i;
uint32_t tmp;
for(i = 0; i < 8; i++)
qemu_get_betls(f, &env->gregs[i]);
for(i = 0; i < NWINDOWS * 16; i++)
qemu_get_betls(f, &env->regbase[i]);
/* FPU */
for(i = 0; i < TARGET_FPREGS; i++) {
union {
float32 f;
uint32_t i;
} u;
u.i = qemu_get_be32(f);
env->fpr[i] = u.f;
}
qemu_get_betls(f, &env->pc);
qemu_get_betls(f, &env->npc);
qemu_get_betls(f, &env->y);
tmp = qemu_get_be32(f);
env->cwp = 0; /* needed to ensure that the wrapping registers are
correctly updated */
PUT_PSR(env, tmp);
qemu_get_betls(f, &env->fsr);
qemu_get_betls(f, &env->tbr);
#ifndef TARGET_SPARC64
qemu_get_be32s(f, &env->wim);
/* MMU */
for(i = 0; i < 16; i++)
qemu_get_be32s(f, &env->mmuregs[i]);
#endif
tlb_flush(env, 1);
return 0;
}

619
vl.c
View File

@ -6319,557 +6319,6 @@ void do_info_snapshots(void)
qemu_free(sn_tab); qemu_free(sn_tab);
} }
/***********************************************************/
/* cpu save/restore */
#if defined(TARGET_I386)
static void cpu_put_seg(QEMUFile *f, SegmentCache *dt)
{
qemu_put_be32(f, dt->selector);
qemu_put_betl(f, dt->base);
qemu_put_be32(f, dt->limit);
qemu_put_be32(f, dt->flags);
}
static void cpu_get_seg(QEMUFile *f, SegmentCache *dt)
{
dt->selector = qemu_get_be32(f);
dt->base = qemu_get_betl(f);
dt->limit = qemu_get_be32(f);
dt->flags = qemu_get_be32(f);
}
void cpu_save(QEMUFile *f, void *opaque)
{
CPUState *env = opaque;
uint16_t fptag, fpus, fpuc, fpregs_format;
uint32_t hflags;
int i;
for(i = 0; i < CPU_NB_REGS; i++)
qemu_put_betls(f, &env->regs[i]);
qemu_put_betls(f, &env->eip);
qemu_put_betls(f, &env->eflags);
hflags = env->hflags; /* XXX: suppress most of the redundant hflags */
qemu_put_be32s(f, &hflags);
/* FPU */
fpuc = env->fpuc;
fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
fptag = 0;
for(i = 0; i < 8; i++) {
fptag |= ((!env->fptags[i]) << i);
}
qemu_put_be16s(f, &fpuc);
qemu_put_be16s(f, &fpus);
qemu_put_be16s(f, &fptag);
#ifdef USE_X86LDOUBLE
fpregs_format = 0;
#else
fpregs_format = 1;
#endif
qemu_put_be16s(f, &fpregs_format);
for(i = 0; i < 8; i++) {
#ifdef USE_X86LDOUBLE
{
uint64_t mant;
uint16_t exp;
/* we save the real CPU data (in case of MMX usage only 'mant'
contains the MMX register */
cpu_get_fp80(&mant, &exp, env->fpregs[i].d);
qemu_put_be64(f, mant);
qemu_put_be16(f, exp);
}
#else
/* if we use doubles for float emulation, we save the doubles to
avoid losing information in case of MMX usage. It can give
problems if the image is restored on a CPU where long
doubles are used instead. */
qemu_put_be64(f, env->fpregs[i].mmx.MMX_Q(0));
#endif
}
for(i = 0; i < 6; i++)
cpu_put_seg(f, &env->segs[i]);
cpu_put_seg(f, &env->ldt);
cpu_put_seg(f, &env->tr);
cpu_put_seg(f, &env->gdt);
cpu_put_seg(f, &env->idt);
qemu_put_be32s(f, &env->sysenter_cs);
qemu_put_be32s(f, &env->sysenter_esp);
qemu_put_be32s(f, &env->sysenter_eip);
qemu_put_betls(f, &env->cr[0]);
qemu_put_betls(f, &env->cr[2]);
qemu_put_betls(f, &env->cr[3]);
qemu_put_betls(f, &env->cr[4]);
for(i = 0; i < 8; i++)
qemu_put_betls(f, &env->dr[i]);
/* MMU */
qemu_put_be32s(f, &env->a20_mask);
/* XMM */
qemu_put_be32s(f, &env->mxcsr);
for(i = 0; i < CPU_NB_REGS; i++) {
qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(0));
qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(1));
}
#ifdef TARGET_X86_64
qemu_put_be64s(f, &env->efer);
qemu_put_be64s(f, &env->star);
qemu_put_be64s(f, &env->lstar);
qemu_put_be64s(f, &env->cstar);
qemu_put_be64s(f, &env->fmask);
qemu_put_be64s(f, &env->kernelgsbase);
#endif
qemu_put_be32s(f, &env->smbase);
}
#ifdef USE_X86LDOUBLE
/* XXX: add that in a FPU generic layer */
union x86_longdouble {
uint64_t mant;
uint16_t exp;
};
#define MANTD1(fp) (fp & ((1LL << 52) - 1))
#define EXPBIAS1 1023
#define EXPD1(fp) ((fp >> 52) & 0x7FF)
#define SIGND1(fp) ((fp >> 32) & 0x80000000)
static void fp64_to_fp80(union x86_longdouble *p, uint64_t temp)
{
int e;
/* mantissa */
p->mant = (MANTD1(temp) << 11) | (1LL << 63);
/* exponent + sign */
e = EXPD1(temp) - EXPBIAS1 + 16383;
e |= SIGND1(temp) >> 16;
p->exp = e;
}
#endif
int cpu_load(QEMUFile *f, void *opaque, int version_id)
{
CPUState *env = opaque;
int i, guess_mmx;
uint32_t hflags;
uint16_t fpus, fpuc, fptag, fpregs_format;
if (version_id != 3 && version_id != 4)
return -EINVAL;
for(i = 0; i < CPU_NB_REGS; i++)
qemu_get_betls(f, &env->regs[i]);
qemu_get_betls(f, &env->eip);
qemu_get_betls(f, &env->eflags);
qemu_get_be32s(f, &hflags);
qemu_get_be16s(f, &fpuc);
qemu_get_be16s(f, &fpus);
qemu_get_be16s(f, &fptag);
qemu_get_be16s(f, &fpregs_format);
/* NOTE: we cannot always restore the FPU state if the image come
from a host with a different 'USE_X86LDOUBLE' define. We guess
if we are in an MMX state to restore correctly in that case. */
guess_mmx = ((fptag == 0xff) && (fpus & 0x3800) == 0);
for(i = 0; i < 8; i++) {
uint64_t mant;
uint16_t exp;
switch(fpregs_format) {
case 0:
mant = qemu_get_be64(f);
exp = qemu_get_be16(f);
#ifdef USE_X86LDOUBLE
env->fpregs[i].d = cpu_set_fp80(mant, exp);
#else
/* difficult case */
if (guess_mmx)
env->fpregs[i].mmx.MMX_Q(0) = mant;
else
env->fpregs[i].d = cpu_set_fp80(mant, exp);
#endif
break;
case 1:
mant = qemu_get_be64(f);
#ifdef USE_X86LDOUBLE
{
union x86_longdouble *p;
/* difficult case */
p = (void *)&env->fpregs[i];
if (guess_mmx) {
p->mant = mant;
p->exp = 0xffff;
} else {
fp64_to_fp80(p, mant);
}
}
#else
env->fpregs[i].mmx.MMX_Q(0) = mant;
#endif
break;
default:
return -EINVAL;
}
}
env->fpuc = fpuc;
/* XXX: restore FPU round state */
env->fpstt = (fpus >> 11) & 7;
env->fpus = fpus & ~0x3800;
fptag ^= 0xff;
for(i = 0; i < 8; i++) {
env->fptags[i] = (fptag >> i) & 1;
}
for(i = 0; i < 6; i++)
cpu_get_seg(f, &env->segs[i]);
cpu_get_seg(f, &env->ldt);
cpu_get_seg(f, &env->tr);
cpu_get_seg(f, &env->gdt);
cpu_get_seg(f, &env->idt);
qemu_get_be32s(f, &env->sysenter_cs);
qemu_get_be32s(f, &env->sysenter_esp);
qemu_get_be32s(f, &env->sysenter_eip);
qemu_get_betls(f, &env->cr[0]);
qemu_get_betls(f, &env->cr[2]);
qemu_get_betls(f, &env->cr[3]);
qemu_get_betls(f, &env->cr[4]);
for(i = 0; i < 8; i++)
qemu_get_betls(f, &env->dr[i]);
/* MMU */
qemu_get_be32s(f, &env->a20_mask);
qemu_get_be32s(f, &env->mxcsr);
for(i = 0; i < CPU_NB_REGS; i++) {
qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(0));
qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(1));
}
#ifdef TARGET_X86_64
qemu_get_be64s(f, &env->efer);
qemu_get_be64s(f, &env->star);
qemu_get_be64s(f, &env->lstar);
qemu_get_be64s(f, &env->cstar);
qemu_get_be64s(f, &env->fmask);
qemu_get_be64s(f, &env->kernelgsbase);
#endif
if (version_id >= 4)
qemu_get_be32s(f, &env->smbase);
/* XXX: compute hflags from scratch, except for CPL and IIF */
env->hflags = hflags;
tlb_flush(env, 1);
return 0;
}
#elif defined(TARGET_PPC)
void cpu_save(QEMUFile *f, void *opaque)
{
}
int cpu_load(QEMUFile *f, void *opaque, int version_id)
{
return 0;
}
#elif defined(TARGET_MIPS)
void cpu_save(QEMUFile *f, void *opaque)
{
}
int cpu_load(QEMUFile *f, void *opaque, int version_id)
{
return 0;
}
#elif defined(TARGET_SPARC)
void cpu_save(QEMUFile *f, void *opaque)
{
CPUState *env = opaque;
int i;
uint32_t tmp;
for(i = 0; i < 8; i++)
qemu_put_betls(f, &env->gregs[i]);
for(i = 0; i < NWINDOWS * 16; i++)
qemu_put_betls(f, &env->regbase[i]);
/* FPU */
for(i = 0; i < TARGET_FPREGS; i++) {
union {
float32 f;
uint32_t i;
} u;
u.f = env->fpr[i];
qemu_put_be32(f, u.i);
}
qemu_put_betls(f, &env->pc);
qemu_put_betls(f, &env->npc);
qemu_put_betls(f, &env->y);
tmp = GET_PSR(env);
qemu_put_be32(f, tmp);
qemu_put_betls(f, &env->fsr);
qemu_put_betls(f, &env->tbr);
#ifndef TARGET_SPARC64
qemu_put_be32s(f, &env->wim);
/* MMU */
for(i = 0; i < 16; i++)
qemu_put_be32s(f, &env->mmuregs[i]);
#endif
}
int cpu_load(QEMUFile *f, void *opaque, int version_id)
{
CPUState *env = opaque;
int i;
uint32_t tmp;
for(i = 0; i < 8; i++)
qemu_get_betls(f, &env->gregs[i]);
for(i = 0; i < NWINDOWS * 16; i++)
qemu_get_betls(f, &env->regbase[i]);
/* FPU */
for(i = 0; i < TARGET_FPREGS; i++) {
union {
float32 f;
uint32_t i;
} u;
u.i = qemu_get_be32(f);
env->fpr[i] = u.f;
}
qemu_get_betls(f, &env->pc);
qemu_get_betls(f, &env->npc);
qemu_get_betls(f, &env->y);
tmp = qemu_get_be32(f);
env->cwp = 0; /* needed to ensure that the wrapping registers are
correctly updated */
PUT_PSR(env, tmp);
qemu_get_betls(f, &env->fsr);
qemu_get_betls(f, &env->tbr);
#ifndef TARGET_SPARC64
qemu_get_be32s(f, &env->wim);
/* MMU */
for(i = 0; i < 16; i++)
qemu_get_be32s(f, &env->mmuregs[i]);
#endif
tlb_flush(env, 1);
return 0;
}
#elif defined(TARGET_ARM)
void cpu_save(QEMUFile *f, void *opaque)
{
int i;
CPUARMState *env = (CPUARMState *)opaque;
for (i = 0; i < 16; i++) {
qemu_put_be32(f, env->regs[i]);
}
qemu_put_be32(f, cpsr_read(env));
qemu_put_be32(f, env->spsr);
for (i = 0; i < 6; i++) {
qemu_put_be32(f, env->banked_spsr[i]);
qemu_put_be32(f, env->banked_r13[i]);
qemu_put_be32(f, env->banked_r14[i]);
}
for (i = 0; i < 5; i++) {
qemu_put_be32(f, env->usr_regs[i]);
qemu_put_be32(f, env->fiq_regs[i]);
}
qemu_put_be32(f, env->cp15.c0_cpuid);
qemu_put_be32(f, env->cp15.c0_cachetype);
qemu_put_be32(f, env->cp15.c1_sys);
qemu_put_be32(f, env->cp15.c1_coproc);
qemu_put_be32(f, env->cp15.c1_xscaleauxcr);
qemu_put_be32(f, env->cp15.c2_base0);
qemu_put_be32(f, env->cp15.c2_base1);
qemu_put_be32(f, env->cp15.c2_mask);
qemu_put_be32(f, env->cp15.c2_data);
qemu_put_be32(f, env->cp15.c2_insn);
qemu_put_be32(f, env->cp15.c3);
qemu_put_be32(f, env->cp15.c5_insn);
qemu_put_be32(f, env->cp15.c5_data);
for (i = 0; i < 8; i++) {
qemu_put_be32(f, env->cp15.c6_region[i]);
}
qemu_put_be32(f, env->cp15.c6_insn);
qemu_put_be32(f, env->cp15.c6_data);
qemu_put_be32(f, env->cp15.c9_insn);
qemu_put_be32(f, env->cp15.c9_data);
qemu_put_be32(f, env->cp15.c13_fcse);
qemu_put_be32(f, env->cp15.c13_context);
qemu_put_be32(f, env->cp15.c13_tls1);
qemu_put_be32(f, env->cp15.c13_tls2);
qemu_put_be32(f, env->cp15.c13_tls3);
qemu_put_be32(f, env->cp15.c15_cpar);
qemu_put_be32(f, env->features);
if (arm_feature(env, ARM_FEATURE_VFP)) {
for (i = 0; i < 16; i++) {
CPU_DoubleU u;
u.d = env->vfp.regs[i];
qemu_put_be32(f, u.l.upper);
qemu_put_be32(f, u.l.lower);
}
for (i = 0; i < 16; i++) {
qemu_put_be32(f, env->vfp.xregs[i]);
}
/* TODO: Should use proper FPSCR access functions. */
qemu_put_be32(f, env->vfp.vec_len);
qemu_put_be32(f, env->vfp.vec_stride);
if (arm_feature(env, ARM_FEATURE_VFP3)) {
for (i = 16; i < 32; i++) {
CPU_DoubleU u;
u.d = env->vfp.regs[i];
qemu_put_be32(f, u.l.upper);
qemu_put_be32(f, u.l.lower);
}
}
}
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
for (i = 0; i < 16; i++) {
qemu_put_be64(f, env->iwmmxt.regs[i]);
}
for (i = 0; i < 16; i++) {
qemu_put_be32(f, env->iwmmxt.cregs[i]);
}
}
if (arm_feature(env, ARM_FEATURE_M)) {
qemu_put_be32(f, env->v7m.other_sp);
qemu_put_be32(f, env->v7m.vecbase);
qemu_put_be32(f, env->v7m.basepri);
qemu_put_be32(f, env->v7m.control);
qemu_put_be32(f, env->v7m.current_sp);
qemu_put_be32(f, env->v7m.exception);
}
}
int cpu_load(QEMUFile *f, void *opaque, int version_id)
{
CPUARMState *env = (CPUARMState *)opaque;
int i;
if (version_id != ARM_CPU_SAVE_VERSION)
return -EINVAL;
for (i = 0; i < 16; i++) {
env->regs[i] = qemu_get_be32(f);
}
cpsr_write(env, qemu_get_be32(f), 0xffffffff);
env->spsr = qemu_get_be32(f);
for (i = 0; i < 6; i++) {
env->banked_spsr[i] = qemu_get_be32(f);
env->banked_r13[i] = qemu_get_be32(f);
env->banked_r14[i] = qemu_get_be32(f);
}
for (i = 0; i < 5; i++) {
env->usr_regs[i] = qemu_get_be32(f);
env->fiq_regs[i] = qemu_get_be32(f);
}
env->cp15.c0_cpuid = qemu_get_be32(f);
env->cp15.c0_cachetype = qemu_get_be32(f);
env->cp15.c1_sys = qemu_get_be32(f);
env->cp15.c1_coproc = qemu_get_be32(f);
env->cp15.c1_xscaleauxcr = qemu_get_be32(f);
env->cp15.c2_base0 = qemu_get_be32(f);
env->cp15.c2_base1 = qemu_get_be32(f);
env->cp15.c2_mask = qemu_get_be32(f);
env->cp15.c2_data = qemu_get_be32(f);
env->cp15.c2_insn = qemu_get_be32(f);
env->cp15.c3 = qemu_get_be32(f);
env->cp15.c5_insn = qemu_get_be32(f);
env->cp15.c5_data = qemu_get_be32(f);
for (i = 0; i < 8; i++) {
env->cp15.c6_region[i] = qemu_get_be32(f);
}
env->cp15.c6_insn = qemu_get_be32(f);
env->cp15.c6_data = qemu_get_be32(f);
env->cp15.c9_insn = qemu_get_be32(f);
env->cp15.c9_data = qemu_get_be32(f);
env->cp15.c13_fcse = qemu_get_be32(f);
env->cp15.c13_context = qemu_get_be32(f);
env->cp15.c13_tls1 = qemu_get_be32(f);
env->cp15.c13_tls2 = qemu_get_be32(f);
env->cp15.c13_tls3 = qemu_get_be32(f);
env->cp15.c15_cpar = qemu_get_be32(f);
env->features = qemu_get_be32(f);
if (arm_feature(env, ARM_FEATURE_VFP)) {
for (i = 0; i < 16; i++) {
CPU_DoubleU u;
u.l.upper = qemu_get_be32(f);
u.l.lower = qemu_get_be32(f);
env->vfp.regs[i] = u.d;
}
for (i = 0; i < 16; i++) {
env->vfp.xregs[i] = qemu_get_be32(f);
}
/* TODO: Should use proper FPSCR access functions. */
env->vfp.vec_len = qemu_get_be32(f);
env->vfp.vec_stride = qemu_get_be32(f);
if (arm_feature(env, ARM_FEATURE_VFP3)) {
for (i = 0; i < 16; i++) {
CPU_DoubleU u;
u.l.upper = qemu_get_be32(f);
u.l.lower = qemu_get_be32(f);
env->vfp.regs[i] = u.d;
}
}
}
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
for (i = 0; i < 16; i++) {
env->iwmmxt.regs[i] = qemu_get_be64(f);
}
for (i = 0; i < 16; i++) {
env->iwmmxt.cregs[i] = qemu_get_be32(f);
}
}
if (arm_feature(env, ARM_FEATURE_M)) {
env->v7m.other_sp = qemu_get_be32(f);
env->v7m.vecbase = qemu_get_be32(f);
env->v7m.basepri = qemu_get_be32(f);
env->v7m.control = qemu_get_be32(f);
env->v7m.current_sp = qemu_get_be32(f);
env->v7m.exception = qemu_get_be32(f);
}
return 0;
}
#else
//#warning No CPU save/restore functions
#endif
/***********************************************************/ /***********************************************************/
/* ram save/restore */ /* ram save/restore */
@ -8025,74 +7474,6 @@ static void read_passwords(void)
} }
} }
/* XXX: currently we cannot use simultaneously different CPUs */
static void register_machines(void)
{
#if defined(TARGET_I386)
qemu_register_machine(&pc_machine);
qemu_register_machine(&isapc_machine);
#elif defined(TARGET_PPC)
qemu_register_machine(&heathrow_machine);
qemu_register_machine(&core99_machine);
qemu_register_machine(&prep_machine);
qemu_register_machine(&ref405ep_machine);
qemu_register_machine(&taihu_machine);
#elif defined(TARGET_MIPS)
qemu_register_machine(&mips_machine);
qemu_register_machine(&mips_magnum_machine);
qemu_register_machine(&mips_malta_machine);
qemu_register_machine(&mips_pica61_machine);
qemu_register_machine(&mips_mipssim_machine);
#elif defined(TARGET_SPARC)
#ifdef TARGET_SPARC64
qemu_register_machine(&sun4u_machine);
#else
qemu_register_machine(&ss5_machine);
qemu_register_machine(&ss10_machine);
qemu_register_machine(&ss600mp_machine);
qemu_register_machine(&ss20_machine);
qemu_register_machine(&ss2_machine);
qemu_register_machine(&voyager_machine);
qemu_register_machine(&ss_lx_machine);
qemu_register_machine(&ss4_machine);
qemu_register_machine(&scls_machine);
qemu_register_machine(&sbook_machine);
qemu_register_machine(&ss1000_machine);
qemu_register_machine(&ss2000_machine);
#endif
#elif defined(TARGET_ARM)
qemu_register_machine(&integratorcp_machine);
qemu_register_machine(&versatilepb_machine);
qemu_register_machine(&versatileab_machine);
qemu_register_machine(&realview_machine);
qemu_register_machine(&akitapda_machine);
qemu_register_machine(&spitzpda_machine);
qemu_register_machine(&borzoipda_machine);
qemu_register_machine(&terrierpda_machine);
qemu_register_machine(&palmte_machine);
qemu_register_machine(&n800_machine);
qemu_register_machine(&lm3s811evb_machine);
qemu_register_machine(&lm3s6965evb_machine);
qemu_register_machine(&connex_machine);
qemu_register_machine(&verdex_machine);
qemu_register_machine(&mainstone2_machine);
qemu_register_machine(&musicpal_machine);
#elif defined(TARGET_SH4)
qemu_register_machine(&shix_machine);
qemu_register_machine(&r2d_machine);
#elif defined(TARGET_ALPHA)
/* XXX: TODO */
#elif defined(TARGET_M68K)
qemu_register_machine(&mcf5208evb_machine);
qemu_register_machine(&an5206_machine);
qemu_register_machine(&dummy_m68k_machine);
#elif defined(TARGET_CRIS)
qemu_register_machine(&bareetraxfs_machine);
#else
#error unsupported CPU
#endif
}
#ifdef HAS_AUDIO #ifdef HAS_AUDIO
struct soundhw soundhw[] = { struct soundhw soundhw[] = {
#ifdef HAS_AUDIO_CHOICE #ifdef HAS_AUDIO_CHOICE