target-ppc: Drop cpu_ppc_close()
[qemu/ar7.git] / target-sparc / cpu.c
blob24f90f1dedff629aae07a1f4a4f25dd98b8c31ee
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 cpu_reset(ENV_GET_CPU(env));
31 /* CPUClass::reset() */
32 static void sparc_cpu_reset(CPUState *s)
34 SPARCCPU *cpu = SPARC_CPU(s);
35 SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(cpu);
36 CPUSPARCState *env = &cpu->env;
38 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
39 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
40 log_cpu_state(env, 0);
43 scc->parent_reset(s);
45 memset(env, 0, offsetof(CPUSPARCState, breakpoints));
46 tlb_flush(env, 1);
47 env->cwp = 0;
48 #ifndef TARGET_SPARC64
49 env->wim = 1;
50 #endif
51 env->regwptr = env->regbase + (env->cwp * 16);
52 CC_OP = CC_OP_FLAGS;
53 #if defined(CONFIG_USER_ONLY)
54 #ifdef TARGET_SPARC64
55 env->cleanwin = env->nwindows - 2;
56 env->cansave = env->nwindows - 2;
57 env->pstate = PS_RMO | PS_PEF | PS_IE;
58 env->asi = 0x82; /* Primary no-fault */
59 #endif
60 #else
61 #if !defined(TARGET_SPARC64)
62 env->psret = 0;
63 env->psrs = 1;
64 env->psrps = 1;
65 #endif
66 #ifdef TARGET_SPARC64
67 env->pstate = PS_PRIV|PS_RED|PS_PEF|PS_AG;
68 env->hpstate = cpu_has_hypervisor(env) ? HS_PRIV : 0;
69 env->tl = env->maxtl;
70 cpu_tsptr(env)->tt = TT_POWER_ON_RESET;
71 env->lsu = 0;
72 #else
73 env->mmuregs[0] &= ~(MMU_E | MMU_NF);
74 env->mmuregs[0] |= env->def->mmu_bm;
75 #endif
76 env->pc = 0;
77 env->npc = env->pc + 4;
78 #endif
79 env->cache_control = 0;
82 static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
84 sparc_def_t def1, *def = &def1;
86 if (cpu_sparc_find_by_name(def, cpu_model) < 0) {
87 return -1;
90 env->def = g_new0(sparc_def_t, 1);
91 memcpy(env->def, def, sizeof(*def));
92 #if defined(CONFIG_USER_ONLY)
93 if ((env->def->features & CPU_FEATURE_FLOAT)) {
94 env->def->features |= CPU_FEATURE_FLOAT128;
96 #endif
97 env->cpu_model_str = cpu_model;
98 env->version = def->iu_version;
99 env->fsr = def->fpu_version;
100 env->nwindows = def->nwindows;
101 #if !defined(TARGET_SPARC64)
102 env->mmuregs[0] |= def->mmu_version;
103 cpu_sparc_set_id(env, 0);
104 env->mxccregs[7] |= def->mxcc_version;
105 #else
106 env->mmu_version = def->mmu_version;
107 env->maxtl = def->maxtl;
108 env->version |= def->maxtl << 8;
109 env->version |= def->nwindows - 1;
110 #endif
111 return 0;
114 CPUSPARCState *cpu_sparc_init(const char *cpu_model)
116 SPARCCPU *cpu;
117 CPUSPARCState *env;
119 cpu = SPARC_CPU(object_new(TYPE_SPARC_CPU));
120 env = &cpu->env;
122 gen_intermediate_code_init(env);
124 if (cpu_sparc_register(env, cpu_model) < 0) {
125 object_delete(OBJECT(cpu));
126 return NULL;
128 qemu_init_vcpu(env);
130 return env;
133 void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
135 #if !defined(TARGET_SPARC64)
136 env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
137 #endif
140 static const sparc_def_t sparc_defs[] = {
141 #ifdef TARGET_SPARC64
143 .name = "Fujitsu Sparc64",
144 .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)),
145 .fpu_version = 0x00000000,
146 .mmu_version = mmu_us_12,
147 .nwindows = 4,
148 .maxtl = 4,
149 .features = CPU_DEFAULT_FEATURES,
152 .name = "Fujitsu Sparc64 III",
153 .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)),
154 .fpu_version = 0x00000000,
155 .mmu_version = mmu_us_12,
156 .nwindows = 5,
157 .maxtl = 4,
158 .features = CPU_DEFAULT_FEATURES,
161 .name = "Fujitsu Sparc64 IV",
162 .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)),
163 .fpu_version = 0x00000000,
164 .mmu_version = mmu_us_12,
165 .nwindows = 8,
166 .maxtl = 5,
167 .features = CPU_DEFAULT_FEATURES,
170 .name = "Fujitsu Sparc64 V",
171 .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)),
172 .fpu_version = 0x00000000,
173 .mmu_version = mmu_us_12,
174 .nwindows = 8,
175 .maxtl = 5,
176 .features = CPU_DEFAULT_FEATURES,
179 .name = "TI UltraSparc I",
180 .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
181 .fpu_version = 0x00000000,
182 .mmu_version = mmu_us_12,
183 .nwindows = 8,
184 .maxtl = 5,
185 .features = CPU_DEFAULT_FEATURES,
188 .name = "TI UltraSparc II",
189 .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)),
190 .fpu_version = 0x00000000,
191 .mmu_version = mmu_us_12,
192 .nwindows = 8,
193 .maxtl = 5,
194 .features = CPU_DEFAULT_FEATURES,
197 .name = "TI UltraSparc IIi",
198 .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)),
199 .fpu_version = 0x00000000,
200 .mmu_version = mmu_us_12,
201 .nwindows = 8,
202 .maxtl = 5,
203 .features = CPU_DEFAULT_FEATURES,
206 .name = "TI UltraSparc IIe",
207 .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)),
208 .fpu_version = 0x00000000,
209 .mmu_version = mmu_us_12,
210 .nwindows = 8,
211 .maxtl = 5,
212 .features = CPU_DEFAULT_FEATURES,
215 .name = "Sun UltraSparc III",
216 .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)),
217 .fpu_version = 0x00000000,
218 .mmu_version = mmu_us_12,
219 .nwindows = 8,
220 .maxtl = 5,
221 .features = CPU_DEFAULT_FEATURES,
224 .name = "Sun UltraSparc III Cu",
225 .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)),
226 .fpu_version = 0x00000000,
227 .mmu_version = mmu_us_3,
228 .nwindows = 8,
229 .maxtl = 5,
230 .features = CPU_DEFAULT_FEATURES,
233 .name = "Sun UltraSparc IIIi",
234 .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)),
235 .fpu_version = 0x00000000,
236 .mmu_version = mmu_us_12,
237 .nwindows = 8,
238 .maxtl = 5,
239 .features = CPU_DEFAULT_FEATURES,
242 .name = "Sun UltraSparc IV",
243 .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)),
244 .fpu_version = 0x00000000,
245 .mmu_version = mmu_us_4,
246 .nwindows = 8,
247 .maxtl = 5,
248 .features = CPU_DEFAULT_FEATURES,
251 .name = "Sun UltraSparc IV+",
252 .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)),
253 .fpu_version = 0x00000000,
254 .mmu_version = mmu_us_12,
255 .nwindows = 8,
256 .maxtl = 5,
257 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT,
260 .name = "Sun UltraSparc IIIi+",
261 .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)),
262 .fpu_version = 0x00000000,
263 .mmu_version = mmu_us_3,
264 .nwindows = 8,
265 .maxtl = 5,
266 .features = CPU_DEFAULT_FEATURES,
269 .name = "Sun UltraSparc T1",
270 /* defined in sparc_ifu_fdp.v and ctu.h */
271 .iu_version = ((0x3eULL << 48) | (0x23ULL << 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 = "Sun UltraSparc T2",
281 /* defined in tlu_asi_ctl.v and n2_revid_cust.v */
282 .iu_version = ((0x3eULL << 48) | (0x24ULL << 32) | (0x02ULL << 24)),
283 .fpu_version = 0x00000000,
284 .mmu_version = mmu_sun4v,
285 .nwindows = 8,
286 .maxtl = 6,
287 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
288 | CPU_FEATURE_GL,
291 .name = "NEC UltraSparc I",
292 .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
293 .fpu_version = 0x00000000,
294 .mmu_version = mmu_us_12,
295 .nwindows = 8,
296 .maxtl = 5,
297 .features = CPU_DEFAULT_FEATURES,
299 #else
301 .name = "Fujitsu MB86900",
302 .iu_version = 0x00 << 24, /* Impl 0, ver 0 */
303 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
304 .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */
305 .mmu_bm = 0x00004000,
306 .mmu_ctpr_mask = 0x007ffff0,
307 .mmu_cxr_mask = 0x0000003f,
308 .mmu_sfsr_mask = 0xffffffff,
309 .mmu_trcr_mask = 0xffffffff,
310 .nwindows = 7,
311 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_FSMULD,
314 .name = "Fujitsu MB86904",
315 .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
316 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
317 .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
318 .mmu_bm = 0x00004000,
319 .mmu_ctpr_mask = 0x00ffffc0,
320 .mmu_cxr_mask = 0x000000ff,
321 .mmu_sfsr_mask = 0x00016fff,
322 .mmu_trcr_mask = 0x00ffffff,
323 .nwindows = 8,
324 .features = CPU_DEFAULT_FEATURES,
327 .name = "Fujitsu MB86907",
328 .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
329 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
330 .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
331 .mmu_bm = 0x00004000,
332 .mmu_ctpr_mask = 0xffffffc0,
333 .mmu_cxr_mask = 0x000000ff,
334 .mmu_sfsr_mask = 0x00016fff,
335 .mmu_trcr_mask = 0xffffffff,
336 .nwindows = 8,
337 .features = CPU_DEFAULT_FEATURES,
340 .name = "LSI L64811",
341 .iu_version = 0x10 << 24, /* Impl 1, ver 0 */
342 .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */
343 .mmu_version = 0x10 << 24,
344 .mmu_bm = 0x00004000,
345 .mmu_ctpr_mask = 0x007ffff0,
346 .mmu_cxr_mask = 0x0000003f,
347 .mmu_sfsr_mask = 0xffffffff,
348 .mmu_trcr_mask = 0xffffffff,
349 .nwindows = 8,
350 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
351 CPU_FEATURE_FSMULD,
354 .name = "Cypress CY7C601",
355 .iu_version = 0x11 << 24, /* Impl 1, ver 1 */
356 .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
357 .mmu_version = 0x10 << 24,
358 .mmu_bm = 0x00004000,
359 .mmu_ctpr_mask = 0x007ffff0,
360 .mmu_cxr_mask = 0x0000003f,
361 .mmu_sfsr_mask = 0xffffffff,
362 .mmu_trcr_mask = 0xffffffff,
363 .nwindows = 8,
364 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
365 CPU_FEATURE_FSMULD,
368 .name = "Cypress CY7C611",
369 .iu_version = 0x13 << 24, /* Impl 1, ver 3 */
370 .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
371 .mmu_version = 0x10 << 24,
372 .mmu_bm = 0x00004000,
373 .mmu_ctpr_mask = 0x007ffff0,
374 .mmu_cxr_mask = 0x0000003f,
375 .mmu_sfsr_mask = 0xffffffff,
376 .mmu_trcr_mask = 0xffffffff,
377 .nwindows = 8,
378 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
379 CPU_FEATURE_FSMULD,
382 .name = "TI MicroSparc I",
383 .iu_version = 0x41000000,
384 .fpu_version = 4 << 17,
385 .mmu_version = 0x41000000,
386 .mmu_bm = 0x00004000,
387 .mmu_ctpr_mask = 0x007ffff0,
388 .mmu_cxr_mask = 0x0000003f,
389 .mmu_sfsr_mask = 0x00016fff,
390 .mmu_trcr_mask = 0x0000003f,
391 .nwindows = 7,
392 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL |
393 CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT |
394 CPU_FEATURE_FMUL,
397 .name = "TI MicroSparc II",
398 .iu_version = 0x42000000,
399 .fpu_version = 4 << 17,
400 .mmu_version = 0x02000000,
401 .mmu_bm = 0x00004000,
402 .mmu_ctpr_mask = 0x00ffffc0,
403 .mmu_cxr_mask = 0x000000ff,
404 .mmu_sfsr_mask = 0x00016fff,
405 .mmu_trcr_mask = 0x00ffffff,
406 .nwindows = 8,
407 .features = CPU_DEFAULT_FEATURES,
410 .name = "TI MicroSparc IIep",
411 .iu_version = 0x42000000,
412 .fpu_version = 4 << 17,
413 .mmu_version = 0x04000000,
414 .mmu_bm = 0x00004000,
415 .mmu_ctpr_mask = 0x00ffffc0,
416 .mmu_cxr_mask = 0x000000ff,
417 .mmu_sfsr_mask = 0x00016bff,
418 .mmu_trcr_mask = 0x00ffffff,
419 .nwindows = 8,
420 .features = CPU_DEFAULT_FEATURES,
423 .name = "TI SuperSparc 40", /* STP1020NPGA */
424 .iu_version = 0x41000000, /* SuperSPARC 2.x */
425 .fpu_version = 0 << 17,
426 .mmu_version = 0x00000800, /* SuperSPARC 2.x, no MXCC */
427 .mmu_bm = 0x00002000,
428 .mmu_ctpr_mask = 0xffffffc0,
429 .mmu_cxr_mask = 0x0000ffff,
430 .mmu_sfsr_mask = 0xffffffff,
431 .mmu_trcr_mask = 0xffffffff,
432 .nwindows = 8,
433 .features = CPU_DEFAULT_FEATURES,
436 .name = "TI SuperSparc 50", /* STP1020PGA */
437 .iu_version = 0x40000000, /* SuperSPARC 3.x */
438 .fpu_version = 0 << 17,
439 .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
440 .mmu_bm = 0x00002000,
441 .mmu_ctpr_mask = 0xffffffc0,
442 .mmu_cxr_mask = 0x0000ffff,
443 .mmu_sfsr_mask = 0xffffffff,
444 .mmu_trcr_mask = 0xffffffff,
445 .nwindows = 8,
446 .features = CPU_DEFAULT_FEATURES,
449 .name = "TI SuperSparc 51",
450 .iu_version = 0x40000000, /* SuperSPARC 3.x */
451 .fpu_version = 0 << 17,
452 .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
453 .mmu_bm = 0x00002000,
454 .mmu_ctpr_mask = 0xffffffc0,
455 .mmu_cxr_mask = 0x0000ffff,
456 .mmu_sfsr_mask = 0xffffffff,
457 .mmu_trcr_mask = 0xffffffff,
458 .mxcc_version = 0x00000104,
459 .nwindows = 8,
460 .features = CPU_DEFAULT_FEATURES,
463 .name = "TI SuperSparc 60", /* STP1020APGA */
464 .iu_version = 0x40000000, /* SuperSPARC 3.x */
465 .fpu_version = 0 << 17,
466 .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
467 .mmu_bm = 0x00002000,
468 .mmu_ctpr_mask = 0xffffffc0,
469 .mmu_cxr_mask = 0x0000ffff,
470 .mmu_sfsr_mask = 0xffffffff,
471 .mmu_trcr_mask = 0xffffffff,
472 .nwindows = 8,
473 .features = CPU_DEFAULT_FEATURES,
476 .name = "TI SuperSparc 61",
477 .iu_version = 0x44000000, /* SuperSPARC 3.x */
478 .fpu_version = 0 << 17,
479 .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
480 .mmu_bm = 0x00002000,
481 .mmu_ctpr_mask = 0xffffffc0,
482 .mmu_cxr_mask = 0x0000ffff,
483 .mmu_sfsr_mask = 0xffffffff,
484 .mmu_trcr_mask = 0xffffffff,
485 .mxcc_version = 0x00000104,
486 .nwindows = 8,
487 .features = CPU_DEFAULT_FEATURES,
490 .name = "TI SuperSparc II",
491 .iu_version = 0x40000000, /* SuperSPARC II 1.x */
492 .fpu_version = 0 << 17,
493 .mmu_version = 0x08000000, /* SuperSPARC II 1.x, MXCC */
494 .mmu_bm = 0x00002000,
495 .mmu_ctpr_mask = 0xffffffc0,
496 .mmu_cxr_mask = 0x0000ffff,
497 .mmu_sfsr_mask = 0xffffffff,
498 .mmu_trcr_mask = 0xffffffff,
499 .mxcc_version = 0x00000104,
500 .nwindows = 8,
501 .features = CPU_DEFAULT_FEATURES,
504 .name = "Ross RT625",
505 .iu_version = 0x1e000000,
506 .fpu_version = 1 << 17,
507 .mmu_version = 0x1e000000,
508 .mmu_bm = 0x00004000,
509 .mmu_ctpr_mask = 0x007ffff0,
510 .mmu_cxr_mask = 0x0000003f,
511 .mmu_sfsr_mask = 0xffffffff,
512 .mmu_trcr_mask = 0xffffffff,
513 .nwindows = 8,
514 .features = CPU_DEFAULT_FEATURES,
517 .name = "Ross RT620",
518 .iu_version = 0x1f000000,
519 .fpu_version = 1 << 17,
520 .mmu_version = 0x1f000000,
521 .mmu_bm = 0x00004000,
522 .mmu_ctpr_mask = 0x007ffff0,
523 .mmu_cxr_mask = 0x0000003f,
524 .mmu_sfsr_mask = 0xffffffff,
525 .mmu_trcr_mask = 0xffffffff,
526 .nwindows = 8,
527 .features = CPU_DEFAULT_FEATURES,
530 .name = "BIT B5010",
531 .iu_version = 0x20000000,
532 .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
533 .mmu_version = 0x20000000,
534 .mmu_bm = 0x00004000,
535 .mmu_ctpr_mask = 0x007ffff0,
536 .mmu_cxr_mask = 0x0000003f,
537 .mmu_sfsr_mask = 0xffffffff,
538 .mmu_trcr_mask = 0xffffffff,
539 .nwindows = 8,
540 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
541 CPU_FEATURE_FSMULD,
544 .name = "Matsushita MN10501",
545 .iu_version = 0x50000000,
546 .fpu_version = 0 << 17,
547 .mmu_version = 0x50000000,
548 .mmu_bm = 0x00004000,
549 .mmu_ctpr_mask = 0x007ffff0,
550 .mmu_cxr_mask = 0x0000003f,
551 .mmu_sfsr_mask = 0xffffffff,
552 .mmu_trcr_mask = 0xffffffff,
553 .nwindows = 8,
554 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_MUL | CPU_FEATURE_FSQRT |
555 CPU_FEATURE_FSMULD,
558 .name = "Weitek W8601",
559 .iu_version = 0x90 << 24, /* Impl 9, ver 0 */
560 .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */
561 .mmu_version = 0x10 << 24,
562 .mmu_bm = 0x00004000,
563 .mmu_ctpr_mask = 0x007ffff0,
564 .mmu_cxr_mask = 0x0000003f,
565 .mmu_sfsr_mask = 0xffffffff,
566 .mmu_trcr_mask = 0xffffffff,
567 .nwindows = 8,
568 .features = CPU_DEFAULT_FEATURES,
571 .name = "LEON2",
572 .iu_version = 0xf2000000,
573 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
574 .mmu_version = 0xf2000000,
575 .mmu_bm = 0x00004000,
576 .mmu_ctpr_mask = 0x007ffff0,
577 .mmu_cxr_mask = 0x0000003f,
578 .mmu_sfsr_mask = 0xffffffff,
579 .mmu_trcr_mask = 0xffffffff,
580 .nwindows = 8,
581 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN,
584 .name = "LEON3",
585 .iu_version = 0xf3000000,
586 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
587 .mmu_version = 0xf3000000,
588 .mmu_bm = 0x00000000,
589 .mmu_ctpr_mask = 0x007ffff0,
590 .mmu_cxr_mask = 0x0000003f,
591 .mmu_sfsr_mask = 0xffffffff,
592 .mmu_trcr_mask = 0xffffffff,
593 .nwindows = 8,
594 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN |
595 CPU_FEATURE_ASR17 | CPU_FEATURE_CACHE_CTRL,
597 #endif
600 static const char * const feature_name[] = {
601 "float",
602 "float128",
603 "swap",
604 "mul",
605 "div",
606 "flush",
607 "fsqrt",
608 "fmul",
609 "vis1",
610 "vis2",
611 "fsmuld",
612 "hypv",
613 "cmt",
614 "gl",
617 static void print_features(FILE *f, fprintf_function cpu_fprintf,
618 uint32_t features, const char *prefix)
620 unsigned int i;
622 for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
623 if (feature_name[i] && (features & (1 << i))) {
624 if (prefix) {
625 (*cpu_fprintf)(f, "%s", prefix);
627 (*cpu_fprintf)(f, "%s ", feature_name[i]);
632 static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features)
634 unsigned int i;
636 for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
637 if (feature_name[i] && !strcmp(flagname, feature_name[i])) {
638 *features |= 1 << i;
639 return;
642 fprintf(stderr, "CPU feature %s not found\n", flagname);
645 static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
647 unsigned int i;
648 const sparc_def_t *def = NULL;
649 char *s = strdup(cpu_model);
650 char *featurestr, *name = strtok(s, ",");
651 uint32_t plus_features = 0;
652 uint32_t minus_features = 0;
653 uint64_t iu_version;
654 uint32_t fpu_version, mmu_version, nwindows;
656 for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
657 if (strcasecmp(name, sparc_defs[i].name) == 0) {
658 def = &sparc_defs[i];
661 if (!def) {
662 goto error;
664 memcpy(cpu_def, def, sizeof(*def));
666 featurestr = strtok(NULL, ",");
667 while (featurestr) {
668 char *val;
670 if (featurestr[0] == '+') {
671 add_flagname_to_bitmaps(featurestr + 1, &plus_features);
672 } else if (featurestr[0] == '-') {
673 add_flagname_to_bitmaps(featurestr + 1, &minus_features);
674 } else if ((val = strchr(featurestr, '='))) {
675 *val = 0; val++;
676 if (!strcmp(featurestr, "iu_version")) {
677 char *err;
679 iu_version = strtoll(val, &err, 0);
680 if (!*val || *err) {
681 fprintf(stderr, "bad numerical value %s\n", val);
682 goto error;
684 cpu_def->iu_version = iu_version;
685 #ifdef DEBUG_FEATURES
686 fprintf(stderr, "iu_version %" PRIx64 "\n", iu_version);
687 #endif
688 } else if (!strcmp(featurestr, "fpu_version")) {
689 char *err;
691 fpu_version = strtol(val, &err, 0);
692 if (!*val || *err) {
693 fprintf(stderr, "bad numerical value %s\n", val);
694 goto error;
696 cpu_def->fpu_version = fpu_version;
697 #ifdef DEBUG_FEATURES
698 fprintf(stderr, "fpu_version %x\n", fpu_version);
699 #endif
700 } else if (!strcmp(featurestr, "mmu_version")) {
701 char *err;
703 mmu_version = strtol(val, &err, 0);
704 if (!*val || *err) {
705 fprintf(stderr, "bad numerical value %s\n", val);
706 goto error;
708 cpu_def->mmu_version = mmu_version;
709 #ifdef DEBUG_FEATURES
710 fprintf(stderr, "mmu_version %x\n", mmu_version);
711 #endif
712 } else if (!strcmp(featurestr, "nwindows")) {
713 char *err;
715 nwindows = strtol(val, &err, 0);
716 if (!*val || *err || nwindows > MAX_NWINDOWS ||
717 nwindows < MIN_NWINDOWS) {
718 fprintf(stderr, "bad numerical value %s\n", val);
719 goto error;
721 cpu_def->nwindows = nwindows;
722 #ifdef DEBUG_FEATURES
723 fprintf(stderr, "nwindows %d\n", nwindows);
724 #endif
725 } else {
726 fprintf(stderr, "unrecognized feature %s\n", featurestr);
727 goto error;
729 } else {
730 fprintf(stderr, "feature string `%s' not in format "
731 "(+feature|-feature|feature=xyz)\n", featurestr);
732 goto error;
734 featurestr = strtok(NULL, ",");
736 cpu_def->features |= plus_features;
737 cpu_def->features &= ~minus_features;
738 #ifdef DEBUG_FEATURES
739 print_features(stderr, fprintf, cpu_def->features, NULL);
740 #endif
741 free(s);
742 return 0;
744 error:
745 free(s);
746 return -1;
749 void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf)
751 unsigned int i;
753 for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
754 (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx
755 " FPU %08x MMU %08x NWINS %d ",
756 sparc_defs[i].name,
757 sparc_defs[i].iu_version,
758 sparc_defs[i].fpu_version,
759 sparc_defs[i].mmu_version,
760 sparc_defs[i].nwindows);
761 print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES &
762 ~sparc_defs[i].features, "-");
763 print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES &
764 sparc_defs[i].features, "+");
765 (*cpu_fprintf)(f, "\n");
767 (*cpu_fprintf)(f, "Default CPU feature flags (use '-' to remove): ");
768 print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES, NULL);
769 (*cpu_fprintf)(f, "\n");
770 (*cpu_fprintf)(f, "Available CPU feature flags (use '+' to add): ");
771 print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES, NULL);
772 (*cpu_fprintf)(f, "\n");
773 (*cpu_fprintf)(f, "Numerical features (use '=' to set): iu_version "
774 "fpu_version mmu_version nwindows\n");
777 static void cpu_print_cc(FILE *f, fprintf_function cpu_fprintf,
778 uint32_t cc)
780 cpu_fprintf(f, "%c%c%c%c", cc & PSR_NEG ? 'N' : '-',
781 cc & PSR_ZERO ? 'Z' : '-', cc & PSR_OVF ? 'V' : '-',
782 cc & PSR_CARRY ? 'C' : '-');
785 #ifdef TARGET_SPARC64
786 #define REGS_PER_LINE 4
787 #else
788 #define REGS_PER_LINE 8
789 #endif
791 void cpu_dump_state(CPUSPARCState *env, FILE *f, fprintf_function cpu_fprintf,
792 int flags)
794 int i, x;
796 cpu_fprintf(f, "pc: " TARGET_FMT_lx " npc: " TARGET_FMT_lx "\n", env->pc,
797 env->npc);
798 cpu_fprintf(f, "General Registers:\n");
800 for (i = 0; i < 8; i++) {
801 if (i % REGS_PER_LINE == 0) {
802 cpu_fprintf(f, "%%g%d-%d:", i, i + REGS_PER_LINE - 1);
804 cpu_fprintf(f, " " TARGET_FMT_lx, env->gregs[i]);
805 if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
806 cpu_fprintf(f, "\n");
809 cpu_fprintf(f, "\nCurrent Register Window:\n");
810 for (x = 0; x < 3; x++) {
811 for (i = 0; i < 8; i++) {
812 if (i % REGS_PER_LINE == 0) {
813 cpu_fprintf(f, "%%%c%d-%d: ",
814 x == 0 ? 'o' : (x == 1 ? 'l' : 'i'),
815 i, i + REGS_PER_LINE - 1);
817 cpu_fprintf(f, TARGET_FMT_lx " ", env->regwptr[i + x * 8]);
818 if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
819 cpu_fprintf(f, "\n");
823 cpu_fprintf(f, "\nFloating Point Registers:\n");
824 for (i = 0; i < TARGET_DPREGS; i++) {
825 if ((i & 3) == 0) {
826 cpu_fprintf(f, "%%f%02d:", i * 2);
828 cpu_fprintf(f, " %016" PRIx64, env->fpr[i].ll);
829 if ((i & 3) == 3) {
830 cpu_fprintf(f, "\n");
833 #ifdef TARGET_SPARC64
834 cpu_fprintf(f, "pstate: %08x ccr: %02x (icc: ", env->pstate,
835 (unsigned)cpu_get_ccr(env));
836 cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << PSR_CARRY_SHIFT);
837 cpu_fprintf(f, " xcc: ");
838 cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << (PSR_CARRY_SHIFT - 4));
839 cpu_fprintf(f, ") asi: %02x tl: %d pil: %x\n", env->asi, env->tl,
840 env->psrpil);
841 cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate: %d "
842 "cleanwin: %d cwp: %d\n",
843 env->cansave, env->canrestore, env->otherwin, env->wstate,
844 env->cleanwin, env->nwindows - 1 - env->cwp);
845 cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: "
846 TARGET_FMT_lx "\n", env->fsr, env->y, env->fprs);
847 #else
848 cpu_fprintf(f, "psr: %08x (icc: ", cpu_get_psr(env));
849 cpu_print_cc(f, cpu_fprintf, cpu_get_psr(env));
850 cpu_fprintf(f, " SPE: %c%c%c) wim: %08x\n", env->psrs ? 'S' : '-',
851 env->psrps ? 'P' : '-', env->psret ? 'E' : '-',
852 env->wim);
853 cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx "\n",
854 env->fsr, env->y);
855 #endif
858 static void sparc_cpu_initfn(Object *obj)
860 SPARCCPU *cpu = SPARC_CPU(obj);
861 CPUSPARCState *env = &cpu->env;
863 cpu_exec_init(env);
866 static void sparc_cpu_uninitfn(Object *obj)
868 SPARCCPU *cpu = SPARC_CPU(obj);
869 CPUSPARCState *env = &cpu->env;
871 g_free(env->def);
874 static void sparc_cpu_class_init(ObjectClass *oc, void *data)
876 SPARCCPUClass *scc = SPARC_CPU_CLASS(oc);
877 CPUClass *cc = CPU_CLASS(oc);
879 scc->parent_reset = cc->reset;
880 cc->reset = sparc_cpu_reset;
883 static const TypeInfo sparc_cpu_type_info = {
884 .name = TYPE_SPARC_CPU,
885 .parent = TYPE_CPU,
886 .instance_size = sizeof(SPARCCPU),
887 .instance_init = sparc_cpu_initfn,
888 .instance_finalize = sparc_cpu_uninitfn,
889 .abstract = false,
890 .class_size = sizeof(SPARCCPUClass),
891 .class_init = sparc_cpu_class_init,
894 static void sparc_cpu_register_types(void)
896 type_register_static(&sparc_cpu_type_info);
899 type_init(sparc_cpu_register_types)