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