hw/i386/pc: format load_linux function
[qemu/ar7.git] / target-sparc / cpu.c
blobab1adfd7ea8b4c3cc45b6e4e048e040724d84a56
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 (cpu_sparc_register(env, cpu_model) < 0) {
118 object_unref(OBJECT(cpu));
119 return NULL;
122 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
124 return cpu;
127 void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
129 #if !defined(TARGET_SPARC64)
130 env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
131 #endif
134 static const sparc_def_t sparc_defs[] = {
135 #ifdef TARGET_SPARC64
137 .name = "Fujitsu Sparc64",
138 .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)),
139 .fpu_version = 0x00000000,
140 .mmu_version = mmu_us_12,
141 .nwindows = 4,
142 .maxtl = 4,
143 .features = CPU_DEFAULT_FEATURES,
146 .name = "Fujitsu Sparc64 III",
147 .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)),
148 .fpu_version = 0x00000000,
149 .mmu_version = mmu_us_12,
150 .nwindows = 5,
151 .maxtl = 4,
152 .features = CPU_DEFAULT_FEATURES,
155 .name = "Fujitsu Sparc64 IV",
156 .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)),
157 .fpu_version = 0x00000000,
158 .mmu_version = mmu_us_12,
159 .nwindows = 8,
160 .maxtl = 5,
161 .features = CPU_DEFAULT_FEATURES,
164 .name = "Fujitsu Sparc64 V",
165 .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)),
166 .fpu_version = 0x00000000,
167 .mmu_version = mmu_us_12,
168 .nwindows = 8,
169 .maxtl = 5,
170 .features = CPU_DEFAULT_FEATURES,
173 .name = "TI UltraSparc I",
174 .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
175 .fpu_version = 0x00000000,
176 .mmu_version = mmu_us_12,
177 .nwindows = 8,
178 .maxtl = 5,
179 .features = CPU_DEFAULT_FEATURES,
182 .name = "TI UltraSparc II",
183 .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)),
184 .fpu_version = 0x00000000,
185 .mmu_version = mmu_us_12,
186 .nwindows = 8,
187 .maxtl = 5,
188 .features = CPU_DEFAULT_FEATURES,
191 .name = "TI UltraSparc IIi",
192 .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)),
193 .fpu_version = 0x00000000,
194 .mmu_version = mmu_us_12,
195 .nwindows = 8,
196 .maxtl = 5,
197 .features = CPU_DEFAULT_FEATURES,
200 .name = "TI UltraSparc IIe",
201 .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)),
202 .fpu_version = 0x00000000,
203 .mmu_version = mmu_us_12,
204 .nwindows = 8,
205 .maxtl = 5,
206 .features = CPU_DEFAULT_FEATURES,
209 .name = "Sun UltraSparc III",
210 .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)),
211 .fpu_version = 0x00000000,
212 .mmu_version = mmu_us_12,
213 .nwindows = 8,
214 .maxtl = 5,
215 .features = CPU_DEFAULT_FEATURES,
218 .name = "Sun UltraSparc III Cu",
219 .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)),
220 .fpu_version = 0x00000000,
221 .mmu_version = mmu_us_3,
222 .nwindows = 8,
223 .maxtl = 5,
224 .features = CPU_DEFAULT_FEATURES,
227 .name = "Sun UltraSparc IIIi",
228 .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)),
229 .fpu_version = 0x00000000,
230 .mmu_version = mmu_us_12,
231 .nwindows = 8,
232 .maxtl = 5,
233 .features = CPU_DEFAULT_FEATURES,
236 .name = "Sun UltraSparc IV",
237 .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)),
238 .fpu_version = 0x00000000,
239 .mmu_version = mmu_us_4,
240 .nwindows = 8,
241 .maxtl = 5,
242 .features = CPU_DEFAULT_FEATURES,
245 .name = "Sun UltraSparc IV+",
246 .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)),
247 .fpu_version = 0x00000000,
248 .mmu_version = mmu_us_12,
249 .nwindows = 8,
250 .maxtl = 5,
251 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT,
254 .name = "Sun UltraSparc IIIi+",
255 .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)),
256 .fpu_version = 0x00000000,
257 .mmu_version = mmu_us_3,
258 .nwindows = 8,
259 .maxtl = 5,
260 .features = CPU_DEFAULT_FEATURES,
263 .name = "Sun UltraSparc T1",
264 /* defined in sparc_ifu_fdp.v and ctu.h */
265 .iu_version = ((0x3eULL << 48) | (0x23ULL << 32) | (0x02ULL << 24)),
266 .fpu_version = 0x00000000,
267 .mmu_version = mmu_sun4v,
268 .nwindows = 8,
269 .maxtl = 6,
270 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
271 | CPU_FEATURE_GL,
274 .name = "Sun UltraSparc T2",
275 /* defined in tlu_asi_ctl.v and n2_revid_cust.v */
276 .iu_version = ((0x3eULL << 48) | (0x24ULL << 32) | (0x02ULL << 24)),
277 .fpu_version = 0x00000000,
278 .mmu_version = mmu_sun4v,
279 .nwindows = 8,
280 .maxtl = 6,
281 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
282 | CPU_FEATURE_GL,
285 .name = "NEC UltraSparc I",
286 .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
287 .fpu_version = 0x00000000,
288 .mmu_version = mmu_us_12,
289 .nwindows = 8,
290 .maxtl = 5,
291 .features = CPU_DEFAULT_FEATURES,
293 #else
295 .name = "Fujitsu MB86900",
296 .iu_version = 0x00 << 24, /* Impl 0, ver 0 */
297 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
298 .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */
299 .mmu_bm = 0x00004000,
300 .mmu_ctpr_mask = 0x007ffff0,
301 .mmu_cxr_mask = 0x0000003f,
302 .mmu_sfsr_mask = 0xffffffff,
303 .mmu_trcr_mask = 0xffffffff,
304 .nwindows = 7,
305 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_FSMULD,
308 .name = "Fujitsu MB86904",
309 .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
310 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
311 .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
312 .mmu_bm = 0x00004000,
313 .mmu_ctpr_mask = 0x00ffffc0,
314 .mmu_cxr_mask = 0x000000ff,
315 .mmu_sfsr_mask = 0x00016fff,
316 .mmu_trcr_mask = 0x00ffffff,
317 .nwindows = 8,
318 .features = CPU_DEFAULT_FEATURES,
321 .name = "Fujitsu MB86907",
322 .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
323 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
324 .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
325 .mmu_bm = 0x00004000,
326 .mmu_ctpr_mask = 0xffffffc0,
327 .mmu_cxr_mask = 0x000000ff,
328 .mmu_sfsr_mask = 0x00016fff,
329 .mmu_trcr_mask = 0xffffffff,
330 .nwindows = 8,
331 .features = CPU_DEFAULT_FEATURES,
334 .name = "LSI L64811",
335 .iu_version = 0x10 << 24, /* Impl 1, ver 0 */
336 .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */
337 .mmu_version = 0x10 << 24,
338 .mmu_bm = 0x00004000,
339 .mmu_ctpr_mask = 0x007ffff0,
340 .mmu_cxr_mask = 0x0000003f,
341 .mmu_sfsr_mask = 0xffffffff,
342 .mmu_trcr_mask = 0xffffffff,
343 .nwindows = 8,
344 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
345 CPU_FEATURE_FSMULD,
348 .name = "Cypress CY7C601",
349 .iu_version = 0x11 << 24, /* Impl 1, ver 1 */
350 .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
351 .mmu_version = 0x10 << 24,
352 .mmu_bm = 0x00004000,
353 .mmu_ctpr_mask = 0x007ffff0,
354 .mmu_cxr_mask = 0x0000003f,
355 .mmu_sfsr_mask = 0xffffffff,
356 .mmu_trcr_mask = 0xffffffff,
357 .nwindows = 8,
358 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
359 CPU_FEATURE_FSMULD,
362 .name = "Cypress CY7C611",
363 .iu_version = 0x13 << 24, /* Impl 1, ver 3 */
364 .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
365 .mmu_version = 0x10 << 24,
366 .mmu_bm = 0x00004000,
367 .mmu_ctpr_mask = 0x007ffff0,
368 .mmu_cxr_mask = 0x0000003f,
369 .mmu_sfsr_mask = 0xffffffff,
370 .mmu_trcr_mask = 0xffffffff,
371 .nwindows = 8,
372 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
373 CPU_FEATURE_FSMULD,
376 .name = "TI MicroSparc I",
377 .iu_version = 0x41000000,
378 .fpu_version = 4 << 17,
379 .mmu_version = 0x41000000,
380 .mmu_bm = 0x00004000,
381 .mmu_ctpr_mask = 0x007ffff0,
382 .mmu_cxr_mask = 0x0000003f,
383 .mmu_sfsr_mask = 0x00016fff,
384 .mmu_trcr_mask = 0x0000003f,
385 .nwindows = 7,
386 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL |
387 CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT |
388 CPU_FEATURE_FMUL,
391 .name = "TI MicroSparc II",
392 .iu_version = 0x42000000,
393 .fpu_version = 4 << 17,
394 .mmu_version = 0x02000000,
395 .mmu_bm = 0x00004000,
396 .mmu_ctpr_mask = 0x00ffffc0,
397 .mmu_cxr_mask = 0x000000ff,
398 .mmu_sfsr_mask = 0x00016fff,
399 .mmu_trcr_mask = 0x00ffffff,
400 .nwindows = 8,
401 .features = CPU_DEFAULT_FEATURES,
404 .name = "TI MicroSparc IIep",
405 .iu_version = 0x42000000,
406 .fpu_version = 4 << 17,
407 .mmu_version = 0x04000000,
408 .mmu_bm = 0x00004000,
409 .mmu_ctpr_mask = 0x00ffffc0,
410 .mmu_cxr_mask = 0x000000ff,
411 .mmu_sfsr_mask = 0x00016bff,
412 .mmu_trcr_mask = 0x00ffffff,
413 .nwindows = 8,
414 .features = CPU_DEFAULT_FEATURES,
417 .name = "TI SuperSparc 40", /* STP1020NPGA */
418 .iu_version = 0x41000000, /* SuperSPARC 2.x */
419 .fpu_version = 0 << 17,
420 .mmu_version = 0x00000800, /* SuperSPARC 2.x, no MXCC */
421 .mmu_bm = 0x00002000,
422 .mmu_ctpr_mask = 0xffffffc0,
423 .mmu_cxr_mask = 0x0000ffff,
424 .mmu_sfsr_mask = 0xffffffff,
425 .mmu_trcr_mask = 0xffffffff,
426 .nwindows = 8,
427 .features = CPU_DEFAULT_FEATURES,
430 .name = "TI SuperSparc 50", /* STP1020PGA */
431 .iu_version = 0x40000000, /* SuperSPARC 3.x */
432 .fpu_version = 0 << 17,
433 .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
434 .mmu_bm = 0x00002000,
435 .mmu_ctpr_mask = 0xffffffc0,
436 .mmu_cxr_mask = 0x0000ffff,
437 .mmu_sfsr_mask = 0xffffffff,
438 .mmu_trcr_mask = 0xffffffff,
439 .nwindows = 8,
440 .features = CPU_DEFAULT_FEATURES,
443 .name = "TI SuperSparc 51",
444 .iu_version = 0x40000000, /* SuperSPARC 3.x */
445 .fpu_version = 0 << 17,
446 .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
447 .mmu_bm = 0x00002000,
448 .mmu_ctpr_mask = 0xffffffc0,
449 .mmu_cxr_mask = 0x0000ffff,
450 .mmu_sfsr_mask = 0xffffffff,
451 .mmu_trcr_mask = 0xffffffff,
452 .mxcc_version = 0x00000104,
453 .nwindows = 8,
454 .features = CPU_DEFAULT_FEATURES,
457 .name = "TI SuperSparc 60", /* STP1020APGA */
458 .iu_version = 0x40000000, /* SuperSPARC 3.x */
459 .fpu_version = 0 << 17,
460 .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
461 .mmu_bm = 0x00002000,
462 .mmu_ctpr_mask = 0xffffffc0,
463 .mmu_cxr_mask = 0x0000ffff,
464 .mmu_sfsr_mask = 0xffffffff,
465 .mmu_trcr_mask = 0xffffffff,
466 .nwindows = 8,
467 .features = CPU_DEFAULT_FEATURES,
470 .name = "TI SuperSparc 61",
471 .iu_version = 0x44000000, /* SuperSPARC 3.x */
472 .fpu_version = 0 << 17,
473 .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
474 .mmu_bm = 0x00002000,
475 .mmu_ctpr_mask = 0xffffffc0,
476 .mmu_cxr_mask = 0x0000ffff,
477 .mmu_sfsr_mask = 0xffffffff,
478 .mmu_trcr_mask = 0xffffffff,
479 .mxcc_version = 0x00000104,
480 .nwindows = 8,
481 .features = CPU_DEFAULT_FEATURES,
484 .name = "TI SuperSparc II",
485 .iu_version = 0x40000000, /* SuperSPARC II 1.x */
486 .fpu_version = 0 << 17,
487 .mmu_version = 0x08000000, /* SuperSPARC II 1.x, MXCC */
488 .mmu_bm = 0x00002000,
489 .mmu_ctpr_mask = 0xffffffc0,
490 .mmu_cxr_mask = 0x0000ffff,
491 .mmu_sfsr_mask = 0xffffffff,
492 .mmu_trcr_mask = 0xffffffff,
493 .mxcc_version = 0x00000104,
494 .nwindows = 8,
495 .features = CPU_DEFAULT_FEATURES,
498 .name = "Ross RT625",
499 .iu_version = 0x1e000000,
500 .fpu_version = 1 << 17,
501 .mmu_version = 0x1e000000,
502 .mmu_bm = 0x00004000,
503 .mmu_ctpr_mask = 0x007ffff0,
504 .mmu_cxr_mask = 0x0000003f,
505 .mmu_sfsr_mask = 0xffffffff,
506 .mmu_trcr_mask = 0xffffffff,
507 .nwindows = 8,
508 .features = CPU_DEFAULT_FEATURES,
511 .name = "Ross RT620",
512 .iu_version = 0x1f000000,
513 .fpu_version = 1 << 17,
514 .mmu_version = 0x1f000000,
515 .mmu_bm = 0x00004000,
516 .mmu_ctpr_mask = 0x007ffff0,
517 .mmu_cxr_mask = 0x0000003f,
518 .mmu_sfsr_mask = 0xffffffff,
519 .mmu_trcr_mask = 0xffffffff,
520 .nwindows = 8,
521 .features = CPU_DEFAULT_FEATURES,
524 .name = "BIT B5010",
525 .iu_version = 0x20000000,
526 .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
527 .mmu_version = 0x20000000,
528 .mmu_bm = 0x00004000,
529 .mmu_ctpr_mask = 0x007ffff0,
530 .mmu_cxr_mask = 0x0000003f,
531 .mmu_sfsr_mask = 0xffffffff,
532 .mmu_trcr_mask = 0xffffffff,
533 .nwindows = 8,
534 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
535 CPU_FEATURE_FSMULD,
538 .name = "Matsushita MN10501",
539 .iu_version = 0x50000000,
540 .fpu_version = 0 << 17,
541 .mmu_version = 0x50000000,
542 .mmu_bm = 0x00004000,
543 .mmu_ctpr_mask = 0x007ffff0,
544 .mmu_cxr_mask = 0x0000003f,
545 .mmu_sfsr_mask = 0xffffffff,
546 .mmu_trcr_mask = 0xffffffff,
547 .nwindows = 8,
548 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_MUL | CPU_FEATURE_FSQRT |
549 CPU_FEATURE_FSMULD,
552 .name = "Weitek W8601",
553 .iu_version = 0x90 << 24, /* Impl 9, ver 0 */
554 .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */
555 .mmu_version = 0x10 << 24,
556 .mmu_bm = 0x00004000,
557 .mmu_ctpr_mask = 0x007ffff0,
558 .mmu_cxr_mask = 0x0000003f,
559 .mmu_sfsr_mask = 0xffffffff,
560 .mmu_trcr_mask = 0xffffffff,
561 .nwindows = 8,
562 .features = CPU_DEFAULT_FEATURES,
565 .name = "LEON2",
566 .iu_version = 0xf2000000,
567 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
568 .mmu_version = 0xf2000000,
569 .mmu_bm = 0x00004000,
570 .mmu_ctpr_mask = 0x007ffff0,
571 .mmu_cxr_mask = 0x0000003f,
572 .mmu_sfsr_mask = 0xffffffff,
573 .mmu_trcr_mask = 0xffffffff,
574 .nwindows = 8,
575 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN,
578 .name = "LEON3",
579 .iu_version = 0xf3000000,
580 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
581 .mmu_version = 0xf3000000,
582 .mmu_bm = 0x00000000,
583 .mmu_ctpr_mask = 0xfffffffc,
584 .mmu_cxr_mask = 0x000000ff,
585 .mmu_sfsr_mask = 0xffffffff,
586 .mmu_trcr_mask = 0xffffffff,
587 .nwindows = 8,
588 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN |
589 CPU_FEATURE_ASR17 | CPU_FEATURE_CACHE_CTRL | CPU_FEATURE_POWERDOWN,
591 #endif
594 static const char * const feature_name[] = {
595 "float",
596 "float128",
597 "swap",
598 "mul",
599 "div",
600 "flush",
601 "fsqrt",
602 "fmul",
603 "vis1",
604 "vis2",
605 "fsmuld",
606 "hypv",
607 "cmt",
608 "gl",
611 static void print_features(FILE *f, fprintf_function cpu_fprintf,
612 uint32_t features, const char *prefix)
614 unsigned int i;
616 for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
617 if (feature_name[i] && (features & (1 << i))) {
618 if (prefix) {
619 (*cpu_fprintf)(f, "%s", prefix);
621 (*cpu_fprintf)(f, "%s ", feature_name[i]);
626 static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features)
628 unsigned int i;
630 for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
631 if (feature_name[i] && !strcmp(flagname, feature_name[i])) {
632 *features |= 1 << i;
633 return;
636 fprintf(stderr, "CPU feature %s not found\n", flagname);
639 static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
641 unsigned int i;
642 const sparc_def_t *def = NULL;
643 char *s = g_strdup(cpu_model);
644 char *featurestr, *name = strtok(s, ",");
645 uint32_t plus_features = 0;
646 uint32_t minus_features = 0;
647 uint64_t iu_version;
648 uint32_t fpu_version, mmu_version, nwindows;
650 for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
651 if (strcasecmp(name, sparc_defs[i].name) == 0) {
652 def = &sparc_defs[i];
655 if (!def) {
656 goto error;
658 memcpy(cpu_def, def, sizeof(*def));
660 featurestr = strtok(NULL, ",");
661 while (featurestr) {
662 char *val;
664 if (featurestr[0] == '+') {
665 add_flagname_to_bitmaps(featurestr + 1, &plus_features);
666 } else if (featurestr[0] == '-') {
667 add_flagname_to_bitmaps(featurestr + 1, &minus_features);
668 } else if ((val = strchr(featurestr, '='))) {
669 *val = 0; val++;
670 if (!strcmp(featurestr, "iu_version")) {
671 char *err;
673 iu_version = strtoll(val, &err, 0);
674 if (!*val || *err) {
675 fprintf(stderr, "bad numerical value %s\n", val);
676 goto error;
678 cpu_def->iu_version = iu_version;
679 #ifdef DEBUG_FEATURES
680 fprintf(stderr, "iu_version %" PRIx64 "\n", iu_version);
681 #endif
682 } else if (!strcmp(featurestr, "fpu_version")) {
683 char *err;
685 fpu_version = strtol(val, &err, 0);
686 if (!*val || *err) {
687 fprintf(stderr, "bad numerical value %s\n", val);
688 goto error;
690 cpu_def->fpu_version = fpu_version;
691 #ifdef DEBUG_FEATURES
692 fprintf(stderr, "fpu_version %x\n", fpu_version);
693 #endif
694 } else if (!strcmp(featurestr, "mmu_version")) {
695 char *err;
697 mmu_version = strtol(val, &err, 0);
698 if (!*val || *err) {
699 fprintf(stderr, "bad numerical value %s\n", val);
700 goto error;
702 cpu_def->mmu_version = mmu_version;
703 #ifdef DEBUG_FEATURES
704 fprintf(stderr, "mmu_version %x\n", mmu_version);
705 #endif
706 } else if (!strcmp(featurestr, "nwindows")) {
707 char *err;
709 nwindows = strtol(val, &err, 0);
710 if (!*val || *err || nwindows > MAX_NWINDOWS ||
711 nwindows < MIN_NWINDOWS) {
712 fprintf(stderr, "bad numerical value %s\n", val);
713 goto error;
715 cpu_def->nwindows = nwindows;
716 #ifdef DEBUG_FEATURES
717 fprintf(stderr, "nwindows %d\n", nwindows);
718 #endif
719 } else {
720 fprintf(stderr, "unrecognized feature %s\n", featurestr);
721 goto error;
723 } else {
724 fprintf(stderr, "feature string `%s' not in format "
725 "(+feature|-feature|feature=xyz)\n", featurestr);
726 goto error;
728 featurestr = strtok(NULL, ",");
730 cpu_def->features |= plus_features;
731 cpu_def->features &= ~minus_features;
732 #ifdef DEBUG_FEATURES
733 print_features(stderr, fprintf, cpu_def->features, NULL);
734 #endif
735 g_free(s);
736 return 0;
738 error:
739 free(s);
740 return -1;
743 void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf)
745 unsigned int i;
747 for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
748 (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx
749 " FPU %08x MMU %08x NWINS %d ",
750 sparc_defs[i].name,
751 sparc_defs[i].iu_version,
752 sparc_defs[i].fpu_version,
753 sparc_defs[i].mmu_version,
754 sparc_defs[i].nwindows);
755 print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES &
756 ~sparc_defs[i].features, "-");
757 print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES &
758 sparc_defs[i].features, "+");
759 (*cpu_fprintf)(f, "\n");
761 (*cpu_fprintf)(f, "Default CPU feature flags (use '-' to remove): ");
762 print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES, NULL);
763 (*cpu_fprintf)(f, "\n");
764 (*cpu_fprintf)(f, "Available CPU feature flags (use '+' to add): ");
765 print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES, NULL);
766 (*cpu_fprintf)(f, "\n");
767 (*cpu_fprintf)(f, "Numerical features (use '=' to set): iu_version "
768 "fpu_version mmu_version nwindows\n");
771 static void cpu_print_cc(FILE *f, fprintf_function cpu_fprintf,
772 uint32_t cc)
774 cpu_fprintf(f, "%c%c%c%c", cc & PSR_NEG ? 'N' : '-',
775 cc & PSR_ZERO ? 'Z' : '-', cc & PSR_OVF ? 'V' : '-',
776 cc & PSR_CARRY ? 'C' : '-');
779 #ifdef TARGET_SPARC64
780 #define REGS_PER_LINE 4
781 #else
782 #define REGS_PER_LINE 8
783 #endif
785 void cpu_dump_state(CPUSPARCState *env, FILE *f, fprintf_function cpu_fprintf,
786 int flags)
788 int i, x;
790 cpu_fprintf(f, "pc: " TARGET_FMT_lx " npc: " TARGET_FMT_lx "\n", env->pc,
791 env->npc);
793 for (i = 0; i < 8; i++) {
794 if (i % REGS_PER_LINE == 0) {
795 cpu_fprintf(f, "%%g%d-%d:", i, i + REGS_PER_LINE - 1);
797 cpu_fprintf(f, " " TARGET_FMT_lx, env->gregs[i]);
798 if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
799 cpu_fprintf(f, "\n");
802 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");
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
848 cpu_fprintf(f, "\n");
851 static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
853 SPARCCPU *cpu = SPARC_CPU(dev);
854 SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(dev);
856 qemu_init_vcpu(&cpu->env);
858 scc->parent_realize(dev, errp);
861 static void sparc_cpu_initfn(Object *obj)
863 CPUState *cs = CPU(obj);
864 SPARCCPU *cpu = SPARC_CPU(obj);
865 CPUSPARCState *env = &cpu->env;
867 cs->env_ptr = env;
868 cpu_exec_init(env);
870 if (tcg_enabled()) {
871 gen_intermediate_code_init(env);
875 static void sparc_cpu_uninitfn(Object *obj)
877 SPARCCPU *cpu = SPARC_CPU(obj);
878 CPUSPARCState *env = &cpu->env;
880 g_free(env->def);
883 static void sparc_cpu_class_init(ObjectClass *oc, void *data)
885 SPARCCPUClass *scc = SPARC_CPU_CLASS(oc);
886 CPUClass *cc = CPU_CLASS(oc);
887 DeviceClass *dc = DEVICE_CLASS(oc);
889 scc->parent_realize = dc->realize;
890 dc->realize = sparc_cpu_realizefn;
892 scc->parent_reset = cc->reset;
893 cc->reset = sparc_cpu_reset;
895 cc->do_interrupt = sparc_cpu_do_interrupt;
898 static const TypeInfo sparc_cpu_type_info = {
899 .name = TYPE_SPARC_CPU,
900 .parent = TYPE_CPU,
901 .instance_size = sizeof(SPARCCPU),
902 .instance_init = sparc_cpu_initfn,
903 .instance_finalize = sparc_cpu_uninitfn,
904 .abstract = false,
905 .class_size = sizeof(SPARCCPUClass),
906 .class_init = sparc_cpu_class_init,
909 static void sparc_cpu_register_types(void)
911 type_register_static(&sparc_cpu_type_info);
914 type_init(sparc_cpu_register_types)