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