machine.c 7.6 KB
Newer Older
A
aurel32 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
#include "hw/hw.h"
#include "hw/boards.h"

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);
P
Paul Brook 已提交
25
    qemu_put_be32(f, env->cp15.c0_cssel);
A
aurel32 已提交
26 27 28
    qemu_put_be32(f, env->cp15.c1_sys);
    qemu_put_be32(f, env->cp15.c1_coproc);
    qemu_put_be32(f, env->cp15.c1_xscaleauxcr);
29
    qemu_put_be32(f, env->cp15.c1_scr);
A
aurel32 已提交
30 31
    qemu_put_be32(f, env->cp15.c2_base0);
    qemu_put_be32(f, env->cp15.c2_base1);
P
Paul Brook 已提交
32
    qemu_put_be32(f, env->cp15.c2_control);
A
aurel32 已提交
33
    qemu_put_be32(f, env->cp15.c2_mask);
P
Paul Brook 已提交
34
    qemu_put_be32(f, env->cp15.c2_base_mask);
A
aurel32 已提交
35 36 37 38 39 40 41 42 43 44
    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);
45
    qemu_put_be32(f, env->cp15.c7_par);
A
aurel32 已提交
46 47
    qemu_put_be32(f, env->cp15.c9_insn);
    qemu_put_be32(f, env->cp15.c9_data);
48 49 50 51 52 53
    qemu_put_be32(f, env->cp15.c9_pmcr);
    qemu_put_be32(f, env->cp15.c9_pmcnten);
    qemu_put_be32(f, env->cp15.c9_pmovsr);
    qemu_put_be32(f, env->cp15.c9_pmxevtyper);
    qemu_put_be32(f, env->cp15.c9_pmuserenr);
    qemu_put_be32(f, env->cp15.c9_pminten);
A
aurel32 已提交
54 55 56 57 58 59
    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);
60 61 62
    qemu_put_be32(f, env->cp15.c15_power_control);
    qemu_put_be32(f, env->cp15.c15_diagnostic);
    qemu_put_be32(f, env->cp15.c15_power_diagnostic);
A
aurel32 已提交
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107

    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);
    }
P
Paul Brook 已提交
108 109 110 111 112

    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
        qemu_put_be32(f, env->teecr);
        qemu_put_be32(f, env->teehbr);
    }
A
aurel32 已提交
113 114 115 116 117 118
}

int cpu_load(QEMUFile *f, void *opaque, int version_id)
{
    CPUARMState *env = (CPUARMState *)opaque;
    int i;
P
Paul Brook 已提交
119
    uint32_t val;
A
aurel32 已提交
120

121
    if (version_id != CPU_SAVE_VERSION)
A
aurel32 已提交
122 123 124 125 126
        return -EINVAL;

    for (i = 0; i < 16; i++) {
        env->regs[i] = qemu_get_be32(f);
    }
P
Paul Brook 已提交
127 128 129 130
    val = qemu_get_be32(f);
    /* Avoid mode switch when restoring CPSR.  */
    env->uncached_cpsr = val & CPSR_M;
    cpsr_write(env, val, 0xffffffff);
A
aurel32 已提交
131 132 133 134 135 136 137 138 139 140 141 142
    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);
P
Paul Brook 已提交
143
    env->cp15.c0_cssel = qemu_get_be32(f);
A
aurel32 已提交
144 145 146
    env->cp15.c1_sys = qemu_get_be32(f);
    env->cp15.c1_coproc = qemu_get_be32(f);
    env->cp15.c1_xscaleauxcr = qemu_get_be32(f);
147
    env->cp15.c1_scr = qemu_get_be32(f);
A
aurel32 已提交
148 149
    env->cp15.c2_base0 = qemu_get_be32(f);
    env->cp15.c2_base1 = qemu_get_be32(f);
P
Paul Brook 已提交
150
    env->cp15.c2_control = qemu_get_be32(f);
A
aurel32 已提交
151
    env->cp15.c2_mask = qemu_get_be32(f);
P
Paul Brook 已提交
152
    env->cp15.c2_base_mask = qemu_get_be32(f);
A
aurel32 已提交
153 154 155 156 157 158 159 160 161 162
    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);
163
    env->cp15.c7_par = qemu_get_be32(f);
A
aurel32 已提交
164 165
    env->cp15.c9_insn = qemu_get_be32(f);
    env->cp15.c9_data = qemu_get_be32(f);
166 167 168 169 170 171
    env->cp15.c9_pmcr = qemu_get_be32(f);
    env->cp15.c9_pmcnten = qemu_get_be32(f);
    env->cp15.c9_pmovsr = qemu_get_be32(f);
    env->cp15.c9_pmxevtyper = qemu_get_be32(f);
    env->cp15.c9_pmuserenr = qemu_get_be32(f);
    env->cp15.c9_pminten = qemu_get_be32(f);
A
aurel32 已提交
172 173 174 175 176 177
    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);
178 179 180
    env->cp15.c15_power_control = qemu_get_be32(f);
    env->cp15.c15_diagnostic = qemu_get_be32(f);
    env->cp15.c15_power_diagnostic = qemu_get_be32(f);
A
aurel32 已提交
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199

    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)) {
200
            for (i = 16;  i < 32; i++) {
A
aurel32 已提交
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
                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);
    }

P
Paul Brook 已提交
227 228 229 230 231
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
        env->teecr = qemu_get_be32(f);
        env->teehbr = qemu_get_be32(f);
    }

A
aurel32 已提交
232 233
    return 0;
}