target/riscv: avoid env_archcpu() in cpu_get_tb_cpu_state()
[qemu/armbru.git] / target / sparc / cpu.c
blob1734ef8dc6b5dd383d85100349632653573a58dc
1 /*
2 * Sparc CPU init helpers
4 * Copyright (c) 2003-2005 Fabrice Bellard
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.
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.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 #include "qemu/osdep.h"
21 #include "qapi/error.h"
22 #include "cpu.h"
23 #include "qemu/module.h"
24 #include "qemu/qemu-print.h"
25 #include "exec/exec-all.h"
26 #include "hw/qdev-properties.h"
27 #include "qapi/visitor.h"
29 //#define DEBUG_FEATURES
31 static void sparc_cpu_reset_hold(Object *obj)
33 CPUState *s = CPU(obj);
34 SPARCCPU *cpu = SPARC_CPU(s);
35 SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(cpu);
36 CPUSPARCState *env = &cpu->env;
38 if (scc->parent_phases.hold) {
39 scc->parent_phases.hold(obj);
42 memset(env, 0, offsetof(CPUSPARCState, end_reset_fields));
43 env->cwp = 0;
44 #ifndef TARGET_SPARC64
45 env->wim = 1;
46 #endif
47 env->regwptr = env->regbase + (env->cwp * 16);
48 CC_OP = CC_OP_FLAGS;
49 #if defined(CONFIG_USER_ONLY)
50 #ifdef TARGET_SPARC64
51 env->cleanwin = env->nwindows - 2;
52 env->cansave = env->nwindows - 2;
53 env->pstate = PS_RMO | PS_PEF | PS_IE;
54 env->asi = 0x82; /* Primary no-fault */
55 #endif
56 #else
57 #if !defined(TARGET_SPARC64)
58 env->psret = 0;
59 env->psrs = 1;
60 env->psrps = 1;
61 #endif
62 #ifdef TARGET_SPARC64
63 env->pstate = PS_PRIV | PS_RED | PS_PEF;
64 if (!cpu_has_hypervisor(env)) {
65 env->pstate |= PS_AG;
67 env->hpstate = cpu_has_hypervisor(env) ? HS_PRIV : 0;
68 env->tl = env->maxtl;
69 env->gl = 2;
70 cpu_tsptr(env)->tt = TT_POWER_ON_RESET;
71 env->lsu = 0;
72 #else
73 env->mmuregs[0] &= ~(MMU_E | MMU_NF);
74 env->mmuregs[0] |= env->def.mmu_bm;
75 #endif
76 env->pc = 0;
77 env->npc = env->pc + 4;
78 #endif
79 env->cache_control = 0;
82 #ifndef CONFIG_USER_ONLY
83 static bool sparc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
85 if (interrupt_request & CPU_INTERRUPT_HARD) {
86 SPARCCPU *cpu = SPARC_CPU(cs);
87 CPUSPARCState *env = &cpu->env;
89 if (cpu_interrupts_enabled(env) && env->interrupt_index > 0) {
90 int pil = env->interrupt_index & 0xf;
91 int type = env->interrupt_index & 0xf0;
93 if (type != TT_EXTINT || cpu_pil_allowed(env, pil)) {
94 cs->exception_index = env->interrupt_index;
95 sparc_cpu_do_interrupt(cs);
96 return true;
100 return false;
102 #endif /* !CONFIG_USER_ONLY */
104 static void cpu_sparc_disas_set_info(CPUState *cpu, disassemble_info *info)
106 info->print_insn = print_insn_sparc;
107 #ifdef TARGET_SPARC64
108 info->mach = bfd_mach_sparc_v9b;
109 #endif
112 static void
113 cpu_add_feat_as_prop(const char *typename, const char *name, const char *val)
115 GlobalProperty *prop = g_new0(typeof(*prop), 1);
116 prop->driver = typename;
117 prop->property = g_strdup(name);
118 prop->value = g_strdup(val);
119 qdev_prop_register_global(prop);
122 /* Parse "+feature,-feature,feature=foo" CPU feature string */
123 static void sparc_cpu_parse_features(const char *typename, char *features,
124 Error **errp)
126 GList *l, *plus_features = NULL, *minus_features = NULL;
127 char *featurestr; /* Single 'key=value" string being parsed */
128 static bool cpu_globals_initialized;
130 if (cpu_globals_initialized) {
131 return;
133 cpu_globals_initialized = true;
135 if (!features) {
136 return;
139 for (featurestr = strtok(features, ",");
140 featurestr;
141 featurestr = strtok(NULL, ",")) {
142 const char *name;
143 const char *val = NULL;
144 char *eq = NULL;
146 /* Compatibility syntax: */
147 if (featurestr[0] == '+') {
148 plus_features = g_list_append(plus_features,
149 g_strdup(featurestr + 1));
150 continue;
151 } else if (featurestr[0] == '-') {
152 minus_features = g_list_append(minus_features,
153 g_strdup(featurestr + 1));
154 continue;
157 eq = strchr(featurestr, '=');
158 name = featurestr;
159 if (eq) {
160 *eq++ = 0;
161 val = eq;
164 * Temporarily, only +feat/-feat will be supported
165 * for boolean properties until we remove the
166 * minus-overrides-plus semantics and just follow
167 * the order options appear on the command-line.
169 * TODO: warn if user is relying on minus-override-plus semantics
170 * TODO: remove minus-override-plus semantics after
171 * warning for a few releases
173 if (!strcasecmp(val, "on") ||
174 !strcasecmp(val, "off") ||
175 !strcasecmp(val, "true") ||
176 !strcasecmp(val, "false")) {
177 error_setg(errp, "Boolean properties in format %s=%s"
178 " are not supported", name, val);
179 return;
181 } else {
182 error_setg(errp, "Unsupported property format: %s", name);
183 return;
185 cpu_add_feat_as_prop(typename, name, val);
188 for (l = plus_features; l; l = l->next) {
189 const char *name = l->data;
190 cpu_add_feat_as_prop(typename, name, "on");
192 g_list_free_full(plus_features, g_free);
194 for (l = minus_features; l; l = l->next) {
195 const char *name = l->data;
196 cpu_add_feat_as_prop(typename, name, "off");
198 g_list_free_full(minus_features, g_free);
201 void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
203 #if !defined(TARGET_SPARC64)
204 env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
205 #endif
208 static const sparc_def_t sparc_defs[] = {
209 #ifdef TARGET_SPARC64
211 .name = "Fujitsu Sparc64",
212 .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)),
213 .fpu_version = 0x00000000,
214 .mmu_version = mmu_us_12,
215 .nwindows = 4,
216 .maxtl = 4,
217 .features = CPU_DEFAULT_FEATURES,
220 .name = "Fujitsu Sparc64 III",
221 .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)),
222 .fpu_version = 0x00000000,
223 .mmu_version = mmu_us_12,
224 .nwindows = 5,
225 .maxtl = 4,
226 .features = CPU_DEFAULT_FEATURES,
229 .name = "Fujitsu Sparc64 IV",
230 .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)),
231 .fpu_version = 0x00000000,
232 .mmu_version = mmu_us_12,
233 .nwindows = 8,
234 .maxtl = 5,
235 .features = CPU_DEFAULT_FEATURES,
238 .name = "Fujitsu Sparc64 V",
239 .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)),
240 .fpu_version = 0x00000000,
241 .mmu_version = mmu_us_12,
242 .nwindows = 8,
243 .maxtl = 5,
244 .features = CPU_DEFAULT_FEATURES,
247 .name = "TI UltraSparc I",
248 .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
249 .fpu_version = 0x00000000,
250 .mmu_version = mmu_us_12,
251 .nwindows = 8,
252 .maxtl = 5,
253 .features = CPU_DEFAULT_FEATURES,
256 .name = "TI UltraSparc II",
257 .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)),
258 .fpu_version = 0x00000000,
259 .mmu_version = mmu_us_12,
260 .nwindows = 8,
261 .maxtl = 5,
262 .features = CPU_DEFAULT_FEATURES,
265 .name = "TI UltraSparc IIi",
266 .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)),
267 .fpu_version = 0x00000000,
268 .mmu_version = mmu_us_12,
269 .nwindows = 8,
270 .maxtl = 5,
271 .features = CPU_DEFAULT_FEATURES,
274 .name = "TI UltraSparc IIe",
275 .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)),
276 .fpu_version = 0x00000000,
277 .mmu_version = mmu_us_12,
278 .nwindows = 8,
279 .maxtl = 5,
280 .features = CPU_DEFAULT_FEATURES,
283 .name = "Sun UltraSparc III",
284 .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)),
285 .fpu_version = 0x00000000,
286 .mmu_version = mmu_us_12,
287 .nwindows = 8,
288 .maxtl = 5,
289 .features = CPU_DEFAULT_FEATURES,
292 .name = "Sun UltraSparc III Cu",
293 .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)),
294 .fpu_version = 0x00000000,
295 .mmu_version = mmu_us_3,
296 .nwindows = 8,
297 .maxtl = 5,
298 .features = CPU_DEFAULT_FEATURES,
301 .name = "Sun UltraSparc IIIi",
302 .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)),
303 .fpu_version = 0x00000000,
304 .mmu_version = mmu_us_12,
305 .nwindows = 8,
306 .maxtl = 5,
307 .features = CPU_DEFAULT_FEATURES,
310 .name = "Sun UltraSparc IV",
311 .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)),
312 .fpu_version = 0x00000000,
313 .mmu_version = mmu_us_4,
314 .nwindows = 8,
315 .maxtl = 5,
316 .features = CPU_DEFAULT_FEATURES,
319 .name = "Sun UltraSparc IV+",
320 .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)),
321 .fpu_version = 0x00000000,
322 .mmu_version = mmu_us_12,
323 .nwindows = 8,
324 .maxtl = 5,
325 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT,
328 .name = "Sun UltraSparc IIIi+",
329 .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)),
330 .fpu_version = 0x00000000,
331 .mmu_version = mmu_us_3,
332 .nwindows = 8,
333 .maxtl = 5,
334 .features = CPU_DEFAULT_FEATURES,
337 .name = "Sun UltraSparc T1",
338 /* defined in sparc_ifu_fdp.v and ctu.h */
339 .iu_version = ((0x3eULL << 48) | (0x23ULL << 32) | (0x02ULL << 24)),
340 .fpu_version = 0x00000000,
341 .mmu_version = mmu_sun4v,
342 .nwindows = 8,
343 .maxtl = 6,
344 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
345 | CPU_FEATURE_GL,
348 .name = "Sun UltraSparc T2",
349 /* defined in tlu_asi_ctl.v and n2_revid_cust.v */
350 .iu_version = ((0x3eULL << 48) | (0x24ULL << 32) | (0x02ULL << 24)),
351 .fpu_version = 0x00000000,
352 .mmu_version = mmu_sun4v,
353 .nwindows = 8,
354 .maxtl = 6,
355 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
356 | CPU_FEATURE_GL,
359 .name = "NEC UltraSparc I",
360 .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
361 .fpu_version = 0x00000000,
362 .mmu_version = mmu_us_12,
363 .nwindows = 8,
364 .maxtl = 5,
365 .features = CPU_DEFAULT_FEATURES,
367 #else
369 .name = "Fujitsu MB86904",
370 .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
371 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
372 .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
373 .mmu_bm = 0x00004000,
374 .mmu_ctpr_mask = 0x00ffffc0,
375 .mmu_cxr_mask = 0x000000ff,
376 .mmu_sfsr_mask = 0x00016fff,
377 .mmu_trcr_mask = 0x00ffffff,
378 .nwindows = 8,
379 .features = CPU_DEFAULT_FEATURES,
382 .name = "Fujitsu MB86907",
383 .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
384 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
385 .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
386 .mmu_bm = 0x00004000,
387 .mmu_ctpr_mask = 0xffffffc0,
388 .mmu_cxr_mask = 0x000000ff,
389 .mmu_sfsr_mask = 0x00016fff,
390 .mmu_trcr_mask = 0xffffffff,
391 .nwindows = 8,
392 .features = CPU_DEFAULT_FEATURES,
395 .name = "TI MicroSparc I",
396 .iu_version = 0x41000000,
397 .fpu_version = 4 << 17,
398 .mmu_version = 0x41000000,
399 .mmu_bm = 0x00004000,
400 .mmu_ctpr_mask = 0x007ffff0,
401 .mmu_cxr_mask = 0x0000003f,
402 .mmu_sfsr_mask = 0x00016fff,
403 .mmu_trcr_mask = 0x0000003f,
404 .nwindows = 7,
405 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL |
406 CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT |
407 CPU_FEATURE_FMUL,
410 .name = "TI MicroSparc II",
411 .iu_version = 0x42000000,
412 .fpu_version = 4 << 17,
413 .mmu_version = 0x02000000,
414 .mmu_bm = 0x00004000,
415 .mmu_ctpr_mask = 0x00ffffc0,
416 .mmu_cxr_mask = 0x000000ff,
417 .mmu_sfsr_mask = 0x00016fff,
418 .mmu_trcr_mask = 0x00ffffff,
419 .nwindows = 8,
420 .features = CPU_DEFAULT_FEATURES,
423 .name = "TI MicroSparc IIep",
424 .iu_version = 0x42000000,
425 .fpu_version = 4 << 17,
426 .mmu_version = 0x04000000,
427 .mmu_bm = 0x00004000,
428 .mmu_ctpr_mask = 0x00ffffc0,
429 .mmu_cxr_mask = 0x000000ff,
430 .mmu_sfsr_mask = 0x00016bff,
431 .mmu_trcr_mask = 0x00ffffff,
432 .nwindows = 8,
433 .features = CPU_DEFAULT_FEATURES,
436 .name = "TI SuperSparc 40", /* STP1020NPGA */
437 .iu_version = 0x41000000, /* SuperSPARC 2.x */
438 .fpu_version = 0 << 17,
439 .mmu_version = 0x00000800, /* SuperSPARC 2.x, no MXCC */
440 .mmu_bm = 0x00002000,
441 .mmu_ctpr_mask = 0xffffffc0,
442 .mmu_cxr_mask = 0x0000ffff,
443 .mmu_sfsr_mask = 0xffffffff,
444 .mmu_trcr_mask = 0xffffffff,
445 .nwindows = 8,
446 .features = CPU_DEFAULT_FEATURES,
449 .name = "TI SuperSparc 50", /* STP1020PGA */
450 .iu_version = 0x40000000, /* SuperSPARC 3.x */
451 .fpu_version = 0 << 17,
452 .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
453 .mmu_bm = 0x00002000,
454 .mmu_ctpr_mask = 0xffffffc0,
455 .mmu_cxr_mask = 0x0000ffff,
456 .mmu_sfsr_mask = 0xffffffff,
457 .mmu_trcr_mask = 0xffffffff,
458 .nwindows = 8,
459 .features = CPU_DEFAULT_FEATURES,
462 .name = "TI SuperSparc 51",
463 .iu_version = 0x40000000, /* SuperSPARC 3.x */
464 .fpu_version = 0 << 17,
465 .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
466 .mmu_bm = 0x00002000,
467 .mmu_ctpr_mask = 0xffffffc0,
468 .mmu_cxr_mask = 0x0000ffff,
469 .mmu_sfsr_mask = 0xffffffff,
470 .mmu_trcr_mask = 0xffffffff,
471 .mxcc_version = 0x00000104,
472 .nwindows = 8,
473 .features = CPU_DEFAULT_FEATURES,
476 .name = "TI SuperSparc 60", /* STP1020APGA */
477 .iu_version = 0x40000000, /* SuperSPARC 3.x */
478 .fpu_version = 0 << 17,
479 .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
480 .mmu_bm = 0x00002000,
481 .mmu_ctpr_mask = 0xffffffc0,
482 .mmu_cxr_mask = 0x0000ffff,
483 .mmu_sfsr_mask = 0xffffffff,
484 .mmu_trcr_mask = 0xffffffff,
485 .nwindows = 8,
486 .features = CPU_DEFAULT_FEATURES,
489 .name = "TI SuperSparc 61",
490 .iu_version = 0x44000000, /* SuperSPARC 3.x */
491 .fpu_version = 0 << 17,
492 .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
493 .mmu_bm = 0x00002000,
494 .mmu_ctpr_mask = 0xffffffc0,
495 .mmu_cxr_mask = 0x0000ffff,
496 .mmu_sfsr_mask = 0xffffffff,
497 .mmu_trcr_mask = 0xffffffff,
498 .mxcc_version = 0x00000104,
499 .nwindows = 8,
500 .features = CPU_DEFAULT_FEATURES,
503 .name = "TI SuperSparc II",
504 .iu_version = 0x40000000, /* SuperSPARC II 1.x */
505 .fpu_version = 0 << 17,
506 .mmu_version = 0x08000000, /* SuperSPARC II 1.x, MXCC */
507 .mmu_bm = 0x00002000,
508 .mmu_ctpr_mask = 0xffffffc0,
509 .mmu_cxr_mask = 0x0000ffff,
510 .mmu_sfsr_mask = 0xffffffff,
511 .mmu_trcr_mask = 0xffffffff,
512 .mxcc_version = 0x00000104,
513 .nwindows = 8,
514 .features = CPU_DEFAULT_FEATURES,
517 .name = "LEON2",
518 .iu_version = 0xf2000000,
519 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
520 .mmu_version = 0xf2000000,
521 .mmu_bm = 0x00004000,
522 .mmu_ctpr_mask = 0x007ffff0,
523 .mmu_cxr_mask = 0x0000003f,
524 .mmu_sfsr_mask = 0xffffffff,
525 .mmu_trcr_mask = 0xffffffff,
526 .nwindows = 8,
527 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN,
530 .name = "LEON3",
531 .iu_version = 0xf3000000,
532 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
533 .mmu_version = 0xf3000000,
534 .mmu_bm = 0x00000000,
535 .mmu_ctpr_mask = 0xfffffffc,
536 .mmu_cxr_mask = 0x000000ff,
537 .mmu_sfsr_mask = 0xffffffff,
538 .mmu_trcr_mask = 0xffffffff,
539 .nwindows = 8,
540 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN |
541 CPU_FEATURE_ASR17 | CPU_FEATURE_CACHE_CTRL | CPU_FEATURE_POWERDOWN |
542 CPU_FEATURE_CASA,
544 #endif
547 static const char * const feature_name[] = {
548 "float",
549 "float128",
550 "swap",
551 "mul",
552 "div",
553 "flush",
554 "fsqrt",
555 "fmul",
556 "vis1",
557 "vis2",
558 "fsmuld",
559 "hypv",
560 "cmt",
561 "gl",
564 static void print_features(uint32_t features, const char *prefix)
566 unsigned int i;
568 for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
569 if (feature_name[i] && (features & (1 << i))) {
570 if (prefix) {
571 qemu_printf("%s", prefix);
573 qemu_printf("%s ", feature_name[i]);
578 void sparc_cpu_list(void)
580 unsigned int i;
582 for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
583 qemu_printf("Sparc %16s IU " TARGET_FMT_lx
584 " FPU %08x MMU %08x NWINS %d ",
585 sparc_defs[i].name,
586 sparc_defs[i].iu_version,
587 sparc_defs[i].fpu_version,
588 sparc_defs[i].mmu_version,
589 sparc_defs[i].nwindows);
590 print_features(CPU_DEFAULT_FEATURES & ~sparc_defs[i].features, "-");
591 print_features(~CPU_DEFAULT_FEATURES & sparc_defs[i].features, "+");
592 qemu_printf("\n");
594 qemu_printf("Default CPU feature flags (use '-' to remove): ");
595 print_features(CPU_DEFAULT_FEATURES, NULL);
596 qemu_printf("\n");
597 qemu_printf("Available CPU feature flags (use '+' to add): ");
598 print_features(~CPU_DEFAULT_FEATURES, NULL);
599 qemu_printf("\n");
600 qemu_printf("Numerical features (use '=' to set): iu_version "
601 "fpu_version mmu_version nwindows\n");
604 static void cpu_print_cc(FILE *f, uint32_t cc)
606 qemu_fprintf(f, "%c%c%c%c", cc & PSR_NEG ? 'N' : '-',
607 cc & PSR_ZERO ? 'Z' : '-', cc & PSR_OVF ? 'V' : '-',
608 cc & PSR_CARRY ? 'C' : '-');
611 #ifdef TARGET_SPARC64
612 #define REGS_PER_LINE 4
613 #else
614 #define REGS_PER_LINE 8
615 #endif
617 static void sparc_cpu_dump_state(CPUState *cs, FILE *f, int flags)
619 SPARCCPU *cpu = SPARC_CPU(cs);
620 CPUSPARCState *env = &cpu->env;
621 int i, x;
623 qemu_fprintf(f, "pc: " TARGET_FMT_lx " npc: " TARGET_FMT_lx "\n", env->pc,
624 env->npc);
626 for (i = 0; i < 8; i++) {
627 if (i % REGS_PER_LINE == 0) {
628 qemu_fprintf(f, "%%g%d-%d:", i, i + REGS_PER_LINE - 1);
630 qemu_fprintf(f, " " TARGET_FMT_lx, env->gregs[i]);
631 if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
632 qemu_fprintf(f, "\n");
635 for (x = 0; x < 3; x++) {
636 for (i = 0; i < 8; i++) {
637 if (i % REGS_PER_LINE == 0) {
638 qemu_fprintf(f, "%%%c%d-%d: ",
639 x == 0 ? 'o' : (x == 1 ? 'l' : 'i'),
640 i, i + REGS_PER_LINE - 1);
642 qemu_fprintf(f, TARGET_FMT_lx " ", env->regwptr[i + x * 8]);
643 if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
644 qemu_fprintf(f, "\n");
649 if (flags & CPU_DUMP_FPU) {
650 for (i = 0; i < TARGET_DPREGS; i++) {
651 if ((i & 3) == 0) {
652 qemu_fprintf(f, "%%f%02d: ", i * 2);
654 qemu_fprintf(f, " %016" PRIx64, env->fpr[i].ll);
655 if ((i & 3) == 3) {
656 qemu_fprintf(f, "\n");
661 #ifdef TARGET_SPARC64
662 qemu_fprintf(f, "pstate: %08x ccr: %02x (icc: ", env->pstate,
663 (unsigned)cpu_get_ccr(env));
664 cpu_print_cc(f, cpu_get_ccr(env) << PSR_CARRY_SHIFT);
665 qemu_fprintf(f, " xcc: ");
666 cpu_print_cc(f, cpu_get_ccr(env) << (PSR_CARRY_SHIFT - 4));
667 qemu_fprintf(f, ") asi: %02x tl: %d pil: %x gl: %d\n", env->asi, env->tl,
668 env->psrpil, env->gl);
669 qemu_fprintf(f, "tbr: " TARGET_FMT_lx " hpstate: " TARGET_FMT_lx " htba: "
670 TARGET_FMT_lx "\n", env->tbr, env->hpstate, env->htba);
671 qemu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate: %d "
672 "cleanwin: %d cwp: %d\n",
673 env->cansave, env->canrestore, env->otherwin, env->wstate,
674 env->cleanwin, env->nwindows - 1 - env->cwp);
675 qemu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: "
676 TARGET_FMT_lx "\n", env->fsr, env->y, env->fprs);
678 #else
679 qemu_fprintf(f, "psr: %08x (icc: ", cpu_get_psr(env));
680 cpu_print_cc(f, cpu_get_psr(env));
681 qemu_fprintf(f, " SPE: %c%c%c) wim: %08x\n", env->psrs ? 'S' : '-',
682 env->psrps ? 'P' : '-', env->psret ? 'E' : '-',
683 env->wim);
684 qemu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx "\n",
685 env->fsr, env->y);
686 #endif
687 qemu_fprintf(f, "\n");
690 static void sparc_cpu_set_pc(CPUState *cs, vaddr value)
692 SPARCCPU *cpu = SPARC_CPU(cs);
694 cpu->env.pc = value;
695 cpu->env.npc = value + 4;
698 static vaddr sparc_cpu_get_pc(CPUState *cs)
700 SPARCCPU *cpu = SPARC_CPU(cs);
702 return cpu->env.pc;
705 static void sparc_cpu_synchronize_from_tb(CPUState *cs,
706 const TranslationBlock *tb)
708 SPARCCPU *cpu = SPARC_CPU(cs);
710 cpu->env.pc = tb_pc(tb);
711 cpu->env.npc = tb->cs_base;
714 static bool sparc_cpu_has_work(CPUState *cs)
716 SPARCCPU *cpu = SPARC_CPU(cs);
717 CPUSPARCState *env = &cpu->env;
719 return (cs->interrupt_request & CPU_INTERRUPT_HARD) &&
720 cpu_interrupts_enabled(env);
723 static char *sparc_cpu_type_name(const char *cpu_model)
725 char *name = g_strdup_printf(SPARC_CPU_TYPE_NAME("%s"), cpu_model);
726 char *s = name;
728 /* SPARC cpu model names happen to have whitespaces,
729 * as type names shouldn't have spaces replace them with '-'
731 while ((s = strchr(s, ' '))) {
732 *s = '-';
735 return name;
738 static ObjectClass *sparc_cpu_class_by_name(const char *cpu_model)
740 ObjectClass *oc;
741 char *typename;
743 typename = sparc_cpu_type_name(cpu_model);
744 oc = object_class_by_name(typename);
745 g_free(typename);
746 return oc;
749 static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
751 CPUState *cs = CPU(dev);
752 SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(dev);
753 Error *local_err = NULL;
754 SPARCCPU *cpu = SPARC_CPU(dev);
755 CPUSPARCState *env = &cpu->env;
757 #if defined(CONFIG_USER_ONLY)
758 if ((env->def.features & CPU_FEATURE_FLOAT)) {
759 env->def.features |= CPU_FEATURE_FLOAT128;
761 #endif
763 env->version = env->def.iu_version;
764 env->fsr = env->def.fpu_version;
765 env->nwindows = env->def.nwindows;
766 #if !defined(TARGET_SPARC64)
767 env->mmuregs[0] |= env->def.mmu_version;
768 cpu_sparc_set_id(env, 0);
769 env->mxccregs[7] |= env->def.mxcc_version;
770 #else
771 env->mmu_version = env->def.mmu_version;
772 env->maxtl = env->def.maxtl;
773 env->version |= env->def.maxtl << 8;
774 env->version |= env->def.nwindows - 1;
775 #endif
777 cpu_exec_realizefn(cs, &local_err);
778 if (local_err != NULL) {
779 error_propagate(errp, local_err);
780 return;
783 qemu_init_vcpu(cs);
785 scc->parent_realize(dev, errp);
788 static void sparc_cpu_initfn(Object *obj)
790 SPARCCPU *cpu = SPARC_CPU(obj);
791 SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(obj);
792 CPUSPARCState *env = &cpu->env;
794 cpu_set_cpustate_pointers(cpu);
796 if (scc->cpu_def) {
797 env->def = *scc->cpu_def;
801 static void sparc_get_nwindows(Object *obj, Visitor *v, const char *name,
802 void *opaque, Error **errp)
804 SPARCCPU *cpu = SPARC_CPU(obj);
805 int64_t value = cpu->env.def.nwindows;
807 visit_type_int(v, name, &value, errp);
810 static void sparc_set_nwindows(Object *obj, Visitor *v, const char *name,
811 void *opaque, Error **errp)
813 const int64_t min = MIN_NWINDOWS;
814 const int64_t max = MAX_NWINDOWS;
815 SPARCCPU *cpu = SPARC_CPU(obj);
816 int64_t value;
818 if (!visit_type_int(v, name, &value, errp)) {
819 return;
822 if (value < min || value > max) {
823 error_setg(errp, "Property %s.%s doesn't take value %" PRId64
824 " (minimum: %" PRId64 ", maximum: %" PRId64 ")",
825 object_get_typename(obj), name ? name : "null",
826 value, min, max);
827 return;
829 cpu->env.def.nwindows = value;
832 static PropertyInfo qdev_prop_nwindows = {
833 .name = "int",
834 .get = sparc_get_nwindows,
835 .set = sparc_set_nwindows,
838 static Property sparc_cpu_properties[] = {
839 DEFINE_PROP_BIT("float", SPARCCPU, env.def.features, 0, false),
840 DEFINE_PROP_BIT("float128", SPARCCPU, env.def.features, 1, false),
841 DEFINE_PROP_BIT("swap", SPARCCPU, env.def.features, 2, false),
842 DEFINE_PROP_BIT("mul", SPARCCPU, env.def.features, 3, false),
843 DEFINE_PROP_BIT("div", SPARCCPU, env.def.features, 4, false),
844 DEFINE_PROP_BIT("flush", SPARCCPU, env.def.features, 5, false),
845 DEFINE_PROP_BIT("fsqrt", SPARCCPU, env.def.features, 6, false),
846 DEFINE_PROP_BIT("fmul", SPARCCPU, env.def.features, 7, false),
847 DEFINE_PROP_BIT("vis1", SPARCCPU, env.def.features, 8, false),
848 DEFINE_PROP_BIT("vis2", SPARCCPU, env.def.features, 9, false),
849 DEFINE_PROP_BIT("fsmuld", SPARCCPU, env.def.features, 10, false),
850 DEFINE_PROP_BIT("hypv", SPARCCPU, env.def.features, 11, false),
851 DEFINE_PROP_BIT("cmt", SPARCCPU, env.def.features, 12, false),
852 DEFINE_PROP_BIT("gl", SPARCCPU, env.def.features, 13, false),
853 DEFINE_PROP_UNSIGNED("iu-version", SPARCCPU, env.def.iu_version, 0,
854 qdev_prop_uint64, target_ulong),
855 DEFINE_PROP_UINT32("fpu-version", SPARCCPU, env.def.fpu_version, 0),
856 DEFINE_PROP_UINT32("mmu-version", SPARCCPU, env.def.mmu_version, 0),
857 DEFINE_PROP("nwindows", SPARCCPU, env.def.nwindows,
858 qdev_prop_nwindows, uint32_t),
859 DEFINE_PROP_END_OF_LIST()
862 #ifndef CONFIG_USER_ONLY
863 #include "hw/core/sysemu-cpu-ops.h"
865 static const struct SysemuCPUOps sparc_sysemu_ops = {
866 .get_phys_page_debug = sparc_cpu_get_phys_page_debug,
867 .legacy_vmsd = &vmstate_sparc_cpu,
869 #endif
871 #ifdef CONFIG_TCG
872 #include "hw/core/tcg-cpu-ops.h"
874 static const struct TCGCPUOps sparc_tcg_ops = {
875 .initialize = sparc_tcg_init,
876 .synchronize_from_tb = sparc_cpu_synchronize_from_tb,
877 .restore_state_to_opc = sparc_restore_state_to_opc,
879 #ifndef CONFIG_USER_ONLY
880 .tlb_fill = sparc_cpu_tlb_fill,
881 .cpu_exec_interrupt = sparc_cpu_exec_interrupt,
882 .do_interrupt = sparc_cpu_do_interrupt,
883 .do_transaction_failed = sparc_cpu_do_transaction_failed,
884 .do_unaligned_access = sparc_cpu_do_unaligned_access,
885 #endif /* !CONFIG_USER_ONLY */
887 #endif /* CONFIG_TCG */
889 static void sparc_cpu_class_init(ObjectClass *oc, void *data)
891 SPARCCPUClass *scc = SPARC_CPU_CLASS(oc);
892 CPUClass *cc = CPU_CLASS(oc);
893 DeviceClass *dc = DEVICE_CLASS(oc);
894 ResettableClass *rc = RESETTABLE_CLASS(oc);
896 device_class_set_parent_realize(dc, sparc_cpu_realizefn,
897 &scc->parent_realize);
898 device_class_set_props(dc, sparc_cpu_properties);
900 resettable_class_set_parent_phases(rc, NULL, sparc_cpu_reset_hold, NULL,
901 &scc->parent_phases);
903 cc->class_by_name = sparc_cpu_class_by_name;
904 cc->parse_features = sparc_cpu_parse_features;
905 cc->has_work = sparc_cpu_has_work;
906 cc->dump_state = sparc_cpu_dump_state;
907 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
908 cc->memory_rw_debug = sparc_cpu_memory_rw_debug;
909 #endif
910 cc->set_pc = sparc_cpu_set_pc;
911 cc->get_pc = sparc_cpu_get_pc;
912 cc->gdb_read_register = sparc_cpu_gdb_read_register;
913 cc->gdb_write_register = sparc_cpu_gdb_write_register;
914 #ifndef CONFIG_USER_ONLY
915 cc->sysemu_ops = &sparc_sysemu_ops;
916 #endif
917 cc->disas_set_info = cpu_sparc_disas_set_info;
919 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
920 cc->gdb_num_core_regs = 86;
921 #else
922 cc->gdb_num_core_regs = 72;
923 #endif
924 cc->tcg_ops = &sparc_tcg_ops;
927 static const TypeInfo sparc_cpu_type_info = {
928 .name = TYPE_SPARC_CPU,
929 .parent = TYPE_CPU,
930 .instance_size = sizeof(SPARCCPU),
931 .instance_init = sparc_cpu_initfn,
932 .abstract = true,
933 .class_size = sizeof(SPARCCPUClass),
934 .class_init = sparc_cpu_class_init,
937 static void sparc_cpu_cpudef_class_init(ObjectClass *oc, void *data)
939 SPARCCPUClass *scc = SPARC_CPU_CLASS(oc);
940 scc->cpu_def = data;
943 static void sparc_register_cpudef_type(const struct sparc_def_t *def)
945 char *typename = sparc_cpu_type_name(def->name);
946 TypeInfo ti = {
947 .name = typename,
948 .parent = TYPE_SPARC_CPU,
949 .class_init = sparc_cpu_cpudef_class_init,
950 .class_data = (void *)def,
953 type_register(&ti);
954 g_free(typename);
957 static void sparc_cpu_register_types(void)
959 int i;
961 type_register_static(&sparc_cpu_type_info);
962 for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
963 sparc_register_cpudef_type(&sparc_defs[i]);
967 type_init(sparc_cpu_register_types)