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