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