linux-headers: update to 3.12-rc1
[qemu/ar7.git] / target-sparc / cpu.c
blob47ce60de4aacc221021c43570d61797840581518
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 scc->parent_reset(s);
35 memset(env, 0, offsetof(CPUSPARCState, breakpoints));
36 tlb_flush(env, 1);
37 env->cwp = 0;
38 #ifndef TARGET_SPARC64
39 env->wim = 1;
40 #endif
41 env->regwptr = env->regbase + (env->cwp * 16);
42 CC_OP = CC_OP_FLAGS;
43 #if defined(CONFIG_USER_ONLY)
44 #ifdef TARGET_SPARC64
45 env->cleanwin = env->nwindows - 2;
46 env->cansave = env->nwindows - 2;
47 env->pstate = PS_RMO | PS_PEF | PS_IE;
48 env->asi = 0x82; /* Primary no-fault */
49 #endif
50 #else
51 #if !defined(TARGET_SPARC64)
52 env->psret = 0;
53 env->psrs = 1;
54 env->psrps = 1;
55 #endif
56 #ifdef TARGET_SPARC64
57 env->pstate = PS_PRIV|PS_RED|PS_PEF|PS_AG;
58 env->hpstate = cpu_has_hypervisor(env) ? HS_PRIV : 0;
59 env->tl = env->maxtl;
60 cpu_tsptr(env)->tt = TT_POWER_ON_RESET;
61 env->lsu = 0;
62 #else
63 env->mmuregs[0] &= ~(MMU_E | MMU_NF);
64 env->mmuregs[0] |= env->def->mmu_bm;
65 #endif
66 env->pc = 0;
67 env->npc = env->pc + 4;
68 #endif
69 env->cache_control = 0;
72 static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
74 sparc_def_t def1, *def = &def1;
76 if (cpu_sparc_find_by_name(def, cpu_model) < 0) {
77 return -1;
80 env->def = g_new0(sparc_def_t, 1);
81 memcpy(env->def, def, sizeof(*def));
82 #if defined(CONFIG_USER_ONLY)
83 if ((env->def->features & CPU_FEATURE_FLOAT)) {
84 env->def->features |= CPU_FEATURE_FLOAT128;
86 #endif
87 env->cpu_model_str = cpu_model;
88 env->version = def->iu_version;
89 env->fsr = def->fpu_version;
90 env->nwindows = def->nwindows;
91 #if !defined(TARGET_SPARC64)
92 env->mmuregs[0] |= def->mmu_version;
93 cpu_sparc_set_id(env, 0);
94 env->mxccregs[7] |= def->mxcc_version;
95 #else
96 env->mmu_version = def->mmu_version;
97 env->maxtl = def->maxtl;
98 env->version |= def->maxtl << 8;
99 env->version |= def->nwindows - 1;
100 #endif
101 return 0;
104 SPARCCPU *cpu_sparc_init(const char *cpu_model)
106 SPARCCPU *cpu;
107 CPUSPARCState *env;
109 cpu = SPARC_CPU(object_new(TYPE_SPARC_CPU));
110 env = &cpu->env;
112 if (cpu_sparc_register(env, cpu_model) < 0) {
113 object_unref(OBJECT(cpu));
114 return NULL;
117 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
119 return cpu;
122 void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
124 #if !defined(TARGET_SPARC64)
125 env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
126 #endif
129 static const sparc_def_t sparc_defs[] = {
130 #ifdef TARGET_SPARC64
132 .name = "Fujitsu Sparc64",
133 .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)),
134 .fpu_version = 0x00000000,
135 .mmu_version = mmu_us_12,
136 .nwindows = 4,
137 .maxtl = 4,
138 .features = CPU_DEFAULT_FEATURES,
141 .name = "Fujitsu Sparc64 III",
142 .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)),
143 .fpu_version = 0x00000000,
144 .mmu_version = mmu_us_12,
145 .nwindows = 5,
146 .maxtl = 4,
147 .features = CPU_DEFAULT_FEATURES,
150 .name = "Fujitsu Sparc64 IV",
151 .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)),
152 .fpu_version = 0x00000000,
153 .mmu_version = mmu_us_12,
154 .nwindows = 8,
155 .maxtl = 5,
156 .features = CPU_DEFAULT_FEATURES,
159 .name = "Fujitsu Sparc64 V",
160 .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)),
161 .fpu_version = 0x00000000,
162 .mmu_version = mmu_us_12,
163 .nwindows = 8,
164 .maxtl = 5,
165 .features = CPU_DEFAULT_FEATURES,
168 .name = "TI UltraSparc I",
169 .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
170 .fpu_version = 0x00000000,
171 .mmu_version = mmu_us_12,
172 .nwindows = 8,
173 .maxtl = 5,
174 .features = CPU_DEFAULT_FEATURES,
177 .name = "TI UltraSparc II",
178 .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)),
179 .fpu_version = 0x00000000,
180 .mmu_version = mmu_us_12,
181 .nwindows = 8,
182 .maxtl = 5,
183 .features = CPU_DEFAULT_FEATURES,
186 .name = "TI UltraSparc IIi",
187 .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)),
188 .fpu_version = 0x00000000,
189 .mmu_version = mmu_us_12,
190 .nwindows = 8,
191 .maxtl = 5,
192 .features = CPU_DEFAULT_FEATURES,
195 .name = "TI UltraSparc IIe",
196 .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)),
197 .fpu_version = 0x00000000,
198 .mmu_version = mmu_us_12,
199 .nwindows = 8,
200 .maxtl = 5,
201 .features = CPU_DEFAULT_FEATURES,
204 .name = "Sun UltraSparc III",
205 .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)),
206 .fpu_version = 0x00000000,
207 .mmu_version = mmu_us_12,
208 .nwindows = 8,
209 .maxtl = 5,
210 .features = CPU_DEFAULT_FEATURES,
213 .name = "Sun UltraSparc III Cu",
214 .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)),
215 .fpu_version = 0x00000000,
216 .mmu_version = mmu_us_3,
217 .nwindows = 8,
218 .maxtl = 5,
219 .features = CPU_DEFAULT_FEATURES,
222 .name = "Sun UltraSparc IIIi",
223 .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)),
224 .fpu_version = 0x00000000,
225 .mmu_version = mmu_us_12,
226 .nwindows = 8,
227 .maxtl = 5,
228 .features = CPU_DEFAULT_FEATURES,
231 .name = "Sun UltraSparc IV",
232 .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)),
233 .fpu_version = 0x00000000,
234 .mmu_version = mmu_us_4,
235 .nwindows = 8,
236 .maxtl = 5,
237 .features = CPU_DEFAULT_FEATURES,
240 .name = "Sun UltraSparc IV+",
241 .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)),
242 .fpu_version = 0x00000000,
243 .mmu_version = mmu_us_12,
244 .nwindows = 8,
245 .maxtl = 5,
246 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT,
249 .name = "Sun UltraSparc IIIi+",
250 .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)),
251 .fpu_version = 0x00000000,
252 .mmu_version = mmu_us_3,
253 .nwindows = 8,
254 .maxtl = 5,
255 .features = CPU_DEFAULT_FEATURES,
258 .name = "Sun UltraSparc T1",
259 /* defined in sparc_ifu_fdp.v and ctu.h */
260 .iu_version = ((0x3eULL << 48) | (0x23ULL << 32) | (0x02ULL << 24)),
261 .fpu_version = 0x00000000,
262 .mmu_version = mmu_sun4v,
263 .nwindows = 8,
264 .maxtl = 6,
265 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
266 | CPU_FEATURE_GL,
269 .name = "Sun UltraSparc T2",
270 /* defined in tlu_asi_ctl.v and n2_revid_cust.v */
271 .iu_version = ((0x3eULL << 48) | (0x24ULL << 32) | (0x02ULL << 24)),
272 .fpu_version = 0x00000000,
273 .mmu_version = mmu_sun4v,
274 .nwindows = 8,
275 .maxtl = 6,
276 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
277 | CPU_FEATURE_GL,
280 .name = "NEC UltraSparc I",
281 .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
282 .fpu_version = 0x00000000,
283 .mmu_version = mmu_us_12,
284 .nwindows = 8,
285 .maxtl = 5,
286 .features = CPU_DEFAULT_FEATURES,
288 #else
290 .name = "Fujitsu MB86904",
291 .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
292 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
293 .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
294 .mmu_bm = 0x00004000,
295 .mmu_ctpr_mask = 0x00ffffc0,
296 .mmu_cxr_mask = 0x000000ff,
297 .mmu_sfsr_mask = 0x00016fff,
298 .mmu_trcr_mask = 0x00ffffff,
299 .nwindows = 8,
300 .features = CPU_DEFAULT_FEATURES,
303 .name = "Fujitsu MB86907",
304 .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
305 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
306 .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
307 .mmu_bm = 0x00004000,
308 .mmu_ctpr_mask = 0xffffffc0,
309 .mmu_cxr_mask = 0x000000ff,
310 .mmu_sfsr_mask = 0x00016fff,
311 .mmu_trcr_mask = 0xffffffff,
312 .nwindows = 8,
313 .features = CPU_DEFAULT_FEATURES,
316 .name = "TI MicroSparc I",
317 .iu_version = 0x41000000,
318 .fpu_version = 4 << 17,
319 .mmu_version = 0x41000000,
320 .mmu_bm = 0x00004000,
321 .mmu_ctpr_mask = 0x007ffff0,
322 .mmu_cxr_mask = 0x0000003f,
323 .mmu_sfsr_mask = 0x00016fff,
324 .mmu_trcr_mask = 0x0000003f,
325 .nwindows = 7,
326 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL |
327 CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT |
328 CPU_FEATURE_FMUL,
331 .name = "TI MicroSparc II",
332 .iu_version = 0x42000000,
333 .fpu_version = 4 << 17,
334 .mmu_version = 0x02000000,
335 .mmu_bm = 0x00004000,
336 .mmu_ctpr_mask = 0x00ffffc0,
337 .mmu_cxr_mask = 0x000000ff,
338 .mmu_sfsr_mask = 0x00016fff,
339 .mmu_trcr_mask = 0x00ffffff,
340 .nwindows = 8,
341 .features = CPU_DEFAULT_FEATURES,
344 .name = "TI MicroSparc IIep",
345 .iu_version = 0x42000000,
346 .fpu_version = 4 << 17,
347 .mmu_version = 0x04000000,
348 .mmu_bm = 0x00004000,
349 .mmu_ctpr_mask = 0x00ffffc0,
350 .mmu_cxr_mask = 0x000000ff,
351 .mmu_sfsr_mask = 0x00016bff,
352 .mmu_trcr_mask = 0x00ffffff,
353 .nwindows = 8,
354 .features = CPU_DEFAULT_FEATURES,
357 .name = "TI SuperSparc 40", /* STP1020NPGA */
358 .iu_version = 0x41000000, /* SuperSPARC 2.x */
359 .fpu_version = 0 << 17,
360 .mmu_version = 0x00000800, /* SuperSPARC 2.x, no MXCC */
361 .mmu_bm = 0x00002000,
362 .mmu_ctpr_mask = 0xffffffc0,
363 .mmu_cxr_mask = 0x0000ffff,
364 .mmu_sfsr_mask = 0xffffffff,
365 .mmu_trcr_mask = 0xffffffff,
366 .nwindows = 8,
367 .features = CPU_DEFAULT_FEATURES,
370 .name = "TI SuperSparc 50", /* STP1020PGA */
371 .iu_version = 0x40000000, /* SuperSPARC 3.x */
372 .fpu_version = 0 << 17,
373 .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
374 .mmu_bm = 0x00002000,
375 .mmu_ctpr_mask = 0xffffffc0,
376 .mmu_cxr_mask = 0x0000ffff,
377 .mmu_sfsr_mask = 0xffffffff,
378 .mmu_trcr_mask = 0xffffffff,
379 .nwindows = 8,
380 .features = CPU_DEFAULT_FEATURES,
383 .name = "TI SuperSparc 51",
384 .iu_version = 0x40000000, /* SuperSPARC 3.x */
385 .fpu_version = 0 << 17,
386 .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
387 .mmu_bm = 0x00002000,
388 .mmu_ctpr_mask = 0xffffffc0,
389 .mmu_cxr_mask = 0x0000ffff,
390 .mmu_sfsr_mask = 0xffffffff,
391 .mmu_trcr_mask = 0xffffffff,
392 .mxcc_version = 0x00000104,
393 .nwindows = 8,
394 .features = CPU_DEFAULT_FEATURES,
397 .name = "TI SuperSparc 60", /* STP1020APGA */
398 .iu_version = 0x40000000, /* SuperSPARC 3.x */
399 .fpu_version = 0 << 17,
400 .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
401 .mmu_bm = 0x00002000,
402 .mmu_ctpr_mask = 0xffffffc0,
403 .mmu_cxr_mask = 0x0000ffff,
404 .mmu_sfsr_mask = 0xffffffff,
405 .mmu_trcr_mask = 0xffffffff,
406 .nwindows = 8,
407 .features = CPU_DEFAULT_FEATURES,
410 .name = "TI SuperSparc 61",
411 .iu_version = 0x44000000, /* SuperSPARC 3.x */
412 .fpu_version = 0 << 17,
413 .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
414 .mmu_bm = 0x00002000,
415 .mmu_ctpr_mask = 0xffffffc0,
416 .mmu_cxr_mask = 0x0000ffff,
417 .mmu_sfsr_mask = 0xffffffff,
418 .mmu_trcr_mask = 0xffffffff,
419 .mxcc_version = 0x00000104,
420 .nwindows = 8,
421 .features = CPU_DEFAULT_FEATURES,
424 .name = "TI SuperSparc II",
425 .iu_version = 0x40000000, /* SuperSPARC II 1.x */
426 .fpu_version = 0 << 17,
427 .mmu_version = 0x08000000, /* SuperSPARC II 1.x, MXCC */
428 .mmu_bm = 0x00002000,
429 .mmu_ctpr_mask = 0xffffffc0,
430 .mmu_cxr_mask = 0x0000ffff,
431 .mmu_sfsr_mask = 0xffffffff,
432 .mmu_trcr_mask = 0xffffffff,
433 .mxcc_version = 0x00000104,
434 .nwindows = 8,
435 .features = CPU_DEFAULT_FEATURES,
438 .name = "LEON2",
439 .iu_version = 0xf2000000,
440 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
441 .mmu_version = 0xf2000000,
442 .mmu_bm = 0x00004000,
443 .mmu_ctpr_mask = 0x007ffff0,
444 .mmu_cxr_mask = 0x0000003f,
445 .mmu_sfsr_mask = 0xffffffff,
446 .mmu_trcr_mask = 0xffffffff,
447 .nwindows = 8,
448 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN,
451 .name = "LEON3",
452 .iu_version = 0xf3000000,
453 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
454 .mmu_version = 0xf3000000,
455 .mmu_bm = 0x00000000,
456 .mmu_ctpr_mask = 0xfffffffc,
457 .mmu_cxr_mask = 0x000000ff,
458 .mmu_sfsr_mask = 0xffffffff,
459 .mmu_trcr_mask = 0xffffffff,
460 .nwindows = 8,
461 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN |
462 CPU_FEATURE_ASR17 | CPU_FEATURE_CACHE_CTRL | CPU_FEATURE_POWERDOWN,
464 #endif
467 static const char * const feature_name[] = {
468 "float",
469 "float128",
470 "swap",
471 "mul",
472 "div",
473 "flush",
474 "fsqrt",
475 "fmul",
476 "vis1",
477 "vis2",
478 "fsmuld",
479 "hypv",
480 "cmt",
481 "gl",
484 static void print_features(FILE *f, fprintf_function cpu_fprintf,
485 uint32_t features, const char *prefix)
487 unsigned int i;
489 for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
490 if (feature_name[i] && (features & (1 << i))) {
491 if (prefix) {
492 (*cpu_fprintf)(f, "%s", prefix);
494 (*cpu_fprintf)(f, "%s ", feature_name[i]);
499 static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features)
501 unsigned int i;
503 for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
504 if (feature_name[i] && !strcmp(flagname, feature_name[i])) {
505 *features |= 1 << i;
506 return;
509 fprintf(stderr, "CPU feature %s not found\n", flagname);
512 static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
514 unsigned int i;
515 const sparc_def_t *def = NULL;
516 char *s = g_strdup(cpu_model);
517 char *featurestr, *name = strtok(s, ",");
518 uint32_t plus_features = 0;
519 uint32_t minus_features = 0;
520 uint64_t iu_version;
521 uint32_t fpu_version, mmu_version, nwindows;
523 for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
524 if (strcasecmp(name, sparc_defs[i].name) == 0) {
525 def = &sparc_defs[i];
528 if (!def) {
529 goto error;
531 memcpy(cpu_def, def, sizeof(*def));
533 featurestr = strtok(NULL, ",");
534 while (featurestr) {
535 char *val;
537 if (featurestr[0] == '+') {
538 add_flagname_to_bitmaps(featurestr + 1, &plus_features);
539 } else if (featurestr[0] == '-') {
540 add_flagname_to_bitmaps(featurestr + 1, &minus_features);
541 } else if ((val = strchr(featurestr, '='))) {
542 *val = 0; val++;
543 if (!strcmp(featurestr, "iu_version")) {
544 char *err;
546 iu_version = strtoll(val, &err, 0);
547 if (!*val || *err) {
548 fprintf(stderr, "bad numerical value %s\n", val);
549 goto error;
551 cpu_def->iu_version = iu_version;
552 #ifdef DEBUG_FEATURES
553 fprintf(stderr, "iu_version %" PRIx64 "\n", iu_version);
554 #endif
555 } else if (!strcmp(featurestr, "fpu_version")) {
556 char *err;
558 fpu_version = strtol(val, &err, 0);
559 if (!*val || *err) {
560 fprintf(stderr, "bad numerical value %s\n", val);
561 goto error;
563 cpu_def->fpu_version = fpu_version;
564 #ifdef DEBUG_FEATURES
565 fprintf(stderr, "fpu_version %x\n", fpu_version);
566 #endif
567 } else if (!strcmp(featurestr, "mmu_version")) {
568 char *err;
570 mmu_version = strtol(val, &err, 0);
571 if (!*val || *err) {
572 fprintf(stderr, "bad numerical value %s\n", val);
573 goto error;
575 cpu_def->mmu_version = mmu_version;
576 #ifdef DEBUG_FEATURES
577 fprintf(stderr, "mmu_version %x\n", mmu_version);
578 #endif
579 } else if (!strcmp(featurestr, "nwindows")) {
580 char *err;
582 nwindows = strtol(val, &err, 0);
583 if (!*val || *err || nwindows > MAX_NWINDOWS ||
584 nwindows < MIN_NWINDOWS) {
585 fprintf(stderr, "bad numerical value %s\n", val);
586 goto error;
588 cpu_def->nwindows = nwindows;
589 #ifdef DEBUG_FEATURES
590 fprintf(stderr, "nwindows %d\n", nwindows);
591 #endif
592 } else {
593 fprintf(stderr, "unrecognized feature %s\n", featurestr);
594 goto error;
596 } else {
597 fprintf(stderr, "feature string `%s' not in format "
598 "(+feature|-feature|feature=xyz)\n", featurestr);
599 goto error;
601 featurestr = strtok(NULL, ",");
603 cpu_def->features |= plus_features;
604 cpu_def->features &= ~minus_features;
605 #ifdef DEBUG_FEATURES
606 print_features(stderr, fprintf, cpu_def->features, NULL);
607 #endif
608 g_free(s);
609 return 0;
611 error:
612 g_free(s);
613 return -1;
616 void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf)
618 unsigned int i;
620 for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
621 (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx
622 " FPU %08x MMU %08x NWINS %d ",
623 sparc_defs[i].name,
624 sparc_defs[i].iu_version,
625 sparc_defs[i].fpu_version,
626 sparc_defs[i].mmu_version,
627 sparc_defs[i].nwindows);
628 print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES &
629 ~sparc_defs[i].features, "-");
630 print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES &
631 sparc_defs[i].features, "+");
632 (*cpu_fprintf)(f, "\n");
634 (*cpu_fprintf)(f, "Default CPU feature flags (use '-' to remove): ");
635 print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES, NULL);
636 (*cpu_fprintf)(f, "\n");
637 (*cpu_fprintf)(f, "Available CPU feature flags (use '+' to add): ");
638 print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES, NULL);
639 (*cpu_fprintf)(f, "\n");
640 (*cpu_fprintf)(f, "Numerical features (use '=' to set): iu_version "
641 "fpu_version mmu_version nwindows\n");
644 static void cpu_print_cc(FILE *f, fprintf_function cpu_fprintf,
645 uint32_t cc)
647 cpu_fprintf(f, "%c%c%c%c", cc & PSR_NEG ? 'N' : '-',
648 cc & PSR_ZERO ? 'Z' : '-', cc & PSR_OVF ? 'V' : '-',
649 cc & PSR_CARRY ? 'C' : '-');
652 #ifdef TARGET_SPARC64
653 #define REGS_PER_LINE 4
654 #else
655 #define REGS_PER_LINE 8
656 #endif
658 void sparc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
659 int flags)
661 SPARCCPU *cpu = SPARC_CPU(cs);
662 CPUSPARCState *env = &cpu->env;
663 int i, x;
665 cpu_fprintf(f, "pc: " TARGET_FMT_lx " npc: " TARGET_FMT_lx "\n", env->pc,
666 env->npc);
668 for (i = 0; i < 8; i++) {
669 if (i % REGS_PER_LINE == 0) {
670 cpu_fprintf(f, "%%g%d-%d:", i, i + REGS_PER_LINE - 1);
672 cpu_fprintf(f, " " TARGET_FMT_lx, env->gregs[i]);
673 if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
674 cpu_fprintf(f, "\n");
677 for (x = 0; x < 3; x++) {
678 for (i = 0; i < 8; i++) {
679 if (i % REGS_PER_LINE == 0) {
680 cpu_fprintf(f, "%%%c%d-%d: ",
681 x == 0 ? 'o' : (x == 1 ? 'l' : 'i'),
682 i, i + REGS_PER_LINE - 1);
684 cpu_fprintf(f, TARGET_FMT_lx " ", env->regwptr[i + x * 8]);
685 if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
686 cpu_fprintf(f, "\n");
691 for (i = 0; i < TARGET_DPREGS; i++) {
692 if ((i & 3) == 0) {
693 cpu_fprintf(f, "%%f%02d: ", i * 2);
695 cpu_fprintf(f, " %016" PRIx64, env->fpr[i].ll);
696 if ((i & 3) == 3) {
697 cpu_fprintf(f, "\n");
700 #ifdef TARGET_SPARC64
701 cpu_fprintf(f, "pstate: %08x ccr: %02x (icc: ", env->pstate,
702 (unsigned)cpu_get_ccr(env));
703 cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << PSR_CARRY_SHIFT);
704 cpu_fprintf(f, " xcc: ");
705 cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << (PSR_CARRY_SHIFT - 4));
706 cpu_fprintf(f, ") asi: %02x tl: %d pil: %x\n", env->asi, env->tl,
707 env->psrpil);
708 cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate: %d "
709 "cleanwin: %d cwp: %d\n",
710 env->cansave, env->canrestore, env->otherwin, env->wstate,
711 env->cleanwin, env->nwindows - 1 - env->cwp);
712 cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: "
713 TARGET_FMT_lx "\n", env->fsr, env->y, env->fprs);
714 #else
715 cpu_fprintf(f, "psr: %08x (icc: ", cpu_get_psr(env));
716 cpu_print_cc(f, cpu_fprintf, cpu_get_psr(env));
717 cpu_fprintf(f, " SPE: %c%c%c) wim: %08x\n", env->psrs ? 'S' : '-',
718 env->psrps ? 'P' : '-', env->psret ? 'E' : '-',
719 env->wim);
720 cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx "\n",
721 env->fsr, env->y);
722 #endif
723 cpu_fprintf(f, "\n");
726 static void sparc_cpu_set_pc(CPUState *cs, vaddr value)
728 SPARCCPU *cpu = SPARC_CPU(cs);
730 cpu->env.pc = value;
731 cpu->env.npc = value + 4;
734 static void sparc_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
736 SPARCCPU *cpu = SPARC_CPU(cs);
738 cpu->env.pc = tb->pc;
739 cpu->env.npc = tb->cs_base;
742 static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
744 SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(dev);
746 qemu_init_vcpu(CPU(dev));
748 scc->parent_realize(dev, errp);
751 static void sparc_cpu_initfn(Object *obj)
753 CPUState *cs = CPU(obj);
754 SPARCCPU *cpu = SPARC_CPU(obj);
755 CPUSPARCState *env = &cpu->env;
757 cs->env_ptr = env;
758 cpu_exec_init(env);
760 if (tcg_enabled()) {
761 gen_intermediate_code_init(env);
765 static void sparc_cpu_uninitfn(Object *obj)
767 SPARCCPU *cpu = SPARC_CPU(obj);
768 CPUSPARCState *env = &cpu->env;
770 g_free(env->def);
773 static void sparc_cpu_class_init(ObjectClass *oc, void *data)
775 SPARCCPUClass *scc = SPARC_CPU_CLASS(oc);
776 CPUClass *cc = CPU_CLASS(oc);
777 DeviceClass *dc = DEVICE_CLASS(oc);
779 scc->parent_realize = dc->realize;
780 dc->realize = sparc_cpu_realizefn;
782 scc->parent_reset = cc->reset;
783 cc->reset = sparc_cpu_reset;
785 cc->do_interrupt = sparc_cpu_do_interrupt;
786 cc->dump_state = sparc_cpu_dump_state;
787 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
788 cc->memory_rw_debug = sparc_cpu_memory_rw_debug;
789 #endif
790 cc->set_pc = sparc_cpu_set_pc;
791 cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb;
792 cc->gdb_read_register = sparc_cpu_gdb_read_register;
793 cc->gdb_write_register = sparc_cpu_gdb_write_register;
794 #ifndef CONFIG_USER_ONLY
795 cc->do_unassigned_access = sparc_cpu_unassigned_access;
796 cc->get_phys_page_debug = sparc_cpu_get_phys_page_debug;
797 #endif
799 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
800 cc->gdb_num_core_regs = 86;
801 #else
802 cc->gdb_num_core_regs = 72;
803 #endif
806 static const TypeInfo sparc_cpu_type_info = {
807 .name = TYPE_SPARC_CPU,
808 .parent = TYPE_CPU,
809 .instance_size = sizeof(SPARCCPU),
810 .instance_init = sparc_cpu_initfn,
811 .instance_finalize = sparc_cpu_uninitfn,
812 .abstract = false,
813 .class_size = sizeof(SPARCCPUClass),
814 .class_init = sparc_cpu_class_init,
817 static void sparc_cpu_register_types(void)
819 type_register_static(&sparc_cpu_type_info);
822 type_init(sparc_cpu_register_types)