./configure: request pkg-config to provide private libs when static linking
[qemu/ar7.git] / target-sparc / cpu_init.c
blobc7269b54a8973dde207a40125e402696f8896553
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_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 tlb_flush(env, 1);
34 env->cwp = 0;
35 #ifndef TARGET_SPARC64
36 env->wim = 1;
37 #endif
38 env->regwptr = env->regbase + (env->cwp * 16);
39 CC_OP = CC_OP_FLAGS;
40 #if defined(CONFIG_USER_ONLY)
41 #ifdef TARGET_SPARC64
42 env->cleanwin = env->nwindows - 2;
43 env->cansave = env->nwindows - 2;
44 env->pstate = PS_RMO | PS_PEF | PS_IE;
45 env->asi = 0x82; /* Primary no-fault */
46 #endif
47 #else
48 #if !defined(TARGET_SPARC64)
49 env->psret = 0;
50 env->psrs = 1;
51 env->psrps = 1;
52 #endif
53 #ifdef TARGET_SPARC64
54 env->pstate = PS_PRIV|PS_RED|PS_PEF|PS_AG;
55 env->hpstate = cpu_has_hypervisor(env) ? HS_PRIV : 0;
56 env->tl = env->maxtl;
57 cpu_tsptr(env)->tt = TT_POWER_ON_RESET;
58 env->lsu = 0;
59 #else
60 env->mmuregs[0] &= ~(MMU_E | MMU_NF);
61 env->mmuregs[0] |= env->def->mmu_bm;
62 #endif
63 env->pc = 0;
64 env->npc = env->pc + 4;
65 #endif
66 env->cache_control = 0;
69 static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
71 sparc_def_t def1, *def = &def1;
73 if (cpu_sparc_find_by_name(def, cpu_model) < 0) {
74 return -1;
77 env->def = g_new0(sparc_def_t, 1);
78 memcpy(env->def, def, sizeof(*def));
79 #if defined(CONFIG_USER_ONLY)
80 if ((env->def->features & CPU_FEATURE_FLOAT)) {
81 env->def->features |= CPU_FEATURE_FLOAT128;
83 #endif
84 env->cpu_model_str = cpu_model;
85 env->version = def->iu_version;
86 env->fsr = def->fpu_version;
87 env->nwindows = def->nwindows;
88 #if !defined(TARGET_SPARC64)
89 env->mmuregs[0] |= def->mmu_version;
90 cpu_sparc_set_id(env, 0);
91 env->mxccregs[7] |= def->mxcc_version;
92 #else
93 env->mmu_version = def->mmu_version;
94 env->maxtl = def->maxtl;
95 env->version |= def->maxtl << 8;
96 env->version |= def->nwindows - 1;
97 #endif
98 return 0;
101 static void cpu_sparc_close(CPUSPARCState *env)
103 g_free(env->def);
104 g_free(env);
107 CPUSPARCState *cpu_sparc_init(const char *cpu_model)
109 CPUSPARCState *env;
111 env = g_new0(CPUSPARCState, 1);
112 cpu_exec_init(env);
114 gen_intermediate_code_init(env);
116 if (cpu_sparc_register(env, cpu_model) < 0) {
117 cpu_sparc_close(env);
118 return NULL;
120 qemu_init_vcpu(env);
122 return env;
125 void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
127 #if !defined(TARGET_SPARC64)
128 env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
129 #endif
132 static const sparc_def_t sparc_defs[] = {
133 #ifdef TARGET_SPARC64
135 .name = "Fujitsu Sparc64",
136 .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)),
137 .fpu_version = 0x00000000,
138 .mmu_version = mmu_us_12,
139 .nwindows = 4,
140 .maxtl = 4,
141 .features = CPU_DEFAULT_FEATURES,
144 .name = "Fujitsu Sparc64 III",
145 .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)),
146 .fpu_version = 0x00000000,
147 .mmu_version = mmu_us_12,
148 .nwindows = 5,
149 .maxtl = 4,
150 .features = CPU_DEFAULT_FEATURES,
153 .name = "Fujitsu Sparc64 IV",
154 .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)),
155 .fpu_version = 0x00000000,
156 .mmu_version = mmu_us_12,
157 .nwindows = 8,
158 .maxtl = 5,
159 .features = CPU_DEFAULT_FEATURES,
162 .name = "Fujitsu Sparc64 V",
163 .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)),
164 .fpu_version = 0x00000000,
165 .mmu_version = mmu_us_12,
166 .nwindows = 8,
167 .maxtl = 5,
168 .features = CPU_DEFAULT_FEATURES,
171 .name = "TI UltraSparc I",
172 .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
173 .fpu_version = 0x00000000,
174 .mmu_version = mmu_us_12,
175 .nwindows = 8,
176 .maxtl = 5,
177 .features = CPU_DEFAULT_FEATURES,
180 .name = "TI UltraSparc II",
181 .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)),
182 .fpu_version = 0x00000000,
183 .mmu_version = mmu_us_12,
184 .nwindows = 8,
185 .maxtl = 5,
186 .features = CPU_DEFAULT_FEATURES,
189 .name = "TI UltraSparc IIi",
190 .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)),
191 .fpu_version = 0x00000000,
192 .mmu_version = mmu_us_12,
193 .nwindows = 8,
194 .maxtl = 5,
195 .features = CPU_DEFAULT_FEATURES,
198 .name = "TI UltraSparc IIe",
199 .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)),
200 .fpu_version = 0x00000000,
201 .mmu_version = mmu_us_12,
202 .nwindows = 8,
203 .maxtl = 5,
204 .features = CPU_DEFAULT_FEATURES,
207 .name = "Sun UltraSparc III",
208 .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)),
209 .fpu_version = 0x00000000,
210 .mmu_version = mmu_us_12,
211 .nwindows = 8,
212 .maxtl = 5,
213 .features = CPU_DEFAULT_FEATURES,
216 .name = "Sun UltraSparc III Cu",
217 .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)),
218 .fpu_version = 0x00000000,
219 .mmu_version = mmu_us_3,
220 .nwindows = 8,
221 .maxtl = 5,
222 .features = CPU_DEFAULT_FEATURES,
225 .name = "Sun UltraSparc IIIi",
226 .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)),
227 .fpu_version = 0x00000000,
228 .mmu_version = mmu_us_12,
229 .nwindows = 8,
230 .maxtl = 5,
231 .features = CPU_DEFAULT_FEATURES,
234 .name = "Sun UltraSparc IV",
235 .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)),
236 .fpu_version = 0x00000000,
237 .mmu_version = mmu_us_4,
238 .nwindows = 8,
239 .maxtl = 5,
240 .features = CPU_DEFAULT_FEATURES,
243 .name = "Sun UltraSparc IV+",
244 .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)),
245 .fpu_version = 0x00000000,
246 .mmu_version = mmu_us_12,
247 .nwindows = 8,
248 .maxtl = 5,
249 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT,
252 .name = "Sun UltraSparc IIIi+",
253 .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)),
254 .fpu_version = 0x00000000,
255 .mmu_version = mmu_us_3,
256 .nwindows = 8,
257 .maxtl = 5,
258 .features = CPU_DEFAULT_FEATURES,
261 .name = "Sun UltraSparc T1",
262 /* defined in sparc_ifu_fdp.v and ctu.h */
263 .iu_version = ((0x3eULL << 48) | (0x23ULL << 32) | (0x02ULL << 24)),
264 .fpu_version = 0x00000000,
265 .mmu_version = mmu_sun4v,
266 .nwindows = 8,
267 .maxtl = 6,
268 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
269 | CPU_FEATURE_GL,
272 .name = "Sun UltraSparc T2",
273 /* defined in tlu_asi_ctl.v and n2_revid_cust.v */
274 .iu_version = ((0x3eULL << 48) | (0x24ULL << 32) | (0x02ULL << 24)),
275 .fpu_version = 0x00000000,
276 .mmu_version = mmu_sun4v,
277 .nwindows = 8,
278 .maxtl = 6,
279 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
280 | CPU_FEATURE_GL,
283 .name = "NEC UltraSparc I",
284 .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
285 .fpu_version = 0x00000000,
286 .mmu_version = mmu_us_12,
287 .nwindows = 8,
288 .maxtl = 5,
289 .features = CPU_DEFAULT_FEATURES,
291 #else
293 .name = "Fujitsu MB86900",
294 .iu_version = 0x00 << 24, /* Impl 0, ver 0 */
295 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
296 .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */
297 .mmu_bm = 0x00004000,
298 .mmu_ctpr_mask = 0x007ffff0,
299 .mmu_cxr_mask = 0x0000003f,
300 .mmu_sfsr_mask = 0xffffffff,
301 .mmu_trcr_mask = 0xffffffff,
302 .nwindows = 7,
303 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_FSMULD,
306 .name = "Fujitsu MB86904",
307 .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
308 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
309 .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
310 .mmu_bm = 0x00004000,
311 .mmu_ctpr_mask = 0x00ffffc0,
312 .mmu_cxr_mask = 0x000000ff,
313 .mmu_sfsr_mask = 0x00016fff,
314 .mmu_trcr_mask = 0x00ffffff,
315 .nwindows = 8,
316 .features = CPU_DEFAULT_FEATURES,
319 .name = "Fujitsu MB86907",
320 .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
321 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
322 .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
323 .mmu_bm = 0x00004000,
324 .mmu_ctpr_mask = 0xffffffc0,
325 .mmu_cxr_mask = 0x000000ff,
326 .mmu_sfsr_mask = 0x00016fff,
327 .mmu_trcr_mask = 0xffffffff,
328 .nwindows = 8,
329 .features = CPU_DEFAULT_FEATURES,
332 .name = "LSI L64811",
333 .iu_version = 0x10 << 24, /* Impl 1, ver 0 */
334 .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */
335 .mmu_version = 0x10 << 24,
336 .mmu_bm = 0x00004000,
337 .mmu_ctpr_mask = 0x007ffff0,
338 .mmu_cxr_mask = 0x0000003f,
339 .mmu_sfsr_mask = 0xffffffff,
340 .mmu_trcr_mask = 0xffffffff,
341 .nwindows = 8,
342 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
343 CPU_FEATURE_FSMULD,
346 .name = "Cypress CY7C601",
347 .iu_version = 0x11 << 24, /* Impl 1, ver 1 */
348 .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
349 .mmu_version = 0x10 << 24,
350 .mmu_bm = 0x00004000,
351 .mmu_ctpr_mask = 0x007ffff0,
352 .mmu_cxr_mask = 0x0000003f,
353 .mmu_sfsr_mask = 0xffffffff,
354 .mmu_trcr_mask = 0xffffffff,
355 .nwindows = 8,
356 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
357 CPU_FEATURE_FSMULD,
360 .name = "Cypress CY7C611",
361 .iu_version = 0x13 << 24, /* Impl 1, ver 3 */
362 .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
363 .mmu_version = 0x10 << 24,
364 .mmu_bm = 0x00004000,
365 .mmu_ctpr_mask = 0x007ffff0,
366 .mmu_cxr_mask = 0x0000003f,
367 .mmu_sfsr_mask = 0xffffffff,
368 .mmu_trcr_mask = 0xffffffff,
369 .nwindows = 8,
370 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
371 CPU_FEATURE_FSMULD,
374 .name = "TI MicroSparc I",
375 .iu_version = 0x41000000,
376 .fpu_version = 4 << 17,
377 .mmu_version = 0x41000000,
378 .mmu_bm = 0x00004000,
379 .mmu_ctpr_mask = 0x007ffff0,
380 .mmu_cxr_mask = 0x0000003f,
381 .mmu_sfsr_mask = 0x00016fff,
382 .mmu_trcr_mask = 0x0000003f,
383 .nwindows = 7,
384 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL |
385 CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT |
386 CPU_FEATURE_FMUL,
389 .name = "TI MicroSparc II",
390 .iu_version = 0x42000000,
391 .fpu_version = 4 << 17,
392 .mmu_version = 0x02000000,
393 .mmu_bm = 0x00004000,
394 .mmu_ctpr_mask = 0x00ffffc0,
395 .mmu_cxr_mask = 0x000000ff,
396 .mmu_sfsr_mask = 0x00016fff,
397 .mmu_trcr_mask = 0x00ffffff,
398 .nwindows = 8,
399 .features = CPU_DEFAULT_FEATURES,
402 .name = "TI MicroSparc IIep",
403 .iu_version = 0x42000000,
404 .fpu_version = 4 << 17,
405 .mmu_version = 0x04000000,
406 .mmu_bm = 0x00004000,
407 .mmu_ctpr_mask = 0x00ffffc0,
408 .mmu_cxr_mask = 0x000000ff,
409 .mmu_sfsr_mask = 0x00016bff,
410 .mmu_trcr_mask = 0x00ffffff,
411 .nwindows = 8,
412 .features = CPU_DEFAULT_FEATURES,
415 .name = "TI SuperSparc 40", /* STP1020NPGA */
416 .iu_version = 0x41000000, /* SuperSPARC 2.x */
417 .fpu_version = 0 << 17,
418 .mmu_version = 0x00000800, /* SuperSPARC 2.x, no 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 .nwindows = 8,
425 .features = CPU_DEFAULT_FEATURES,
428 .name = "TI SuperSparc 50", /* STP1020PGA */
429 .iu_version = 0x40000000, /* SuperSPARC 3.x */
430 .fpu_version = 0 << 17,
431 .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
432 .mmu_bm = 0x00002000,
433 .mmu_ctpr_mask = 0xffffffc0,
434 .mmu_cxr_mask = 0x0000ffff,
435 .mmu_sfsr_mask = 0xffffffff,
436 .mmu_trcr_mask = 0xffffffff,
437 .nwindows = 8,
438 .features = CPU_DEFAULT_FEATURES,
441 .name = "TI SuperSparc 51",
442 .iu_version = 0x40000000, /* SuperSPARC 3.x */
443 .fpu_version = 0 << 17,
444 .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
445 .mmu_bm = 0x00002000,
446 .mmu_ctpr_mask = 0xffffffc0,
447 .mmu_cxr_mask = 0x0000ffff,
448 .mmu_sfsr_mask = 0xffffffff,
449 .mmu_trcr_mask = 0xffffffff,
450 .mxcc_version = 0x00000104,
451 .nwindows = 8,
452 .features = CPU_DEFAULT_FEATURES,
455 .name = "TI SuperSparc 60", /* STP1020APGA */
456 .iu_version = 0x40000000, /* SuperSPARC 3.x */
457 .fpu_version = 0 << 17,
458 .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
459 .mmu_bm = 0x00002000,
460 .mmu_ctpr_mask = 0xffffffc0,
461 .mmu_cxr_mask = 0x0000ffff,
462 .mmu_sfsr_mask = 0xffffffff,
463 .mmu_trcr_mask = 0xffffffff,
464 .nwindows = 8,
465 .features = CPU_DEFAULT_FEATURES,
468 .name = "TI SuperSparc 61",
469 .iu_version = 0x44000000, /* SuperSPARC 3.x */
470 .fpu_version = 0 << 17,
471 .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
472 .mmu_bm = 0x00002000,
473 .mmu_ctpr_mask = 0xffffffc0,
474 .mmu_cxr_mask = 0x0000ffff,
475 .mmu_sfsr_mask = 0xffffffff,
476 .mmu_trcr_mask = 0xffffffff,
477 .mxcc_version = 0x00000104,
478 .nwindows = 8,
479 .features = CPU_DEFAULT_FEATURES,
482 .name = "TI SuperSparc II",
483 .iu_version = 0x40000000, /* SuperSPARC II 1.x */
484 .fpu_version = 0 << 17,
485 .mmu_version = 0x08000000, /* SuperSPARC II 1.x, MXCC */
486 .mmu_bm = 0x00002000,
487 .mmu_ctpr_mask = 0xffffffc0,
488 .mmu_cxr_mask = 0x0000ffff,
489 .mmu_sfsr_mask = 0xffffffff,
490 .mmu_trcr_mask = 0xffffffff,
491 .mxcc_version = 0x00000104,
492 .nwindows = 8,
493 .features = CPU_DEFAULT_FEATURES,
496 .name = "Ross RT625",
497 .iu_version = 0x1e000000,
498 .fpu_version = 1 << 17,
499 .mmu_version = 0x1e000000,
500 .mmu_bm = 0x00004000,
501 .mmu_ctpr_mask = 0x007ffff0,
502 .mmu_cxr_mask = 0x0000003f,
503 .mmu_sfsr_mask = 0xffffffff,
504 .mmu_trcr_mask = 0xffffffff,
505 .nwindows = 8,
506 .features = CPU_DEFAULT_FEATURES,
509 .name = "Ross RT620",
510 .iu_version = 0x1f000000,
511 .fpu_version = 1 << 17,
512 .mmu_version = 0x1f000000,
513 .mmu_bm = 0x00004000,
514 .mmu_ctpr_mask = 0x007ffff0,
515 .mmu_cxr_mask = 0x0000003f,
516 .mmu_sfsr_mask = 0xffffffff,
517 .mmu_trcr_mask = 0xffffffff,
518 .nwindows = 8,
519 .features = CPU_DEFAULT_FEATURES,
522 .name = "BIT B5010",
523 .iu_version = 0x20000000,
524 .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
525 .mmu_version = 0x20000000,
526 .mmu_bm = 0x00004000,
527 .mmu_ctpr_mask = 0x007ffff0,
528 .mmu_cxr_mask = 0x0000003f,
529 .mmu_sfsr_mask = 0xffffffff,
530 .mmu_trcr_mask = 0xffffffff,
531 .nwindows = 8,
532 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
533 CPU_FEATURE_FSMULD,
536 .name = "Matsushita MN10501",
537 .iu_version = 0x50000000,
538 .fpu_version = 0 << 17,
539 .mmu_version = 0x50000000,
540 .mmu_bm = 0x00004000,
541 .mmu_ctpr_mask = 0x007ffff0,
542 .mmu_cxr_mask = 0x0000003f,
543 .mmu_sfsr_mask = 0xffffffff,
544 .mmu_trcr_mask = 0xffffffff,
545 .nwindows = 8,
546 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_MUL | CPU_FEATURE_FSQRT |
547 CPU_FEATURE_FSMULD,
550 .name = "Weitek W8601",
551 .iu_version = 0x90 << 24, /* Impl 9, ver 0 */
552 .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */
553 .mmu_version = 0x10 << 24,
554 .mmu_bm = 0x00004000,
555 .mmu_ctpr_mask = 0x007ffff0,
556 .mmu_cxr_mask = 0x0000003f,
557 .mmu_sfsr_mask = 0xffffffff,
558 .mmu_trcr_mask = 0xffffffff,
559 .nwindows = 8,
560 .features = CPU_DEFAULT_FEATURES,
563 .name = "LEON2",
564 .iu_version = 0xf2000000,
565 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
566 .mmu_version = 0xf2000000,
567 .mmu_bm = 0x00004000,
568 .mmu_ctpr_mask = 0x007ffff0,
569 .mmu_cxr_mask = 0x0000003f,
570 .mmu_sfsr_mask = 0xffffffff,
571 .mmu_trcr_mask = 0xffffffff,
572 .nwindows = 8,
573 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN,
576 .name = "LEON3",
577 .iu_version = 0xf3000000,
578 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
579 .mmu_version = 0xf3000000,
580 .mmu_bm = 0x00000000,
581 .mmu_ctpr_mask = 0x007ffff0,
582 .mmu_cxr_mask = 0x0000003f,
583 .mmu_sfsr_mask = 0xffffffff,
584 .mmu_trcr_mask = 0xffffffff,
585 .nwindows = 8,
586 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN |
587 CPU_FEATURE_ASR17 | CPU_FEATURE_CACHE_CTRL,
589 #endif
592 static const char * const feature_name[] = {
593 "float",
594 "float128",
595 "swap",
596 "mul",
597 "div",
598 "flush",
599 "fsqrt",
600 "fmul",
601 "vis1",
602 "vis2",
603 "fsmuld",
604 "hypv",
605 "cmt",
606 "gl",
609 static void print_features(FILE *f, fprintf_function cpu_fprintf,
610 uint32_t features, const char *prefix)
612 unsigned int i;
614 for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
615 if (feature_name[i] && (features & (1 << i))) {
616 if (prefix) {
617 (*cpu_fprintf)(f, "%s", prefix);
619 (*cpu_fprintf)(f, "%s ", feature_name[i]);
624 static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features)
626 unsigned int i;
628 for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
629 if (feature_name[i] && !strcmp(flagname, feature_name[i])) {
630 *features |= 1 << i;
631 return;
634 fprintf(stderr, "CPU feature %s not found\n", flagname);
637 static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
639 unsigned int i;
640 const sparc_def_t *def = NULL;
641 char *s = strdup(cpu_model);
642 char *featurestr, *name = strtok(s, ",");
643 uint32_t plus_features = 0;
644 uint32_t minus_features = 0;
645 uint64_t iu_version;
646 uint32_t fpu_version, mmu_version, nwindows;
648 for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
649 if (strcasecmp(name, sparc_defs[i].name) == 0) {
650 def = &sparc_defs[i];
653 if (!def) {
654 goto error;
656 memcpy(cpu_def, def, sizeof(*def));
658 featurestr = strtok(NULL, ",");
659 while (featurestr) {
660 char *val;
662 if (featurestr[0] == '+') {
663 add_flagname_to_bitmaps(featurestr + 1, &plus_features);
664 } else if (featurestr[0] == '-') {
665 add_flagname_to_bitmaps(featurestr + 1, &minus_features);
666 } else if ((val = strchr(featurestr, '='))) {
667 *val = 0; val++;
668 if (!strcmp(featurestr, "iu_version")) {
669 char *err;
671 iu_version = strtoll(val, &err, 0);
672 if (!*val || *err) {
673 fprintf(stderr, "bad numerical value %s\n", val);
674 goto error;
676 cpu_def->iu_version = iu_version;
677 #ifdef DEBUG_FEATURES
678 fprintf(stderr, "iu_version %" PRIx64 "\n", iu_version);
679 #endif
680 } else if (!strcmp(featurestr, "fpu_version")) {
681 char *err;
683 fpu_version = strtol(val, &err, 0);
684 if (!*val || *err) {
685 fprintf(stderr, "bad numerical value %s\n", val);
686 goto error;
688 cpu_def->fpu_version = fpu_version;
689 #ifdef DEBUG_FEATURES
690 fprintf(stderr, "fpu_version %x\n", fpu_version);
691 #endif
692 } else if (!strcmp(featurestr, "mmu_version")) {
693 char *err;
695 mmu_version = strtol(val, &err, 0);
696 if (!*val || *err) {
697 fprintf(stderr, "bad numerical value %s\n", val);
698 goto error;
700 cpu_def->mmu_version = mmu_version;
701 #ifdef DEBUG_FEATURES
702 fprintf(stderr, "mmu_version %x\n", mmu_version);
703 #endif
704 } else if (!strcmp(featurestr, "nwindows")) {
705 char *err;
707 nwindows = strtol(val, &err, 0);
708 if (!*val || *err || nwindows > MAX_NWINDOWS ||
709 nwindows < MIN_NWINDOWS) {
710 fprintf(stderr, "bad numerical value %s\n", val);
711 goto error;
713 cpu_def->nwindows = nwindows;
714 #ifdef DEBUG_FEATURES
715 fprintf(stderr, "nwindows %d\n", nwindows);
716 #endif
717 } else {
718 fprintf(stderr, "unrecognized feature %s\n", featurestr);
719 goto error;
721 } else {
722 fprintf(stderr, "feature string `%s' not in format "
723 "(+feature|-feature|feature=xyz)\n", featurestr);
724 goto error;
726 featurestr = strtok(NULL, ",");
728 cpu_def->features |= plus_features;
729 cpu_def->features &= ~minus_features;
730 #ifdef DEBUG_FEATURES
731 print_features(stderr, fprintf, cpu_def->features, NULL);
732 #endif
733 free(s);
734 return 0;
736 error:
737 free(s);
738 return -1;
741 void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf)
743 unsigned int i;
745 for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
746 (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx
747 " FPU %08x MMU %08x NWINS %d ",
748 sparc_defs[i].name,
749 sparc_defs[i].iu_version,
750 sparc_defs[i].fpu_version,
751 sparc_defs[i].mmu_version,
752 sparc_defs[i].nwindows);
753 print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES &
754 ~sparc_defs[i].features, "-");
755 print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES &
756 sparc_defs[i].features, "+");
757 (*cpu_fprintf)(f, "\n");
759 (*cpu_fprintf)(f, "Default CPU feature flags (use '-' to remove): ");
760 print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES, NULL);
761 (*cpu_fprintf)(f, "\n");
762 (*cpu_fprintf)(f, "Available CPU feature flags (use '+' to add): ");
763 print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES, NULL);
764 (*cpu_fprintf)(f, "\n");
765 (*cpu_fprintf)(f, "Numerical features (use '=' to set): iu_version "
766 "fpu_version mmu_version nwindows\n");
769 static void cpu_print_cc(FILE *f, fprintf_function cpu_fprintf,
770 uint32_t cc)
772 cpu_fprintf(f, "%c%c%c%c", cc & PSR_NEG ? 'N' : '-',
773 cc & PSR_ZERO ? 'Z' : '-', cc & PSR_OVF ? 'V' : '-',
774 cc & PSR_CARRY ? 'C' : '-');
777 #ifdef TARGET_SPARC64
778 #define REGS_PER_LINE 4
779 #else
780 #define REGS_PER_LINE 8
781 #endif
783 void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
784 int flags)
786 int i, x;
788 cpu_fprintf(f, "pc: " TARGET_FMT_lx " npc: " TARGET_FMT_lx "\n", env->pc,
789 env->npc);
790 cpu_fprintf(f, "General Registers:\n");
792 for (i = 0; i < 8; i++) {
793 if (i % REGS_PER_LINE == 0) {
794 cpu_fprintf(f, "%%g%d-%d:", i, i + REGS_PER_LINE - 1);
796 cpu_fprintf(f, " " TARGET_FMT_lx, env->gregs[i]);
797 if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
798 cpu_fprintf(f, "\n");
801 cpu_fprintf(f, "\nCurrent Register Window:\n");
802 for (x = 0; x < 3; x++) {
803 for (i = 0; i < 8; i++) {
804 if (i % REGS_PER_LINE == 0) {
805 cpu_fprintf(f, "%%%c%d-%d: ",
806 x == 0 ? 'o' : (x == 1 ? 'l' : 'i'),
807 i, i + REGS_PER_LINE - 1);
809 cpu_fprintf(f, TARGET_FMT_lx " ", env->regwptr[i + x * 8]);
810 if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
811 cpu_fprintf(f, "\n");
815 cpu_fprintf(f, "\nFloating Point Registers:\n");
816 for (i = 0; i < TARGET_DPREGS; i++) {
817 if ((i & 3) == 0) {
818 cpu_fprintf(f, "%%f%02d:", i * 2);
820 cpu_fprintf(f, " %016" PRIx64, env->fpr[i].ll);
821 if ((i & 3) == 3) {
822 cpu_fprintf(f, "\n");
825 #ifdef TARGET_SPARC64
826 cpu_fprintf(f, "pstate: %08x ccr: %02x (icc: ", env->pstate,
827 (unsigned)cpu_get_ccr(env));
828 cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << PSR_CARRY_SHIFT);
829 cpu_fprintf(f, " xcc: ");
830 cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << (PSR_CARRY_SHIFT - 4));
831 cpu_fprintf(f, ") asi: %02x tl: %d pil: %x\n", env->asi, env->tl,
832 env->psrpil);
833 cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate: %d "
834 "cleanwin: %d cwp: %d\n",
835 env->cansave, env->canrestore, env->otherwin, env->wstate,
836 env->cleanwin, env->nwindows - 1 - env->cwp);
837 cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: "
838 TARGET_FMT_lx "\n", env->fsr, env->y, env->fprs);
839 #else
840 cpu_fprintf(f, "psr: %08x (icc: ", cpu_get_psr(env));
841 cpu_print_cc(f, cpu_fprintf, cpu_get_psr(env));
842 cpu_fprintf(f, " SPE: %c%c%c) wim: %08x\n", env->psrs ? 'S' : '-',
843 env->psrps ? 'P' : '-', env->psret ? 'E' : '-',
844 env->wim);
845 cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx "\n",
846 env->fsr, env->y);
847 #endif