qemu/target/arm/machine.c
<<
>>
Prefs
   1#include "qemu/osdep.h"
   2#include "qemu-common.h"
   3#include "cpu.h"
   4#include "hw/hw.h"
   5#include "hw/boards.h"
   6#include "qemu/error-report.h"
   7#include "sysemu/kvm.h"
   8#include "kvm_arm.h"
   9#include "internals.h"
  10#include "migration/cpu.h"
  11
  12static bool vfp_needed(void *opaque)
  13{
  14    ARMCPU *cpu = opaque;
  15    CPUARMState *env = &cpu->env;
  16
  17    return arm_feature(env, ARM_FEATURE_VFP);
  18}
  19
  20static int get_fpscr(QEMUFile *f, void *opaque, size_t size,
  21                     VMStateField *field)
  22{
  23    ARMCPU *cpu = opaque;
  24    CPUARMState *env = &cpu->env;
  25    uint32_t val = qemu_get_be32(f);
  26
  27    vfp_set_fpscr(env, val);
  28    return 0;
  29}
  30
  31static int put_fpscr(QEMUFile *f, void *opaque, size_t size,
  32                     VMStateField *field, QJSON *vmdesc)
  33{
  34    ARMCPU *cpu = opaque;
  35    CPUARMState *env = &cpu->env;
  36
  37    qemu_put_be32(f, vfp_get_fpscr(env));
  38    return 0;
  39}
  40
  41static const VMStateInfo vmstate_fpscr = {
  42    .name = "fpscr",
  43    .get = get_fpscr,
  44    .put = put_fpscr,
  45};
  46
  47static const VMStateDescription vmstate_vfp = {
  48    .name = "cpu/vfp",
  49    .version_id = 3,
  50    .minimum_version_id = 3,
  51    .needed = vfp_needed,
  52    .fields = (VMStateField[]) {
  53        VMSTATE_FLOAT64_ARRAY(env.vfp.regs, ARMCPU, 64),
  54        /* The xregs array is a little awkward because element 1 (FPSCR)
  55         * requires a specific accessor, so we have to split it up in
  56         * the vmstate:
  57         */
  58        VMSTATE_UINT32(env.vfp.xregs[0], ARMCPU),
  59        VMSTATE_UINT32_SUB_ARRAY(env.vfp.xregs, ARMCPU, 2, 14),
  60        {
  61            .name = "fpscr",
  62            .version_id = 0,
  63            .size = sizeof(uint32_t),
  64            .info = &vmstate_fpscr,
  65            .flags = VMS_SINGLE,
  66            .offset = 0,
  67        },
  68        VMSTATE_END_OF_LIST()
  69    }
  70};
  71
  72static bool iwmmxt_needed(void *opaque)
  73{
  74    ARMCPU *cpu = opaque;
  75    CPUARMState *env = &cpu->env;
  76
  77    return arm_feature(env, ARM_FEATURE_IWMMXT);
  78}
  79
  80static const VMStateDescription vmstate_iwmmxt = {
  81    .name = "cpu/iwmmxt",
  82    .version_id = 1,
  83    .minimum_version_id = 1,
  84    .needed = iwmmxt_needed,
  85    .fields = (VMStateField[]) {
  86        VMSTATE_UINT64_ARRAY(env.iwmmxt.regs, ARMCPU, 16),
  87        VMSTATE_UINT32_ARRAY(env.iwmmxt.cregs, ARMCPU, 16),
  88        VMSTATE_END_OF_LIST()
  89    }
  90};
  91
  92static bool m_needed(void *opaque)
  93{
  94    ARMCPU *cpu = opaque;
  95    CPUARMState *env = &cpu->env;
  96
  97    return arm_feature(env, ARM_FEATURE_M);
  98}
  99
 100static const VMStateDescription vmstate_m_faultmask_primask = {
 101    .name = "cpu/m/faultmask-primask",
 102    .version_id = 1,
 103    .minimum_version_id = 1,
 104    .fields = (VMStateField[]) {
 105        VMSTATE_UINT32(env.v7m.faultmask[M_REG_NS], ARMCPU),
 106        VMSTATE_UINT32(env.v7m.primask[M_REG_NS], ARMCPU),
 107        VMSTATE_END_OF_LIST()
 108    }
 109};
 110
 111static const VMStateDescription vmstate_m = {
 112    .name = "cpu/m",
 113    .version_id = 4,
 114    .minimum_version_id = 4,
 115    .needed = m_needed,
 116    .fields = (VMStateField[]) {
 117        VMSTATE_UINT32(env.v7m.vecbase[M_REG_NS], ARMCPU),
 118        VMSTATE_UINT32(env.v7m.basepri[M_REG_NS], ARMCPU),
 119        VMSTATE_UINT32(env.v7m.control[M_REG_NS], ARMCPU),
 120        VMSTATE_UINT32(env.v7m.ccr[M_REG_NS], ARMCPU),
 121        VMSTATE_UINT32(env.v7m.cfsr[M_REG_NS], ARMCPU),
 122        VMSTATE_UINT32(env.v7m.hfsr, ARMCPU),
 123        VMSTATE_UINT32(env.v7m.dfsr, ARMCPU),
 124        VMSTATE_UINT32(env.v7m.mmfar[M_REG_NS], ARMCPU),
 125        VMSTATE_UINT32(env.v7m.bfar, ARMCPU),
 126        VMSTATE_UINT32(env.v7m.mpu_ctrl[M_REG_NS], ARMCPU),
 127        VMSTATE_INT32(env.v7m.exception, ARMCPU),
 128        VMSTATE_END_OF_LIST()
 129    },
 130    .subsections = (const VMStateDescription*[]) {
 131        &vmstate_m_faultmask_primask,
 132        NULL
 133    }
 134};
 135
 136static bool thumb2ee_needed(void *opaque)
 137{
 138    ARMCPU *cpu = opaque;
 139    CPUARMState *env = &cpu->env;
 140
 141    return arm_feature(env, ARM_FEATURE_THUMB2EE);
 142}
 143
 144static const VMStateDescription vmstate_thumb2ee = {
 145    .name = "cpu/thumb2ee",
 146    .version_id = 1,
 147    .minimum_version_id = 1,
 148    .needed = thumb2ee_needed,
 149    .fields = (VMStateField[]) {
 150        VMSTATE_UINT32(env.teecr, ARMCPU),
 151        VMSTATE_UINT32(env.teehbr, ARMCPU),
 152        VMSTATE_END_OF_LIST()
 153    }
 154};
 155
 156static bool pmsav7_needed(void *opaque)
 157{
 158    ARMCPU *cpu = opaque;
 159    CPUARMState *env = &cpu->env;
 160
 161    return arm_feature(env, ARM_FEATURE_PMSA) &&
 162           arm_feature(env, ARM_FEATURE_V7) &&
 163           !arm_feature(env, ARM_FEATURE_V8);
 164}
 165
 166static bool pmsav7_rgnr_vmstate_validate(void *opaque, int version_id)
 167{
 168    ARMCPU *cpu = opaque;
 169
 170    return cpu->env.pmsav7.rnr[M_REG_NS] < cpu->pmsav7_dregion;
 171}
 172
 173static const VMStateDescription vmstate_pmsav7 = {
 174    .name = "cpu/pmsav7",
 175    .version_id = 1,
 176    .minimum_version_id = 1,
 177    .needed = pmsav7_needed,
 178    .fields = (VMStateField[]) {
 179        VMSTATE_VARRAY_UINT32(env.pmsav7.drbar, ARMCPU, pmsav7_dregion, 0,
 180                              vmstate_info_uint32, uint32_t),
 181        VMSTATE_VARRAY_UINT32(env.pmsav7.drsr, ARMCPU, pmsav7_dregion, 0,
 182                              vmstate_info_uint32, uint32_t),
 183        VMSTATE_VARRAY_UINT32(env.pmsav7.dracr, ARMCPU, pmsav7_dregion, 0,
 184                              vmstate_info_uint32, uint32_t),
 185        VMSTATE_VALIDATE("rgnr is valid", pmsav7_rgnr_vmstate_validate),
 186        VMSTATE_END_OF_LIST()
 187    }
 188};
 189
 190static bool pmsav7_rnr_needed(void *opaque)
 191{
 192    ARMCPU *cpu = opaque;
 193    CPUARMState *env = &cpu->env;
 194
 195    /* For R profile cores pmsav7.rnr is migrated via the cpreg
 196     * "RGNR" definition in helper.h. For M profile we have to
 197     * migrate it separately.
 198     */
 199    return arm_feature(env, ARM_FEATURE_M);
 200}
 201
 202static const VMStateDescription vmstate_pmsav7_rnr = {
 203    .name = "cpu/pmsav7-rnr",
 204    .version_id = 1,
 205    .minimum_version_id = 1,
 206    .needed = pmsav7_rnr_needed,
 207    .fields = (VMStateField[]) {
 208        VMSTATE_UINT32(env.pmsav7.rnr[M_REG_NS], ARMCPU),
 209        VMSTATE_END_OF_LIST()
 210    }
 211};
 212
 213static bool pmsav8_needed(void *opaque)
 214{
 215    ARMCPU *cpu = opaque;
 216    CPUARMState *env = &cpu->env;
 217
 218    return arm_feature(env, ARM_FEATURE_PMSA) &&
 219        arm_feature(env, ARM_FEATURE_V8);
 220}
 221
 222static const VMStateDescription vmstate_pmsav8 = {
 223    .name = "cpu/pmsav8",
 224    .version_id = 1,
 225    .minimum_version_id = 1,
 226    .needed = pmsav8_needed,
 227    .fields = (VMStateField[]) {
 228        VMSTATE_VARRAY_UINT32(env.pmsav8.rbar[M_REG_NS], ARMCPU, pmsav7_dregion,
 229                              0, vmstate_info_uint32, uint32_t),
 230        VMSTATE_VARRAY_UINT32(env.pmsav8.rlar[M_REG_NS], ARMCPU, pmsav7_dregion,
 231                              0, vmstate_info_uint32, uint32_t),
 232        VMSTATE_UINT32(env.pmsav8.mair0[M_REG_NS], ARMCPU),
 233        VMSTATE_UINT32(env.pmsav8.mair1[M_REG_NS], ARMCPU),
 234        VMSTATE_END_OF_LIST()
 235    }
 236};
 237
 238static bool s_rnr_vmstate_validate(void *opaque, int version_id)
 239{
 240    ARMCPU *cpu = opaque;
 241
 242    return cpu->env.pmsav7.rnr[M_REG_S] < cpu->pmsav7_dregion;
 243}
 244
 245static bool sau_rnr_vmstate_validate(void *opaque, int version_id)
 246{
 247    ARMCPU *cpu = opaque;
 248
 249    return cpu->env.sau.rnr < cpu->sau_sregion;
 250}
 251
 252static bool m_security_needed(void *opaque)
 253{
 254    ARMCPU *cpu = opaque;
 255    CPUARMState *env = &cpu->env;
 256
 257    return arm_feature(env, ARM_FEATURE_M_SECURITY);
 258}
 259
 260static const VMStateDescription vmstate_m_security = {
 261    .name = "cpu/m-security",
 262    .version_id = 1,
 263    .minimum_version_id = 1,
 264    .needed = m_security_needed,
 265    .fields = (VMStateField[]) {
 266        VMSTATE_UINT32(env.v7m.secure, ARMCPU),
 267        VMSTATE_UINT32(env.v7m.other_ss_msp, ARMCPU),
 268        VMSTATE_UINT32(env.v7m.other_ss_psp, ARMCPU),
 269        VMSTATE_UINT32(env.v7m.basepri[M_REG_S], ARMCPU),
 270        VMSTATE_UINT32(env.v7m.primask[M_REG_S], ARMCPU),
 271        VMSTATE_UINT32(env.v7m.faultmask[M_REG_S], ARMCPU),
 272        VMSTATE_UINT32(env.v7m.control[M_REG_S], ARMCPU),
 273        VMSTATE_UINT32(env.v7m.vecbase[M_REG_S], ARMCPU),
 274        VMSTATE_UINT32(env.pmsav8.mair0[M_REG_S], ARMCPU),
 275        VMSTATE_UINT32(env.pmsav8.mair1[M_REG_S], ARMCPU),
 276        VMSTATE_VARRAY_UINT32(env.pmsav8.rbar[M_REG_S], ARMCPU, pmsav7_dregion,
 277                              0, vmstate_info_uint32, uint32_t),
 278        VMSTATE_VARRAY_UINT32(env.pmsav8.rlar[M_REG_S], ARMCPU, pmsav7_dregion,
 279                              0, vmstate_info_uint32, uint32_t),
 280        VMSTATE_UINT32(env.pmsav7.rnr[M_REG_S], ARMCPU),
 281        VMSTATE_VALIDATE("secure MPU_RNR is valid", s_rnr_vmstate_validate),
 282        VMSTATE_UINT32(env.v7m.mpu_ctrl[M_REG_S], ARMCPU),
 283        VMSTATE_UINT32(env.v7m.ccr[M_REG_S], ARMCPU),
 284        VMSTATE_UINT32(env.v7m.mmfar[M_REG_S], ARMCPU),
 285        VMSTATE_UINT32(env.v7m.cfsr[M_REG_S], ARMCPU),
 286        VMSTATE_UINT32(env.v7m.sfsr, ARMCPU),
 287        VMSTATE_UINT32(env.v7m.sfar, ARMCPU),
 288        VMSTATE_VARRAY_UINT32(env.sau.rbar, ARMCPU, sau_sregion, 0,
 289                              vmstate_info_uint32, uint32_t),
 290        VMSTATE_VARRAY_UINT32(env.sau.rlar, ARMCPU, sau_sregion, 0,
 291                              vmstate_info_uint32, uint32_t),
 292        VMSTATE_UINT32(env.sau.rnr, ARMCPU),
 293        VMSTATE_VALIDATE("SAU_RNR is valid", sau_rnr_vmstate_validate),
 294        VMSTATE_UINT32(env.sau.ctrl, ARMCPU),
 295        VMSTATE_END_OF_LIST()
 296    }
 297};
 298
 299static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
 300                    VMStateField *field)
 301{
 302    ARMCPU *cpu = opaque;
 303    CPUARMState *env = &cpu->env;
 304    uint32_t val = qemu_get_be32(f);
 305
 306    if (arm_feature(env, ARM_FEATURE_M)) {
 307        if (val & XPSR_EXCP) {
 308            /* This is a CPSR format value from an older QEMU. (We can tell
 309             * because values transferred in XPSR format always have zero
 310             * for the EXCP field, and CPSR format will always have bit 4
 311             * set in CPSR_M.) Rearrange it into XPSR format. The significant
 312             * differences are that the T bit is not in the same place, the
 313             * primask/faultmask info may be in the CPSR I and F bits, and
 314             * we do not want the mode bits.
 315             * We know that this cleanup happened before v8M, so there
 316             * is no complication with banked primask/faultmask.
 317             */
 318            uint32_t newval = val;
 319
 320            assert(!arm_feature(env, ARM_FEATURE_M_SECURITY));
 321
 322            newval &= (CPSR_NZCV | CPSR_Q | CPSR_IT | CPSR_GE);
 323            if (val & CPSR_T) {
 324                newval |= XPSR_T;
 325            }
 326            /* If the I or F bits are set then this is a migration from
 327             * an old QEMU which still stored the M profile FAULTMASK
 328             * and PRIMASK in env->daif. For a new QEMU, the data is
 329             * transferred using the vmstate_m_faultmask_primask subsection.
 330             */
 331            if (val & CPSR_F) {
 332                env->v7m.faultmask[M_REG_NS] = 1;
 333            }
 334            if (val & CPSR_I) {
 335                env->v7m.primask[M_REG_NS] = 1;
 336            }
 337            val = newval;
 338        }
 339        /* Ignore the low bits, they are handled by vmstate_m. */
 340        xpsr_write(env, val, ~XPSR_EXCP);
 341        return 0;
 342    }
 343
 344    env->aarch64 = ((val & PSTATE_nRW) == 0);
 345
 346    if (is_a64(env)) {
 347        pstate_write(env, val);
 348        return 0;
 349    }
 350
 351    cpsr_write(env, val, 0xffffffff, CPSRWriteRaw);
 352    return 0;
 353}
 354
 355static int put_cpsr(QEMUFile *f, void *opaque, size_t size,
 356                    VMStateField *field, QJSON *vmdesc)
 357{
 358    ARMCPU *cpu = opaque;
 359    CPUARMState *env = &cpu->env;
 360    uint32_t val;
 361
 362    if (arm_feature(env, ARM_FEATURE_M)) {
 363        /* The low 9 bits are v7m.exception, which is handled by vmstate_m. */
 364        val = xpsr_read(env) & ~XPSR_EXCP;
 365    } else if (is_a64(env)) {
 366        val = pstate_read(env);
 367    } else {
 368        val = cpsr_read(env);
 369    }
 370
 371    qemu_put_be32(f, val);
 372    return 0;
 373}
 374
 375static const VMStateInfo vmstate_cpsr = {
 376    .name = "cpsr",
 377    .get = get_cpsr,
 378    .put = put_cpsr,
 379};
 380
 381static int get_power(QEMUFile *f, void *opaque, size_t size,
 382                    VMStateField *field)
 383{
 384    ARMCPU *cpu = opaque;
 385    bool powered_off = qemu_get_byte(f);
 386    cpu->power_state = powered_off ? PSCI_OFF : PSCI_ON;
 387    return 0;
 388}
 389
 390static int put_power(QEMUFile *f, void *opaque, size_t size,
 391                    VMStateField *field, QJSON *vmdesc)
 392{
 393    ARMCPU *cpu = opaque;
 394
 395    /* Migration should never happen while we transition power states */
 396
 397    if (cpu->power_state == PSCI_ON ||
 398        cpu->power_state == PSCI_OFF) {
 399        bool powered_off = (cpu->power_state == PSCI_OFF) ? true : false;
 400        qemu_put_byte(f, powered_off);
 401        return 0;
 402    } else {
 403        return 1;
 404    }
 405}
 406
 407static const VMStateInfo vmstate_powered_off = {
 408    .name = "powered_off",
 409    .get = get_power,
 410    .put = put_power,
 411};
 412
 413static int cpu_pre_save(void *opaque)
 414{
 415    ARMCPU *cpu = opaque;
 416
 417    if (kvm_enabled()) {
 418        if (!write_kvmstate_to_list(cpu)) {
 419            /* This should never fail */
 420            abort();
 421        }
 422    } else {
 423        if (!write_cpustate_to_list(cpu)) {
 424            /* This should never fail. */
 425            abort();
 426        }
 427    }
 428
 429    cpu->cpreg_vmstate_array_len = cpu->cpreg_array_len;
 430    memcpy(cpu->cpreg_vmstate_indexes, cpu->cpreg_indexes,
 431           cpu->cpreg_array_len * sizeof(uint64_t));
 432    memcpy(cpu->cpreg_vmstate_values, cpu->cpreg_values,
 433           cpu->cpreg_array_len * sizeof(uint64_t));
 434
 435    return 0;
 436}
 437
 438static int cpu_post_load(void *opaque, int version_id)
 439{
 440    ARMCPU *cpu = opaque;
 441    int i, v;
 442
 443    /* Update the values list from the incoming migration data.
 444     * Anything in the incoming data which we don't know about is
 445     * a migration failure; anything we know about but the incoming
 446     * data doesn't specify retains its current (reset) value.
 447     * The indexes list remains untouched -- we only inspect the
 448     * incoming migration index list so we can match the values array
 449     * entries with the right slots in our own values array.
 450     */
 451
 452    for (i = 0, v = 0; i < cpu->cpreg_array_len
 453             && v < cpu->cpreg_vmstate_array_len; i++) {
 454        if (cpu->cpreg_vmstate_indexes[v] > cpu->cpreg_indexes[i]) {
 455            /* register in our list but not incoming : skip it */
 456            continue;
 457        }
 458        if (cpu->cpreg_vmstate_indexes[v] < cpu->cpreg_indexes[i]) {
 459            /* register in their list but not ours: fail migration */
 460            return -1;
 461        }
 462        /* matching register, copy the value over */
 463        cpu->cpreg_values[i] = cpu->cpreg_vmstate_values[v];
 464        v++;
 465    }
 466
 467    if (kvm_enabled()) {
 468        if (!write_list_to_kvmstate(cpu, KVM_PUT_FULL_STATE)) {
 469            return -1;
 470        }
 471        /* Note that it's OK for the TCG side not to know about
 472         * every register in the list; KVM is authoritative if
 473         * we're using it.
 474         */
 475        write_list_to_cpustate(cpu);
 476    } else {
 477        if (!write_list_to_cpustate(cpu)) {
 478            return -1;
 479        }
 480    }
 481
 482    hw_breakpoint_update_all(cpu);
 483    hw_watchpoint_update_all(cpu);
 484
 485    return 0;
 486}
 487
 488const VMStateDescription vmstate_arm_cpu = {
 489    .name = "cpu",
 490    .version_id = 22,
 491    .minimum_version_id = 22,
 492    .pre_save = cpu_pre_save,
 493    .post_load = cpu_post_load,
 494    .fields = (VMStateField[]) {
 495        VMSTATE_UINT32_ARRAY(env.regs, ARMCPU, 16),
 496        VMSTATE_UINT64_ARRAY(env.xregs, ARMCPU, 32),
 497        VMSTATE_UINT64(env.pc, ARMCPU),
 498        {
 499            .name = "cpsr",
 500            .version_id = 0,
 501            .size = sizeof(uint32_t),
 502            .info = &vmstate_cpsr,
 503            .flags = VMS_SINGLE,
 504            .offset = 0,
 505        },
 506        VMSTATE_UINT32(env.spsr, ARMCPU),
 507        VMSTATE_UINT64_ARRAY(env.banked_spsr, ARMCPU, 8),
 508        VMSTATE_UINT32_ARRAY(env.banked_r13, ARMCPU, 8),
 509        VMSTATE_UINT32_ARRAY(env.banked_r14, ARMCPU, 8),
 510        VMSTATE_UINT32_ARRAY(env.usr_regs, ARMCPU, 5),
 511        VMSTATE_UINT32_ARRAY(env.fiq_regs, ARMCPU, 5),
 512        VMSTATE_UINT64_ARRAY(env.elr_el, ARMCPU, 4),
 513        VMSTATE_UINT64_ARRAY(env.sp_el, ARMCPU, 4),
 514        /* The length-check must come before the arrays to avoid
 515         * incoming data possibly overflowing the array.
 516         */
 517        VMSTATE_INT32_POSITIVE_LE(cpreg_vmstate_array_len, ARMCPU),
 518        VMSTATE_VARRAY_INT32(cpreg_vmstate_indexes, ARMCPU,
 519                             cpreg_vmstate_array_len,
 520                             0, vmstate_info_uint64, uint64_t),
 521        VMSTATE_VARRAY_INT32(cpreg_vmstate_values, ARMCPU,
 522                             cpreg_vmstate_array_len,
 523                             0, vmstate_info_uint64, uint64_t),
 524        VMSTATE_UINT64(env.exclusive_addr, ARMCPU),
 525        VMSTATE_UINT64(env.exclusive_val, ARMCPU),
 526        VMSTATE_UINT64(env.exclusive_high, ARMCPU),
 527        VMSTATE_UINT64(env.features, ARMCPU),
 528        VMSTATE_UINT32(env.exception.syndrome, ARMCPU),
 529        VMSTATE_UINT32(env.exception.fsr, ARMCPU),
 530        VMSTATE_UINT64(env.exception.vaddress, ARMCPU),
 531        VMSTATE_TIMER_PTR(gt_timer[GTIMER_PHYS], ARMCPU),
 532        VMSTATE_TIMER_PTR(gt_timer[GTIMER_VIRT], ARMCPU),
 533        {
 534            .name = "power_state",
 535            .version_id = 0,
 536            .size = sizeof(bool),
 537            .info = &vmstate_powered_off,
 538            .flags = VMS_SINGLE,
 539            .offset = 0,
 540        },
 541        VMSTATE_END_OF_LIST()
 542    },
 543    .subsections = (const VMStateDescription*[]) {
 544        &vmstate_vfp,
 545        &vmstate_iwmmxt,
 546        &vmstate_m,
 547        &vmstate_thumb2ee,
 548        /* pmsav7_rnr must come before pmsav7 so that we have the
 549         * region number before we test it in the VMSTATE_VALIDATE
 550         * in vmstate_pmsav7.
 551         */
 552        &vmstate_pmsav7_rnr,
 553        &vmstate_pmsav7,
 554        &vmstate_pmsav8,
 555        &vmstate_m_security,
 556        NULL
 557    }
 558};
 559