qdev: release parent properties on dc->init failure
[qemu/ar7.git] / target-sparc / cpu.c
blob7ac6bdb05820358c3912f8878db1c06de0d81ac4
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 if (tcg_enabled()) {
123 gen_intermediate_code_init(env);
126 if (cpu_sparc_register(env, cpu_model) < 0) {
127 object_delete(OBJECT(cpu));
128 return NULL;
130 qemu_init_vcpu(env);
132 return env;
135 void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
137 #if !defined(TARGET_SPARC64)
138 env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
139 #endif
142 static const sparc_def_t sparc_defs[] = {
143 #ifdef TARGET_SPARC64
145 .name = "Fujitsu Sparc64",
146 .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)),
147 .fpu_version = 0x00000000,
148 .mmu_version = mmu_us_12,
149 .nwindows = 4,
150 .maxtl = 4,
151 .features = CPU_DEFAULT_FEATURES,
154 .name = "Fujitsu Sparc64 III",
155 .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)),
156 .fpu_version = 0x00000000,
157 .mmu_version = mmu_us_12,
158 .nwindows = 5,
159 .maxtl = 4,
160 .features = CPU_DEFAULT_FEATURES,
163 .name = "Fujitsu Sparc64 IV",
164 .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)),
165 .fpu_version = 0x00000000,
166 .mmu_version = mmu_us_12,
167 .nwindows = 8,
168 .maxtl = 5,
169 .features = CPU_DEFAULT_FEATURES,
172 .name = "Fujitsu Sparc64 V",
173 .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 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 I",
182 .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 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 II",
191 .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 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 IIi",
200 .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)),
201 .fpu_version = 0x00000000,
202 .mmu_version = mmu_us_12,
203 .nwindows = 8,
204 .maxtl = 5,
205 .features = CPU_DEFAULT_FEATURES,
208 .name = "TI UltraSparc IIe",
209 .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 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",
218 .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)),
219 .fpu_version = 0x00000000,
220 .mmu_version = mmu_us_12,
221 .nwindows = 8,
222 .maxtl = 5,
223 .features = CPU_DEFAULT_FEATURES,
226 .name = "Sun UltraSparc III Cu",
227 .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)),
228 .fpu_version = 0x00000000,
229 .mmu_version = mmu_us_3,
230 .nwindows = 8,
231 .maxtl = 5,
232 .features = CPU_DEFAULT_FEATURES,
235 .name = "Sun UltraSparc IIIi",
236 .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)),
237 .fpu_version = 0x00000000,
238 .mmu_version = mmu_us_12,
239 .nwindows = 8,
240 .maxtl = 5,
241 .features = CPU_DEFAULT_FEATURES,
244 .name = "Sun UltraSparc IV",
245 .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)),
246 .fpu_version = 0x00000000,
247 .mmu_version = mmu_us_4,
248 .nwindows = 8,
249 .maxtl = 5,
250 .features = CPU_DEFAULT_FEATURES,
253 .name = "Sun UltraSparc IV+",
254 .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)),
255 .fpu_version = 0x00000000,
256 .mmu_version = mmu_us_12,
257 .nwindows = 8,
258 .maxtl = 5,
259 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT,
262 .name = "Sun UltraSparc IIIi+",
263 .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)),
264 .fpu_version = 0x00000000,
265 .mmu_version = mmu_us_3,
266 .nwindows = 8,
267 .maxtl = 5,
268 .features = CPU_DEFAULT_FEATURES,
271 .name = "Sun UltraSparc T1",
272 /* defined in sparc_ifu_fdp.v and ctu.h */
273 .iu_version = ((0x3eULL << 48) | (0x23ULL << 32) | (0x02ULL << 24)),
274 .fpu_version = 0x00000000,
275 .mmu_version = mmu_sun4v,
276 .nwindows = 8,
277 .maxtl = 6,
278 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
279 | CPU_FEATURE_GL,
282 .name = "Sun UltraSparc T2",
283 /* defined in tlu_asi_ctl.v and n2_revid_cust.v */
284 .iu_version = ((0x3eULL << 48) | (0x24ULL << 32) | (0x02ULL << 24)),
285 .fpu_version = 0x00000000,
286 .mmu_version = mmu_sun4v,
287 .nwindows = 8,
288 .maxtl = 6,
289 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
290 | CPU_FEATURE_GL,
293 .name = "NEC UltraSparc I",
294 .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
295 .fpu_version = 0x00000000,
296 .mmu_version = mmu_us_12,
297 .nwindows = 8,
298 .maxtl = 5,
299 .features = CPU_DEFAULT_FEATURES,
301 #else
303 .name = "Fujitsu MB86900",
304 .iu_version = 0x00 << 24, /* Impl 0, ver 0 */
305 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
306 .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */
307 .mmu_bm = 0x00004000,
308 .mmu_ctpr_mask = 0x007ffff0,
309 .mmu_cxr_mask = 0x0000003f,
310 .mmu_sfsr_mask = 0xffffffff,
311 .mmu_trcr_mask = 0xffffffff,
312 .nwindows = 7,
313 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_FSMULD,
316 .name = "Fujitsu MB86904",
317 .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
318 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
319 .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
320 .mmu_bm = 0x00004000,
321 .mmu_ctpr_mask = 0x00ffffc0,
322 .mmu_cxr_mask = 0x000000ff,
323 .mmu_sfsr_mask = 0x00016fff,
324 .mmu_trcr_mask = 0x00ffffff,
325 .nwindows = 8,
326 .features = CPU_DEFAULT_FEATURES,
329 .name = "Fujitsu MB86907",
330 .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
331 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
332 .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
333 .mmu_bm = 0x00004000,
334 .mmu_ctpr_mask = 0xffffffc0,
335 .mmu_cxr_mask = 0x000000ff,
336 .mmu_sfsr_mask = 0x00016fff,
337 .mmu_trcr_mask = 0xffffffff,
338 .nwindows = 8,
339 .features = CPU_DEFAULT_FEATURES,
342 .name = "LSI L64811",
343 .iu_version = 0x10 << 24, /* Impl 1, ver 0 */
344 .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */
345 .mmu_version = 0x10 << 24,
346 .mmu_bm = 0x00004000,
347 .mmu_ctpr_mask = 0x007ffff0,
348 .mmu_cxr_mask = 0x0000003f,
349 .mmu_sfsr_mask = 0xffffffff,
350 .mmu_trcr_mask = 0xffffffff,
351 .nwindows = 8,
352 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
353 CPU_FEATURE_FSMULD,
356 .name = "Cypress CY7C601",
357 .iu_version = 0x11 << 24, /* Impl 1, ver 1 */
358 .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
359 .mmu_version = 0x10 << 24,
360 .mmu_bm = 0x00004000,
361 .mmu_ctpr_mask = 0x007ffff0,
362 .mmu_cxr_mask = 0x0000003f,
363 .mmu_sfsr_mask = 0xffffffff,
364 .mmu_trcr_mask = 0xffffffff,
365 .nwindows = 8,
366 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
367 CPU_FEATURE_FSMULD,
370 .name = "Cypress CY7C611",
371 .iu_version = 0x13 << 24, /* Impl 1, ver 3 */
372 .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
373 .mmu_version = 0x10 << 24,
374 .mmu_bm = 0x00004000,
375 .mmu_ctpr_mask = 0x007ffff0,
376 .mmu_cxr_mask = 0x0000003f,
377 .mmu_sfsr_mask = 0xffffffff,
378 .mmu_trcr_mask = 0xffffffff,
379 .nwindows = 8,
380 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
381 CPU_FEATURE_FSMULD,
384 .name = "TI MicroSparc I",
385 .iu_version = 0x41000000,
386 .fpu_version = 4 << 17,
387 .mmu_version = 0x41000000,
388 .mmu_bm = 0x00004000,
389 .mmu_ctpr_mask = 0x007ffff0,
390 .mmu_cxr_mask = 0x0000003f,
391 .mmu_sfsr_mask = 0x00016fff,
392 .mmu_trcr_mask = 0x0000003f,
393 .nwindows = 7,
394 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL |
395 CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT |
396 CPU_FEATURE_FMUL,
399 .name = "TI MicroSparc II",
400 .iu_version = 0x42000000,
401 .fpu_version = 4 << 17,
402 .mmu_version = 0x02000000,
403 .mmu_bm = 0x00004000,
404 .mmu_ctpr_mask = 0x00ffffc0,
405 .mmu_cxr_mask = 0x000000ff,
406 .mmu_sfsr_mask = 0x00016fff,
407 .mmu_trcr_mask = 0x00ffffff,
408 .nwindows = 8,
409 .features = CPU_DEFAULT_FEATURES,
412 .name = "TI MicroSparc IIep",
413 .iu_version = 0x42000000,
414 .fpu_version = 4 << 17,
415 .mmu_version = 0x04000000,
416 .mmu_bm = 0x00004000,
417 .mmu_ctpr_mask = 0x00ffffc0,
418 .mmu_cxr_mask = 0x000000ff,
419 .mmu_sfsr_mask = 0x00016bff,
420 .mmu_trcr_mask = 0x00ffffff,
421 .nwindows = 8,
422 .features = CPU_DEFAULT_FEATURES,
425 .name = "TI SuperSparc 40", /* STP1020NPGA */
426 .iu_version = 0x41000000, /* SuperSPARC 2.x */
427 .fpu_version = 0 << 17,
428 .mmu_version = 0x00000800, /* SuperSPARC 2.x, no MXCC */
429 .mmu_bm = 0x00002000,
430 .mmu_ctpr_mask = 0xffffffc0,
431 .mmu_cxr_mask = 0x0000ffff,
432 .mmu_sfsr_mask = 0xffffffff,
433 .mmu_trcr_mask = 0xffffffff,
434 .nwindows = 8,
435 .features = CPU_DEFAULT_FEATURES,
438 .name = "TI SuperSparc 50", /* STP1020PGA */
439 .iu_version = 0x40000000, /* SuperSPARC 3.x */
440 .fpu_version = 0 << 17,
441 .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
442 .mmu_bm = 0x00002000,
443 .mmu_ctpr_mask = 0xffffffc0,
444 .mmu_cxr_mask = 0x0000ffff,
445 .mmu_sfsr_mask = 0xffffffff,
446 .mmu_trcr_mask = 0xffffffff,
447 .nwindows = 8,
448 .features = CPU_DEFAULT_FEATURES,
451 .name = "TI SuperSparc 51",
452 .iu_version = 0x40000000, /* SuperSPARC 3.x */
453 .fpu_version = 0 << 17,
454 .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
455 .mmu_bm = 0x00002000,
456 .mmu_ctpr_mask = 0xffffffc0,
457 .mmu_cxr_mask = 0x0000ffff,
458 .mmu_sfsr_mask = 0xffffffff,
459 .mmu_trcr_mask = 0xffffffff,
460 .mxcc_version = 0x00000104,
461 .nwindows = 8,
462 .features = CPU_DEFAULT_FEATURES,
465 .name = "TI SuperSparc 60", /* STP1020APGA */
466 .iu_version = 0x40000000, /* SuperSPARC 3.x */
467 .fpu_version = 0 << 17,
468 .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
469 .mmu_bm = 0x00002000,
470 .mmu_ctpr_mask = 0xffffffc0,
471 .mmu_cxr_mask = 0x0000ffff,
472 .mmu_sfsr_mask = 0xffffffff,
473 .mmu_trcr_mask = 0xffffffff,
474 .nwindows = 8,
475 .features = CPU_DEFAULT_FEATURES,
478 .name = "TI SuperSparc 61",
479 .iu_version = 0x44000000, /* SuperSPARC 3.x */
480 .fpu_version = 0 << 17,
481 .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
482 .mmu_bm = 0x00002000,
483 .mmu_ctpr_mask = 0xffffffc0,
484 .mmu_cxr_mask = 0x0000ffff,
485 .mmu_sfsr_mask = 0xffffffff,
486 .mmu_trcr_mask = 0xffffffff,
487 .mxcc_version = 0x00000104,
488 .nwindows = 8,
489 .features = CPU_DEFAULT_FEATURES,
492 .name = "TI SuperSparc II",
493 .iu_version = 0x40000000, /* SuperSPARC II 1.x */
494 .fpu_version = 0 << 17,
495 .mmu_version = 0x08000000, /* SuperSPARC II 1.x, MXCC */
496 .mmu_bm = 0x00002000,
497 .mmu_ctpr_mask = 0xffffffc0,
498 .mmu_cxr_mask = 0x0000ffff,
499 .mmu_sfsr_mask = 0xffffffff,
500 .mmu_trcr_mask = 0xffffffff,
501 .mxcc_version = 0x00000104,
502 .nwindows = 8,
503 .features = CPU_DEFAULT_FEATURES,
506 .name = "Ross RT625",
507 .iu_version = 0x1e000000,
508 .fpu_version = 1 << 17,
509 .mmu_version = 0x1e000000,
510 .mmu_bm = 0x00004000,
511 .mmu_ctpr_mask = 0x007ffff0,
512 .mmu_cxr_mask = 0x0000003f,
513 .mmu_sfsr_mask = 0xffffffff,
514 .mmu_trcr_mask = 0xffffffff,
515 .nwindows = 8,
516 .features = CPU_DEFAULT_FEATURES,
519 .name = "Ross RT620",
520 .iu_version = 0x1f000000,
521 .fpu_version = 1 << 17,
522 .mmu_version = 0x1f000000,
523 .mmu_bm = 0x00004000,
524 .mmu_ctpr_mask = 0x007ffff0,
525 .mmu_cxr_mask = 0x0000003f,
526 .mmu_sfsr_mask = 0xffffffff,
527 .mmu_trcr_mask = 0xffffffff,
528 .nwindows = 8,
529 .features = CPU_DEFAULT_FEATURES,
532 .name = "BIT B5010",
533 .iu_version = 0x20000000,
534 .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
535 .mmu_version = 0x20000000,
536 .mmu_bm = 0x00004000,
537 .mmu_ctpr_mask = 0x007ffff0,
538 .mmu_cxr_mask = 0x0000003f,
539 .mmu_sfsr_mask = 0xffffffff,
540 .mmu_trcr_mask = 0xffffffff,
541 .nwindows = 8,
542 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
543 CPU_FEATURE_FSMULD,
546 .name = "Matsushita MN10501",
547 .iu_version = 0x50000000,
548 .fpu_version = 0 << 17,
549 .mmu_version = 0x50000000,
550 .mmu_bm = 0x00004000,
551 .mmu_ctpr_mask = 0x007ffff0,
552 .mmu_cxr_mask = 0x0000003f,
553 .mmu_sfsr_mask = 0xffffffff,
554 .mmu_trcr_mask = 0xffffffff,
555 .nwindows = 8,
556 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_MUL | CPU_FEATURE_FSQRT |
557 CPU_FEATURE_FSMULD,
560 .name = "Weitek W8601",
561 .iu_version = 0x90 << 24, /* Impl 9, ver 0 */
562 .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */
563 .mmu_version = 0x10 << 24,
564 .mmu_bm = 0x00004000,
565 .mmu_ctpr_mask = 0x007ffff0,
566 .mmu_cxr_mask = 0x0000003f,
567 .mmu_sfsr_mask = 0xffffffff,
568 .mmu_trcr_mask = 0xffffffff,
569 .nwindows = 8,
570 .features = CPU_DEFAULT_FEATURES,
573 .name = "LEON2",
574 .iu_version = 0xf2000000,
575 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
576 .mmu_version = 0xf2000000,
577 .mmu_bm = 0x00004000,
578 .mmu_ctpr_mask = 0x007ffff0,
579 .mmu_cxr_mask = 0x0000003f,
580 .mmu_sfsr_mask = 0xffffffff,
581 .mmu_trcr_mask = 0xffffffff,
582 .nwindows = 8,
583 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN,
586 .name = "LEON3",
587 .iu_version = 0xf3000000,
588 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
589 .mmu_version = 0xf3000000,
590 .mmu_bm = 0x00000000,
591 .mmu_ctpr_mask = 0x007ffff0,
592 .mmu_cxr_mask = 0x0000003f,
593 .mmu_sfsr_mask = 0xffffffff,
594 .mmu_trcr_mask = 0xffffffff,
595 .nwindows = 8,
596 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN |
597 CPU_FEATURE_ASR17 | CPU_FEATURE_CACHE_CTRL,
599 #endif
602 static const char * const feature_name[] = {
603 "float",
604 "float128",
605 "swap",
606 "mul",
607 "div",
608 "flush",
609 "fsqrt",
610 "fmul",
611 "vis1",
612 "vis2",
613 "fsmuld",
614 "hypv",
615 "cmt",
616 "gl",
619 static void print_features(FILE *f, fprintf_function cpu_fprintf,
620 uint32_t features, const char *prefix)
622 unsigned int i;
624 for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
625 if (feature_name[i] && (features & (1 << i))) {
626 if (prefix) {
627 (*cpu_fprintf)(f, "%s", prefix);
629 (*cpu_fprintf)(f, "%s ", feature_name[i]);
634 static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features)
636 unsigned int i;
638 for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
639 if (feature_name[i] && !strcmp(flagname, feature_name[i])) {
640 *features |= 1 << i;
641 return;
644 fprintf(stderr, "CPU feature %s not found\n", flagname);
647 static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
649 unsigned int i;
650 const sparc_def_t *def = NULL;
651 char *s = strdup(cpu_model);
652 char *featurestr, *name = strtok(s, ",");
653 uint32_t plus_features = 0;
654 uint32_t minus_features = 0;
655 uint64_t iu_version;
656 uint32_t fpu_version, mmu_version, nwindows;
658 for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
659 if (strcasecmp(name, sparc_defs[i].name) == 0) {
660 def = &sparc_defs[i];
663 if (!def) {
664 goto error;
666 memcpy(cpu_def, def, sizeof(*def));
668 featurestr = strtok(NULL, ",");
669 while (featurestr) {
670 char *val;
672 if (featurestr[0] == '+') {
673 add_flagname_to_bitmaps(featurestr + 1, &plus_features);
674 } else if (featurestr[0] == '-') {
675 add_flagname_to_bitmaps(featurestr + 1, &minus_features);
676 } else if ((val = strchr(featurestr, '='))) {
677 *val = 0; val++;
678 if (!strcmp(featurestr, "iu_version")) {
679 char *err;
681 iu_version = strtoll(val, &err, 0);
682 if (!*val || *err) {
683 fprintf(stderr, "bad numerical value %s\n", val);
684 goto error;
686 cpu_def->iu_version = iu_version;
687 #ifdef DEBUG_FEATURES
688 fprintf(stderr, "iu_version %" PRIx64 "\n", iu_version);
689 #endif
690 } else if (!strcmp(featurestr, "fpu_version")) {
691 char *err;
693 fpu_version = strtol(val, &err, 0);
694 if (!*val || *err) {
695 fprintf(stderr, "bad numerical value %s\n", val);
696 goto error;
698 cpu_def->fpu_version = fpu_version;
699 #ifdef DEBUG_FEATURES
700 fprintf(stderr, "fpu_version %x\n", fpu_version);
701 #endif
702 } else if (!strcmp(featurestr, "mmu_version")) {
703 char *err;
705 mmu_version = strtol(val, &err, 0);
706 if (!*val || *err) {
707 fprintf(stderr, "bad numerical value %s\n", val);
708 goto error;
710 cpu_def->mmu_version = mmu_version;
711 #ifdef DEBUG_FEATURES
712 fprintf(stderr, "mmu_version %x\n", mmu_version);
713 #endif
714 } else if (!strcmp(featurestr, "nwindows")) {
715 char *err;
717 nwindows = strtol(val, &err, 0);
718 if (!*val || *err || nwindows > MAX_NWINDOWS ||
719 nwindows < MIN_NWINDOWS) {
720 fprintf(stderr, "bad numerical value %s\n", val);
721 goto error;
723 cpu_def->nwindows = nwindows;
724 #ifdef DEBUG_FEATURES
725 fprintf(stderr, "nwindows %d\n", nwindows);
726 #endif
727 } else {
728 fprintf(stderr, "unrecognized feature %s\n", featurestr);
729 goto error;
731 } else {
732 fprintf(stderr, "feature string `%s' not in format "
733 "(+feature|-feature|feature=xyz)\n", featurestr);
734 goto error;
736 featurestr = strtok(NULL, ",");
738 cpu_def->features |= plus_features;
739 cpu_def->features &= ~minus_features;
740 #ifdef DEBUG_FEATURES
741 print_features(stderr, fprintf, cpu_def->features, NULL);
742 #endif
743 free(s);
744 return 0;
746 error:
747 free(s);
748 return -1;
751 void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf)
753 unsigned int i;
755 for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
756 (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx
757 " FPU %08x MMU %08x NWINS %d ",
758 sparc_defs[i].name,
759 sparc_defs[i].iu_version,
760 sparc_defs[i].fpu_version,
761 sparc_defs[i].mmu_version,
762 sparc_defs[i].nwindows);
763 print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES &
764 ~sparc_defs[i].features, "-");
765 print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES &
766 sparc_defs[i].features, "+");
767 (*cpu_fprintf)(f, "\n");
769 (*cpu_fprintf)(f, "Default CPU feature flags (use '-' to remove): ");
770 print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES, NULL);
771 (*cpu_fprintf)(f, "\n");
772 (*cpu_fprintf)(f, "Available CPU feature flags (use '+' to add): ");
773 print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES, NULL);
774 (*cpu_fprintf)(f, "\n");
775 (*cpu_fprintf)(f, "Numerical features (use '=' to set): iu_version "
776 "fpu_version mmu_version nwindows\n");
779 static void cpu_print_cc(FILE *f, fprintf_function cpu_fprintf,
780 uint32_t cc)
782 cpu_fprintf(f, "%c%c%c%c", cc & PSR_NEG ? 'N' : '-',
783 cc & PSR_ZERO ? 'Z' : '-', cc & PSR_OVF ? 'V' : '-',
784 cc & PSR_CARRY ? 'C' : '-');
787 #ifdef TARGET_SPARC64
788 #define REGS_PER_LINE 4
789 #else
790 #define REGS_PER_LINE 8
791 #endif
793 void cpu_dump_state(CPUSPARCState *env, FILE *f, fprintf_function cpu_fprintf,
794 int flags)
796 int i, x;
798 cpu_fprintf(f, "pc: " TARGET_FMT_lx " npc: " TARGET_FMT_lx "\n", env->pc,
799 env->npc);
800 cpu_fprintf(f, "General Registers:\n");
802 for (i = 0; i < 8; i++) {
803 if (i % REGS_PER_LINE == 0) {
804 cpu_fprintf(f, "%%g%d-%d:", i, i + REGS_PER_LINE - 1);
806 cpu_fprintf(f, " " TARGET_FMT_lx, env->gregs[i]);
807 if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
808 cpu_fprintf(f, "\n");
811 cpu_fprintf(f, "\nCurrent Register Window:\n");
812 for (x = 0; x < 3; x++) {
813 for (i = 0; i < 8; i++) {
814 if (i % REGS_PER_LINE == 0) {
815 cpu_fprintf(f, "%%%c%d-%d: ",
816 x == 0 ? 'o' : (x == 1 ? 'l' : 'i'),
817 i, i + REGS_PER_LINE - 1);
819 cpu_fprintf(f, TARGET_FMT_lx " ", env->regwptr[i + x * 8]);
820 if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
821 cpu_fprintf(f, "\n");
825 cpu_fprintf(f, "\nFloating Point Registers:\n");
826 for (i = 0; i < TARGET_DPREGS; i++) {
827 if ((i & 3) == 0) {
828 cpu_fprintf(f, "%%f%02d:", i * 2);
830 cpu_fprintf(f, " %016" PRIx64, env->fpr[i].ll);
831 if ((i & 3) == 3) {
832 cpu_fprintf(f, "\n");
835 #ifdef TARGET_SPARC64
836 cpu_fprintf(f, "pstate: %08x ccr: %02x (icc: ", env->pstate,
837 (unsigned)cpu_get_ccr(env));
838 cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << PSR_CARRY_SHIFT);
839 cpu_fprintf(f, " xcc: ");
840 cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << (PSR_CARRY_SHIFT - 4));
841 cpu_fprintf(f, ") asi: %02x tl: %d pil: %x\n", env->asi, env->tl,
842 env->psrpil);
843 cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate: %d "
844 "cleanwin: %d cwp: %d\n",
845 env->cansave, env->canrestore, env->otherwin, env->wstate,
846 env->cleanwin, env->nwindows - 1 - env->cwp);
847 cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: "
848 TARGET_FMT_lx "\n", env->fsr, env->y, env->fprs);
849 #else
850 cpu_fprintf(f, "psr: %08x (icc: ", cpu_get_psr(env));
851 cpu_print_cc(f, cpu_fprintf, cpu_get_psr(env));
852 cpu_fprintf(f, " SPE: %c%c%c) wim: %08x\n", env->psrs ? 'S' : '-',
853 env->psrps ? 'P' : '-', env->psret ? 'E' : '-',
854 env->wim);
855 cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx "\n",
856 env->fsr, env->y);
857 #endif
860 static void sparc_cpu_initfn(Object *obj)
862 SPARCCPU *cpu = SPARC_CPU(obj);
863 CPUSPARCState *env = &cpu->env;
865 cpu_exec_init(env);
868 static void sparc_cpu_uninitfn(Object *obj)
870 SPARCCPU *cpu = SPARC_CPU(obj);
871 CPUSPARCState *env = &cpu->env;
873 g_free(env->def);
876 static void sparc_cpu_class_init(ObjectClass *oc, void *data)
878 SPARCCPUClass *scc = SPARC_CPU_CLASS(oc);
879 CPUClass *cc = CPU_CLASS(oc);
881 scc->parent_reset = cc->reset;
882 cc->reset = sparc_cpu_reset;
885 static const TypeInfo sparc_cpu_type_info = {
886 .name = TYPE_SPARC_CPU,
887 .parent = TYPE_CPU,
888 .instance_size = sizeof(SPARCCPU),
889 .instance_init = sparc_cpu_initfn,
890 .instance_finalize = sparc_cpu_uninitfn,
891 .abstract = false,
892 .class_size = sizeof(SPARCCPUClass),
893 .class_init = sparc_cpu_class_init,
896 static void sparc_cpu_register_types(void)
898 type_register_static(&sparc_cpu_type_info);
901 type_init(sparc_cpu_register_types)