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