ioport: Switch dispatching to memory core layer
[qemu.git] / target-sparc / cpu.c
blob65ae6f73bf771f7b895a5e4ba4901b8a066da67c
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 sparc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
664 int flags)
666 SPARCCPU *cpu = SPARC_CPU(cs);
667 CPUSPARCState *env = &cpu->env;
668 int i, x;
670 cpu_fprintf(f, "pc: " TARGET_FMT_lx " npc: " TARGET_FMT_lx "\n", env->pc,
671 env->npc);
673 for (i = 0; i < 8; i++) {
674 if (i % REGS_PER_LINE == 0) {
675 cpu_fprintf(f, "%%g%d-%d:", i, i + REGS_PER_LINE - 1);
677 cpu_fprintf(f, " " TARGET_FMT_lx, env->gregs[i]);
678 if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
679 cpu_fprintf(f, "\n");
682 for (x = 0; x < 3; x++) {
683 for (i = 0; i < 8; i++) {
684 if (i % REGS_PER_LINE == 0) {
685 cpu_fprintf(f, "%%%c%d-%d: ",
686 x == 0 ? 'o' : (x == 1 ? 'l' : 'i'),
687 i, i + REGS_PER_LINE - 1);
689 cpu_fprintf(f, TARGET_FMT_lx " ", env->regwptr[i + x * 8]);
690 if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
691 cpu_fprintf(f, "\n");
696 for (i = 0; i < TARGET_DPREGS; i++) {
697 if ((i & 3) == 0) {
698 cpu_fprintf(f, "%%f%02d: ", i * 2);
700 cpu_fprintf(f, " %016" PRIx64, env->fpr[i].ll);
701 if ((i & 3) == 3) {
702 cpu_fprintf(f, "\n");
705 #ifdef TARGET_SPARC64
706 cpu_fprintf(f, "pstate: %08x ccr: %02x (icc: ", env->pstate,
707 (unsigned)cpu_get_ccr(env));
708 cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << PSR_CARRY_SHIFT);
709 cpu_fprintf(f, " xcc: ");
710 cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << (PSR_CARRY_SHIFT - 4));
711 cpu_fprintf(f, ") asi: %02x tl: %d pil: %x\n", env->asi, env->tl,
712 env->psrpil);
713 cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate: %d "
714 "cleanwin: %d cwp: %d\n",
715 env->cansave, env->canrestore, env->otherwin, env->wstate,
716 env->cleanwin, env->nwindows - 1 - env->cwp);
717 cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: "
718 TARGET_FMT_lx "\n", env->fsr, env->y, env->fprs);
719 #else
720 cpu_fprintf(f, "psr: %08x (icc: ", cpu_get_psr(env));
721 cpu_print_cc(f, cpu_fprintf, cpu_get_psr(env));
722 cpu_fprintf(f, " SPE: %c%c%c) wim: %08x\n", env->psrs ? 'S' : '-',
723 env->psrps ? 'P' : '-', env->psret ? 'E' : '-',
724 env->wim);
725 cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx "\n",
726 env->fsr, env->y);
727 #endif
728 cpu_fprintf(f, "\n");
731 static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
733 SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(dev);
735 scc->parent_realize(dev, errp);
738 static void sparc_cpu_initfn(Object *obj)
740 CPUState *cs = CPU(obj);
741 SPARCCPU *cpu = SPARC_CPU(obj);
742 CPUSPARCState *env = &cpu->env;
744 cs->env_ptr = env;
745 cpu_exec_init(env);
747 if (tcg_enabled()) {
748 gen_intermediate_code_init(env);
752 static void sparc_cpu_uninitfn(Object *obj)
754 SPARCCPU *cpu = SPARC_CPU(obj);
755 CPUSPARCState *env = &cpu->env;
757 g_free(env->def);
760 static void sparc_cpu_class_init(ObjectClass *oc, void *data)
762 SPARCCPUClass *scc = SPARC_CPU_CLASS(oc);
763 CPUClass *cc = CPU_CLASS(oc);
764 DeviceClass *dc = DEVICE_CLASS(oc);
766 scc->parent_realize = dc->realize;
767 dc->realize = sparc_cpu_realizefn;
769 scc->parent_reset = cc->reset;
770 cc->reset = sparc_cpu_reset;
772 cc->do_interrupt = sparc_cpu_do_interrupt;
773 cc->dump_state = sparc_cpu_dump_state;
774 cpu_class_set_do_unassigned_access(cc, sparc_cpu_unassigned_access);
777 static const TypeInfo sparc_cpu_type_info = {
778 .name = TYPE_SPARC_CPU,
779 .parent = TYPE_CPU,
780 .instance_size = sizeof(SPARCCPU),
781 .instance_init = sparc_cpu_initfn,
782 .instance_finalize = sparc_cpu_uninitfn,
783 .abstract = false,
784 .class_size = sizeof(SPARCCPUClass),
785 .class_init = sparc_cpu_class_init,
788 static void sparc_cpu_register_types(void)
790 type_register_static(&sparc_cpu_type_info);
793 type_init(sparc_cpu_register_types)