chardev: add Chardev.gcontext field
[qemu/ar7.git] / target / sparc / cpu.c
blob0806d699e6f222040f6afd268b39f28daf3bf500
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 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/error-report.h"
24 #include "exec/exec-all.h"
25 #include "hw/qdev-properties.h"
26 #include "qapi/visitor.h"
28 //#define DEBUG_FEATURES
30 /* CPUClass::reset() */
31 static void sparc_cpu_reset(CPUState *s)
33 SPARCCPU *cpu = SPARC_CPU(s);
34 SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(cpu);
35 CPUSPARCState *env = &cpu->env;
37 scc->parent_reset(s);
39 memset(env, 0, offsetof(CPUSPARCState, end_reset_fields));
40 env->cwp = 0;
41 #ifndef TARGET_SPARC64
42 env->wim = 1;
43 #endif
44 env->regwptr = env->regbase + (env->cwp * 16);
45 CC_OP = CC_OP_FLAGS;
46 #if defined(CONFIG_USER_ONLY)
47 #ifdef TARGET_SPARC64
48 env->cleanwin = env->nwindows - 2;
49 env->cansave = env->nwindows - 2;
50 env->pstate = PS_RMO | PS_PEF | PS_IE;
51 env->asi = 0x82; /* Primary no-fault */
52 #endif
53 #else
54 #if !defined(TARGET_SPARC64)
55 env->psret = 0;
56 env->psrs = 1;
57 env->psrps = 1;
58 #endif
59 #ifdef TARGET_SPARC64
60 env->pstate = PS_PRIV | PS_RED | PS_PEF;
61 if (!cpu_has_hypervisor(env)) {
62 env->pstate |= PS_AG;
64 env->hpstate = cpu_has_hypervisor(env) ? HS_PRIV : 0;
65 env->tl = env->maxtl;
66 env->gl = 2;
67 cpu_tsptr(env)->tt = TT_POWER_ON_RESET;
68 env->lsu = 0;
69 #else
70 env->mmuregs[0] &= ~(MMU_E | MMU_NF);
71 env->mmuregs[0] |= env->def.mmu_bm;
72 #endif
73 env->pc = 0;
74 env->npc = env->pc + 4;
75 #endif
76 env->cache_control = 0;
79 static bool sparc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
81 if (interrupt_request & CPU_INTERRUPT_HARD) {
82 SPARCCPU *cpu = SPARC_CPU(cs);
83 CPUSPARCState *env = &cpu->env;
85 if (cpu_interrupts_enabled(env) && env->interrupt_index > 0) {
86 int pil = env->interrupt_index & 0xf;
87 int type = env->interrupt_index & 0xf0;
89 if (type != TT_EXTINT || cpu_pil_allowed(env, pil)) {
90 cs->exception_index = env->interrupt_index;
91 sparc_cpu_do_interrupt(cs);
92 return true;
96 return false;
99 static void cpu_sparc_disas_set_info(CPUState *cpu, disassemble_info *info)
101 info->print_insn = print_insn_sparc;
102 #ifdef TARGET_SPARC64
103 info->mach = bfd_mach_sparc_v9b;
104 #endif
107 static void
108 cpu_add_feat_as_prop(const char *typename, const char *name, const char *val)
110 GlobalProperty *prop = g_new0(typeof(*prop), 1);
111 prop->driver = typename;
112 prop->property = g_strdup(name);
113 prop->value = g_strdup(val);
114 prop->errp = &error_fatal;
115 qdev_prop_register_global(prop);
118 /* Parse "+feature,-feature,feature=foo" CPU feature string */
119 static void sparc_cpu_parse_features(const char *typename, char *features,
120 Error **errp)
122 GList *l, *plus_features = NULL, *minus_features = NULL;
123 char *featurestr; /* Single 'key=value" string being parsed */
124 static bool cpu_globals_initialized;
126 if (cpu_globals_initialized) {
127 return;
129 cpu_globals_initialized = true;
131 if (!features) {
132 return;
135 for (featurestr = strtok(features, ",");
136 featurestr;
137 featurestr = strtok(NULL, ",")) {
138 const char *name;
139 const char *val = NULL;
140 char *eq = NULL;
142 /* Compatibility syntax: */
143 if (featurestr[0] == '+') {
144 plus_features = g_list_append(plus_features,
145 g_strdup(featurestr + 1));
146 continue;
147 } else if (featurestr[0] == '-') {
148 minus_features = g_list_append(minus_features,
149 g_strdup(featurestr + 1));
150 continue;
153 eq = strchr(featurestr, '=');
154 name = featurestr;
155 if (eq) {
156 *eq++ = 0;
157 val = eq;
160 * Temporarily, only +feat/-feat will be supported
161 * for boolean properties until we remove the
162 * minus-overrides-plus semantics and just follow
163 * the order options appear on the command-line.
165 * TODO: warn if user is relying on minus-override-plus semantics
166 * TODO: remove minus-override-plus semantics after
167 * warning for a few releases
169 if (!strcasecmp(val, "on") ||
170 !strcasecmp(val, "off") ||
171 !strcasecmp(val, "true") ||
172 !strcasecmp(val, "false")) {
173 error_setg(errp, "Boolean properties in format %s=%s"
174 " are not supported", name, val);
175 return;
177 } else {
178 error_setg(errp, "Unsupported property format: %s", name);
179 return;
181 cpu_add_feat_as_prop(typename, name, val);
184 for (l = plus_features; l; l = l->next) {
185 const char *name = l->data;
186 cpu_add_feat_as_prop(typename, name, "on");
188 g_list_free_full(plus_features, g_free);
190 for (l = minus_features; l; l = l->next) {
191 const char *name = l->data;
192 cpu_add_feat_as_prop(typename, name, "off");
194 g_list_free_full(minus_features, g_free);
197 void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
199 #if !defined(TARGET_SPARC64)
200 env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
201 #endif
204 static const sparc_def_t sparc_defs[] = {
205 #ifdef TARGET_SPARC64
207 .name = "Fujitsu Sparc64",
208 .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)),
209 .fpu_version = 0x00000000,
210 .mmu_version = mmu_us_12,
211 .nwindows = 4,
212 .maxtl = 4,
213 .features = CPU_DEFAULT_FEATURES,
216 .name = "Fujitsu Sparc64 III",
217 .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)),
218 .fpu_version = 0x00000000,
219 .mmu_version = mmu_us_12,
220 .nwindows = 5,
221 .maxtl = 4,
222 .features = CPU_DEFAULT_FEATURES,
225 .name = "Fujitsu Sparc64 IV",
226 .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)),
227 .fpu_version = 0x00000000,
228 .mmu_version = mmu_us_12,
229 .nwindows = 8,
230 .maxtl = 5,
231 .features = CPU_DEFAULT_FEATURES,
234 .name = "Fujitsu Sparc64 V",
235 .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)),
236 .fpu_version = 0x00000000,
237 .mmu_version = mmu_us_12,
238 .nwindows = 8,
239 .maxtl = 5,
240 .features = CPU_DEFAULT_FEATURES,
243 .name = "TI UltraSparc I",
244 .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
245 .fpu_version = 0x00000000,
246 .mmu_version = mmu_us_12,
247 .nwindows = 8,
248 .maxtl = 5,
249 .features = CPU_DEFAULT_FEATURES,
252 .name = "TI UltraSparc II",
253 .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)),
254 .fpu_version = 0x00000000,
255 .mmu_version = mmu_us_12,
256 .nwindows = 8,
257 .maxtl = 5,
258 .features = CPU_DEFAULT_FEATURES,
261 .name = "TI UltraSparc IIi",
262 .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)),
263 .fpu_version = 0x00000000,
264 .mmu_version = mmu_us_12,
265 .nwindows = 8,
266 .maxtl = 5,
267 .features = CPU_DEFAULT_FEATURES,
270 .name = "TI UltraSparc IIe",
271 .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)),
272 .fpu_version = 0x00000000,
273 .mmu_version = mmu_us_12,
274 .nwindows = 8,
275 .maxtl = 5,
276 .features = CPU_DEFAULT_FEATURES,
279 .name = "Sun UltraSparc III",
280 .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)),
281 .fpu_version = 0x00000000,
282 .mmu_version = mmu_us_12,
283 .nwindows = 8,
284 .maxtl = 5,
285 .features = CPU_DEFAULT_FEATURES,
288 .name = "Sun UltraSparc III Cu",
289 .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)),
290 .fpu_version = 0x00000000,
291 .mmu_version = mmu_us_3,
292 .nwindows = 8,
293 .maxtl = 5,
294 .features = CPU_DEFAULT_FEATURES,
297 .name = "Sun UltraSparc IIIi",
298 .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)),
299 .fpu_version = 0x00000000,
300 .mmu_version = mmu_us_12,
301 .nwindows = 8,
302 .maxtl = 5,
303 .features = CPU_DEFAULT_FEATURES,
306 .name = "Sun UltraSparc IV",
307 .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)),
308 .fpu_version = 0x00000000,
309 .mmu_version = mmu_us_4,
310 .nwindows = 8,
311 .maxtl = 5,
312 .features = CPU_DEFAULT_FEATURES,
315 .name = "Sun UltraSparc IV+",
316 .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)),
317 .fpu_version = 0x00000000,
318 .mmu_version = mmu_us_12,
319 .nwindows = 8,
320 .maxtl = 5,
321 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT,
324 .name = "Sun UltraSparc IIIi+",
325 .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)),
326 .fpu_version = 0x00000000,
327 .mmu_version = mmu_us_3,
328 .nwindows = 8,
329 .maxtl = 5,
330 .features = CPU_DEFAULT_FEATURES,
333 .name = "Sun UltraSparc T1",
334 /* defined in sparc_ifu_fdp.v and ctu.h */
335 .iu_version = ((0x3eULL << 48) | (0x23ULL << 32) | (0x02ULL << 24)),
336 .fpu_version = 0x00000000,
337 .mmu_version = mmu_sun4v,
338 .nwindows = 8,
339 .maxtl = 6,
340 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
341 | CPU_FEATURE_GL,
344 .name = "Sun UltraSparc T2",
345 /* defined in tlu_asi_ctl.v and n2_revid_cust.v */
346 .iu_version = ((0x3eULL << 48) | (0x24ULL << 32) | (0x02ULL << 24)),
347 .fpu_version = 0x00000000,
348 .mmu_version = mmu_sun4v,
349 .nwindows = 8,
350 .maxtl = 6,
351 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
352 | CPU_FEATURE_GL,
355 .name = "NEC UltraSparc I",
356 .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
357 .fpu_version = 0x00000000,
358 .mmu_version = mmu_us_12,
359 .nwindows = 8,
360 .maxtl = 5,
361 .features = CPU_DEFAULT_FEATURES,
363 #else
365 .name = "Fujitsu MB86904",
366 .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
367 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
368 .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
369 .mmu_bm = 0x00004000,
370 .mmu_ctpr_mask = 0x00ffffc0,
371 .mmu_cxr_mask = 0x000000ff,
372 .mmu_sfsr_mask = 0x00016fff,
373 .mmu_trcr_mask = 0x00ffffff,
374 .nwindows = 8,
375 .features = CPU_DEFAULT_FEATURES,
378 .name = "Fujitsu MB86907",
379 .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
380 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
381 .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
382 .mmu_bm = 0x00004000,
383 .mmu_ctpr_mask = 0xffffffc0,
384 .mmu_cxr_mask = 0x000000ff,
385 .mmu_sfsr_mask = 0x00016fff,
386 .mmu_trcr_mask = 0xffffffff,
387 .nwindows = 8,
388 .features = CPU_DEFAULT_FEATURES,
391 .name = "TI MicroSparc I",
392 .iu_version = 0x41000000,
393 .fpu_version = 4 << 17,
394 .mmu_version = 0x41000000,
395 .mmu_bm = 0x00004000,
396 .mmu_ctpr_mask = 0x007ffff0,
397 .mmu_cxr_mask = 0x0000003f,
398 .mmu_sfsr_mask = 0x00016fff,
399 .mmu_trcr_mask = 0x0000003f,
400 .nwindows = 7,
401 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL |
402 CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT |
403 CPU_FEATURE_FMUL,
406 .name = "TI MicroSparc II",
407 .iu_version = 0x42000000,
408 .fpu_version = 4 << 17,
409 .mmu_version = 0x02000000,
410 .mmu_bm = 0x00004000,
411 .mmu_ctpr_mask = 0x00ffffc0,
412 .mmu_cxr_mask = 0x000000ff,
413 .mmu_sfsr_mask = 0x00016fff,
414 .mmu_trcr_mask = 0x00ffffff,
415 .nwindows = 8,
416 .features = CPU_DEFAULT_FEATURES,
419 .name = "TI MicroSparc IIep",
420 .iu_version = 0x42000000,
421 .fpu_version = 4 << 17,
422 .mmu_version = 0x04000000,
423 .mmu_bm = 0x00004000,
424 .mmu_ctpr_mask = 0x00ffffc0,
425 .mmu_cxr_mask = 0x000000ff,
426 .mmu_sfsr_mask = 0x00016bff,
427 .mmu_trcr_mask = 0x00ffffff,
428 .nwindows = 8,
429 .features = CPU_DEFAULT_FEATURES,
432 .name = "TI SuperSparc 40", /* STP1020NPGA */
433 .iu_version = 0x41000000, /* SuperSPARC 2.x */
434 .fpu_version = 0 << 17,
435 .mmu_version = 0x00000800, /* SuperSPARC 2.x, no MXCC */
436 .mmu_bm = 0x00002000,
437 .mmu_ctpr_mask = 0xffffffc0,
438 .mmu_cxr_mask = 0x0000ffff,
439 .mmu_sfsr_mask = 0xffffffff,
440 .mmu_trcr_mask = 0xffffffff,
441 .nwindows = 8,
442 .features = CPU_DEFAULT_FEATURES,
445 .name = "TI SuperSparc 50", /* STP1020PGA */
446 .iu_version = 0x40000000, /* SuperSPARC 3.x */
447 .fpu_version = 0 << 17,
448 .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
449 .mmu_bm = 0x00002000,
450 .mmu_ctpr_mask = 0xffffffc0,
451 .mmu_cxr_mask = 0x0000ffff,
452 .mmu_sfsr_mask = 0xffffffff,
453 .mmu_trcr_mask = 0xffffffff,
454 .nwindows = 8,
455 .features = CPU_DEFAULT_FEATURES,
458 .name = "TI SuperSparc 51",
459 .iu_version = 0x40000000, /* SuperSPARC 3.x */
460 .fpu_version = 0 << 17,
461 .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
462 .mmu_bm = 0x00002000,
463 .mmu_ctpr_mask = 0xffffffc0,
464 .mmu_cxr_mask = 0x0000ffff,
465 .mmu_sfsr_mask = 0xffffffff,
466 .mmu_trcr_mask = 0xffffffff,
467 .mxcc_version = 0x00000104,
468 .nwindows = 8,
469 .features = CPU_DEFAULT_FEATURES,
472 .name = "TI SuperSparc 60", /* STP1020APGA */
473 .iu_version = 0x40000000, /* SuperSPARC 3.x */
474 .fpu_version = 0 << 17,
475 .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
476 .mmu_bm = 0x00002000,
477 .mmu_ctpr_mask = 0xffffffc0,
478 .mmu_cxr_mask = 0x0000ffff,
479 .mmu_sfsr_mask = 0xffffffff,
480 .mmu_trcr_mask = 0xffffffff,
481 .nwindows = 8,
482 .features = CPU_DEFAULT_FEATURES,
485 .name = "TI SuperSparc 61",
486 .iu_version = 0x44000000, /* SuperSPARC 3.x */
487 .fpu_version = 0 << 17,
488 .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
489 .mmu_bm = 0x00002000,
490 .mmu_ctpr_mask = 0xffffffc0,
491 .mmu_cxr_mask = 0x0000ffff,
492 .mmu_sfsr_mask = 0xffffffff,
493 .mmu_trcr_mask = 0xffffffff,
494 .mxcc_version = 0x00000104,
495 .nwindows = 8,
496 .features = CPU_DEFAULT_FEATURES,
499 .name = "TI SuperSparc II",
500 .iu_version = 0x40000000, /* SuperSPARC II 1.x */
501 .fpu_version = 0 << 17,
502 .mmu_version = 0x08000000, /* SuperSPARC II 1.x, MXCC */
503 .mmu_bm = 0x00002000,
504 .mmu_ctpr_mask = 0xffffffc0,
505 .mmu_cxr_mask = 0x0000ffff,
506 .mmu_sfsr_mask = 0xffffffff,
507 .mmu_trcr_mask = 0xffffffff,
508 .mxcc_version = 0x00000104,
509 .nwindows = 8,
510 .features = CPU_DEFAULT_FEATURES,
513 .name = "LEON2",
514 .iu_version = 0xf2000000,
515 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
516 .mmu_version = 0xf2000000,
517 .mmu_bm = 0x00004000,
518 .mmu_ctpr_mask = 0x007ffff0,
519 .mmu_cxr_mask = 0x0000003f,
520 .mmu_sfsr_mask = 0xffffffff,
521 .mmu_trcr_mask = 0xffffffff,
522 .nwindows = 8,
523 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN,
526 .name = "LEON3",
527 .iu_version = 0xf3000000,
528 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
529 .mmu_version = 0xf3000000,
530 .mmu_bm = 0x00000000,
531 .mmu_ctpr_mask = 0xfffffffc,
532 .mmu_cxr_mask = 0x000000ff,
533 .mmu_sfsr_mask = 0xffffffff,
534 .mmu_trcr_mask = 0xffffffff,
535 .nwindows = 8,
536 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN |
537 CPU_FEATURE_ASR17 | CPU_FEATURE_CACHE_CTRL | CPU_FEATURE_POWERDOWN |
538 CPU_FEATURE_CASA,
540 #endif
543 static const char * const feature_name[] = {
544 "float",
545 "float128",
546 "swap",
547 "mul",
548 "div",
549 "flush",
550 "fsqrt",
551 "fmul",
552 "vis1",
553 "vis2",
554 "fsmuld",
555 "hypv",
556 "cmt",
557 "gl",
560 static void print_features(FILE *f, fprintf_function cpu_fprintf,
561 uint32_t features, const char *prefix)
563 unsigned int i;
565 for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
566 if (feature_name[i] && (features & (1 << i))) {
567 if (prefix) {
568 (*cpu_fprintf)(f, "%s", prefix);
570 (*cpu_fprintf)(f, "%s ", feature_name[i]);
575 void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf)
577 unsigned int i;
579 for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
580 (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx
581 " FPU %08x MMU %08x NWINS %d ",
582 sparc_defs[i].name,
583 sparc_defs[i].iu_version,
584 sparc_defs[i].fpu_version,
585 sparc_defs[i].mmu_version,
586 sparc_defs[i].nwindows);
587 print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES &
588 ~sparc_defs[i].features, "-");
589 print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES &
590 sparc_defs[i].features, "+");
591 (*cpu_fprintf)(f, "\n");
593 (*cpu_fprintf)(f, "Default CPU feature flags (use '-' to remove): ");
594 print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES, NULL);
595 (*cpu_fprintf)(f, "\n");
596 (*cpu_fprintf)(f, "Available CPU feature flags (use '+' to add): ");
597 print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES, NULL);
598 (*cpu_fprintf)(f, "\n");
599 (*cpu_fprintf)(f, "Numerical features (use '=' to set): iu_version "
600 "fpu_version mmu_version nwindows\n");
603 static void cpu_print_cc(FILE *f, fprintf_function cpu_fprintf,
604 uint32_t cc)
606 cpu_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 void sparc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
618 int flags)
620 SPARCCPU *cpu = SPARC_CPU(cs);
621 CPUSPARCState *env = &cpu->env;
622 int i, x;
624 cpu_fprintf(f, "pc: " TARGET_FMT_lx " npc: " TARGET_FMT_lx "\n", env->pc,
625 env->npc);
627 for (i = 0; i < 8; i++) {
628 if (i % REGS_PER_LINE == 0) {
629 cpu_fprintf(f, "%%g%d-%d:", i, i + REGS_PER_LINE - 1);
631 cpu_fprintf(f, " " TARGET_FMT_lx, env->gregs[i]);
632 if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
633 cpu_fprintf(f, "\n");
636 for (x = 0; x < 3; x++) {
637 for (i = 0; i < 8; i++) {
638 if (i % REGS_PER_LINE == 0) {
639 cpu_fprintf(f, "%%%c%d-%d: ",
640 x == 0 ? 'o' : (x == 1 ? 'l' : 'i'),
641 i, i + REGS_PER_LINE - 1);
643 cpu_fprintf(f, TARGET_FMT_lx " ", env->regwptr[i + x * 8]);
644 if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
645 cpu_fprintf(f, "\n");
650 for (i = 0; i < TARGET_DPREGS; i++) {
651 if ((i & 3) == 0) {
652 cpu_fprintf(f, "%%f%02d: ", i * 2);
654 cpu_fprintf(f, " %016" PRIx64, env->fpr[i].ll);
655 if ((i & 3) == 3) {
656 cpu_fprintf(f, "\n");
659 #ifdef TARGET_SPARC64
660 cpu_fprintf(f, "pstate: %08x ccr: %02x (icc: ", env->pstate,
661 (unsigned)cpu_get_ccr(env));
662 cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << PSR_CARRY_SHIFT);
663 cpu_fprintf(f, " xcc: ");
664 cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << (PSR_CARRY_SHIFT - 4));
665 cpu_fprintf(f, ") asi: %02x tl: %d pil: %x gl: %d\n", env->asi, env->tl,
666 env->psrpil, env->gl);
667 cpu_fprintf(f, "tbr: " TARGET_FMT_lx " hpstate: " TARGET_FMT_lx " htba: "
668 TARGET_FMT_lx "\n", env->tbr, env->hpstate, env->htba);
669 cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate: %d "
670 "cleanwin: %d cwp: %d\n",
671 env->cansave, env->canrestore, env->otherwin, env->wstate,
672 env->cleanwin, env->nwindows - 1 - env->cwp);
673 cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: "
674 TARGET_FMT_lx "\n", env->fsr, env->y, env->fprs);
676 #else
677 cpu_fprintf(f, "psr: %08x (icc: ", cpu_get_psr(env));
678 cpu_print_cc(f, cpu_fprintf, cpu_get_psr(env));
679 cpu_fprintf(f, " SPE: %c%c%c) wim: %08x\n", env->psrs ? 'S' : '-',
680 env->psrps ? 'P' : '-', env->psret ? 'E' : '-',
681 env->wim);
682 cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx "\n",
683 env->fsr, env->y);
684 #endif
685 cpu_fprintf(f, "\n");
688 static void sparc_cpu_set_pc(CPUState *cs, vaddr value)
690 SPARCCPU *cpu = SPARC_CPU(cs);
692 cpu->env.pc = value;
693 cpu->env.npc = value + 4;
696 static void sparc_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
698 SPARCCPU *cpu = SPARC_CPU(cs);
700 cpu->env.pc = tb->pc;
701 cpu->env.npc = tb->cs_base;
704 static bool sparc_cpu_has_work(CPUState *cs)
706 SPARCCPU *cpu = SPARC_CPU(cs);
707 CPUSPARCState *env = &cpu->env;
709 return (cs->interrupt_request & CPU_INTERRUPT_HARD) &&
710 cpu_interrupts_enabled(env);
713 static char *sparc_cpu_type_name(const char *cpu_model)
715 char *name = g_strdup_printf("%s-" TYPE_SPARC_CPU, cpu_model);
716 char *s = name;
718 /* SPARC cpu model names happen to have whitespaces,
719 * as type names shouldn't have spaces replace them with '-'
721 while ((s = strchr(s, ' '))) {
722 *s = '-';
725 return name;
728 static ObjectClass *sparc_cpu_class_by_name(const char *cpu_model)
730 ObjectClass *oc;
731 char *typename;
733 if (cpu_model == NULL) {
734 return NULL;
737 typename = sparc_cpu_type_name(cpu_model);
738 oc = object_class_by_name(typename);
739 g_free(typename);
740 return oc;
743 static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
745 CPUState *cs = CPU(dev);
746 SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(dev);
747 Error *local_err = NULL;
748 SPARCCPU *cpu = SPARC_CPU(dev);
749 CPUSPARCState *env = &cpu->env;
751 #if defined(CONFIG_USER_ONLY)
752 if ((env->def.features & CPU_FEATURE_FLOAT)) {
753 env->def.features |= CPU_FEATURE_FLOAT128;
755 #endif
757 env->version = env->def.iu_version;
758 env->fsr = env->def.fpu_version;
759 env->nwindows = env->def.nwindows;
760 #if !defined(TARGET_SPARC64)
761 env->mmuregs[0] |= env->def.mmu_version;
762 cpu_sparc_set_id(env, 0);
763 env->mxccregs[7] |= env->def.mxcc_version;
764 #else
765 env->mmu_version = env->def.mmu_version;
766 env->maxtl = env->def.maxtl;
767 env->version |= env->def.maxtl << 8;
768 env->version |= env->def.nwindows - 1;
769 #endif
771 cpu_exec_realizefn(cs, &local_err);
772 if (local_err != NULL) {
773 error_propagate(errp, local_err);
774 return;
777 qemu_init_vcpu(cs);
779 scc->parent_realize(dev, errp);
782 static void sparc_cpu_initfn(Object *obj)
784 CPUState *cs = CPU(obj);
785 SPARCCPU *cpu = SPARC_CPU(obj);
786 SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(obj);
787 CPUSPARCState *env = &cpu->env;
789 cs->env_ptr = env;
791 if (tcg_enabled()) {
792 gen_intermediate_code_init(env);
795 if (scc->cpu_def) {
796 env->def = *scc->cpu_def;
800 static void sparc_get_nwindows(Object *obj, Visitor *v, const char *name,
801 void *opaque, Error **errp)
803 SPARCCPU *cpu = SPARC_CPU(obj);
804 int64_t value = cpu->env.def.nwindows;
806 visit_type_int(v, name, &value, errp);
809 static void sparc_set_nwindows(Object *obj, Visitor *v, const char *name,
810 void *opaque, Error **errp)
812 const int64_t min = MIN_NWINDOWS;
813 const int64_t max = MAX_NWINDOWS;
814 SPARCCPU *cpu = SPARC_CPU(obj);
815 Error *err = NULL;
816 int64_t value;
818 visit_type_int(v, name, &value, &err);
819 if (err) {
820 error_propagate(errp, err);
821 return;
824 if (value < min || value > max) {
825 error_setg(errp, "Property %s.%s doesn't take value %" PRId64
826 " (minimum: %" PRId64 ", maximum: %" PRId64 ")",
827 object_get_typename(obj), name ? name : "null",
828 value, min, max);
829 return;
831 cpu->env.def.nwindows = value;
834 static PropertyInfo qdev_prop_nwindows = {
835 .name = "int",
836 .get = sparc_get_nwindows,
837 .set = sparc_set_nwindows,
840 static Property sparc_cpu_properties[] = {
841 DEFINE_PROP_BIT("float", SPARCCPU, env.def.features, 0, false),
842 DEFINE_PROP_BIT("float128", SPARCCPU, env.def.features, 1, false),
843 DEFINE_PROP_BIT("swap", SPARCCPU, env.def.features, 2, false),
844 DEFINE_PROP_BIT("mul", SPARCCPU, env.def.features, 3, false),
845 DEFINE_PROP_BIT("div", SPARCCPU, env.def.features, 4, false),
846 DEFINE_PROP_BIT("flush", SPARCCPU, env.def.features, 5, false),
847 DEFINE_PROP_BIT("fsqrt", SPARCCPU, env.def.features, 6, false),
848 DEFINE_PROP_BIT("fmul", SPARCCPU, env.def.features, 7, false),
849 DEFINE_PROP_BIT("vis1", SPARCCPU, env.def.features, 8, false),
850 DEFINE_PROP_BIT("vis2", SPARCCPU, env.def.features, 9, false),
851 DEFINE_PROP_BIT("fsmuld", SPARCCPU, env.def.features, 10, false),
852 DEFINE_PROP_BIT("hypv", SPARCCPU, env.def.features, 11, false),
853 DEFINE_PROP_BIT("cmt", SPARCCPU, env.def.features, 12, false),
854 DEFINE_PROP_BIT("gl", SPARCCPU, env.def.features, 13, false),
855 DEFINE_PROP_UNSIGNED("iu-version", SPARCCPU, env.def.iu_version, 0,
856 qdev_prop_uint64, target_ulong),
857 DEFINE_PROP_UINT32("fpu-version", SPARCCPU, env.def.fpu_version, 0),
858 DEFINE_PROP_UINT32("mmu-version", SPARCCPU, env.def.mmu_version, 0),
859 { .name = "nwindows", .info = &qdev_prop_nwindows },
860 DEFINE_PROP_END_OF_LIST()
863 static void sparc_cpu_class_init(ObjectClass *oc, void *data)
865 SPARCCPUClass *scc = SPARC_CPU_CLASS(oc);
866 CPUClass *cc = CPU_CLASS(oc);
867 DeviceClass *dc = DEVICE_CLASS(oc);
869 scc->parent_realize = dc->realize;
870 dc->realize = sparc_cpu_realizefn;
871 dc->props = sparc_cpu_properties;
873 scc->parent_reset = cc->reset;
874 cc->reset = sparc_cpu_reset;
876 cc->class_by_name = sparc_cpu_class_by_name;
877 cc->parse_features = sparc_cpu_parse_features;
878 cc->has_work = sparc_cpu_has_work;
879 cc->do_interrupt = sparc_cpu_do_interrupt;
880 cc->cpu_exec_interrupt = sparc_cpu_exec_interrupt;
881 cc->dump_state = sparc_cpu_dump_state;
882 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
883 cc->memory_rw_debug = sparc_cpu_memory_rw_debug;
884 #endif
885 cc->set_pc = sparc_cpu_set_pc;
886 cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb;
887 cc->gdb_read_register = sparc_cpu_gdb_read_register;
888 cc->gdb_write_register = sparc_cpu_gdb_write_register;
889 #ifdef CONFIG_USER_ONLY
890 cc->handle_mmu_fault = sparc_cpu_handle_mmu_fault;
891 #else
892 cc->do_unassigned_access = sparc_cpu_unassigned_access;
893 cc->do_unaligned_access = sparc_cpu_do_unaligned_access;
894 cc->get_phys_page_debug = sparc_cpu_get_phys_page_debug;
895 cc->vmsd = &vmstate_sparc_cpu;
896 #endif
897 cc->disas_set_info = cpu_sparc_disas_set_info;
899 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
900 cc->gdb_num_core_regs = 86;
901 #else
902 cc->gdb_num_core_regs = 72;
903 #endif
906 static const TypeInfo sparc_cpu_type_info = {
907 .name = TYPE_SPARC_CPU,
908 .parent = TYPE_CPU,
909 .instance_size = sizeof(SPARCCPU),
910 .instance_init = sparc_cpu_initfn,
911 .abstract = true,
912 .class_size = sizeof(SPARCCPUClass),
913 .class_init = sparc_cpu_class_init,
916 static void sparc_cpu_cpudef_class_init(ObjectClass *oc, void *data)
918 SPARCCPUClass *scc = SPARC_CPU_CLASS(oc);
919 scc->cpu_def = data;
922 static void sparc_register_cpudef_type(const struct sparc_def_t *def)
924 char *typename = sparc_cpu_type_name(def->name);
925 TypeInfo ti = {
926 .name = typename,
927 .parent = TYPE_SPARC_CPU,
928 .class_init = sparc_cpu_cpudef_class_init,
929 .class_data = (void *)def,
932 type_register(&ti);
933 g_free(typename);
936 static void sparc_cpu_register_types(void)
938 int i;
940 type_register_static(&sparc_cpu_type_info);
941 for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
942 sparc_register_cpudef_type(&sparc_defs[i]);
946 type_init(sparc_cpu_register_types)