block: change default of .has_zero_init to 0
[qemu/ar7.git] / target-sparc / cpu.c
blob13bb7bb94ac05f7b420f1fca5f3719f3de7b03fc
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 "cpu.h"
22 //#define DEBUG_FEATURES
24 static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model);
26 /* CPUClass::reset() */
27 static void sparc_cpu_reset(CPUState *s)
29 SPARCCPU *cpu = SPARC_CPU(s);
30 SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(cpu);
31 CPUSPARCState *env = &cpu->env;
33 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
34 qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
35 log_cpu_state(env, 0);
38 scc->parent_reset(s);
40 memset(env, 0, offsetof(CPUSPARCState, breakpoints));
41 tlb_flush(env, 1);
42 env->cwp = 0;
43 #ifndef TARGET_SPARC64
44 env->wim = 1;
45 #endif
46 env->regwptr = env->regbase + (env->cwp * 16);
47 CC_OP = CC_OP_FLAGS;
48 #if defined(CONFIG_USER_ONLY)
49 #ifdef TARGET_SPARC64
50 env->cleanwin = env->nwindows - 2;
51 env->cansave = env->nwindows - 2;
52 env->pstate = PS_RMO | PS_PEF | PS_IE;
53 env->asi = 0x82; /* Primary no-fault */
54 #endif
55 #else
56 #if !defined(TARGET_SPARC64)
57 env->psret = 0;
58 env->psrs = 1;
59 env->psrps = 1;
60 #endif
61 #ifdef TARGET_SPARC64
62 env->pstate = PS_PRIV|PS_RED|PS_PEF|PS_AG;
63 env->hpstate = cpu_has_hypervisor(env) ? HS_PRIV : 0;
64 env->tl = env->maxtl;
65 cpu_tsptr(env)->tt = TT_POWER_ON_RESET;
66 env->lsu = 0;
67 #else
68 env->mmuregs[0] &= ~(MMU_E | MMU_NF);
69 env->mmuregs[0] |= env->def->mmu_bm;
70 #endif
71 env->pc = 0;
72 env->npc = env->pc + 4;
73 #endif
74 env->cache_control = 0;
77 static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
79 sparc_def_t def1, *def = &def1;
81 if (cpu_sparc_find_by_name(def, cpu_model) < 0) {
82 return -1;
85 env->def = g_new0(sparc_def_t, 1);
86 memcpy(env->def, def, sizeof(*def));
87 #if defined(CONFIG_USER_ONLY)
88 if ((env->def->features & CPU_FEATURE_FLOAT)) {
89 env->def->features |= CPU_FEATURE_FLOAT128;
91 #endif
92 env->cpu_model_str = cpu_model;
93 env->version = def->iu_version;
94 env->fsr = def->fpu_version;
95 env->nwindows = def->nwindows;
96 #if !defined(TARGET_SPARC64)
97 env->mmuregs[0] |= def->mmu_version;
98 cpu_sparc_set_id(env, 0);
99 env->mxccregs[7] |= def->mxcc_version;
100 #else
101 env->mmu_version = def->mmu_version;
102 env->maxtl = def->maxtl;
103 env->version |= def->maxtl << 8;
104 env->version |= def->nwindows - 1;
105 #endif
106 return 0;
109 SPARCCPU *cpu_sparc_init(const char *cpu_model)
111 SPARCCPU *cpu;
112 CPUSPARCState *env;
114 cpu = SPARC_CPU(object_new(TYPE_SPARC_CPU));
115 env = &cpu->env;
117 if (cpu_sparc_register(env, cpu_model) < 0) {
118 object_unref(OBJECT(cpu));
119 return NULL;
122 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
124 return cpu;
127 void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
129 #if !defined(TARGET_SPARC64)
130 env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
131 #endif
134 static const sparc_def_t sparc_defs[] = {
135 #ifdef TARGET_SPARC64
137 .name = "Fujitsu Sparc64",
138 .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)),
139 .fpu_version = 0x00000000,
140 .mmu_version = mmu_us_12,
141 .nwindows = 4,
142 .maxtl = 4,
143 .features = CPU_DEFAULT_FEATURES,
146 .name = "Fujitsu Sparc64 III",
147 .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)),
148 .fpu_version = 0x00000000,
149 .mmu_version = mmu_us_12,
150 .nwindows = 5,
151 .maxtl = 4,
152 .features = CPU_DEFAULT_FEATURES,
155 .name = "Fujitsu Sparc64 IV",
156 .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)),
157 .fpu_version = 0x00000000,
158 .mmu_version = mmu_us_12,
159 .nwindows = 8,
160 .maxtl = 5,
161 .features = CPU_DEFAULT_FEATURES,
164 .name = "Fujitsu Sparc64 V",
165 .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)),
166 .fpu_version = 0x00000000,
167 .mmu_version = mmu_us_12,
168 .nwindows = 8,
169 .maxtl = 5,
170 .features = CPU_DEFAULT_FEATURES,
173 .name = "TI UltraSparc I",
174 .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
175 .fpu_version = 0x00000000,
176 .mmu_version = mmu_us_12,
177 .nwindows = 8,
178 .maxtl = 5,
179 .features = CPU_DEFAULT_FEATURES,
182 .name = "TI UltraSparc II",
183 .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)),
184 .fpu_version = 0x00000000,
185 .mmu_version = mmu_us_12,
186 .nwindows = 8,
187 .maxtl = 5,
188 .features = CPU_DEFAULT_FEATURES,
191 .name = "TI UltraSparc IIi",
192 .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)),
193 .fpu_version = 0x00000000,
194 .mmu_version = mmu_us_12,
195 .nwindows = 8,
196 .maxtl = 5,
197 .features = CPU_DEFAULT_FEATURES,
200 .name = "TI UltraSparc IIe",
201 .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)),
202 .fpu_version = 0x00000000,
203 .mmu_version = mmu_us_12,
204 .nwindows = 8,
205 .maxtl = 5,
206 .features = CPU_DEFAULT_FEATURES,
209 .name = "Sun UltraSparc III",
210 .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)),
211 .fpu_version = 0x00000000,
212 .mmu_version = mmu_us_12,
213 .nwindows = 8,
214 .maxtl = 5,
215 .features = CPU_DEFAULT_FEATURES,
218 .name = "Sun UltraSparc III Cu",
219 .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)),
220 .fpu_version = 0x00000000,
221 .mmu_version = mmu_us_3,
222 .nwindows = 8,
223 .maxtl = 5,
224 .features = CPU_DEFAULT_FEATURES,
227 .name = "Sun UltraSparc IIIi",
228 .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)),
229 .fpu_version = 0x00000000,
230 .mmu_version = mmu_us_12,
231 .nwindows = 8,
232 .maxtl = 5,
233 .features = CPU_DEFAULT_FEATURES,
236 .name = "Sun UltraSparc IV",
237 .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)),
238 .fpu_version = 0x00000000,
239 .mmu_version = mmu_us_4,
240 .nwindows = 8,
241 .maxtl = 5,
242 .features = CPU_DEFAULT_FEATURES,
245 .name = "Sun UltraSparc IV+",
246 .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)),
247 .fpu_version = 0x00000000,
248 .mmu_version = mmu_us_12,
249 .nwindows = 8,
250 .maxtl = 5,
251 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT,
254 .name = "Sun UltraSparc IIIi+",
255 .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)),
256 .fpu_version = 0x00000000,
257 .mmu_version = mmu_us_3,
258 .nwindows = 8,
259 .maxtl = 5,
260 .features = CPU_DEFAULT_FEATURES,
263 .name = "Sun UltraSparc T1",
264 /* defined in sparc_ifu_fdp.v and ctu.h */
265 .iu_version = ((0x3eULL << 48) | (0x23ULL << 32) | (0x02ULL << 24)),
266 .fpu_version = 0x00000000,
267 .mmu_version = mmu_sun4v,
268 .nwindows = 8,
269 .maxtl = 6,
270 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
271 | CPU_FEATURE_GL,
274 .name = "Sun UltraSparc T2",
275 /* defined in tlu_asi_ctl.v and n2_revid_cust.v */
276 .iu_version = ((0x3eULL << 48) | (0x24ULL << 32) | (0x02ULL << 24)),
277 .fpu_version = 0x00000000,
278 .mmu_version = mmu_sun4v,
279 .nwindows = 8,
280 .maxtl = 6,
281 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
282 | CPU_FEATURE_GL,
285 .name = "NEC UltraSparc I",
286 .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
287 .fpu_version = 0x00000000,
288 .mmu_version = mmu_us_12,
289 .nwindows = 8,
290 .maxtl = 5,
291 .features = CPU_DEFAULT_FEATURES,
293 #else
295 .name = "Fujitsu MB86904",
296 .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
297 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
298 .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
299 .mmu_bm = 0x00004000,
300 .mmu_ctpr_mask = 0x00ffffc0,
301 .mmu_cxr_mask = 0x000000ff,
302 .mmu_sfsr_mask = 0x00016fff,
303 .mmu_trcr_mask = 0x00ffffff,
304 .nwindows = 8,
305 .features = CPU_DEFAULT_FEATURES,
308 .name = "Fujitsu MB86907",
309 .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
310 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
311 .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
312 .mmu_bm = 0x00004000,
313 .mmu_ctpr_mask = 0xffffffc0,
314 .mmu_cxr_mask = 0x000000ff,
315 .mmu_sfsr_mask = 0x00016fff,
316 .mmu_trcr_mask = 0xffffffff,
317 .nwindows = 8,
318 .features = CPU_DEFAULT_FEATURES,
321 .name = "TI MicroSparc I",
322 .iu_version = 0x41000000,
323 .fpu_version = 4 << 17,
324 .mmu_version = 0x41000000,
325 .mmu_bm = 0x00004000,
326 .mmu_ctpr_mask = 0x007ffff0,
327 .mmu_cxr_mask = 0x0000003f,
328 .mmu_sfsr_mask = 0x00016fff,
329 .mmu_trcr_mask = 0x0000003f,
330 .nwindows = 7,
331 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL |
332 CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT |
333 CPU_FEATURE_FMUL,
336 .name = "TI MicroSparc II",
337 .iu_version = 0x42000000,
338 .fpu_version = 4 << 17,
339 .mmu_version = 0x02000000,
340 .mmu_bm = 0x00004000,
341 .mmu_ctpr_mask = 0x00ffffc0,
342 .mmu_cxr_mask = 0x000000ff,
343 .mmu_sfsr_mask = 0x00016fff,
344 .mmu_trcr_mask = 0x00ffffff,
345 .nwindows = 8,
346 .features = CPU_DEFAULT_FEATURES,
349 .name = "TI MicroSparc IIep",
350 .iu_version = 0x42000000,
351 .fpu_version = 4 << 17,
352 .mmu_version = 0x04000000,
353 .mmu_bm = 0x00004000,
354 .mmu_ctpr_mask = 0x00ffffc0,
355 .mmu_cxr_mask = 0x000000ff,
356 .mmu_sfsr_mask = 0x00016bff,
357 .mmu_trcr_mask = 0x00ffffff,
358 .nwindows = 8,
359 .features = CPU_DEFAULT_FEATURES,
362 .name = "TI SuperSparc 40", /* STP1020NPGA */
363 .iu_version = 0x41000000, /* SuperSPARC 2.x */
364 .fpu_version = 0 << 17,
365 .mmu_version = 0x00000800, /* SuperSPARC 2.x, no MXCC */
366 .mmu_bm = 0x00002000,
367 .mmu_ctpr_mask = 0xffffffc0,
368 .mmu_cxr_mask = 0x0000ffff,
369 .mmu_sfsr_mask = 0xffffffff,
370 .mmu_trcr_mask = 0xffffffff,
371 .nwindows = 8,
372 .features = CPU_DEFAULT_FEATURES,
375 .name = "TI SuperSparc 50", /* STP1020PGA */
376 .iu_version = 0x40000000, /* SuperSPARC 3.x */
377 .fpu_version = 0 << 17,
378 .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
379 .mmu_bm = 0x00002000,
380 .mmu_ctpr_mask = 0xffffffc0,
381 .mmu_cxr_mask = 0x0000ffff,
382 .mmu_sfsr_mask = 0xffffffff,
383 .mmu_trcr_mask = 0xffffffff,
384 .nwindows = 8,
385 .features = CPU_DEFAULT_FEATURES,
388 .name = "TI SuperSparc 51",
389 .iu_version = 0x40000000, /* SuperSPARC 3.x */
390 .fpu_version = 0 << 17,
391 .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
392 .mmu_bm = 0x00002000,
393 .mmu_ctpr_mask = 0xffffffc0,
394 .mmu_cxr_mask = 0x0000ffff,
395 .mmu_sfsr_mask = 0xffffffff,
396 .mmu_trcr_mask = 0xffffffff,
397 .mxcc_version = 0x00000104,
398 .nwindows = 8,
399 .features = CPU_DEFAULT_FEATURES,
402 .name = "TI SuperSparc 60", /* STP1020APGA */
403 .iu_version = 0x40000000, /* SuperSPARC 3.x */
404 .fpu_version = 0 << 17,
405 .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
406 .mmu_bm = 0x00002000,
407 .mmu_ctpr_mask = 0xffffffc0,
408 .mmu_cxr_mask = 0x0000ffff,
409 .mmu_sfsr_mask = 0xffffffff,
410 .mmu_trcr_mask = 0xffffffff,
411 .nwindows = 8,
412 .features = CPU_DEFAULT_FEATURES,
415 .name = "TI SuperSparc 61",
416 .iu_version = 0x44000000, /* SuperSPARC 3.x */
417 .fpu_version = 0 << 17,
418 .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
419 .mmu_bm = 0x00002000,
420 .mmu_ctpr_mask = 0xffffffc0,
421 .mmu_cxr_mask = 0x0000ffff,
422 .mmu_sfsr_mask = 0xffffffff,
423 .mmu_trcr_mask = 0xffffffff,
424 .mxcc_version = 0x00000104,
425 .nwindows = 8,
426 .features = CPU_DEFAULT_FEATURES,
429 .name = "TI SuperSparc II",
430 .iu_version = 0x40000000, /* SuperSPARC II 1.x */
431 .fpu_version = 0 << 17,
432 .mmu_version = 0x08000000, /* SuperSPARC II 1.x, MXCC */
433 .mmu_bm = 0x00002000,
434 .mmu_ctpr_mask = 0xffffffc0,
435 .mmu_cxr_mask = 0x0000ffff,
436 .mmu_sfsr_mask = 0xffffffff,
437 .mmu_trcr_mask = 0xffffffff,
438 .mxcc_version = 0x00000104,
439 .nwindows = 8,
440 .features = CPU_DEFAULT_FEATURES,
443 .name = "LEON2",
444 .iu_version = 0xf2000000,
445 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
446 .mmu_version = 0xf2000000,
447 .mmu_bm = 0x00004000,
448 .mmu_ctpr_mask = 0x007ffff0,
449 .mmu_cxr_mask = 0x0000003f,
450 .mmu_sfsr_mask = 0xffffffff,
451 .mmu_trcr_mask = 0xffffffff,
452 .nwindows = 8,
453 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN,
456 .name = "LEON3",
457 .iu_version = 0xf3000000,
458 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
459 .mmu_version = 0xf3000000,
460 .mmu_bm = 0x00000000,
461 .mmu_ctpr_mask = 0xfffffffc,
462 .mmu_cxr_mask = 0x000000ff,
463 .mmu_sfsr_mask = 0xffffffff,
464 .mmu_trcr_mask = 0xffffffff,
465 .nwindows = 8,
466 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN |
467 CPU_FEATURE_ASR17 | CPU_FEATURE_CACHE_CTRL | CPU_FEATURE_POWERDOWN,
469 #endif
472 static const char * const feature_name[] = {
473 "float",
474 "float128",
475 "swap",
476 "mul",
477 "div",
478 "flush",
479 "fsqrt",
480 "fmul",
481 "vis1",
482 "vis2",
483 "fsmuld",
484 "hypv",
485 "cmt",
486 "gl",
489 static void print_features(FILE *f, fprintf_function cpu_fprintf,
490 uint32_t features, const char *prefix)
492 unsigned int i;
494 for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
495 if (feature_name[i] && (features & (1 << i))) {
496 if (prefix) {
497 (*cpu_fprintf)(f, "%s", prefix);
499 (*cpu_fprintf)(f, "%s ", feature_name[i]);
504 static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features)
506 unsigned int i;
508 for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
509 if (feature_name[i] && !strcmp(flagname, feature_name[i])) {
510 *features |= 1 << i;
511 return;
514 fprintf(stderr, "CPU feature %s not found\n", flagname);
517 static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
519 unsigned int i;
520 const sparc_def_t *def = NULL;
521 char *s = g_strdup(cpu_model);
522 char *featurestr, *name = strtok(s, ",");
523 uint32_t plus_features = 0;
524 uint32_t minus_features = 0;
525 uint64_t iu_version;
526 uint32_t fpu_version, mmu_version, nwindows;
528 for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
529 if (strcasecmp(name, sparc_defs[i].name) == 0) {
530 def = &sparc_defs[i];
533 if (!def) {
534 goto error;
536 memcpy(cpu_def, def, sizeof(*def));
538 featurestr = strtok(NULL, ",");
539 while (featurestr) {
540 char *val;
542 if (featurestr[0] == '+') {
543 add_flagname_to_bitmaps(featurestr + 1, &plus_features);
544 } else if (featurestr[0] == '-') {
545 add_flagname_to_bitmaps(featurestr + 1, &minus_features);
546 } else if ((val = strchr(featurestr, '='))) {
547 *val = 0; val++;
548 if (!strcmp(featurestr, "iu_version")) {
549 char *err;
551 iu_version = strtoll(val, &err, 0);
552 if (!*val || *err) {
553 fprintf(stderr, "bad numerical value %s\n", val);
554 goto error;
556 cpu_def->iu_version = iu_version;
557 #ifdef DEBUG_FEATURES
558 fprintf(stderr, "iu_version %" PRIx64 "\n", iu_version);
559 #endif
560 } else if (!strcmp(featurestr, "fpu_version")) {
561 char *err;
563 fpu_version = strtol(val, &err, 0);
564 if (!*val || *err) {
565 fprintf(stderr, "bad numerical value %s\n", val);
566 goto error;
568 cpu_def->fpu_version = fpu_version;
569 #ifdef DEBUG_FEATURES
570 fprintf(stderr, "fpu_version %x\n", fpu_version);
571 #endif
572 } else if (!strcmp(featurestr, "mmu_version")) {
573 char *err;
575 mmu_version = strtol(val, &err, 0);
576 if (!*val || *err) {
577 fprintf(stderr, "bad numerical value %s\n", val);
578 goto error;
580 cpu_def->mmu_version = mmu_version;
581 #ifdef DEBUG_FEATURES
582 fprintf(stderr, "mmu_version %x\n", mmu_version);
583 #endif
584 } else if (!strcmp(featurestr, "nwindows")) {
585 char *err;
587 nwindows = strtol(val, &err, 0);
588 if (!*val || *err || nwindows > MAX_NWINDOWS ||
589 nwindows < MIN_NWINDOWS) {
590 fprintf(stderr, "bad numerical value %s\n", val);
591 goto error;
593 cpu_def->nwindows = nwindows;
594 #ifdef DEBUG_FEATURES
595 fprintf(stderr, "nwindows %d\n", nwindows);
596 #endif
597 } else {
598 fprintf(stderr, "unrecognized feature %s\n", featurestr);
599 goto error;
601 } else {
602 fprintf(stderr, "feature string `%s' not in format "
603 "(+feature|-feature|feature=xyz)\n", featurestr);
604 goto error;
606 featurestr = strtok(NULL, ",");
608 cpu_def->features |= plus_features;
609 cpu_def->features &= ~minus_features;
610 #ifdef DEBUG_FEATURES
611 print_features(stderr, fprintf, cpu_def->features, NULL);
612 #endif
613 g_free(s);
614 return 0;
616 error:
617 g_free(s);
618 return -1;
621 void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf)
623 unsigned int i;
625 for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
626 (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx
627 " FPU %08x MMU %08x NWINS %d ",
628 sparc_defs[i].name,
629 sparc_defs[i].iu_version,
630 sparc_defs[i].fpu_version,
631 sparc_defs[i].mmu_version,
632 sparc_defs[i].nwindows);
633 print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES &
634 ~sparc_defs[i].features, "-");
635 print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES &
636 sparc_defs[i].features, "+");
637 (*cpu_fprintf)(f, "\n");
639 (*cpu_fprintf)(f, "Default CPU feature flags (use '-' to remove): ");
640 print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES, NULL);
641 (*cpu_fprintf)(f, "\n");
642 (*cpu_fprintf)(f, "Available CPU feature flags (use '+' to add): ");
643 print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES, NULL);
644 (*cpu_fprintf)(f, "\n");
645 (*cpu_fprintf)(f, "Numerical features (use '=' to set): iu_version "
646 "fpu_version mmu_version nwindows\n");
649 static void cpu_print_cc(FILE *f, fprintf_function cpu_fprintf,
650 uint32_t cc)
652 cpu_fprintf(f, "%c%c%c%c", cc & PSR_NEG ? 'N' : '-',
653 cc & PSR_ZERO ? 'Z' : '-', cc & PSR_OVF ? 'V' : '-',
654 cc & PSR_CARRY ? 'C' : '-');
657 #ifdef TARGET_SPARC64
658 #define REGS_PER_LINE 4
659 #else
660 #define REGS_PER_LINE 8
661 #endif
663 void cpu_dump_state(CPUSPARCState *env, FILE *f, fprintf_function cpu_fprintf,
664 int flags)
666 int i, x;
668 cpu_fprintf(f, "pc: " TARGET_FMT_lx " npc: " TARGET_FMT_lx "\n", env->pc,
669 env->npc);
671 for (i = 0; i < 8; i++) {
672 if (i % REGS_PER_LINE == 0) {
673 cpu_fprintf(f, "%%g%d-%d:", i, i + REGS_PER_LINE - 1);
675 cpu_fprintf(f, " " TARGET_FMT_lx, env->gregs[i]);
676 if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
677 cpu_fprintf(f, "\n");
680 for (x = 0; x < 3; x++) {
681 for (i = 0; i < 8; i++) {
682 if (i % REGS_PER_LINE == 0) {
683 cpu_fprintf(f, "%%%c%d-%d: ",
684 x == 0 ? 'o' : (x == 1 ? 'l' : 'i'),
685 i, i + REGS_PER_LINE - 1);
687 cpu_fprintf(f, TARGET_FMT_lx " ", env->regwptr[i + x * 8]);
688 if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
689 cpu_fprintf(f, "\n");
694 for (i = 0; i < TARGET_DPREGS; i++) {
695 if ((i & 3) == 0) {
696 cpu_fprintf(f, "%%f%02d: ", i * 2);
698 cpu_fprintf(f, " %016" PRIx64, env->fpr[i].ll);
699 if ((i & 3) == 3) {
700 cpu_fprintf(f, "\n");
703 #ifdef TARGET_SPARC64
704 cpu_fprintf(f, "pstate: %08x ccr: %02x (icc: ", env->pstate,
705 (unsigned)cpu_get_ccr(env));
706 cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << PSR_CARRY_SHIFT);
707 cpu_fprintf(f, " xcc: ");
708 cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << (PSR_CARRY_SHIFT - 4));
709 cpu_fprintf(f, ") asi: %02x tl: %d pil: %x\n", env->asi, env->tl,
710 env->psrpil);
711 cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate: %d "
712 "cleanwin: %d cwp: %d\n",
713 env->cansave, env->canrestore, env->otherwin, env->wstate,
714 env->cleanwin, env->nwindows - 1 - env->cwp);
715 cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: "
716 TARGET_FMT_lx "\n", env->fsr, env->y, env->fprs);
717 #else
718 cpu_fprintf(f, "psr: %08x (icc: ", cpu_get_psr(env));
719 cpu_print_cc(f, cpu_fprintf, cpu_get_psr(env));
720 cpu_fprintf(f, " SPE: %c%c%c) wim: %08x\n", env->psrs ? 'S' : '-',
721 env->psrps ? 'P' : '-', env->psret ? 'E' : '-',
722 env->wim);
723 cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx "\n",
724 env->fsr, env->y);
725 #endif
726 cpu_fprintf(f, "\n");
729 static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
731 SPARCCPU *cpu = SPARC_CPU(dev);
732 SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(dev);
734 qemu_init_vcpu(&cpu->env);
736 scc->parent_realize(dev, errp);
739 static void sparc_cpu_initfn(Object *obj)
741 CPUState *cs = CPU(obj);
742 SPARCCPU *cpu = SPARC_CPU(obj);
743 CPUSPARCState *env = &cpu->env;
745 cs->env_ptr = env;
746 cpu_exec_init(env);
748 if (tcg_enabled()) {
749 gen_intermediate_code_init(env);
753 static void sparc_cpu_uninitfn(Object *obj)
755 SPARCCPU *cpu = SPARC_CPU(obj);
756 CPUSPARCState *env = &cpu->env;
758 g_free(env->def);
761 static void sparc_cpu_class_init(ObjectClass *oc, void *data)
763 SPARCCPUClass *scc = SPARC_CPU_CLASS(oc);
764 CPUClass *cc = CPU_CLASS(oc);
765 DeviceClass *dc = DEVICE_CLASS(oc);
767 scc->parent_realize = dc->realize;
768 dc->realize = sparc_cpu_realizefn;
770 scc->parent_reset = cc->reset;
771 cc->reset = sparc_cpu_reset;
773 cc->do_interrupt = sparc_cpu_do_interrupt;
776 static const TypeInfo sparc_cpu_type_info = {
777 .name = TYPE_SPARC_CPU,
778 .parent = TYPE_CPU,
779 .instance_size = sizeof(SPARCCPU),
780 .instance_init = sparc_cpu_initfn,
781 .instance_finalize = sparc_cpu_uninitfn,
782 .abstract = false,
783 .class_size = sizeof(SPARCCPUClass),
784 .class_init = sparc_cpu_class_init,
787 static void sparc_cpu_register_types(void)
789 type_register_static(&sparc_cpu_type_info);
792 type_init(sparc_cpu_register_types)