hw/pxa2xx_timer: Explicitly mark fallthroughs
[qemu/pbrook.git] / target-sparc / cpu.c
blobf404aa8b5fb6922d578d76fad6d03b2a6a395d17
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 (tcg_enabled()) {
118 gen_intermediate_code_init(env);
121 if (cpu_sparc_register(env, cpu_model) < 0) {
122 object_delete(OBJECT(cpu));
123 return NULL;
125 qemu_init_vcpu(env);
127 return cpu;
130 void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
132 #if !defined(TARGET_SPARC64)
133 env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
134 #endif
137 static const sparc_def_t sparc_defs[] = {
138 #ifdef TARGET_SPARC64
140 .name = "Fujitsu Sparc64",
141 .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)),
142 .fpu_version = 0x00000000,
143 .mmu_version = mmu_us_12,
144 .nwindows = 4,
145 .maxtl = 4,
146 .features = CPU_DEFAULT_FEATURES,
149 .name = "Fujitsu Sparc64 III",
150 .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)),
151 .fpu_version = 0x00000000,
152 .mmu_version = mmu_us_12,
153 .nwindows = 5,
154 .maxtl = 4,
155 .features = CPU_DEFAULT_FEATURES,
158 .name = "Fujitsu Sparc64 IV",
159 .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)),
160 .fpu_version = 0x00000000,
161 .mmu_version = mmu_us_12,
162 .nwindows = 8,
163 .maxtl = 5,
164 .features = CPU_DEFAULT_FEATURES,
167 .name = "Fujitsu Sparc64 V",
168 .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)),
169 .fpu_version = 0x00000000,
170 .mmu_version = mmu_us_12,
171 .nwindows = 8,
172 .maxtl = 5,
173 .features = CPU_DEFAULT_FEATURES,
176 .name = "TI UltraSparc I",
177 .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
178 .fpu_version = 0x00000000,
179 .mmu_version = mmu_us_12,
180 .nwindows = 8,
181 .maxtl = 5,
182 .features = CPU_DEFAULT_FEATURES,
185 .name = "TI UltraSparc II",
186 .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)),
187 .fpu_version = 0x00000000,
188 .mmu_version = mmu_us_12,
189 .nwindows = 8,
190 .maxtl = 5,
191 .features = CPU_DEFAULT_FEATURES,
194 .name = "TI UltraSparc IIi",
195 .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)),
196 .fpu_version = 0x00000000,
197 .mmu_version = mmu_us_12,
198 .nwindows = 8,
199 .maxtl = 5,
200 .features = CPU_DEFAULT_FEATURES,
203 .name = "TI UltraSparc IIe",
204 .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)),
205 .fpu_version = 0x00000000,
206 .mmu_version = mmu_us_12,
207 .nwindows = 8,
208 .maxtl = 5,
209 .features = CPU_DEFAULT_FEATURES,
212 .name = "Sun UltraSparc III",
213 .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)),
214 .fpu_version = 0x00000000,
215 .mmu_version = mmu_us_12,
216 .nwindows = 8,
217 .maxtl = 5,
218 .features = CPU_DEFAULT_FEATURES,
221 .name = "Sun UltraSparc III Cu",
222 .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)),
223 .fpu_version = 0x00000000,
224 .mmu_version = mmu_us_3,
225 .nwindows = 8,
226 .maxtl = 5,
227 .features = CPU_DEFAULT_FEATURES,
230 .name = "Sun UltraSparc IIIi",
231 .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)),
232 .fpu_version = 0x00000000,
233 .mmu_version = mmu_us_12,
234 .nwindows = 8,
235 .maxtl = 5,
236 .features = CPU_DEFAULT_FEATURES,
239 .name = "Sun UltraSparc IV",
240 .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)),
241 .fpu_version = 0x00000000,
242 .mmu_version = mmu_us_4,
243 .nwindows = 8,
244 .maxtl = 5,
245 .features = CPU_DEFAULT_FEATURES,
248 .name = "Sun UltraSparc IV+",
249 .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)),
250 .fpu_version = 0x00000000,
251 .mmu_version = mmu_us_12,
252 .nwindows = 8,
253 .maxtl = 5,
254 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT,
257 .name = "Sun UltraSparc IIIi+",
258 .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)),
259 .fpu_version = 0x00000000,
260 .mmu_version = mmu_us_3,
261 .nwindows = 8,
262 .maxtl = 5,
263 .features = CPU_DEFAULT_FEATURES,
266 .name = "Sun UltraSparc T1",
267 /* defined in sparc_ifu_fdp.v and ctu.h */
268 .iu_version = ((0x3eULL << 48) | (0x23ULL << 32) | (0x02ULL << 24)),
269 .fpu_version = 0x00000000,
270 .mmu_version = mmu_sun4v,
271 .nwindows = 8,
272 .maxtl = 6,
273 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
274 | CPU_FEATURE_GL,
277 .name = "Sun UltraSparc T2",
278 /* defined in tlu_asi_ctl.v and n2_revid_cust.v */
279 .iu_version = ((0x3eULL << 48) | (0x24ULL << 32) | (0x02ULL << 24)),
280 .fpu_version = 0x00000000,
281 .mmu_version = mmu_sun4v,
282 .nwindows = 8,
283 .maxtl = 6,
284 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
285 | CPU_FEATURE_GL,
288 .name = "NEC UltraSparc I",
289 .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
290 .fpu_version = 0x00000000,
291 .mmu_version = mmu_us_12,
292 .nwindows = 8,
293 .maxtl = 5,
294 .features = CPU_DEFAULT_FEATURES,
296 #else
298 .name = "Fujitsu MB86900",
299 .iu_version = 0x00 << 24, /* Impl 0, ver 0 */
300 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
301 .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */
302 .mmu_bm = 0x00004000,
303 .mmu_ctpr_mask = 0x007ffff0,
304 .mmu_cxr_mask = 0x0000003f,
305 .mmu_sfsr_mask = 0xffffffff,
306 .mmu_trcr_mask = 0xffffffff,
307 .nwindows = 7,
308 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_FSMULD,
311 .name = "Fujitsu MB86904",
312 .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
313 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
314 .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
315 .mmu_bm = 0x00004000,
316 .mmu_ctpr_mask = 0x00ffffc0,
317 .mmu_cxr_mask = 0x000000ff,
318 .mmu_sfsr_mask = 0x00016fff,
319 .mmu_trcr_mask = 0x00ffffff,
320 .nwindows = 8,
321 .features = CPU_DEFAULT_FEATURES,
324 .name = "Fujitsu MB86907",
325 .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
326 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
327 .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
328 .mmu_bm = 0x00004000,
329 .mmu_ctpr_mask = 0xffffffc0,
330 .mmu_cxr_mask = 0x000000ff,
331 .mmu_sfsr_mask = 0x00016fff,
332 .mmu_trcr_mask = 0xffffffff,
333 .nwindows = 8,
334 .features = CPU_DEFAULT_FEATURES,
337 .name = "LSI L64811",
338 .iu_version = 0x10 << 24, /* Impl 1, ver 0 */
339 .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */
340 .mmu_version = 0x10 << 24,
341 .mmu_bm = 0x00004000,
342 .mmu_ctpr_mask = 0x007ffff0,
343 .mmu_cxr_mask = 0x0000003f,
344 .mmu_sfsr_mask = 0xffffffff,
345 .mmu_trcr_mask = 0xffffffff,
346 .nwindows = 8,
347 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
348 CPU_FEATURE_FSMULD,
351 .name = "Cypress CY7C601",
352 .iu_version = 0x11 << 24, /* Impl 1, ver 1 */
353 .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
354 .mmu_version = 0x10 << 24,
355 .mmu_bm = 0x00004000,
356 .mmu_ctpr_mask = 0x007ffff0,
357 .mmu_cxr_mask = 0x0000003f,
358 .mmu_sfsr_mask = 0xffffffff,
359 .mmu_trcr_mask = 0xffffffff,
360 .nwindows = 8,
361 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
362 CPU_FEATURE_FSMULD,
365 .name = "Cypress CY7C611",
366 .iu_version = 0x13 << 24, /* Impl 1, ver 3 */
367 .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
368 .mmu_version = 0x10 << 24,
369 .mmu_bm = 0x00004000,
370 .mmu_ctpr_mask = 0x007ffff0,
371 .mmu_cxr_mask = 0x0000003f,
372 .mmu_sfsr_mask = 0xffffffff,
373 .mmu_trcr_mask = 0xffffffff,
374 .nwindows = 8,
375 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
376 CPU_FEATURE_FSMULD,
379 .name = "TI MicroSparc I",
380 .iu_version = 0x41000000,
381 .fpu_version = 4 << 17,
382 .mmu_version = 0x41000000,
383 .mmu_bm = 0x00004000,
384 .mmu_ctpr_mask = 0x007ffff0,
385 .mmu_cxr_mask = 0x0000003f,
386 .mmu_sfsr_mask = 0x00016fff,
387 .mmu_trcr_mask = 0x0000003f,
388 .nwindows = 7,
389 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL |
390 CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT |
391 CPU_FEATURE_FMUL,
394 .name = "TI MicroSparc II",
395 .iu_version = 0x42000000,
396 .fpu_version = 4 << 17,
397 .mmu_version = 0x02000000,
398 .mmu_bm = 0x00004000,
399 .mmu_ctpr_mask = 0x00ffffc0,
400 .mmu_cxr_mask = 0x000000ff,
401 .mmu_sfsr_mask = 0x00016fff,
402 .mmu_trcr_mask = 0x00ffffff,
403 .nwindows = 8,
404 .features = CPU_DEFAULT_FEATURES,
407 .name = "TI MicroSparc IIep",
408 .iu_version = 0x42000000,
409 .fpu_version = 4 << 17,
410 .mmu_version = 0x04000000,
411 .mmu_bm = 0x00004000,
412 .mmu_ctpr_mask = 0x00ffffc0,
413 .mmu_cxr_mask = 0x000000ff,
414 .mmu_sfsr_mask = 0x00016bff,
415 .mmu_trcr_mask = 0x00ffffff,
416 .nwindows = 8,
417 .features = CPU_DEFAULT_FEATURES,
420 .name = "TI SuperSparc 40", /* STP1020NPGA */
421 .iu_version = 0x41000000, /* SuperSPARC 2.x */
422 .fpu_version = 0 << 17,
423 .mmu_version = 0x00000800, /* SuperSPARC 2.x, no MXCC */
424 .mmu_bm = 0x00002000,
425 .mmu_ctpr_mask = 0xffffffc0,
426 .mmu_cxr_mask = 0x0000ffff,
427 .mmu_sfsr_mask = 0xffffffff,
428 .mmu_trcr_mask = 0xffffffff,
429 .nwindows = 8,
430 .features = CPU_DEFAULT_FEATURES,
433 .name = "TI SuperSparc 50", /* STP1020PGA */
434 .iu_version = 0x40000000, /* SuperSPARC 3.x */
435 .fpu_version = 0 << 17,
436 .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
437 .mmu_bm = 0x00002000,
438 .mmu_ctpr_mask = 0xffffffc0,
439 .mmu_cxr_mask = 0x0000ffff,
440 .mmu_sfsr_mask = 0xffffffff,
441 .mmu_trcr_mask = 0xffffffff,
442 .nwindows = 8,
443 .features = CPU_DEFAULT_FEATURES,
446 .name = "TI SuperSparc 51",
447 .iu_version = 0x40000000, /* SuperSPARC 3.x */
448 .fpu_version = 0 << 17,
449 .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
450 .mmu_bm = 0x00002000,
451 .mmu_ctpr_mask = 0xffffffc0,
452 .mmu_cxr_mask = 0x0000ffff,
453 .mmu_sfsr_mask = 0xffffffff,
454 .mmu_trcr_mask = 0xffffffff,
455 .mxcc_version = 0x00000104,
456 .nwindows = 8,
457 .features = CPU_DEFAULT_FEATURES,
460 .name = "TI SuperSparc 60", /* STP1020APGA */
461 .iu_version = 0x40000000, /* SuperSPARC 3.x */
462 .fpu_version = 0 << 17,
463 .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
464 .mmu_bm = 0x00002000,
465 .mmu_ctpr_mask = 0xffffffc0,
466 .mmu_cxr_mask = 0x0000ffff,
467 .mmu_sfsr_mask = 0xffffffff,
468 .mmu_trcr_mask = 0xffffffff,
469 .nwindows = 8,
470 .features = CPU_DEFAULT_FEATURES,
473 .name = "TI SuperSparc 61",
474 .iu_version = 0x44000000, /* SuperSPARC 3.x */
475 .fpu_version = 0 << 17,
476 .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
477 .mmu_bm = 0x00002000,
478 .mmu_ctpr_mask = 0xffffffc0,
479 .mmu_cxr_mask = 0x0000ffff,
480 .mmu_sfsr_mask = 0xffffffff,
481 .mmu_trcr_mask = 0xffffffff,
482 .mxcc_version = 0x00000104,
483 .nwindows = 8,
484 .features = CPU_DEFAULT_FEATURES,
487 .name = "TI SuperSparc II",
488 .iu_version = 0x40000000, /* SuperSPARC II 1.x */
489 .fpu_version = 0 << 17,
490 .mmu_version = 0x08000000, /* SuperSPARC II 1.x, MXCC */
491 .mmu_bm = 0x00002000,
492 .mmu_ctpr_mask = 0xffffffc0,
493 .mmu_cxr_mask = 0x0000ffff,
494 .mmu_sfsr_mask = 0xffffffff,
495 .mmu_trcr_mask = 0xffffffff,
496 .mxcc_version = 0x00000104,
497 .nwindows = 8,
498 .features = CPU_DEFAULT_FEATURES,
501 .name = "Ross RT625",
502 .iu_version = 0x1e000000,
503 .fpu_version = 1 << 17,
504 .mmu_version = 0x1e000000,
505 .mmu_bm = 0x00004000,
506 .mmu_ctpr_mask = 0x007ffff0,
507 .mmu_cxr_mask = 0x0000003f,
508 .mmu_sfsr_mask = 0xffffffff,
509 .mmu_trcr_mask = 0xffffffff,
510 .nwindows = 8,
511 .features = CPU_DEFAULT_FEATURES,
514 .name = "Ross RT620",
515 .iu_version = 0x1f000000,
516 .fpu_version = 1 << 17,
517 .mmu_version = 0x1f000000,
518 .mmu_bm = 0x00004000,
519 .mmu_ctpr_mask = 0x007ffff0,
520 .mmu_cxr_mask = 0x0000003f,
521 .mmu_sfsr_mask = 0xffffffff,
522 .mmu_trcr_mask = 0xffffffff,
523 .nwindows = 8,
524 .features = CPU_DEFAULT_FEATURES,
527 .name = "BIT B5010",
528 .iu_version = 0x20000000,
529 .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
530 .mmu_version = 0x20000000,
531 .mmu_bm = 0x00004000,
532 .mmu_ctpr_mask = 0x007ffff0,
533 .mmu_cxr_mask = 0x0000003f,
534 .mmu_sfsr_mask = 0xffffffff,
535 .mmu_trcr_mask = 0xffffffff,
536 .nwindows = 8,
537 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
538 CPU_FEATURE_FSMULD,
541 .name = "Matsushita MN10501",
542 .iu_version = 0x50000000,
543 .fpu_version = 0 << 17,
544 .mmu_version = 0x50000000,
545 .mmu_bm = 0x00004000,
546 .mmu_ctpr_mask = 0x007ffff0,
547 .mmu_cxr_mask = 0x0000003f,
548 .mmu_sfsr_mask = 0xffffffff,
549 .mmu_trcr_mask = 0xffffffff,
550 .nwindows = 8,
551 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_MUL | CPU_FEATURE_FSQRT |
552 CPU_FEATURE_FSMULD,
555 .name = "Weitek W8601",
556 .iu_version = 0x90 << 24, /* Impl 9, ver 0 */
557 .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */
558 .mmu_version = 0x10 << 24,
559 .mmu_bm = 0x00004000,
560 .mmu_ctpr_mask = 0x007ffff0,
561 .mmu_cxr_mask = 0x0000003f,
562 .mmu_sfsr_mask = 0xffffffff,
563 .mmu_trcr_mask = 0xffffffff,
564 .nwindows = 8,
565 .features = CPU_DEFAULT_FEATURES,
568 .name = "LEON2",
569 .iu_version = 0xf2000000,
570 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
571 .mmu_version = 0xf2000000,
572 .mmu_bm = 0x00004000,
573 .mmu_ctpr_mask = 0x007ffff0,
574 .mmu_cxr_mask = 0x0000003f,
575 .mmu_sfsr_mask = 0xffffffff,
576 .mmu_trcr_mask = 0xffffffff,
577 .nwindows = 8,
578 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN,
581 .name = "LEON3",
582 .iu_version = 0xf3000000,
583 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
584 .mmu_version = 0xf3000000,
585 .mmu_bm = 0x00000000,
586 .mmu_ctpr_mask = 0x007ffff0,
587 .mmu_cxr_mask = 0x0000003f,
588 .mmu_sfsr_mask = 0xffffffff,
589 .mmu_trcr_mask = 0xffffffff,
590 .nwindows = 8,
591 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN |
592 CPU_FEATURE_ASR17 | CPU_FEATURE_CACHE_CTRL,
594 #endif
597 static const char * const feature_name[] = {
598 "float",
599 "float128",
600 "swap",
601 "mul",
602 "div",
603 "flush",
604 "fsqrt",
605 "fmul",
606 "vis1",
607 "vis2",
608 "fsmuld",
609 "hypv",
610 "cmt",
611 "gl",
614 static void print_features(FILE *f, fprintf_function cpu_fprintf,
615 uint32_t features, const char *prefix)
617 unsigned int i;
619 for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
620 if (feature_name[i] && (features & (1 << i))) {
621 if (prefix) {
622 (*cpu_fprintf)(f, "%s", prefix);
624 (*cpu_fprintf)(f, "%s ", feature_name[i]);
629 static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features)
631 unsigned int i;
633 for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
634 if (feature_name[i] && !strcmp(flagname, feature_name[i])) {
635 *features |= 1 << i;
636 return;
639 fprintf(stderr, "CPU feature %s not found\n", flagname);
642 static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
644 unsigned int i;
645 const sparc_def_t *def = NULL;
646 char *s = g_strdup(cpu_model);
647 char *featurestr, *name = strtok(s, ",");
648 uint32_t plus_features = 0;
649 uint32_t minus_features = 0;
650 uint64_t iu_version;
651 uint32_t fpu_version, mmu_version, nwindows;
653 for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
654 if (strcasecmp(name, sparc_defs[i].name) == 0) {
655 def = &sparc_defs[i];
658 if (!def) {
659 goto error;
661 memcpy(cpu_def, def, sizeof(*def));
663 featurestr = strtok(NULL, ",");
664 while (featurestr) {
665 char *val;
667 if (featurestr[0] == '+') {
668 add_flagname_to_bitmaps(featurestr + 1, &plus_features);
669 } else if (featurestr[0] == '-') {
670 add_flagname_to_bitmaps(featurestr + 1, &minus_features);
671 } else if ((val = strchr(featurestr, '='))) {
672 *val = 0; val++;
673 if (!strcmp(featurestr, "iu_version")) {
674 char *err;
676 iu_version = strtoll(val, &err, 0);
677 if (!*val || *err) {
678 fprintf(stderr, "bad numerical value %s\n", val);
679 goto error;
681 cpu_def->iu_version = iu_version;
682 #ifdef DEBUG_FEATURES
683 fprintf(stderr, "iu_version %" PRIx64 "\n", iu_version);
684 #endif
685 } else if (!strcmp(featurestr, "fpu_version")) {
686 char *err;
688 fpu_version = strtol(val, &err, 0);
689 if (!*val || *err) {
690 fprintf(stderr, "bad numerical value %s\n", val);
691 goto error;
693 cpu_def->fpu_version = fpu_version;
694 #ifdef DEBUG_FEATURES
695 fprintf(stderr, "fpu_version %x\n", fpu_version);
696 #endif
697 } else if (!strcmp(featurestr, "mmu_version")) {
698 char *err;
700 mmu_version = strtol(val, &err, 0);
701 if (!*val || *err) {
702 fprintf(stderr, "bad numerical value %s\n", val);
703 goto error;
705 cpu_def->mmu_version = mmu_version;
706 #ifdef DEBUG_FEATURES
707 fprintf(stderr, "mmu_version %x\n", mmu_version);
708 #endif
709 } else if (!strcmp(featurestr, "nwindows")) {
710 char *err;
712 nwindows = strtol(val, &err, 0);
713 if (!*val || *err || nwindows > MAX_NWINDOWS ||
714 nwindows < MIN_NWINDOWS) {
715 fprintf(stderr, "bad numerical value %s\n", val);
716 goto error;
718 cpu_def->nwindows = nwindows;
719 #ifdef DEBUG_FEATURES
720 fprintf(stderr, "nwindows %d\n", nwindows);
721 #endif
722 } else {
723 fprintf(stderr, "unrecognized feature %s\n", featurestr);
724 goto error;
726 } else {
727 fprintf(stderr, "feature string `%s' not in format "
728 "(+feature|-feature|feature=xyz)\n", featurestr);
729 goto error;
731 featurestr = strtok(NULL, ",");
733 cpu_def->features |= plus_features;
734 cpu_def->features &= ~minus_features;
735 #ifdef DEBUG_FEATURES
736 print_features(stderr, fprintf, cpu_def->features, NULL);
737 #endif
738 g_free(s);
739 return 0;
741 error:
742 free(s);
743 return -1;
746 void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf)
748 unsigned int i;
750 for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
751 (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx
752 " FPU %08x MMU %08x NWINS %d ",
753 sparc_defs[i].name,
754 sparc_defs[i].iu_version,
755 sparc_defs[i].fpu_version,
756 sparc_defs[i].mmu_version,
757 sparc_defs[i].nwindows);
758 print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES &
759 ~sparc_defs[i].features, "-");
760 print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES &
761 sparc_defs[i].features, "+");
762 (*cpu_fprintf)(f, "\n");
764 (*cpu_fprintf)(f, "Default CPU feature flags (use '-' to remove): ");
765 print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES, NULL);
766 (*cpu_fprintf)(f, "\n");
767 (*cpu_fprintf)(f, "Available CPU feature flags (use '+' to add): ");
768 print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES, NULL);
769 (*cpu_fprintf)(f, "\n");
770 (*cpu_fprintf)(f, "Numerical features (use '=' to set): iu_version "
771 "fpu_version mmu_version nwindows\n");
774 static void cpu_print_cc(FILE *f, fprintf_function cpu_fprintf,
775 uint32_t cc)
777 cpu_fprintf(f, "%c%c%c%c", cc & PSR_NEG ? 'N' : '-',
778 cc & PSR_ZERO ? 'Z' : '-', cc & PSR_OVF ? 'V' : '-',
779 cc & PSR_CARRY ? 'C' : '-');
782 #ifdef TARGET_SPARC64
783 #define REGS_PER_LINE 4
784 #else
785 #define REGS_PER_LINE 8
786 #endif
788 void cpu_dump_state(CPUSPARCState *env, FILE *f, fprintf_function cpu_fprintf,
789 int flags)
791 int i, x;
793 cpu_fprintf(f, "pc: " TARGET_FMT_lx " npc: " TARGET_FMT_lx "\n", env->pc,
794 env->npc);
796 for (i = 0; i < 8; i++) {
797 if (i % REGS_PER_LINE == 0) {
798 cpu_fprintf(f, "%%g%d-%d:", i, i + REGS_PER_LINE - 1);
800 cpu_fprintf(f, " " TARGET_FMT_lx, env->gregs[i]);
801 if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
802 cpu_fprintf(f, "\n");
805 for (x = 0; x < 3; x++) {
806 for (i = 0; i < 8; i++) {
807 if (i % REGS_PER_LINE == 0) {
808 cpu_fprintf(f, "%%%c%d-%d: ",
809 x == 0 ? 'o' : (x == 1 ? 'l' : 'i'),
810 i, i + REGS_PER_LINE - 1);
812 cpu_fprintf(f, TARGET_FMT_lx " ", env->regwptr[i + x * 8]);
813 if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
814 cpu_fprintf(f, "\n");
819 for (i = 0; i < TARGET_DPREGS; i++) {
820 if ((i & 3) == 0) {
821 cpu_fprintf(f, "%%f%02d: ", i * 2);
823 cpu_fprintf(f, " %016" PRIx64, env->fpr[i].ll);
824 if ((i & 3) == 3) {
825 cpu_fprintf(f, "\n");
828 #ifdef TARGET_SPARC64
829 cpu_fprintf(f, "pstate: %08x ccr: %02x (icc: ", env->pstate,
830 (unsigned)cpu_get_ccr(env));
831 cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << PSR_CARRY_SHIFT);
832 cpu_fprintf(f, " xcc: ");
833 cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << (PSR_CARRY_SHIFT - 4));
834 cpu_fprintf(f, ") asi: %02x tl: %d pil: %x\n", env->asi, env->tl,
835 env->psrpil);
836 cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate: %d "
837 "cleanwin: %d cwp: %d\n",
838 env->cansave, env->canrestore, env->otherwin, env->wstate,
839 env->cleanwin, env->nwindows - 1 - env->cwp);
840 cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: "
841 TARGET_FMT_lx "\n", env->fsr, env->y, env->fprs);
842 #else
843 cpu_fprintf(f, "psr: %08x (icc: ", cpu_get_psr(env));
844 cpu_print_cc(f, cpu_fprintf, cpu_get_psr(env));
845 cpu_fprintf(f, " SPE: %c%c%c) wim: %08x\n", env->psrs ? 'S' : '-',
846 env->psrps ? 'P' : '-', env->psret ? 'E' : '-',
847 env->wim);
848 cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx "\n",
849 env->fsr, env->y);
850 #endif
851 cpu_fprintf(f, "\n");
854 static void sparc_cpu_initfn(Object *obj)
856 SPARCCPU *cpu = SPARC_CPU(obj);
857 CPUSPARCState *env = &cpu->env;
859 cpu_exec_init(env);
862 static void sparc_cpu_uninitfn(Object *obj)
864 SPARCCPU *cpu = SPARC_CPU(obj);
865 CPUSPARCState *env = &cpu->env;
867 g_free(env->def);
870 static void sparc_cpu_class_init(ObjectClass *oc, void *data)
872 SPARCCPUClass *scc = SPARC_CPU_CLASS(oc);
873 CPUClass *cc = CPU_CLASS(oc);
875 scc->parent_reset = cc->reset;
876 cc->reset = sparc_cpu_reset;
879 static const TypeInfo sparc_cpu_type_info = {
880 .name = TYPE_SPARC_CPU,
881 .parent = TYPE_CPU,
882 .instance_size = sizeof(SPARCCPU),
883 .instance_init = sparc_cpu_initfn,
884 .instance_finalize = sparc_cpu_uninitfn,
885 .abstract = false,
886 .class_size = sizeof(SPARCCPUClass),
887 .class_init = sparc_cpu_class_init,
890 static void sparc_cpu_register_types(void)
892 type_register_static(&sparc_cpu_type_info);
895 type_init(sparc_cpu_register_types)