qemu/target/m68k/cpu.c
<<
>>
Prefs
   1/*
   2 * QEMU Motorola 68k CPU
   3 *
   4 * Copyright (c) 2012 SUSE LINUX Products GmbH
   5 *
   6 * This library is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU Lesser General Public
   8 * License as published by the Free Software Foundation; either
   9 * version 2.1 of the License, or (at your option) any later version.
  10 *
  11 * This library is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14 * Lesser General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU Lesser General Public
  17 * License along with this library; if not, see
  18 * <http://www.gnu.org/licenses/lgpl-2.1.html>
  19 */
  20
  21#include "qemu/osdep.h"
  22#include "qapi/error.h"
  23#include "cpu.h"
  24#include "migration/vmstate.h"
  25#include "fpu/softfloat.h"
  26
  27static void m68k_cpu_set_pc(CPUState *cs, vaddr value)
  28{
  29    M68kCPU *cpu = M68K_CPU(cs);
  30
  31    cpu->env.pc = value;
  32}
  33
  34static bool m68k_cpu_has_work(CPUState *cs)
  35{
  36    return cs->interrupt_request & CPU_INTERRUPT_HARD;
  37}
  38
  39static void m68k_set_feature(CPUM68KState *env, int feature)
  40{
  41    env->features |= (1u << feature);
  42}
  43
  44static void m68k_unset_feature(CPUM68KState *env, int feature)
  45{
  46    env->features &= (-1u - (1u << feature));
  47}
  48
  49static void m68k_cpu_reset(DeviceState *dev)
  50{
  51    CPUState *s = CPU(dev);
  52    M68kCPU *cpu = M68K_CPU(s);
  53    M68kCPUClass *mcc = M68K_CPU_GET_CLASS(cpu);
  54    CPUM68KState *env = &cpu->env;
  55    floatx80 nan = floatx80_default_nan(NULL);
  56    int i;
  57
  58    mcc->parent_reset(dev);
  59
  60    memset(env, 0, offsetof(CPUM68KState, end_reset_fields));
  61#ifdef CONFIG_SOFTMMU
  62    cpu_m68k_set_sr(env, SR_S | SR_I);
  63#else
  64    cpu_m68k_set_sr(env, 0);
  65#endif
  66    for (i = 0; i < 8; i++) {
  67        env->fregs[i].d = nan;
  68    }
  69    cpu_m68k_set_fpcr(env, 0);
  70    env->fpsr = 0;
  71
  72    /* TODO: We should set PC from the interrupt vector.  */
  73    env->pc = 0;
  74}
  75
  76static void m68k_cpu_disas_set_info(CPUState *s, disassemble_info *info)
  77{
  78    M68kCPU *cpu = M68K_CPU(s);
  79    CPUM68KState *env = &cpu->env;
  80    info->print_insn = print_insn_m68k;
  81    if (m68k_feature(env, M68K_FEATURE_M68000)) {
  82        info->mach = bfd_mach_m68040;
  83    }
  84}
  85
  86/* CPU models */
  87
  88static ObjectClass *m68k_cpu_class_by_name(const char *cpu_model)
  89{
  90    ObjectClass *oc;
  91    char *typename;
  92
  93    typename = g_strdup_printf(M68K_CPU_TYPE_NAME("%s"), cpu_model);
  94    oc = object_class_by_name(typename);
  95    g_free(typename);
  96    if (oc != NULL && (object_class_dynamic_cast(oc, TYPE_M68K_CPU) == NULL ||
  97                       object_class_is_abstract(oc))) {
  98        return NULL;
  99    }
 100    return oc;
 101}
 102
 103static void m5206_cpu_initfn(Object *obj)
 104{
 105    M68kCPU *cpu = M68K_CPU(obj);
 106    CPUM68KState *env = &cpu->env;
 107
 108    m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
 109}
 110
 111/* Base feature set, including isns. for m68k family */
 112static void m68000_cpu_initfn(Object *obj)
 113{
 114    M68kCPU *cpu = M68K_CPU(obj);
 115    CPUM68KState *env = &cpu->env;
 116
 117    m68k_set_feature(env, M68K_FEATURE_M68000);
 118    m68k_set_feature(env, M68K_FEATURE_USP);
 119    m68k_set_feature(env, M68K_FEATURE_WORD_INDEX);
 120    m68k_set_feature(env, M68K_FEATURE_MOVEP);
 121}
 122
 123/*
 124 * Adds BKPT, MOVE-from-SR *now priv instr, and MOVEC, MOVES, RTD
 125 */
 126static void m68010_cpu_initfn(Object *obj)
 127{
 128    M68kCPU *cpu = M68K_CPU(obj);
 129    CPUM68KState *env = &cpu->env;
 130
 131    m68000_cpu_initfn(obj);
 132    m68k_set_feature(env, M68K_FEATURE_M68010);
 133    m68k_set_feature(env, M68K_FEATURE_RTD);
 134    m68k_set_feature(env, M68K_FEATURE_BKPT);
 135    m68k_set_feature(env, M68K_FEATURE_MOVEC);
 136}
 137
 138/*
 139 * Adds BFCHG, BFCLR, BFEXTS, BFEXTU, BFFFO, BFINS, BFSET, BFTST, CAS, CAS2,
 140 *      CHK2, CMP2, DIVSL, DIVUL, EXTB, PACK, TRAPcc, UNPK.
 141 *
 142 * 68020/30 only:
 143 *      CALLM, cpBcc, cpDBcc, cpGEN, cpRESTORE, cpSAVE, cpScc, cpTRAPcc
 144 */
 145static void m68020_cpu_initfn(Object *obj)
 146{
 147    M68kCPU *cpu = M68K_CPU(obj);
 148    CPUM68KState *env = &cpu->env;
 149
 150    m68010_cpu_initfn(obj);
 151    m68k_unset_feature(env, M68K_FEATURE_M68010);
 152    m68k_set_feature(env, M68K_FEATURE_M68020);
 153    m68k_set_feature(env, M68K_FEATURE_QUAD_MULDIV);
 154    m68k_set_feature(env, M68K_FEATURE_BRAL);
 155    m68k_set_feature(env, M68K_FEATURE_BCCL);
 156    m68k_set_feature(env, M68K_FEATURE_BITFIELD);
 157    m68k_set_feature(env, M68K_FEATURE_EXT_FULL);
 158    m68k_set_feature(env, M68K_FEATURE_SCALED_INDEX);
 159    m68k_set_feature(env, M68K_FEATURE_LONG_MULDIV);
 160    m68k_set_feature(env, M68K_FEATURE_FPU);
 161    m68k_set_feature(env, M68K_FEATURE_CAS);
 162    m68k_set_feature(env, M68K_FEATURE_CHK2);
 163    m68k_set_feature(env, M68K_FEATURE_MSP);
 164    m68k_set_feature(env, M68K_FEATURE_UNALIGNED_DATA);
 165}
 166
 167/*
 168 * Adds: PFLUSH (*5)
 169 * 68030 Only: PFLUSHA (*5), PLOAD (*5), PMOVE
 170 * 68030/40 Only: PTEST
 171 *
 172 * NOTES:
 173 *  5. Not valid on MC68EC030
 174 */
 175static void m68030_cpu_initfn(Object *obj)
 176{
 177    M68kCPU *cpu = M68K_CPU(obj);
 178    CPUM68KState *env = &cpu->env;
 179
 180    m68020_cpu_initfn(obj);
 181    m68k_unset_feature(env, M68K_FEATURE_M68020);
 182    m68k_set_feature(env, M68K_FEATURE_M68030);
 183}
 184
 185/*
 186 * Adds: CINV, CPUSH
 187 * Adds all with Note *2: FABS, FSABS, FDABS, FADD, FSADD, FDADD, FBcc, FCMP,
 188 *                        FDBcc, FDIV, FSDIV, FDDIV, FMOVE, FSMOVE, FDMOVE,
 189 *                        FMOVEM, FMUL, FSMUL, FDMUL, FNEG, FSNEG, FDNEG, FNOP,
 190 *                        FRESTORE, FSAVE, FScc, FSQRT, FSSQRT, FDSQRT, FSUB,
 191 *                        FSSUB, FDSUB, FTRAPcc, FTST
 192 *
 193 * Adds with Notes *2, and *3: FACOS, FASIN, FATAN, FATANH, FCOS, FCOSH, FETOX,
 194 *                             FETOXM, FGETEXP, FGETMAN, FINT, FINTRZ, FLOG10,
 195 *                             FLOG2, FLOGN, FLOGNP1, FMOD, FMOVECR, FREM,
 196 *                             FSCALE, FSGLDIV, FSGLMUL, FSIN, FSINCOS, FSINH,
 197 *                             FTAN, FTANH, FTENTOX, FTWOTOX
 198 * NOTES:
 199 * 2. Not applicable to the MC68EC040, MC68LC040, MC68EC060, and MC68LC060.
 200 * 3. These are software-supported instructions on the MC68040 and MC68060.
 201 */
 202static void m68040_cpu_initfn(Object *obj)
 203{
 204    M68kCPU *cpu = M68K_CPU(obj);
 205    CPUM68KState *env = &cpu->env;
 206
 207    m68030_cpu_initfn(obj);
 208    m68k_unset_feature(env, M68K_FEATURE_M68030);
 209    m68k_set_feature(env, M68K_FEATURE_M68040);
 210}
 211
 212/*
 213 * Adds: PLPA
 214 * Adds all with Note *2: CAS, CAS2, MULS, MULU, CHK2, CMP2, DIVS, DIVU
 215 * All Fxxxx instructions are as per m68040 with exception to; FMOVEM NOTE3
 216 *
 217 * Does NOT implement MOVEP
 218 *
 219 * NOTES:
 220 * 2. Not applicable to the MC68EC040, MC68LC040, MC68EC060, and MC68LC060.
 221 * 3. These are software-supported instructions on the MC68040 and MC68060.
 222 */
 223static void m68060_cpu_initfn(Object *obj)
 224{
 225    M68kCPU *cpu = M68K_CPU(obj);
 226    CPUM68KState *env = &cpu->env;
 227
 228    m68040_cpu_initfn(obj);
 229    m68k_unset_feature(env, M68K_FEATURE_M68040);
 230    m68k_set_feature(env, M68K_FEATURE_M68060);
 231    m68k_unset_feature(env, M68K_FEATURE_MOVEP);
 232
 233    /* Implemented as a software feature */
 234    m68k_unset_feature(env, M68K_FEATURE_QUAD_MULDIV);
 235}
 236
 237static void m5208_cpu_initfn(Object *obj)
 238{
 239    M68kCPU *cpu = M68K_CPU(obj);
 240    CPUM68KState *env = &cpu->env;
 241
 242    m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
 243    m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC);
 244    m68k_set_feature(env, M68K_FEATURE_BRAL);
 245    m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
 246    m68k_set_feature(env, M68K_FEATURE_USP);
 247}
 248
 249static void cfv4e_cpu_initfn(Object *obj)
 250{
 251    M68kCPU *cpu = M68K_CPU(obj);
 252    CPUM68KState *env = &cpu->env;
 253
 254    m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
 255    m68k_set_feature(env, M68K_FEATURE_CF_ISA_B);
 256    m68k_set_feature(env, M68K_FEATURE_BRAL);
 257    m68k_set_feature(env, M68K_FEATURE_CF_FPU);
 258    m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
 259    m68k_set_feature(env, M68K_FEATURE_USP);
 260}
 261
 262static void any_cpu_initfn(Object *obj)
 263{
 264    M68kCPU *cpu = M68K_CPU(obj);
 265    CPUM68KState *env = &cpu->env;
 266
 267    m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
 268    m68k_set_feature(env, M68K_FEATURE_CF_ISA_B);
 269    m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC);
 270    m68k_set_feature(env, M68K_FEATURE_BRAL);
 271    m68k_set_feature(env, M68K_FEATURE_CF_FPU);
 272    /*
 273     * MAC and EMAC are mututally exclusive, so pick EMAC.
 274     * It's mostly backwards compatible.
 275     */
 276    m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
 277    m68k_set_feature(env, M68K_FEATURE_CF_EMAC_B);
 278    m68k_set_feature(env, M68K_FEATURE_USP);
 279    m68k_set_feature(env, M68K_FEATURE_EXT_FULL);
 280    m68k_set_feature(env, M68K_FEATURE_WORD_INDEX);
 281}
 282
 283static void m68k_cpu_realizefn(DeviceState *dev, Error **errp)
 284{
 285    CPUState *cs = CPU(dev);
 286    M68kCPU *cpu = M68K_CPU(dev);
 287    M68kCPUClass *mcc = M68K_CPU_GET_CLASS(dev);
 288    Error *local_err = NULL;
 289
 290    register_m68k_insns(&cpu->env);
 291
 292    cpu_exec_realizefn(cs, &local_err);
 293    if (local_err != NULL) {
 294        error_propagate(errp, local_err);
 295        return;
 296    }
 297
 298    m68k_cpu_init_gdb(cpu);
 299
 300    cpu_reset(cs);
 301    qemu_init_vcpu(cs);
 302
 303    mcc->parent_realize(dev, errp);
 304}
 305
 306static void m68k_cpu_initfn(Object *obj)
 307{
 308    M68kCPU *cpu = M68K_CPU(obj);
 309
 310    cpu_set_cpustate_pointers(cpu);
 311}
 312
 313#if defined(CONFIG_SOFTMMU)
 314static bool fpu_needed(void *opaque)
 315{
 316    M68kCPU *s = opaque;
 317
 318    return m68k_feature(&s->env, M68K_FEATURE_CF_FPU) ||
 319           m68k_feature(&s->env, M68K_FEATURE_FPU);
 320}
 321
 322typedef struct m68k_FPReg_tmp {
 323    FPReg *parent;
 324    uint64_t tmp_mant;
 325    uint16_t tmp_exp;
 326} m68k_FPReg_tmp;
 327
 328static void cpu_get_fp80(uint64_t *pmant, uint16_t *pexp, floatx80 f)
 329{
 330    CPU_LDoubleU temp;
 331
 332    temp.d = f;
 333    *pmant = temp.l.lower;
 334    *pexp = temp.l.upper;
 335}
 336
 337static floatx80 cpu_set_fp80(uint64_t mant, uint16_t upper)
 338{
 339    CPU_LDoubleU temp;
 340
 341    temp.l.upper = upper;
 342    temp.l.lower = mant;
 343    return temp.d;
 344}
 345
 346static int freg_pre_save(void *opaque)
 347{
 348    m68k_FPReg_tmp *tmp = opaque;
 349
 350    cpu_get_fp80(&tmp->tmp_mant, &tmp->tmp_exp, tmp->parent->d);
 351
 352    return 0;
 353}
 354
 355static int freg_post_load(void *opaque, int version)
 356{
 357    m68k_FPReg_tmp *tmp = opaque;
 358
 359    tmp->parent->d = cpu_set_fp80(tmp->tmp_mant, tmp->tmp_exp);
 360
 361    return 0;
 362}
 363
 364static const VMStateDescription vmstate_freg_tmp = {
 365    .name = "freg_tmp",
 366    .post_load = freg_post_load,
 367    .pre_save  = freg_pre_save,
 368    .fields = (VMStateField[]) {
 369        VMSTATE_UINT64(tmp_mant, m68k_FPReg_tmp),
 370        VMSTATE_UINT16(tmp_exp, m68k_FPReg_tmp),
 371        VMSTATE_END_OF_LIST()
 372    }
 373};
 374
 375static const VMStateDescription vmstate_freg = {
 376    .name = "freg",
 377    .fields = (VMStateField[]) {
 378        VMSTATE_WITH_TMP(FPReg, m68k_FPReg_tmp, vmstate_freg_tmp),
 379        VMSTATE_END_OF_LIST()
 380    }
 381};
 382
 383static int fpu_post_load(void *opaque, int version)
 384{
 385    M68kCPU *s = opaque;
 386
 387    cpu_m68k_restore_fp_status(&s->env);
 388
 389    return 0;
 390}
 391
 392const VMStateDescription vmmstate_fpu = {
 393    .name = "cpu/fpu",
 394    .version_id = 1,
 395    .minimum_version_id = 1,
 396    .needed = fpu_needed,
 397    .post_load = fpu_post_load,
 398    .fields = (VMStateField[]) {
 399        VMSTATE_UINT32(env.fpcr, M68kCPU),
 400        VMSTATE_UINT32(env.fpsr, M68kCPU),
 401        VMSTATE_STRUCT_ARRAY(env.fregs, M68kCPU, 8, 0, vmstate_freg, FPReg),
 402        VMSTATE_STRUCT(env.fp_result, M68kCPU, 0, vmstate_freg, FPReg),
 403        VMSTATE_END_OF_LIST()
 404    }
 405};
 406
 407static bool cf_spregs_needed(void *opaque)
 408{
 409    M68kCPU *s = opaque;
 410
 411    return m68k_feature(&s->env, M68K_FEATURE_CF_ISA_A);
 412}
 413
 414const VMStateDescription vmstate_cf_spregs = {
 415    .name = "cpu/cf_spregs",
 416    .version_id = 1,
 417    .minimum_version_id = 1,
 418    .needed = cf_spregs_needed,
 419    .fields = (VMStateField[]) {
 420        VMSTATE_UINT64_ARRAY(env.macc, M68kCPU, 4),
 421        VMSTATE_UINT32(env.macsr, M68kCPU),
 422        VMSTATE_UINT32(env.mac_mask, M68kCPU),
 423        VMSTATE_UINT32(env.rambar0, M68kCPU),
 424        VMSTATE_UINT32(env.mbar, M68kCPU),
 425        VMSTATE_END_OF_LIST()
 426    }
 427};
 428
 429static bool cpu_68040_mmu_needed(void *opaque)
 430{
 431    M68kCPU *s = opaque;
 432
 433    return m68k_feature(&s->env, M68K_FEATURE_M68040);
 434}
 435
 436const VMStateDescription vmstate_68040_mmu = {
 437    .name = "cpu/68040_mmu",
 438    .version_id = 1,
 439    .minimum_version_id = 1,
 440    .needed = cpu_68040_mmu_needed,
 441    .fields = (VMStateField[]) {
 442        VMSTATE_UINT32(env.mmu.ar, M68kCPU),
 443        VMSTATE_UINT32(env.mmu.ssw, M68kCPU),
 444        VMSTATE_UINT16(env.mmu.tcr, M68kCPU),
 445        VMSTATE_UINT32(env.mmu.urp, M68kCPU),
 446        VMSTATE_UINT32(env.mmu.srp, M68kCPU),
 447        VMSTATE_BOOL(env.mmu.fault, M68kCPU),
 448        VMSTATE_UINT32_ARRAY(env.mmu.ttr, M68kCPU, 4),
 449        VMSTATE_UINT32(env.mmu.mmusr, M68kCPU),
 450        VMSTATE_END_OF_LIST()
 451    }
 452};
 453
 454static bool cpu_68040_spregs_needed(void *opaque)
 455{
 456    M68kCPU *s = opaque;
 457
 458    return m68k_feature(&s->env, M68K_FEATURE_M68040);
 459}
 460
 461const VMStateDescription vmstate_68040_spregs = {
 462    .name = "cpu/68040_spregs",
 463    .version_id = 1,
 464    .minimum_version_id = 1,
 465    .needed = cpu_68040_spregs_needed,
 466    .fields = (VMStateField[]) {
 467        VMSTATE_UINT32(env.vbr, M68kCPU),
 468        VMSTATE_UINT32(env.cacr, M68kCPU),
 469        VMSTATE_UINT32(env.sfc, M68kCPU),
 470        VMSTATE_UINT32(env.dfc, M68kCPU),
 471        VMSTATE_END_OF_LIST()
 472    }
 473};
 474
 475static const VMStateDescription vmstate_m68k_cpu = {
 476    .name = "cpu",
 477    .version_id = 1,
 478    .minimum_version_id = 1,
 479    .fields      = (VMStateField[]) {
 480        VMSTATE_UINT32_ARRAY(env.dregs, M68kCPU, 8),
 481        VMSTATE_UINT32_ARRAY(env.aregs, M68kCPU, 8),
 482        VMSTATE_UINT32(env.pc, M68kCPU),
 483        VMSTATE_UINT32(env.sr, M68kCPU),
 484        VMSTATE_INT32(env.current_sp, M68kCPU),
 485        VMSTATE_UINT32_ARRAY(env.sp, M68kCPU, 3),
 486        VMSTATE_UINT32(env.cc_op, M68kCPU),
 487        VMSTATE_UINT32(env.cc_x, M68kCPU),
 488        VMSTATE_UINT32(env.cc_n, M68kCPU),
 489        VMSTATE_UINT32(env.cc_v, M68kCPU),
 490        VMSTATE_UINT32(env.cc_c, M68kCPU),
 491        VMSTATE_UINT32(env.cc_z, M68kCPU),
 492        VMSTATE_INT32(env.pending_vector, M68kCPU),
 493        VMSTATE_INT32(env.pending_level, M68kCPU),
 494        VMSTATE_END_OF_LIST()
 495    },
 496    .subsections = (const VMStateDescription * []) {
 497        &vmmstate_fpu,
 498        &vmstate_cf_spregs,
 499        &vmstate_68040_mmu,
 500        &vmstate_68040_spregs,
 501        NULL
 502    },
 503};
 504#endif
 505
 506#include "hw/core/tcg-cpu-ops.h"
 507
 508static struct TCGCPUOps m68k_tcg_ops = {
 509    .initialize = m68k_tcg_init,
 510    .cpu_exec_interrupt = m68k_cpu_exec_interrupt,
 511    .tlb_fill = m68k_cpu_tlb_fill,
 512
 513#ifndef CONFIG_USER_ONLY
 514    .do_interrupt = m68k_cpu_do_interrupt,
 515    .do_transaction_failed = m68k_cpu_transaction_failed,
 516#endif /* !CONFIG_USER_ONLY */
 517};
 518
 519static void m68k_cpu_class_init(ObjectClass *c, void *data)
 520{
 521    M68kCPUClass *mcc = M68K_CPU_CLASS(c);
 522    CPUClass *cc = CPU_CLASS(c);
 523    DeviceClass *dc = DEVICE_CLASS(c);
 524
 525    device_class_set_parent_realize(dc, m68k_cpu_realizefn,
 526                                    &mcc->parent_realize);
 527    device_class_set_parent_reset(dc, m68k_cpu_reset, &mcc->parent_reset);
 528
 529    cc->class_by_name = m68k_cpu_class_by_name;
 530    cc->has_work = m68k_cpu_has_work;
 531    cc->dump_state = m68k_cpu_dump_state;
 532    cc->set_pc = m68k_cpu_set_pc;
 533    cc->gdb_read_register = m68k_cpu_gdb_read_register;
 534    cc->gdb_write_register = m68k_cpu_gdb_write_register;
 535#if defined(CONFIG_SOFTMMU)
 536    cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug;
 537    dc->vmsd = &vmstate_m68k_cpu;
 538#endif
 539    cc->disas_set_info = m68k_cpu_disas_set_info;
 540
 541    cc->gdb_num_core_regs = 18;
 542    cc->tcg_ops = &m68k_tcg_ops;
 543}
 544
 545static void m68k_cpu_class_init_cf_core(ObjectClass *c, void *data)
 546{
 547    CPUClass *cc = CPU_CLASS(c);
 548
 549    cc->gdb_core_xml_file = "cf-core.xml";
 550}
 551
 552#define DEFINE_M68K_CPU_TYPE_CF(model)               \
 553    {                                                \
 554        .name = M68K_CPU_TYPE_NAME(#model),          \
 555        .instance_init = model##_cpu_initfn,         \
 556        .parent = TYPE_M68K_CPU,                     \
 557        .class_init = m68k_cpu_class_init_cf_core    \
 558    }
 559
 560static void m68k_cpu_class_init_m68k_core(ObjectClass *c, void *data)
 561{
 562    CPUClass *cc = CPU_CLASS(c);
 563
 564    cc->gdb_core_xml_file = "m68k-core.xml";
 565}
 566
 567#define DEFINE_M68K_CPU_TYPE_M68K(model)             \
 568    {                                                \
 569        .name = M68K_CPU_TYPE_NAME(#model),          \
 570        .instance_init = model##_cpu_initfn,         \
 571        .parent = TYPE_M68K_CPU,                     \
 572        .class_init = m68k_cpu_class_init_m68k_core  \
 573    }
 574
 575static const TypeInfo m68k_cpus_type_infos[] = {
 576    { /* base class should be registered first */
 577        .name = TYPE_M68K_CPU,
 578        .parent = TYPE_CPU,
 579        .instance_size = sizeof(M68kCPU),
 580        .instance_init = m68k_cpu_initfn,
 581        .abstract = true,
 582        .class_size = sizeof(M68kCPUClass),
 583        .class_init = m68k_cpu_class_init,
 584    },
 585    DEFINE_M68K_CPU_TYPE_M68K(m68000),
 586    DEFINE_M68K_CPU_TYPE_M68K(m68010),
 587    DEFINE_M68K_CPU_TYPE_M68K(m68020),
 588    DEFINE_M68K_CPU_TYPE_M68K(m68030),
 589    DEFINE_M68K_CPU_TYPE_M68K(m68040),
 590    DEFINE_M68K_CPU_TYPE_M68K(m68060),
 591    DEFINE_M68K_CPU_TYPE_CF(m5206),
 592    DEFINE_M68K_CPU_TYPE_CF(m5208),
 593    DEFINE_M68K_CPU_TYPE_CF(cfv4e),
 594    DEFINE_M68K_CPU_TYPE_CF(any),
 595};
 596
 597DEFINE_TYPES(m68k_cpus_type_infos)
 598