vl.c: fix '-cpu ?' segfault
[qemu/ar7.git] / target-sparc / cpu_init.c
blob5c03f0b893bdd5a86a5e2ef8109ce6cb412ea834
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 void cpu_state_reset(CPUSPARCState *env)
28 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
29 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
30 log_cpu_state(env, 0);
33 memset(env, 0, offsetof(CPUSPARCState, breakpoints));
34 tlb_flush(env, 1);
35 env->cwp = 0;
36 #ifndef TARGET_SPARC64
37 env->wim = 1;
38 #endif
39 env->regwptr = env->regbase + (env->cwp * 16);
40 CC_OP = CC_OP_FLAGS;
41 #if defined(CONFIG_USER_ONLY)
42 #ifdef TARGET_SPARC64
43 env->cleanwin = env->nwindows - 2;
44 env->cansave = env->nwindows - 2;
45 env->pstate = PS_RMO | PS_PEF | PS_IE;
46 env->asi = 0x82; /* Primary no-fault */
47 #endif
48 #else
49 #if !defined(TARGET_SPARC64)
50 env->psret = 0;
51 env->psrs = 1;
52 env->psrps = 1;
53 #endif
54 #ifdef TARGET_SPARC64
55 env->pstate = PS_PRIV|PS_RED|PS_PEF|PS_AG;
56 env->hpstate = cpu_has_hypervisor(env) ? HS_PRIV : 0;
57 env->tl = env->maxtl;
58 cpu_tsptr(env)->tt = TT_POWER_ON_RESET;
59 env->lsu = 0;
60 #else
61 env->mmuregs[0] &= ~(MMU_E | MMU_NF);
62 env->mmuregs[0] |= env->def->mmu_bm;
63 #endif
64 env->pc = 0;
65 env->npc = env->pc + 4;
66 #endif
67 env->cache_control = 0;
70 static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
72 sparc_def_t def1, *def = &def1;
74 if (cpu_sparc_find_by_name(def, cpu_model) < 0) {
75 return -1;
78 env->def = g_new0(sparc_def_t, 1);
79 memcpy(env->def, def, sizeof(*def));
80 #if defined(CONFIG_USER_ONLY)
81 if ((env->def->features & CPU_FEATURE_FLOAT)) {
82 env->def->features |= CPU_FEATURE_FLOAT128;
84 #endif
85 env->cpu_model_str = cpu_model;
86 env->version = def->iu_version;
87 env->fsr = def->fpu_version;
88 env->nwindows = def->nwindows;
89 #if !defined(TARGET_SPARC64)
90 env->mmuregs[0] |= def->mmu_version;
91 cpu_sparc_set_id(env, 0);
92 env->mxccregs[7] |= def->mxcc_version;
93 #else
94 env->mmu_version = def->mmu_version;
95 env->maxtl = def->maxtl;
96 env->version |= def->maxtl << 8;
97 env->version |= def->nwindows - 1;
98 #endif
99 return 0;
102 static void cpu_sparc_close(CPUSPARCState *env)
104 g_free(env->def);
105 g_free(env);
108 CPUSPARCState *cpu_sparc_init(const char *cpu_model)
110 CPUSPARCState *env;
112 env = g_new0(CPUSPARCState, 1);
113 cpu_exec_init(env);
115 gen_intermediate_code_init(env);
117 if (cpu_sparc_register(env, cpu_model) < 0) {
118 cpu_sparc_close(env);
119 return NULL;
121 qemu_init_vcpu(env);
123 return env;
126 void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
128 #if !defined(TARGET_SPARC64)
129 env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
130 #endif
133 static const sparc_def_t sparc_defs[] = {
134 #ifdef TARGET_SPARC64
136 .name = "Fujitsu Sparc64",
137 .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)),
138 .fpu_version = 0x00000000,
139 .mmu_version = mmu_us_12,
140 .nwindows = 4,
141 .maxtl = 4,
142 .features = CPU_DEFAULT_FEATURES,
145 .name = "Fujitsu Sparc64 III",
146 .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)),
147 .fpu_version = 0x00000000,
148 .mmu_version = mmu_us_12,
149 .nwindows = 5,
150 .maxtl = 4,
151 .features = CPU_DEFAULT_FEATURES,
154 .name = "Fujitsu Sparc64 IV",
155 .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)),
156 .fpu_version = 0x00000000,
157 .mmu_version = mmu_us_12,
158 .nwindows = 8,
159 .maxtl = 5,
160 .features = CPU_DEFAULT_FEATURES,
163 .name = "Fujitsu Sparc64 V",
164 .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)),
165 .fpu_version = 0x00000000,
166 .mmu_version = mmu_us_12,
167 .nwindows = 8,
168 .maxtl = 5,
169 .features = CPU_DEFAULT_FEATURES,
172 .name = "TI UltraSparc I",
173 .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
174 .fpu_version = 0x00000000,
175 .mmu_version = mmu_us_12,
176 .nwindows = 8,
177 .maxtl = 5,
178 .features = CPU_DEFAULT_FEATURES,
181 .name = "TI UltraSparc II",
182 .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)),
183 .fpu_version = 0x00000000,
184 .mmu_version = mmu_us_12,
185 .nwindows = 8,
186 .maxtl = 5,
187 .features = CPU_DEFAULT_FEATURES,
190 .name = "TI UltraSparc IIi",
191 .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)),
192 .fpu_version = 0x00000000,
193 .mmu_version = mmu_us_12,
194 .nwindows = 8,
195 .maxtl = 5,
196 .features = CPU_DEFAULT_FEATURES,
199 .name = "TI UltraSparc IIe",
200 .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)),
201 .fpu_version = 0x00000000,
202 .mmu_version = mmu_us_12,
203 .nwindows = 8,
204 .maxtl = 5,
205 .features = CPU_DEFAULT_FEATURES,
208 .name = "Sun UltraSparc III",
209 .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)),
210 .fpu_version = 0x00000000,
211 .mmu_version = mmu_us_12,
212 .nwindows = 8,
213 .maxtl = 5,
214 .features = CPU_DEFAULT_FEATURES,
217 .name = "Sun UltraSparc III Cu",
218 .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)),
219 .fpu_version = 0x00000000,
220 .mmu_version = mmu_us_3,
221 .nwindows = 8,
222 .maxtl = 5,
223 .features = CPU_DEFAULT_FEATURES,
226 .name = "Sun UltraSparc IIIi",
227 .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)),
228 .fpu_version = 0x00000000,
229 .mmu_version = mmu_us_12,
230 .nwindows = 8,
231 .maxtl = 5,
232 .features = CPU_DEFAULT_FEATURES,
235 .name = "Sun UltraSparc IV",
236 .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)),
237 .fpu_version = 0x00000000,
238 .mmu_version = mmu_us_4,
239 .nwindows = 8,
240 .maxtl = 5,
241 .features = CPU_DEFAULT_FEATURES,
244 .name = "Sun UltraSparc IV+",
245 .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)),
246 .fpu_version = 0x00000000,
247 .mmu_version = mmu_us_12,
248 .nwindows = 8,
249 .maxtl = 5,
250 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT,
253 .name = "Sun UltraSparc IIIi+",
254 .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)),
255 .fpu_version = 0x00000000,
256 .mmu_version = mmu_us_3,
257 .nwindows = 8,
258 .maxtl = 5,
259 .features = CPU_DEFAULT_FEATURES,
262 .name = "Sun UltraSparc T1",
263 /* defined in sparc_ifu_fdp.v and ctu.h */
264 .iu_version = ((0x3eULL << 48) | (0x23ULL << 32) | (0x02ULL << 24)),
265 .fpu_version = 0x00000000,
266 .mmu_version = mmu_sun4v,
267 .nwindows = 8,
268 .maxtl = 6,
269 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
270 | CPU_FEATURE_GL,
273 .name = "Sun UltraSparc T2",
274 /* defined in tlu_asi_ctl.v and n2_revid_cust.v */
275 .iu_version = ((0x3eULL << 48) | (0x24ULL << 32) | (0x02ULL << 24)),
276 .fpu_version = 0x00000000,
277 .mmu_version = mmu_sun4v,
278 .nwindows = 8,
279 .maxtl = 6,
280 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
281 | CPU_FEATURE_GL,
284 .name = "NEC UltraSparc I",
285 .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
286 .fpu_version = 0x00000000,
287 .mmu_version = mmu_us_12,
288 .nwindows = 8,
289 .maxtl = 5,
290 .features = CPU_DEFAULT_FEATURES,
292 #else
294 .name = "Fujitsu MB86900",
295 .iu_version = 0x00 << 24, /* Impl 0, ver 0 */
296 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
297 .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */
298 .mmu_bm = 0x00004000,
299 .mmu_ctpr_mask = 0x007ffff0,
300 .mmu_cxr_mask = 0x0000003f,
301 .mmu_sfsr_mask = 0xffffffff,
302 .mmu_trcr_mask = 0xffffffff,
303 .nwindows = 7,
304 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_FSMULD,
307 .name = "Fujitsu MB86904",
308 .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
309 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
310 .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
311 .mmu_bm = 0x00004000,
312 .mmu_ctpr_mask = 0x00ffffc0,
313 .mmu_cxr_mask = 0x000000ff,
314 .mmu_sfsr_mask = 0x00016fff,
315 .mmu_trcr_mask = 0x00ffffff,
316 .nwindows = 8,
317 .features = CPU_DEFAULT_FEATURES,
320 .name = "Fujitsu MB86907",
321 .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
322 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
323 .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
324 .mmu_bm = 0x00004000,
325 .mmu_ctpr_mask = 0xffffffc0,
326 .mmu_cxr_mask = 0x000000ff,
327 .mmu_sfsr_mask = 0x00016fff,
328 .mmu_trcr_mask = 0xffffffff,
329 .nwindows = 8,
330 .features = CPU_DEFAULT_FEATURES,
333 .name = "LSI L64811",
334 .iu_version = 0x10 << 24, /* Impl 1, ver 0 */
335 .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */
336 .mmu_version = 0x10 << 24,
337 .mmu_bm = 0x00004000,
338 .mmu_ctpr_mask = 0x007ffff0,
339 .mmu_cxr_mask = 0x0000003f,
340 .mmu_sfsr_mask = 0xffffffff,
341 .mmu_trcr_mask = 0xffffffff,
342 .nwindows = 8,
343 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
344 CPU_FEATURE_FSMULD,
347 .name = "Cypress CY7C601",
348 .iu_version = 0x11 << 24, /* Impl 1, ver 1 */
349 .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
350 .mmu_version = 0x10 << 24,
351 .mmu_bm = 0x00004000,
352 .mmu_ctpr_mask = 0x007ffff0,
353 .mmu_cxr_mask = 0x0000003f,
354 .mmu_sfsr_mask = 0xffffffff,
355 .mmu_trcr_mask = 0xffffffff,
356 .nwindows = 8,
357 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
358 CPU_FEATURE_FSMULD,
361 .name = "Cypress CY7C611",
362 .iu_version = 0x13 << 24, /* Impl 1, ver 3 */
363 .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
364 .mmu_version = 0x10 << 24,
365 .mmu_bm = 0x00004000,
366 .mmu_ctpr_mask = 0x007ffff0,
367 .mmu_cxr_mask = 0x0000003f,
368 .mmu_sfsr_mask = 0xffffffff,
369 .mmu_trcr_mask = 0xffffffff,
370 .nwindows = 8,
371 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
372 CPU_FEATURE_FSMULD,
375 .name = "TI MicroSparc I",
376 .iu_version = 0x41000000,
377 .fpu_version = 4 << 17,
378 .mmu_version = 0x41000000,
379 .mmu_bm = 0x00004000,
380 .mmu_ctpr_mask = 0x007ffff0,
381 .mmu_cxr_mask = 0x0000003f,
382 .mmu_sfsr_mask = 0x00016fff,
383 .mmu_trcr_mask = 0x0000003f,
384 .nwindows = 7,
385 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL |
386 CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT |
387 CPU_FEATURE_FMUL,
390 .name = "TI MicroSparc II",
391 .iu_version = 0x42000000,
392 .fpu_version = 4 << 17,
393 .mmu_version = 0x02000000,
394 .mmu_bm = 0x00004000,
395 .mmu_ctpr_mask = 0x00ffffc0,
396 .mmu_cxr_mask = 0x000000ff,
397 .mmu_sfsr_mask = 0x00016fff,
398 .mmu_trcr_mask = 0x00ffffff,
399 .nwindows = 8,
400 .features = CPU_DEFAULT_FEATURES,
403 .name = "TI MicroSparc IIep",
404 .iu_version = 0x42000000,
405 .fpu_version = 4 << 17,
406 .mmu_version = 0x04000000,
407 .mmu_bm = 0x00004000,
408 .mmu_ctpr_mask = 0x00ffffc0,
409 .mmu_cxr_mask = 0x000000ff,
410 .mmu_sfsr_mask = 0x00016bff,
411 .mmu_trcr_mask = 0x00ffffff,
412 .nwindows = 8,
413 .features = CPU_DEFAULT_FEATURES,
416 .name = "TI SuperSparc 40", /* STP1020NPGA */
417 .iu_version = 0x41000000, /* SuperSPARC 2.x */
418 .fpu_version = 0 << 17,
419 .mmu_version = 0x00000800, /* SuperSPARC 2.x, no MXCC */
420 .mmu_bm = 0x00002000,
421 .mmu_ctpr_mask = 0xffffffc0,
422 .mmu_cxr_mask = 0x0000ffff,
423 .mmu_sfsr_mask = 0xffffffff,
424 .mmu_trcr_mask = 0xffffffff,
425 .nwindows = 8,
426 .features = CPU_DEFAULT_FEATURES,
429 .name = "TI SuperSparc 50", /* STP1020PGA */
430 .iu_version = 0x40000000, /* SuperSPARC 3.x */
431 .fpu_version = 0 << 17,
432 .mmu_version = 0x01000800, /* SuperSPARC 3.x, no 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 .nwindows = 8,
439 .features = CPU_DEFAULT_FEATURES,
442 .name = "TI SuperSparc 51",
443 .iu_version = 0x40000000, /* SuperSPARC 3.x */
444 .fpu_version = 0 << 17,
445 .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
446 .mmu_bm = 0x00002000,
447 .mmu_ctpr_mask = 0xffffffc0,
448 .mmu_cxr_mask = 0x0000ffff,
449 .mmu_sfsr_mask = 0xffffffff,
450 .mmu_trcr_mask = 0xffffffff,
451 .mxcc_version = 0x00000104,
452 .nwindows = 8,
453 .features = CPU_DEFAULT_FEATURES,
456 .name = "TI SuperSparc 60", /* STP1020APGA */
457 .iu_version = 0x40000000, /* SuperSPARC 3.x */
458 .fpu_version = 0 << 17,
459 .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
460 .mmu_bm = 0x00002000,
461 .mmu_ctpr_mask = 0xffffffc0,
462 .mmu_cxr_mask = 0x0000ffff,
463 .mmu_sfsr_mask = 0xffffffff,
464 .mmu_trcr_mask = 0xffffffff,
465 .nwindows = 8,
466 .features = CPU_DEFAULT_FEATURES,
469 .name = "TI SuperSparc 61",
470 .iu_version = 0x44000000, /* SuperSPARC 3.x */
471 .fpu_version = 0 << 17,
472 .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
473 .mmu_bm = 0x00002000,
474 .mmu_ctpr_mask = 0xffffffc0,
475 .mmu_cxr_mask = 0x0000ffff,
476 .mmu_sfsr_mask = 0xffffffff,
477 .mmu_trcr_mask = 0xffffffff,
478 .mxcc_version = 0x00000104,
479 .nwindows = 8,
480 .features = CPU_DEFAULT_FEATURES,
483 .name = "TI SuperSparc II",
484 .iu_version = 0x40000000, /* SuperSPARC II 1.x */
485 .fpu_version = 0 << 17,
486 .mmu_version = 0x08000000, /* SuperSPARC II 1.x, MXCC */
487 .mmu_bm = 0x00002000,
488 .mmu_ctpr_mask = 0xffffffc0,
489 .mmu_cxr_mask = 0x0000ffff,
490 .mmu_sfsr_mask = 0xffffffff,
491 .mmu_trcr_mask = 0xffffffff,
492 .mxcc_version = 0x00000104,
493 .nwindows = 8,
494 .features = CPU_DEFAULT_FEATURES,
497 .name = "Ross RT625",
498 .iu_version = 0x1e000000,
499 .fpu_version = 1 << 17,
500 .mmu_version = 0x1e000000,
501 .mmu_bm = 0x00004000,
502 .mmu_ctpr_mask = 0x007ffff0,
503 .mmu_cxr_mask = 0x0000003f,
504 .mmu_sfsr_mask = 0xffffffff,
505 .mmu_trcr_mask = 0xffffffff,
506 .nwindows = 8,
507 .features = CPU_DEFAULT_FEATURES,
510 .name = "Ross RT620",
511 .iu_version = 0x1f000000,
512 .fpu_version = 1 << 17,
513 .mmu_version = 0x1f000000,
514 .mmu_bm = 0x00004000,
515 .mmu_ctpr_mask = 0x007ffff0,
516 .mmu_cxr_mask = 0x0000003f,
517 .mmu_sfsr_mask = 0xffffffff,
518 .mmu_trcr_mask = 0xffffffff,
519 .nwindows = 8,
520 .features = CPU_DEFAULT_FEATURES,
523 .name = "BIT B5010",
524 .iu_version = 0x20000000,
525 .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
526 .mmu_version = 0x20000000,
527 .mmu_bm = 0x00004000,
528 .mmu_ctpr_mask = 0x007ffff0,
529 .mmu_cxr_mask = 0x0000003f,
530 .mmu_sfsr_mask = 0xffffffff,
531 .mmu_trcr_mask = 0xffffffff,
532 .nwindows = 8,
533 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
534 CPU_FEATURE_FSMULD,
537 .name = "Matsushita MN10501",
538 .iu_version = 0x50000000,
539 .fpu_version = 0 << 17,
540 .mmu_version = 0x50000000,
541 .mmu_bm = 0x00004000,
542 .mmu_ctpr_mask = 0x007ffff0,
543 .mmu_cxr_mask = 0x0000003f,
544 .mmu_sfsr_mask = 0xffffffff,
545 .mmu_trcr_mask = 0xffffffff,
546 .nwindows = 8,
547 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_MUL | CPU_FEATURE_FSQRT |
548 CPU_FEATURE_FSMULD,
551 .name = "Weitek W8601",
552 .iu_version = 0x90 << 24, /* Impl 9, ver 0 */
553 .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */
554 .mmu_version = 0x10 << 24,
555 .mmu_bm = 0x00004000,
556 .mmu_ctpr_mask = 0x007ffff0,
557 .mmu_cxr_mask = 0x0000003f,
558 .mmu_sfsr_mask = 0xffffffff,
559 .mmu_trcr_mask = 0xffffffff,
560 .nwindows = 8,
561 .features = CPU_DEFAULT_FEATURES,
564 .name = "LEON2",
565 .iu_version = 0xf2000000,
566 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
567 .mmu_version = 0xf2000000,
568 .mmu_bm = 0x00004000,
569 .mmu_ctpr_mask = 0x007ffff0,
570 .mmu_cxr_mask = 0x0000003f,
571 .mmu_sfsr_mask = 0xffffffff,
572 .mmu_trcr_mask = 0xffffffff,
573 .nwindows = 8,
574 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN,
577 .name = "LEON3",
578 .iu_version = 0xf3000000,
579 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
580 .mmu_version = 0xf3000000,
581 .mmu_bm = 0x00000000,
582 .mmu_ctpr_mask = 0x007ffff0,
583 .mmu_cxr_mask = 0x0000003f,
584 .mmu_sfsr_mask = 0xffffffff,
585 .mmu_trcr_mask = 0xffffffff,
586 .nwindows = 8,
587 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN |
588 CPU_FEATURE_ASR17 | CPU_FEATURE_CACHE_CTRL,
590 #endif
593 static const char * const feature_name[] = {
594 "float",
595 "float128",
596 "swap",
597 "mul",
598 "div",
599 "flush",
600 "fsqrt",
601 "fmul",
602 "vis1",
603 "vis2",
604 "fsmuld",
605 "hypv",
606 "cmt",
607 "gl",
610 static void print_features(FILE *f, fprintf_function cpu_fprintf,
611 uint32_t features, const char *prefix)
613 unsigned int i;
615 for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
616 if (feature_name[i] && (features & (1 << i))) {
617 if (prefix) {
618 (*cpu_fprintf)(f, "%s", prefix);
620 (*cpu_fprintf)(f, "%s ", feature_name[i]);
625 static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features)
627 unsigned int i;
629 for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
630 if (feature_name[i] && !strcmp(flagname, feature_name[i])) {
631 *features |= 1 << i;
632 return;
635 fprintf(stderr, "CPU feature %s not found\n", flagname);
638 static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
640 unsigned int i;
641 const sparc_def_t *def = NULL;
642 char *s = strdup(cpu_model);
643 char *featurestr, *name = strtok(s, ",");
644 uint32_t plus_features = 0;
645 uint32_t minus_features = 0;
646 uint64_t iu_version;
647 uint32_t fpu_version, mmu_version, nwindows;
649 for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
650 if (strcasecmp(name, sparc_defs[i].name) == 0) {
651 def = &sparc_defs[i];
654 if (!def) {
655 goto error;
657 memcpy(cpu_def, def, sizeof(*def));
659 featurestr = strtok(NULL, ",");
660 while (featurestr) {
661 char *val;
663 if (featurestr[0] == '+') {
664 add_flagname_to_bitmaps(featurestr + 1, &plus_features);
665 } else if (featurestr[0] == '-') {
666 add_flagname_to_bitmaps(featurestr + 1, &minus_features);
667 } else if ((val = strchr(featurestr, '='))) {
668 *val = 0; val++;
669 if (!strcmp(featurestr, "iu_version")) {
670 char *err;
672 iu_version = strtoll(val, &err, 0);
673 if (!*val || *err) {
674 fprintf(stderr, "bad numerical value %s\n", val);
675 goto error;
677 cpu_def->iu_version = iu_version;
678 #ifdef DEBUG_FEATURES
679 fprintf(stderr, "iu_version %" PRIx64 "\n", iu_version);
680 #endif
681 } else if (!strcmp(featurestr, "fpu_version")) {
682 char *err;
684 fpu_version = strtol(val, &err, 0);
685 if (!*val || *err) {
686 fprintf(stderr, "bad numerical value %s\n", val);
687 goto error;
689 cpu_def->fpu_version = fpu_version;
690 #ifdef DEBUG_FEATURES
691 fprintf(stderr, "fpu_version %x\n", fpu_version);
692 #endif
693 } else if (!strcmp(featurestr, "mmu_version")) {
694 char *err;
696 mmu_version = strtol(val, &err, 0);
697 if (!*val || *err) {
698 fprintf(stderr, "bad numerical value %s\n", val);
699 goto error;
701 cpu_def->mmu_version = mmu_version;
702 #ifdef DEBUG_FEATURES
703 fprintf(stderr, "mmu_version %x\n", mmu_version);
704 #endif
705 } else if (!strcmp(featurestr, "nwindows")) {
706 char *err;
708 nwindows = strtol(val, &err, 0);
709 if (!*val || *err || nwindows > MAX_NWINDOWS ||
710 nwindows < MIN_NWINDOWS) {
711 fprintf(stderr, "bad numerical value %s\n", val);
712 goto error;
714 cpu_def->nwindows = nwindows;
715 #ifdef DEBUG_FEATURES
716 fprintf(stderr, "nwindows %d\n", nwindows);
717 #endif
718 } else {
719 fprintf(stderr, "unrecognized feature %s\n", featurestr);
720 goto error;
722 } else {
723 fprintf(stderr, "feature string `%s' not in format "
724 "(+feature|-feature|feature=xyz)\n", featurestr);
725 goto error;
727 featurestr = strtok(NULL, ",");
729 cpu_def->features |= plus_features;
730 cpu_def->features &= ~minus_features;
731 #ifdef DEBUG_FEATURES
732 print_features(stderr, fprintf, cpu_def->features, NULL);
733 #endif
734 free(s);
735 return 0;
737 error:
738 free(s);
739 return -1;
742 void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf)
744 unsigned int i;
746 for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
747 (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx
748 " FPU %08x MMU %08x NWINS %d ",
749 sparc_defs[i].name,
750 sparc_defs[i].iu_version,
751 sparc_defs[i].fpu_version,
752 sparc_defs[i].mmu_version,
753 sparc_defs[i].nwindows);
754 print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES &
755 ~sparc_defs[i].features, "-");
756 print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES &
757 sparc_defs[i].features, "+");
758 (*cpu_fprintf)(f, "\n");
760 (*cpu_fprintf)(f, "Default CPU feature flags (use '-' to remove): ");
761 print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES, NULL);
762 (*cpu_fprintf)(f, "\n");
763 (*cpu_fprintf)(f, "Available CPU feature flags (use '+' to add): ");
764 print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES, NULL);
765 (*cpu_fprintf)(f, "\n");
766 (*cpu_fprintf)(f, "Numerical features (use '=' to set): iu_version "
767 "fpu_version mmu_version nwindows\n");
770 static void cpu_print_cc(FILE *f, fprintf_function cpu_fprintf,
771 uint32_t cc)
773 cpu_fprintf(f, "%c%c%c%c", cc & PSR_NEG ? 'N' : '-',
774 cc & PSR_ZERO ? 'Z' : '-', cc & PSR_OVF ? 'V' : '-',
775 cc & PSR_CARRY ? 'C' : '-');
778 #ifdef TARGET_SPARC64
779 #define REGS_PER_LINE 4
780 #else
781 #define REGS_PER_LINE 8
782 #endif
784 void cpu_dump_state(CPUSPARCState *env, FILE *f, fprintf_function cpu_fprintf,
785 int flags)
787 int i, x;
789 cpu_fprintf(f, "pc: " TARGET_FMT_lx " npc: " TARGET_FMT_lx "\n", env->pc,
790 env->npc);
791 cpu_fprintf(f, "General Registers:\n");
793 for (i = 0; i < 8; i++) {
794 if (i % REGS_PER_LINE == 0) {
795 cpu_fprintf(f, "%%g%d-%d:", i, i + REGS_PER_LINE - 1);
797 cpu_fprintf(f, " " TARGET_FMT_lx, env->gregs[i]);
798 if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
799 cpu_fprintf(f, "\n");
802 cpu_fprintf(f, "\nCurrent Register Window:\n");
803 for (x = 0; x < 3; x++) {
804 for (i = 0; i < 8; i++) {
805 if (i % REGS_PER_LINE == 0) {
806 cpu_fprintf(f, "%%%c%d-%d: ",
807 x == 0 ? 'o' : (x == 1 ? 'l' : 'i'),
808 i, i + REGS_PER_LINE - 1);
810 cpu_fprintf(f, TARGET_FMT_lx " ", env->regwptr[i + x * 8]);
811 if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
812 cpu_fprintf(f, "\n");
816 cpu_fprintf(f, "\nFloating Point Registers:\n");
817 for (i = 0; i < TARGET_DPREGS; i++) {
818 if ((i & 3) == 0) {
819 cpu_fprintf(f, "%%f%02d:", i * 2);
821 cpu_fprintf(f, " %016" PRIx64, env->fpr[i].ll);
822 if ((i & 3) == 3) {
823 cpu_fprintf(f, "\n");
826 #ifdef TARGET_SPARC64
827 cpu_fprintf(f, "pstate: %08x ccr: %02x (icc: ", env->pstate,
828 (unsigned)cpu_get_ccr(env));
829 cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << PSR_CARRY_SHIFT);
830 cpu_fprintf(f, " xcc: ");
831 cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << (PSR_CARRY_SHIFT - 4));
832 cpu_fprintf(f, ") asi: %02x tl: %d pil: %x\n", env->asi, env->tl,
833 env->psrpil);
834 cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate: %d "
835 "cleanwin: %d cwp: %d\n",
836 env->cansave, env->canrestore, env->otherwin, env->wstate,
837 env->cleanwin, env->nwindows - 1 - env->cwp);
838 cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: "
839 TARGET_FMT_lx "\n", env->fsr, env->y, env->fprs);
840 #else
841 cpu_fprintf(f, "psr: %08x (icc: ", cpu_get_psr(env));
842 cpu_print_cc(f, cpu_fprintf, cpu_get_psr(env));
843 cpu_fprintf(f, " SPE: %c%c%c) wim: %08x\n", env->psrs ? 'S' : '-',
844 env->psrps ? 'P' : '-', env->psret ? 'E' : '-',
845 env->wim);
846 cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx "\n",
847 env->fsr, env->y);
848 #endif