master
c 799 lines 24.5 KB
Raw
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 "accel/tcg/cpu-ops.h"
23 #include "fpu/softfloat.h"
24 #include "qapi/error.h"
25 #include "disas/capstone.h"
26 #ifndef CONFIG_USER_ONLY
27 #include "migration/vmstate.h"
28 #include "monitor/hmp.h"
29 #endif
30
31 #include "cpu.h"
32
33 static void m68k_cpu_set_pc(CPUState *cs, vaddr value)
34 {
35 M68kCPU *cpu = M68K_CPU(cs);
36
37 cpu->env.pc = value;
38 }
39
40 static vaddr m68k_cpu_get_pc(CPUState *cs)
41 {
42 M68kCPU *cpu = M68K_CPU(cs);
43
44 return cpu->env.pc;
45 }
46
47 static TCGTBCPUState m68k_get_tb_cpu_state(CPUState *cs)
48 {
49 CPUM68KState *env = cpu_env(cs);
50 uint32_t flags;
51
52 flags = (env->macsr >> 4) & TB_FLAGS_MACSR;
53 if (env->sr & SR_S) {
54 flags |= TB_FLAGS_MSR_S;
55 flags |= (env->sfc << (TB_FLAGS_SFC_S_BIT - 2)) & TB_FLAGS_SFC_S;
56 flags |= (env->dfc << (TB_FLAGS_DFC_S_BIT - 2)) & TB_FLAGS_DFC_S;
57 }
58 if (M68K_SR_TRACE(env->sr) == M68K_SR_TRACE_ANY_INS) {
59 flags |= TB_FLAGS_TRACE;
60 }
61
62 return (TCGTBCPUState){ .pc = env->pc, .flags = flags };
63 }
64
65 static void m68k_restore_state_to_opc(CPUState *cs,
66 const TranslationBlock *tb,
67 const uint64_t *data)
68 {
69 M68kCPU *cpu = M68K_CPU(cs);
70 int cc_op = data[1];
71
72 cpu->env.pc = data[0];
73 if (cc_op != CC_OP_DYNAMIC) {
74 cpu->env.cc_op = cc_op;
75 }
76 }
77
78 #ifndef CONFIG_USER_ONLY
79 static bool m68k_cpu_has_work(CPUState *cs)
80 {
81 return cpu_test_interrupt(cs, CPU_INTERRUPT_HARD);
82 }
83 #endif /* !CONFIG_USER_ONLY */
84
85 static int m68k_cpu_mmu_index(CPUState *cs, bool ifetch)
86 {
87 return cpu_env(cs)->sr & SR_S ? MMU_KERNEL_IDX : MMU_USER_IDX;
88 }
89
90 static void m68k_set_feature(CPUM68KState *env, int feature)
91 {
92 env->features |= BIT_ULL(feature);
93 }
94
95 static void m68k_unset_feature(CPUM68KState *env, int feature)
96 {
97 env->features &= ~BIT_ULL(feature);
98 }
99
100 static void m68k_cpu_reset_hold(Object *obj, ResetType type)
101 {
102 CPUState *cs = CPU(obj);
103 M68kCPUClass *mcc = M68K_CPU_GET_CLASS(obj);
104 CPUM68KState *env = cpu_env(cs);
105 floatx80 nan;
106 int i;
107
108 if (mcc->parent_phases.hold) {
109 mcc->parent_phases.hold(obj, type);
110 }
111
112 memset(env, 0, offsetof(CPUM68KState, end_reset_fields));
113 #ifdef CONFIG_USER_ONLY
114 cpu_m68k_set_sr(env, 0);
115 #else
116 cpu_m68k_set_sr(env, SR_S | SR_I);
117 #endif
118 /*
119 * M68000 FAMILY PROGRAMMER'S REFERENCE MANUAL
120 * 3.4 FLOATING-POINT INSTRUCTION DETAILS
121 * If either operand, but not both operands, of an operation is a
122 * nonsignaling NaN, then that NaN is returned as the result. If both
123 * operands are nonsignaling NaNs, then the destination operand
124 * nonsignaling NaN is returned as the result.
125 * If either operand to an operation is a signaling NaN (SNaN), then the
126 * SNaN bit is set in the FPSR EXC byte. If the SNaN exception enable bit
127 * is set in the FPCR ENABLE byte, then the exception is taken and the
128 * destination is not modified. If the SNaN exception enable bit is not
129 * set, setting the SNaN bit in the operand to a one converts the SNaN to
130 * a nonsignaling NaN. The operation then continues as described in the
131 * preceding paragraph for nonsignaling NaNs.
132 */
133 set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
134 /* Default NaN: sign bit clear, all frac bits set */
135 set_float_default_nan_pattern(0b01111111, &env->fp_status);
136 /*
137 * m68k-specific floatx80 behaviour:
138 * * default Infinity values have a zero Integer bit
139 * * input Infinities may have the Integer bit either 0 or 1
140 * * pseudo-denormals supported for input and output
141 * * don't raise Invalid for pseudo-NaN/pseudo-Inf/Unnormal
142 *
143 * With m68k, the explicit integer bit can be zero in the case of:
144 * - zeros (exp == 0, mantissa == 0)
145 * - denormalized numbers (exp == 0, mantissa != 0)
146 * - unnormalized numbers (exp != 0, exp < 0x7FFF)
147 * - infinities (exp == 0x7FFF, mantissa == 0)
148 * - not-a-numbers (exp == 0x7FFF, mantissa != 0)
149 *
150 * For infinities and NaNs, the explicit integer bit can be either one or
151 * zero.
152 *
153 * The IEEE 754 standard does not define a zero integer bit. Such a number
154 * is an unnormalized number. Hardware does not directly support
155 * denormalized and unnormalized numbers, but implicitly supports them by
156 * trapping them as unimplemented data types, allowing efficient conversion
157 * in software.
158 *
159 * See "M68000 FAMILY PROGRAMMER’S REFERENCE MANUAL",
160 * "1.6 FLOATING-POINT DATA TYPES"
161 *
162 * Note though that QEMU's fp emulation does directly handle both
163 * denormal and unnormal values, and does not trap to guest software.
164 */
165 set_floatx80_behaviour(floatx80_default_inf_int_bit_is_zero |
166 floatx80_pseudo_inf_valid |
167 floatx80_pseudo_nan_valid |
168 floatx80_unnormal_valid |
169 floatx80_pseudo_denormal_valid,
170 &env->fp_status);
171
172 nan = floatx80_default_nan(&env->fp_status);
173 for (i = 0; i < 8; i++) {
174 env->fregs[i].d = nan;
175 }
176 cpu_m68k_set_fpcr(env, 0);
177 env->fpsr = 0;
178
179 /* TODO: We should set PC from the interrupt vector. */
180 env->pc = 0;
181 }
182
183 static void m68k_cpu_disas_set_info(const CPUState *cs, disassemble_info *info)
184 {
185 CPUM68KState *env = cpu_env((CPUState *)cs);
186 int cap_mode = 0;
187
188 info->print_insn = print_insn_m68k;
189 info->endian = BFD_ENDIAN_BIG;
190 info->mach = 0;
191
192 /* m68k support in capstone prior to v6 is unusably bad */
193 if (CS_API_MAJOR < 6) {
194 return;
195 }
196
197 info->cap_arch = CS_ARCH_M68K;
198 info->cap_insn_unit = 2;
199
200 if (m68k_feature(env, M68K_FEATURE_M68K)) {
201 /*
202 * m68k insns may have up to 11 words, and 5 words are common.
203 * Choosing 12 bytes splits after 6 words and disassembly
204 * uses no more than 2 lines.
205 */
206 info->cap_insn_split = 12;
207 if (m68k_feature(env, M68K_FEATURE_M68060)) {
208 cap_mode = CS_MODE_M68K_060;
209 } else if (m68k_feature(env, M68K_FEATURE_M68040)) {
210 cap_mode = CS_MODE_M68K_040;
211 } else if (m68k_feature(env, M68K_FEATURE_M68030)) {
212 cap_mode = CS_MODE_M68K_030;
213 } else if (m68k_feature(env, M68K_FEATURE_M68020)) {
214 cap_mode = CS_MODE_M68K_020;
215 } else if (m68k_feature(env, M68K_FEATURE_M68010)) {
216 cap_mode = CS_MODE_M68K_010;
217 } else {
218 cap_mode = CS_MODE_M68K_000;
219 }
220 } else {
221 /* ColdFire insns may have up to 3 words. */
222 info->cap_insn_split = 6;
223 if (m68k_feature(env, M68K_FEATURE_CF_ISA_A)) {
224 cap_mode |= CS_MODE_M68K_CF_ISA_A;
225 cap_mode |= CS_MODE_M68K_CF_DIV;
226 }
227 if (m68k_feature(env, M68K_FEATURE_CF_ISA_B)) {
228 cap_mode |= CS_MODE_M68K_CF_ISA_B;
229 }
230 if (m68k_feature(env, M68K_FEATURE_CF_ISA_APLUSC)) {
231 cap_mode |= CS_MODE_M68K_CF_ISA_A_PLUS;
232 cap_mode |= CS_MODE_M68K_CF_ISA_C;
233 }
234 if (m68k_feature(env, M68K_FEATURE_USP)) {
235 cap_mode |= CS_MODE_M68K_CF_USP;
236 }
237 if (m68k_feature(env, M68K_FEATURE_CF_FPU)) {
238 cap_mode |= CS_MODE_M68K_CF_FPU;
239 }
240 if (m68k_feature(env, M68K_FEATURE_CF_MAC)) {
241 cap_mode |= CS_MODE_M68K_CF_MAC;
242 }
243 if (m68k_feature(env, M68K_FEATURE_CF_EMAC)) {
244 cap_mode |= CS_MODE_M68K_CF_EMAC;
245 }
246 if (m68k_feature(env, M68K_FEATURE_CF_EMAC_B)) {
247 cap_mode |= CS_MODE_M68K_CF_EMAC_B;
248 }
249 }
250 info->cap_mode = cap_mode;
251 }
252
253 /* CPU models */
254
255 static ObjectClass *m68k_cpu_class_by_name(const char *cpu_model)
256 {
257 ObjectClass *oc;
258 char *typename;
259
260 typename = g_strdup_printf(M68K_CPU_TYPE_NAME("%s"), cpu_model);
261 oc = object_class_by_name(typename);
262 g_free(typename);
263
264 return oc;
265 }
266
267 static void m5206_cpu_initfn(Object *obj)
268 {
269 CPUM68KState *env = cpu_env(CPU(obj));
270
271 m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
272 m68k_set_feature(env, M68K_FEATURE_MOVEFROMSR_PRIV);
273 }
274
275 /* Base feature set, including isns. for m68k family */
276 static void m68000_cpu_initfn(Object *obj)
277 {
278 CPUM68KState *env = cpu_env(CPU(obj));
279
280 m68k_set_feature(env, M68K_FEATURE_M68K);
281 m68k_set_feature(env, M68K_FEATURE_USP);
282 m68k_set_feature(env, M68K_FEATURE_WORD_INDEX);
283 m68k_set_feature(env, M68K_FEATURE_MOVEP);
284 }
285
286 /*
287 * Adds BKPT, MOVE-from-SR *now priv instr, and MOVEC, MOVES, RTD,
288 * format+vector in exception frame.
289 */
290 static void m68010_cpu_initfn(Object *obj)
291 {
292 CPUM68KState *env = cpu_env(CPU(obj));
293
294 m68000_cpu_initfn(obj);
295 m68k_set_feature(env, M68K_FEATURE_M68010);
296 m68k_set_feature(env, M68K_FEATURE_RTD);
297 m68k_set_feature(env, M68K_FEATURE_BKPT);
298 m68k_set_feature(env, M68K_FEATURE_MOVEC);
299 m68k_set_feature(env, M68K_FEATURE_MOVEFROMSR_PRIV);
300 m68k_set_feature(env, M68K_FEATURE_EXCEPTION_FORMAT_VEC);
301 }
302
303 /*
304 * Adds BFCHG, BFCLR, BFEXTS, BFEXTU, BFFFO, BFINS, BFSET, BFTST, CAS, CAS2,
305 * CHK2, CMP2, DIVSL, DIVUL, EXTB, LINKL, PACK, TRAPcc, UNPK.
306 *
307 * 68020/30 only:
308 * CALLM, cpBcc, cpDBcc, cpGEN, cpRESTORE, cpSAVE, cpScc, cpTRAPcc
309 */
310 static void m68020_cpu_initfn(Object *obj)
311 {
312 CPUM68KState *env = cpu_env(CPU(obj));
313
314 m68010_cpu_initfn(obj);
315 m68k_unset_feature(env, M68K_FEATURE_M68010);
316 m68k_set_feature(env, M68K_FEATURE_M68020);
317 m68k_set_feature(env, M68K_FEATURE_QUAD_MULDIV);
318 m68k_set_feature(env, M68K_FEATURE_BRAL);
319 m68k_set_feature(env, M68K_FEATURE_BCCL);
320 m68k_set_feature(env, M68K_FEATURE_BITFIELD);
321 m68k_set_feature(env, M68K_FEATURE_EXT_FULL);
322 m68k_set_feature(env, M68K_FEATURE_SCALED_INDEX);
323 m68k_set_feature(env, M68K_FEATURE_LONG_MULDIV);
324 m68k_set_feature(env, M68K_FEATURE_FPU);
325 m68k_set_feature(env, M68K_FEATURE_CAS);
326 m68k_set_feature(env, M68K_FEATURE_CHK2);
327 m68k_set_feature(env, M68K_FEATURE_MSP);
328 m68k_set_feature(env, M68K_FEATURE_UNALIGNED_DATA);
329 m68k_set_feature(env, M68K_FEATURE_TRAPCC);
330 m68k_set_feature(env, M68K_FEATURE_LINKL);
331 }
332
333 /*
334 * Adds: PFLUSH (*5)
335 * 68030 Only: PFLUSHA (*5), PLOAD (*5), PMOVE
336 * 68030/40 Only: PTEST
337 *
338 * NOTES:
339 * 5. Not valid on MC68EC030
340 */
341 static void m68030_cpu_initfn(Object *obj)
342 {
343 CPUM68KState *env = cpu_env(CPU(obj));
344
345 m68020_cpu_initfn(obj);
346 m68k_unset_feature(env, M68K_FEATURE_M68020);
347 m68k_set_feature(env, M68K_FEATURE_M68030);
348 }
349
350 /*
351 * Adds: CINV, CPUSH
352 * Adds all with Note *2: FABS, FSABS, FDABS, FADD, FSADD, FDADD, FBcc, FCMP,
353 * FDBcc, FDIV, FSDIV, FDDIV, FMOVE, FSMOVE, FDMOVE,
354 * FMOVEM, FMUL, FSMUL, FDMUL, FNEG, FSNEG, FDNEG, FNOP,
355 * FRESTORE, FSAVE, FScc, FSQRT, FSSQRT, FDSQRT, FSUB,
356 * FSSUB, FDSUB, FTRAPcc, FTST
357 *
358 * Adds with Notes *2, and *3: FACOS, FASIN, FATAN, FATANH, FCOS, FCOSH, FETOX,
359 * FETOXM, FGETEXP, FGETMAN, FINT, FINTRZ, FLOG10,
360 * FLOG2, FLOGN, FLOGNP1, FMOD, FMOVECR, FREM,
361 * FSCALE, FSGLDIV, FSGLMUL, FSIN, FSINCOS, FSINH,
362 * FTAN, FTANH, FTENTOX, FTWOTOX
363 * NOTES:
364 * 2. Not applicable to the MC68EC040, MC68LC040, MC68EC060, and MC68LC060.
365 * 3. These are software-supported instructions on the MC68040 and MC68060.
366 */
367 static void m68040_cpu_initfn(Object *obj)
368 {
369 CPUM68KState *env = cpu_env(CPU(obj));
370
371 m68030_cpu_initfn(obj);
372 m68k_unset_feature(env, M68K_FEATURE_M68030);
373 m68k_set_feature(env, M68K_FEATURE_M68040);
374 }
375
376 /*
377 * Adds: PLPA
378 * Adds all with Note *2: CAS, CAS2, MULS, MULU, CHK2, CMP2, DIVS, DIVU
379 * All Fxxxx instructions are as per m68040 with exception to; FMOVEM NOTE3
380 *
381 * Does NOT implement MOVEP
382 *
383 * NOTES:
384 * 2. Not applicable to the MC68EC040, MC68LC040, MC68EC060, and MC68LC060.
385 * 3. These are software-supported instructions on the MC68040 and MC68060.
386 */
387 static void m68060_cpu_initfn(Object *obj)
388 {
389 CPUM68KState *env = cpu_env(CPU(obj));
390
391 m68040_cpu_initfn(obj);
392 m68k_unset_feature(env, M68K_FEATURE_M68040);
393 m68k_set_feature(env, M68K_FEATURE_M68060);
394 m68k_unset_feature(env, M68K_FEATURE_MOVEP);
395
396 /* Implemented as a software feature */
397 m68k_unset_feature(env, M68K_FEATURE_QUAD_MULDIV);
398 }
399
400 static void m5208_cpu_initfn(Object *obj)
401 {
402 CPUM68KState *env = cpu_env(CPU(obj));
403
404 m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
405 m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC);
406 m68k_set_feature(env, M68K_FEATURE_BRAL);
407 m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
408 m68k_set_feature(env, M68K_FEATURE_USP);
409 m68k_set_feature(env, M68K_FEATURE_MOVEFROMSR_PRIV);
410 }
411
412 static void cfv4e_cpu_initfn(Object *obj)
413 {
414 CPUM68KState *env = cpu_env(CPU(obj));
415
416 m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
417 m68k_set_feature(env, M68K_FEATURE_CF_ISA_B);
418 m68k_set_feature(env, M68K_FEATURE_BRAL);
419 m68k_set_feature(env, M68K_FEATURE_CF_FPU);
420 m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
421 m68k_set_feature(env, M68K_FEATURE_USP);
422 m68k_set_feature(env, M68K_FEATURE_MOVEFROMSR_PRIV);
423 }
424
425 static void any_cpu_initfn(Object *obj)
426 {
427 CPUM68KState *env = cpu_env(CPU(obj));
428
429 m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
430 m68k_set_feature(env, M68K_FEATURE_CF_ISA_B);
431 m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC);
432 m68k_set_feature(env, M68K_FEATURE_BRAL);
433 m68k_set_feature(env, M68K_FEATURE_CF_FPU);
434 /*
435 * MAC and EMAC are mututally exclusive, so pick EMAC.
436 * It's mostly backwards compatible.
437 */
438 m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
439 m68k_set_feature(env, M68K_FEATURE_CF_EMAC_B);
440 m68k_set_feature(env, M68K_FEATURE_USP);
441 m68k_set_feature(env, M68K_FEATURE_EXT_FULL);
442 m68k_set_feature(env, M68K_FEATURE_WORD_INDEX);
443 m68k_set_feature(env, M68K_FEATURE_MOVEFROMSR_PRIV);
444 }
445
446 static void m68k_cpu_realizefn(DeviceState *dev, Error **errp)
447 {
448 CPUState *cs = CPU(dev);
449 M68kCPU *cpu = M68K_CPU(dev);
450 M68kCPUClass *mcc = M68K_CPU_GET_CLASS(dev);
451 Error *local_err = NULL;
452
453 register_m68k_insns(&cpu->env);
454
455 cpu_common_realize(cs, &local_err);
456 if (local_err != NULL) {
457 error_propagate(errp, local_err);
458 return;
459 }
460
461 m68k_cpu_init_gdb(cpu);
462
463 cpu_reset(cs);
464 qemu_init_vcpu(cs);
465
466 mcc->parent_realize(dev, errp);
467 }
468
469 #if !defined(CONFIG_USER_ONLY)
470 static bool fpu_needed(void *opaque)
471 {
472 M68kCPU *s = opaque;
473
474 return m68k_feature(&s->env, M68K_FEATURE_CF_FPU) ||
475 m68k_feature(&s->env, M68K_FEATURE_FPU);
476 }
477
478 typedef struct m68k_FPReg_tmp {
479 FPReg *parent;
480 uint64_t tmp_mant;
481 uint16_t tmp_exp;
482 } m68k_FPReg_tmp;
483
484 static void cpu_get_fp80(uint64_t *pmant, uint16_t *pexp, floatx80 f)
485 {
486 CPU_LDoubleU temp;
487
488 temp.d = f;
489 *pmant = temp.l.lower;
490 *pexp = temp.l.upper;
491 }
492
493 static floatx80 cpu_set_fp80(uint64_t mant, uint16_t upper)
494 {
495 CPU_LDoubleU temp;
496
497 temp.l.upper = upper;
498 temp.l.lower = mant;
499 return temp.d;
500 }
501
502 static int freg_pre_save(void *opaque)
503 {
504 m68k_FPReg_tmp *tmp = opaque;
505
506 cpu_get_fp80(&tmp->tmp_mant, &tmp->tmp_exp, tmp->parent->d);
507
508 return 0;
509 }
510
511 static int freg_post_load(void *opaque, int version)
512 {
513 m68k_FPReg_tmp *tmp = opaque;
514
515 tmp->parent->d = cpu_set_fp80(tmp->tmp_mant, tmp->tmp_exp);
516
517 return 0;
518 }
519
520 static const VMStateDescription vmstate_freg_tmp = {
521 .name = "freg_tmp",
522 .post_load = freg_post_load,
523 .pre_save = freg_pre_save,
524 .fields = (const VMStateField[]) {
525 VMSTATE_UINT64(tmp_mant, m68k_FPReg_tmp),
526 VMSTATE_UINT16(tmp_exp, m68k_FPReg_tmp),
527 VMSTATE_END_OF_LIST()
528 }
529 };
530
531 static const VMStateDescription vmstate_freg = {
532 .name = "freg",
533 .fields = (const VMStateField[]) {
534 VMSTATE_WITH_TMP(FPReg, m68k_FPReg_tmp, vmstate_freg_tmp),
535 VMSTATE_END_OF_LIST()
536 }
537 };
538
539 static int fpu_pre_save(void *opaque)
540 {
541 M68kCPU *s = opaque;
542
543 s->env.fpsr = cpu_m68k_get_fpsr(&s->env);
544 return 0;
545 }
546
547 static int fpu_post_load(void *opaque, int version)
548 {
549 M68kCPU *s = opaque;
550
551 cpu_m68k_set_fpsr(&s->env, s->env.fpsr);
552 return 0;
553 }
554
555 const VMStateDescription vmmstate_fpu = {
556 .name = "cpu/fpu",
557 .version_id = 1,
558 .minimum_version_id = 1,
559 .needed = fpu_needed,
560 .pre_save = fpu_pre_save,
561 .post_load = fpu_post_load,
562 .fields = (const VMStateField[]) {
563 VMSTATE_UINT32(env.fpcr, M68kCPU),
564 VMSTATE_UINT32(env.fpsr, M68kCPU),
565 VMSTATE_STRUCT_ARRAY(env.fregs, M68kCPU, 8, 0, vmstate_freg, FPReg),
566 VMSTATE_STRUCT(env.fp_result, M68kCPU, 0, vmstate_freg, FPReg),
567 VMSTATE_END_OF_LIST()
568 }
569 };
570
571 static bool cf_spregs_needed(void *opaque)
572 {
573 M68kCPU *s = opaque;
574
575 return m68k_feature(&s->env, M68K_FEATURE_CF_ISA_A);
576 }
577
578 const VMStateDescription vmstate_cf_spregs = {
579 .name = "cpu/cf_spregs",
580 .version_id = 1,
581 .minimum_version_id = 1,
582 .needed = cf_spregs_needed,
583 .fields = (const VMStateField[]) {
584 VMSTATE_UINT64_ARRAY(env.macc, M68kCPU, 4),
585 VMSTATE_UINT32(env.macsr, M68kCPU),
586 VMSTATE_UINT32(env.mac_mask, M68kCPU),
587 VMSTATE_UINT32(env.rambar0, M68kCPU),
588 VMSTATE_UINT32(env.mbar, M68kCPU),
589 VMSTATE_END_OF_LIST()
590 }
591 };
592
593 static bool cpu_68040_mmu_needed(void *opaque)
594 {
595 M68kCPU *s = opaque;
596
597 return m68k_feature(&s->env, M68K_FEATURE_M68040);
598 }
599
600 const VMStateDescription vmstate_68040_mmu = {
601 .name = "cpu/68040_mmu",
602 .version_id = 1,
603 .minimum_version_id = 1,
604 .needed = cpu_68040_mmu_needed,
605 .fields = (const VMStateField[]) {
606 VMSTATE_UINT32(env.mmu.ar, M68kCPU),
607 VMSTATE_UINT32(env.mmu.ssw, M68kCPU),
608 VMSTATE_UINT16(env.mmu.tcr, M68kCPU),
609 VMSTATE_UINT32(env.mmu.urp, M68kCPU),
610 VMSTATE_UINT32(env.mmu.srp, M68kCPU),
611 VMSTATE_BOOL(env.mmu.fault, M68kCPU),
612 VMSTATE_UINT32_ARRAY(env.mmu.ttr, M68kCPU, 4),
613 VMSTATE_UINT32(env.mmu.mmusr, M68kCPU),
614 VMSTATE_END_OF_LIST()
615 }
616 };
617
618 static bool cpu_68040_spregs_needed(void *opaque)
619 {
620 M68kCPU *s = opaque;
621
622 return m68k_feature(&s->env, M68K_FEATURE_M68040);
623 }
624
625 const VMStateDescription vmstate_68040_spregs = {
626 .name = "cpu/68040_spregs",
627 .version_id = 1,
628 .minimum_version_id = 1,
629 .needed = cpu_68040_spregs_needed,
630 .fields = (const VMStateField[]) {
631 VMSTATE_UINT32(env.vbr, M68kCPU),
632 VMSTATE_UINT32(env.cacr, M68kCPU),
633 VMSTATE_UINT32(env.sfc, M68kCPU),
634 VMSTATE_UINT32(env.dfc, M68kCPU),
635 VMSTATE_END_OF_LIST()
636 }
637 };
638
639 static const VMStateDescription vmstate_m68k_cpu = {
640 .name = "cpu",
641 .version_id = 1,
642 .minimum_version_id = 1,
643 .fields = (const VMStateField[]) {
644 VMSTATE_UINT32_ARRAY(env.dregs, M68kCPU, 8),
645 VMSTATE_UINT32_ARRAY(env.aregs, M68kCPU, 8),
646 VMSTATE_UINT32(env.pc, M68kCPU),
647 VMSTATE_UINT32(env.sr, M68kCPU),
648 VMSTATE_INT32(env.current_sp, M68kCPU),
649 VMSTATE_UINT32_ARRAY(env.sp, M68kCPU, 3),
650 VMSTATE_UINT32(env.cc_op, M68kCPU),
651 VMSTATE_UINT32(env.cc_x, M68kCPU),
652 VMSTATE_UINT32(env.cc_n, M68kCPU),
653 VMSTATE_UINT32(env.cc_v, M68kCPU),
654 VMSTATE_UINT32(env.cc_c, M68kCPU),
655 VMSTATE_UINT32(env.cc_z, M68kCPU),
656 VMSTATE_INT32(env.pending_vector, M68kCPU),
657 VMSTATE_INT32(env.pending_level, M68kCPU),
658 VMSTATE_END_OF_LIST()
659 },
660 .subsections = (const VMStateDescription * const []) {
661 &vmmstate_fpu,
662 &vmstate_cf_spregs,
663 &vmstate_68040_mmu,
664 &vmstate_68040_spregs,
665 NULL
666 },
667 };
668
669 #ifdef CONFIG_HMP
670 static const MonitorDef m68k_monitor_defs[] = {
671 { "ssp", offsetof(CPUM68KState, sp[0]) },
672 { "usp", offsetof(CPUM68KState, sp[1]) },
673 { "isp", offsetof(CPUM68KState, sp[2]) },
674 { "sfc", offsetof(CPUM68KState, sfc) },
675 { "dfc", offsetof(CPUM68KState, dfc) },
676 { "urp", offsetof(CPUM68KState, mmu.urp) },
677 { "srp", offsetof(CPUM68KState, mmu.srp) },
678 { "dttr0", offsetof(CPUM68KState, mmu.ttr[M68K_DTTR0]) },
679 { "dttr1", offsetof(CPUM68KState, mmu.ttr[M68K_DTTR1]) },
680 { "ittr0", offsetof(CPUM68KState, mmu.ttr[M68K_ITTR0]) },
681 { "ittr1", offsetof(CPUM68KState, mmu.ttr[M68K_ITTR1]) },
682 { "mmusr", offsetof(CPUM68KState, mmu.mmusr) },
683 { NULL },
684 };
685 #endif
686
687 #include "hw/core/sysemu-cpu-ops.h"
688
689 static const struct SysemuCPUOps m68k_sysemu_ops = {
690 .has_work = m68k_cpu_has_work,
691 .get_phys_addr_debug = m68k_cpu_get_phys_addr_debug,
692 #ifdef CONFIG_HMP
693 .monitor_defs = m68k_monitor_defs,
694 #endif
695 };
696 #endif /* !CONFIG_USER_ONLY */
697
698 static const TCGCPUOps m68k_tcg_ops = {
699 /* MTTCG not yet supported: require strict ordering */
700 .guest_default_memory_order = TCG_MO_ALL,
701 .mttcg_supported = false,
702
703 .initialize = m68k_tcg_init,
704 .translate_code = m68k_translate_code,
705 .get_tb_cpu_state = m68k_get_tb_cpu_state,
706 .restore_state_to_opc = m68k_restore_state_to_opc,
707 .mmu_index = m68k_cpu_mmu_index,
708
709 #ifndef CONFIG_USER_ONLY
710 .tlb_fill = m68k_cpu_tlb_fill,
711 .pointer_wrap = cpu_pointer_wrap_uint32,
712 .cpu_exec_interrupt = m68k_cpu_exec_interrupt,
713 .cpu_exec_halt = m68k_cpu_has_work,
714 .cpu_exec_reset = cpu_reset,
715 .do_interrupt = m68k_cpu_do_interrupt,
716 .do_transaction_failed = m68k_cpu_transaction_failed,
717 #endif /* !CONFIG_USER_ONLY */
718 };
719
720 static void m68k_cpu_class_init(ObjectClass *c, const void *data)
721 {
722 M68kCPUClass *mcc = M68K_CPU_CLASS(c);
723 CPUClass *cc = CPU_CLASS(c);
724 DeviceClass *dc = DEVICE_CLASS(c);
725 ResettableClass *rc = RESETTABLE_CLASS(c);
726
727 device_class_set_parent_realize(dc, m68k_cpu_realizefn,
728 &mcc->parent_realize);
729 resettable_class_set_parent_phases(rc, NULL, m68k_cpu_reset_hold, NULL,
730 &mcc->parent_phases);
731
732 cc->class_by_name = m68k_cpu_class_by_name;
733 cc->dump_state = m68k_cpu_dump_state;
734 cc->set_pc = m68k_cpu_set_pc;
735 cc->get_pc = m68k_cpu_get_pc;
736 cc->gdb_read_register = m68k_cpu_gdb_read_register;
737 cc->gdb_write_register = m68k_cpu_gdb_write_register;
738 #if !defined(CONFIG_USER_ONLY)
739 dc->vmsd = &vmstate_m68k_cpu;
740 cc->sysemu_ops = &m68k_sysemu_ops;
741 #endif
742 cc->disas_set_info = m68k_cpu_disas_set_info;
743
744 cc->tcg_ops = &m68k_tcg_ops;
745 }
746
747 static void m68k_cpu_class_init_cf_core(ObjectClass *c, const void *data)
748 {
749 CPUClass *cc = CPU_CLASS(c);
750
751 cc->gdb_core_xml_file = "cf-core.xml";
752 }
753
754 #define DEFINE_M68K_CPU_TYPE_CF(model) \
755 { \
756 .name = M68K_CPU_TYPE_NAME(#model), \
757 .instance_init = model##_cpu_initfn, \
758 .parent = TYPE_M68K_CPU, \
759 .class_init = m68k_cpu_class_init_cf_core \
760 }
761
762 static void m68k_cpu_class_init_m68k_core(ObjectClass *c, const void *data)
763 {
764 CPUClass *cc = CPU_CLASS(c);
765
766 cc->gdb_core_xml_file = "m68k-core.xml";
767 }
768
769 #define DEFINE_M68K_CPU_TYPE_M68K(model) \
770 { \
771 .name = M68K_CPU_TYPE_NAME(#model), \
772 .instance_init = model##_cpu_initfn, \
773 .parent = TYPE_M68K_CPU, \
774 .class_init = m68k_cpu_class_init_m68k_core \
775 }
776
777 static const TypeInfo m68k_cpus_type_infos[] = {
778 { /* base class should be registered first */
779 .name = TYPE_M68K_CPU,
780 .parent = TYPE_CPU,
781 .instance_size = sizeof(M68kCPU),
782 .instance_align = __alignof(M68kCPU),
783 .abstract = true,
784 .class_size = sizeof(M68kCPUClass),
785 .class_init = m68k_cpu_class_init,
786 },
787 DEFINE_M68K_CPU_TYPE_M68K(m68000),
788 DEFINE_M68K_CPU_TYPE_M68K(m68010),
789 DEFINE_M68K_CPU_TYPE_M68K(m68020),
790 DEFINE_M68K_CPU_TYPE_M68K(m68030),
791 DEFINE_M68K_CPU_TYPE_M68K(m68040),
792 DEFINE_M68K_CPU_TYPE_M68K(m68060),
793 DEFINE_M68K_CPU_TYPE_CF(m5206),
794 DEFINE_M68K_CPU_TYPE_CF(m5208),
795 DEFINE_M68K_CPU_TYPE_CF(cfv4e),
796 DEFINE_M68K_CPU_TYPE_CF(any),
797 };
798
799 DEFINE_TYPES(m68k_cpus_type_infos)