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