2 * PowerPC CPU initialization for qemu.
4 * Copyright (c) 2003-2007 Jocelyn Mayer
5 * Copyright 2011 Freescale Semiconductor, Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "disas/dis-asm.h"
22 #include "exec/gdbstub.h"
24 #include "sysemu/arch_init.h"
25 #include "sysemu/cpus.h"
26 #include "sysemu/hw_accel.h"
27 #include "sysemu/tcg.h"
28 #include "cpu-models.h"
29 #include "mmu-hash32.h"
30 #include "mmu-hash64.h"
31 #include "qemu/error-report.h"
32 #include "qemu/module.h"
33 #include "qemu/qemu-print.h"
34 #include "qapi/error.h"
35 #include "qapi/qmp/qnull.h"
36 #include "qapi/visitor.h"
37 #include "hw/qdev-properties.h"
38 #include "hw/ppc/ppc.h"
39 #include "mmu-book3s-v3.h"
40 #include "sysemu/qtest.h"
41 #include "qemu/cutils.h"
42 #include "disas/capstone.h"
43 #include "fpu/softfloat.h"
44 #include "qapi/qapi-commands-machine-target.h"
46 /* #define PPC_DUMP_CPU */
47 /* #define PPC_DEBUG_SPR */
48 /* #define PPC_DUMP_SPR_ACCESSES */
49 /* #define USE_APPLE_GDB */
53 * do nothing but store/retrieve spr value
55 static void spr_load_dump_spr(int sprn)
57 #ifdef PPC_DUMP_SPR_ACCESSES
58 TCGv_i32 t0 = tcg_const_i32(sprn);
59 gen_helper_load_dump_spr(cpu_env, t0);
60 tcg_temp_free_i32(t0);
64 static void spr_read_generic(DisasContext *ctx, int gprn, int sprn)
66 gen_load_spr(cpu_gpr[gprn], sprn);
67 spr_load_dump_spr(sprn);
70 static void spr_store_dump_spr(int sprn)
72 #ifdef PPC_DUMP_SPR_ACCESSES
73 TCGv_i32 t0 = tcg_const_i32(sprn);
74 gen_helper_store_dump_spr(cpu_env, t0);
75 tcg_temp_free_i32(t0);
79 static void spr_write_generic(DisasContext *ctx, int sprn, int gprn)
81 gen_store_spr(sprn, cpu_gpr[gprn]);
82 spr_store_dump_spr(sprn);
85 #if !defined(CONFIG_USER_ONLY)
86 static void spr_write_generic32(DisasContext *ctx, int sprn, int gprn)
89 TCGv t0 = tcg_temp_new();
90 tcg_gen_ext32u_tl(t0, cpu_gpr[gprn]);
91 gen_store_spr(sprn, t0);
93 spr_store_dump_spr(sprn);
95 spr_write_generic(ctx, sprn, gprn);
99 static void spr_write_clear(DisasContext *ctx, int sprn, int gprn)
101 TCGv t0 = tcg_temp_new();
102 TCGv t1 = tcg_temp_new();
103 gen_load_spr(t0, sprn);
104 tcg_gen_neg_tl(t1, cpu_gpr[gprn]);
105 tcg_gen_and_tl(t0, t0, t1);
106 gen_store_spr(sprn, t0);
111 static void spr_access_nop(DisasContext *ctx, int sprn, int gprn)
117 /* SPR common to all PowerPC */
119 static void spr_read_xer(DisasContext *ctx, int gprn, int sprn)
121 gen_read_xer(ctx, cpu_gpr[gprn]);
124 static void spr_write_xer(DisasContext *ctx, int sprn, int gprn)
126 gen_write_xer(cpu_gpr[gprn]);
130 static void spr_read_lr(DisasContext *ctx, int gprn, int sprn)
132 tcg_gen_mov_tl(cpu_gpr[gprn], cpu_lr);
135 static void spr_write_lr(DisasContext *ctx, int sprn, int gprn)
137 tcg_gen_mov_tl(cpu_lr, cpu_gpr[gprn]);
141 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
142 static void spr_read_cfar(DisasContext *ctx, int gprn, int sprn)
144 tcg_gen_mov_tl(cpu_gpr[gprn], cpu_cfar);
147 static void spr_write_cfar(DisasContext *ctx, int sprn, int gprn)
149 tcg_gen_mov_tl(cpu_cfar, cpu_gpr[gprn]);
151 #endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
154 static void spr_read_ctr(DisasContext *ctx, int gprn, int sprn)
156 tcg_gen_mov_tl(cpu_gpr[gprn], cpu_ctr);
159 static void spr_write_ctr(DisasContext *ctx, int sprn, int gprn)
161 tcg_gen_mov_tl(cpu_ctr, cpu_gpr[gprn]);
164 /* User read access to SPR */
170 static void spr_read_ureg(DisasContext *ctx, int gprn, int sprn)
172 gen_load_spr(cpu_gpr[gprn], sprn + 0x10);
175 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
176 static void spr_write_ureg(DisasContext *ctx, int sprn, int gprn)
178 gen_store_spr(sprn + 0x10, cpu_gpr[gprn]);
182 /* SPR common to all non-embedded PowerPC */
184 #if !defined(CONFIG_USER_ONLY)
185 static void spr_read_decr(DisasContext *ctx, int gprn, int sprn)
187 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
190 gen_helper_load_decr(cpu_gpr[gprn], cpu_env);
191 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
192 gen_stop_exception(ctx);
196 static void spr_write_decr(DisasContext *ctx, int sprn, int gprn)
198 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
201 gen_helper_store_decr(cpu_env, cpu_gpr[gprn]);
202 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
203 gen_stop_exception(ctx);
208 /* SPR common to all non-embedded PowerPC, except 601 */
210 static void spr_read_tbl(DisasContext *ctx, int gprn, int sprn)
212 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
215 gen_helper_load_tbl(cpu_gpr[gprn], cpu_env);
216 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
218 gen_stop_exception(ctx);
222 static void spr_read_tbu(DisasContext *ctx, int gprn, int sprn)
224 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
227 gen_helper_load_tbu(cpu_gpr[gprn], cpu_env);
228 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
230 gen_stop_exception(ctx);
235 static void spr_read_atbl(DisasContext *ctx, int gprn, int sprn)
237 gen_helper_load_atbl(cpu_gpr[gprn], cpu_env);
241 static void spr_read_atbu(DisasContext *ctx, int gprn, int sprn)
243 gen_helper_load_atbu(cpu_gpr[gprn], cpu_env);
246 #if !defined(CONFIG_USER_ONLY)
247 static void spr_write_tbl(DisasContext *ctx, int sprn, int gprn)
249 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
252 gen_helper_store_tbl(cpu_env, cpu_gpr[gprn]);
253 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
255 gen_stop_exception(ctx);
259 static void spr_write_tbu(DisasContext *ctx, int sprn, int gprn)
261 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
264 gen_helper_store_tbu(cpu_env, cpu_gpr[gprn]);
265 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
267 gen_stop_exception(ctx);
272 static void spr_write_atbl(DisasContext *ctx, int sprn, int gprn)
274 gen_helper_store_atbl(cpu_env, cpu_gpr[gprn]);
278 static void spr_write_atbu(DisasContext *ctx, int sprn, int gprn)
280 gen_helper_store_atbu(cpu_env, cpu_gpr[gprn]);
283 #if defined(TARGET_PPC64)
285 static void spr_read_purr(DisasContext *ctx, int gprn, int sprn)
287 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
290 gen_helper_load_purr(cpu_gpr[gprn], cpu_env);
291 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
292 gen_stop_exception(ctx);
296 static void spr_write_purr(DisasContext *ctx, int sprn, int gprn)
298 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
301 gen_helper_store_purr(cpu_env, cpu_gpr[gprn]);
302 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
303 gen_stop_exception(ctx);
308 static void spr_read_hdecr(DisasContext *ctx, int gprn, int sprn)
310 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
313 gen_helper_load_hdecr(cpu_gpr[gprn], cpu_env);
314 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
316 gen_stop_exception(ctx);
320 static void spr_write_hdecr(DisasContext *ctx, int sprn, int gprn)
322 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
325 gen_helper_store_hdecr(cpu_env, cpu_gpr[gprn]);
326 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
328 gen_stop_exception(ctx);
332 static void spr_read_vtb(DisasContext *ctx, int gprn, int sprn)
334 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
337 gen_helper_load_vtb(cpu_gpr[gprn], cpu_env);
338 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
339 gen_stop_exception(ctx);
343 static void spr_write_vtb(DisasContext *ctx, int sprn, int gprn)
345 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
348 gen_helper_store_vtb(cpu_env, cpu_gpr[gprn]);
349 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
350 gen_stop_exception(ctx);
354 static void spr_write_tbu40(DisasContext *ctx, int sprn, int gprn)
356 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
359 gen_helper_store_tbu40(cpu_env, cpu_gpr[gprn]);
360 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
361 gen_stop_exception(ctx);
368 #if !defined(CONFIG_USER_ONLY)
369 /* IBAT0U...IBAT0U */
370 /* IBAT0L...IBAT7L */
371 static void spr_read_ibat(DisasContext *ctx, int gprn, int sprn)
373 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env,
374 offsetof(CPUPPCState,
375 IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2]));
378 static void spr_read_ibat_h(DisasContext *ctx, int gprn, int sprn)
380 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env,
381 offsetof(CPUPPCState,
382 IBAT[sprn & 1][((sprn - SPR_IBAT4U) / 2) + 4]));
385 static void spr_write_ibatu(DisasContext *ctx, int sprn, int gprn)
387 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2);
388 gen_helper_store_ibatu(cpu_env, t0, cpu_gpr[gprn]);
389 tcg_temp_free_i32(t0);
392 static void spr_write_ibatu_h(DisasContext *ctx, int sprn, int gprn)
394 TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_IBAT4U) / 2) + 4);
395 gen_helper_store_ibatu(cpu_env, t0, cpu_gpr[gprn]);
396 tcg_temp_free_i32(t0);
399 static void spr_write_ibatl(DisasContext *ctx, int sprn, int gprn)
401 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0L) / 2);
402 gen_helper_store_ibatl(cpu_env, t0, cpu_gpr[gprn]);
403 tcg_temp_free_i32(t0);
406 static void spr_write_ibatl_h(DisasContext *ctx, int sprn, int gprn)
408 TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_IBAT4L) / 2) + 4);
409 gen_helper_store_ibatl(cpu_env, t0, cpu_gpr[gprn]);
410 tcg_temp_free_i32(t0);
413 /* DBAT0U...DBAT7U */
414 /* DBAT0L...DBAT7L */
415 static void spr_read_dbat(DisasContext *ctx, int gprn, int sprn)
417 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env,
418 offsetof(CPUPPCState,
419 DBAT[sprn & 1][(sprn - SPR_DBAT0U) / 2]));
422 static void spr_read_dbat_h(DisasContext *ctx, int gprn, int sprn)
424 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env,
425 offsetof(CPUPPCState,
426 DBAT[sprn & 1][((sprn - SPR_DBAT4U) / 2) + 4]));
429 static void spr_write_dbatu(DisasContext *ctx, int sprn, int gprn)
431 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_DBAT0U) / 2);
432 gen_helper_store_dbatu(cpu_env, t0, cpu_gpr[gprn]);
433 tcg_temp_free_i32(t0);
436 static void spr_write_dbatu_h(DisasContext *ctx, int sprn, int gprn)
438 TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_DBAT4U) / 2) + 4);
439 gen_helper_store_dbatu(cpu_env, t0, cpu_gpr[gprn]);
440 tcg_temp_free_i32(t0);
443 static void spr_write_dbatl(DisasContext *ctx, int sprn, int gprn)
445 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_DBAT0L) / 2);
446 gen_helper_store_dbatl(cpu_env, t0, cpu_gpr[gprn]);
447 tcg_temp_free_i32(t0);
450 static void spr_write_dbatl_h(DisasContext *ctx, int sprn, int gprn)
452 TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_DBAT4L) / 2) + 4);
453 gen_helper_store_dbatl(cpu_env, t0, cpu_gpr[gprn]);
454 tcg_temp_free_i32(t0);
458 static void spr_write_sdr1(DisasContext *ctx, int sprn, int gprn)
460 gen_helper_store_sdr1(cpu_env, cpu_gpr[gprn]);
463 #if defined(TARGET_PPC64)
464 /* 64 bits PowerPC specific SPRs */
466 static void spr_write_pidr(DisasContext *ctx, int sprn, int gprn)
468 gen_helper_store_pidr(cpu_env, cpu_gpr[gprn]);
471 static void spr_write_lpidr(DisasContext *ctx, int sprn, int gprn)
473 gen_helper_store_lpidr(cpu_env, cpu_gpr[gprn]);
476 static void spr_read_hior(DisasContext *ctx, int gprn, int sprn)
478 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, excp_prefix));
481 static void spr_write_hior(DisasContext *ctx, int sprn, int gprn)
483 TCGv t0 = tcg_temp_new();
484 tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0x3FFFFF00000ULL);
485 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, excp_prefix));
488 static void spr_write_ptcr(DisasContext *ctx, int sprn, int gprn)
490 gen_helper_store_ptcr(cpu_env, cpu_gpr[gprn]);
493 static void spr_write_pcr(DisasContext *ctx, int sprn, int gprn)
495 gen_helper_store_pcr(cpu_env, cpu_gpr[gprn]);
499 static void spr_read_dpdes(DisasContext *ctx, int gprn, int sprn)
501 gen_helper_load_dpdes(cpu_gpr[gprn], cpu_env);
504 static void spr_write_dpdes(DisasContext *ctx, int sprn, int gprn)
506 gen_helper_store_dpdes(cpu_env, cpu_gpr[gprn]);
511 /* PowerPC 601 specific registers */
513 static void spr_read_601_rtcl(DisasContext *ctx, int gprn, int sprn)
515 gen_helper_load_601_rtcl(cpu_gpr[gprn], cpu_env);
518 static void spr_read_601_rtcu(DisasContext *ctx, int gprn, int sprn)
520 gen_helper_load_601_rtcu(cpu_gpr[gprn], cpu_env);
523 #if !defined(CONFIG_USER_ONLY)
524 static void spr_write_601_rtcu(DisasContext *ctx, int sprn, int gprn)
526 gen_helper_store_601_rtcu(cpu_env, cpu_gpr[gprn]);
529 static void spr_write_601_rtcl(DisasContext *ctx, int sprn, int gprn)
531 gen_helper_store_601_rtcl(cpu_env, cpu_gpr[gprn]);
534 static void spr_write_hid0_601(DisasContext *ctx, int sprn, int gprn)
536 gen_helper_store_hid0_601(cpu_env, cpu_gpr[gprn]);
537 /* Must stop the translation as endianness may have changed */
538 gen_stop_exception(ctx);
543 #if !defined(CONFIG_USER_ONLY)
544 static void spr_read_601_ubat(DisasContext *ctx, int gprn, int sprn)
546 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env,
547 offsetof(CPUPPCState,
548 IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2]));
551 static void spr_write_601_ubatu(DisasContext *ctx, int sprn, int gprn)
553 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2);
554 gen_helper_store_601_batl(cpu_env, t0, cpu_gpr[gprn]);
555 tcg_temp_free_i32(t0);
558 static void spr_write_601_ubatl(DisasContext *ctx, int sprn, int gprn)
560 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2);
561 gen_helper_store_601_batu(cpu_env, t0, cpu_gpr[gprn]);
562 tcg_temp_free_i32(t0);
566 /* PowerPC 40x specific registers */
567 #if !defined(CONFIG_USER_ONLY)
568 static void spr_read_40x_pit(DisasContext *ctx, int gprn, int sprn)
570 gen_helper_load_40x_pit(cpu_gpr[gprn], cpu_env);
573 static void spr_write_40x_pit(DisasContext *ctx, int sprn, int gprn)
575 gen_helper_store_40x_pit(cpu_env, cpu_gpr[gprn]);
578 static void spr_write_40x_dbcr0(DisasContext *ctx, int sprn, int gprn)
580 gen_store_spr(sprn, cpu_gpr[gprn]);
581 gen_helper_store_40x_dbcr0(cpu_env, cpu_gpr[gprn]);
582 /* We must stop translation as we may have rebooted */
583 gen_stop_exception(ctx);
586 static void spr_write_40x_sler(DisasContext *ctx, int sprn, int gprn)
588 gen_helper_store_40x_sler(cpu_env, cpu_gpr[gprn]);
591 static void spr_write_booke_tcr(DisasContext *ctx, int sprn, int gprn)
593 gen_helper_store_booke_tcr(cpu_env, cpu_gpr[gprn]);
596 static void spr_write_booke_tsr(DisasContext *ctx, int sprn, int gprn)
598 gen_helper_store_booke_tsr(cpu_env, cpu_gpr[gprn]);
602 /* PowerPC 403 specific registers */
603 /* PBL1 / PBU1 / PBL2 / PBU2 */
604 #if !defined(CONFIG_USER_ONLY)
605 static void spr_read_403_pbr(DisasContext *ctx, int gprn, int sprn)
607 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env,
608 offsetof(CPUPPCState, pb[sprn - SPR_403_PBL1]));
611 static void spr_write_403_pbr(DisasContext *ctx, int sprn, int gprn)
613 TCGv_i32 t0 = tcg_const_i32(sprn - SPR_403_PBL1);
614 gen_helper_store_403_pbr(cpu_env, t0, cpu_gpr[gprn]);
615 tcg_temp_free_i32(t0);
618 static void spr_write_pir(DisasContext *ctx, int sprn, int gprn)
620 TCGv t0 = tcg_temp_new();
621 tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0xF);
622 gen_store_spr(SPR_PIR, t0);
627 /* SPE specific registers */
628 static void spr_read_spefscr(DisasContext *ctx, int gprn, int sprn)
630 TCGv_i32 t0 = tcg_temp_new_i32();
631 tcg_gen_ld_i32(t0, cpu_env, offsetof(CPUPPCState, spe_fscr));
632 tcg_gen_extu_i32_tl(cpu_gpr[gprn], t0);
633 tcg_temp_free_i32(t0);
636 static void spr_write_spefscr(DisasContext *ctx, int sprn, int gprn)
638 TCGv_i32 t0 = tcg_temp_new_i32();
639 tcg_gen_trunc_tl_i32(t0, cpu_gpr[gprn]);
640 tcg_gen_st_i32(t0, cpu_env, offsetof(CPUPPCState, spe_fscr));
641 tcg_temp_free_i32(t0);
644 #if !defined(CONFIG_USER_ONLY)
645 /* Callback used to write the exception vector base */
646 static void spr_write_excp_prefix(DisasContext *ctx, int sprn, int gprn)
648 TCGv t0 = tcg_temp_new();
649 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUPPCState, ivpr_mask));
650 tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]);
651 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, excp_prefix));
652 gen_store_spr(sprn, t0);
656 static void spr_write_excp_vector(DisasContext *ctx, int sprn, int gprn)
660 if (sprn >= SPR_BOOKE_IVOR0 && sprn <= SPR_BOOKE_IVOR15) {
661 sprn_offs = sprn - SPR_BOOKE_IVOR0;
662 } else if (sprn >= SPR_BOOKE_IVOR32 && sprn <= SPR_BOOKE_IVOR37) {
663 sprn_offs = sprn - SPR_BOOKE_IVOR32 + 32;
664 } else if (sprn >= SPR_BOOKE_IVOR38 && sprn <= SPR_BOOKE_IVOR42) {
665 sprn_offs = sprn - SPR_BOOKE_IVOR38 + 38;
667 printf("Trying to write an unknown exception vector %d %03x\n",
669 gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
673 TCGv t0 = tcg_temp_new();
674 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUPPCState, ivor_mask));
675 tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]);
676 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, excp_vectors[sprn_offs]));
677 gen_store_spr(sprn, t0);
682 static inline void vscr_init(CPUPPCState *env, uint32_t val)
684 /* Altivec always uses round-to-nearest */
685 set_float_rounding_mode(float_round_nearest_even, &env->vec_status);
686 helper_mtvscr(env, val);
689 #ifdef CONFIG_USER_ONLY
690 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
691 oea_read, oea_write, one_reg_id, initial_value) \
692 _spr_register(env, num, name, uea_read, uea_write, initial_value)
693 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
694 oea_read, oea_write, hea_read, hea_write, \
695 one_reg_id, initial_value) \
696 _spr_register(env, num, name, uea_read, uea_write, initial_value)
698 #if !defined(CONFIG_KVM)
699 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
700 oea_read, oea_write, one_reg_id, initial_value) \
701 _spr_register(env, num, name, uea_read, uea_write, \
702 oea_read, oea_write, oea_read, oea_write, initial_value)
703 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
704 oea_read, oea_write, hea_read, hea_write, \
705 one_reg_id, initial_value) \
706 _spr_register(env, num, name, uea_read, uea_write, \
707 oea_read, oea_write, hea_read, hea_write, initial_value)
709 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
710 oea_read, oea_write, one_reg_id, initial_value) \
711 _spr_register(env, num, name, uea_read, uea_write, \
712 oea_read, oea_write, oea_read, oea_write, \
713 one_reg_id, initial_value)
714 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
715 oea_read, oea_write, hea_read, hea_write, \
716 one_reg_id, initial_value) \
717 _spr_register(env, num, name, uea_read, uea_write, \
718 oea_read, oea_write, hea_read, hea_write, \
719 one_reg_id, initial_value)
723 #define spr_register(env, num, name, uea_read, uea_write, \
724 oea_read, oea_write, initial_value) \
725 spr_register_kvm(env, num, name, uea_read, uea_write, \
726 oea_read, oea_write, 0, initial_value)
728 #define spr_register_hv(env, num, name, uea_read, uea_write, \
729 oea_read, oea_write, hea_read, hea_write, \
731 spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
732 oea_read, oea_write, hea_read, hea_write, \
735 static inline void _spr_register(CPUPPCState *env, int num,
737 void (*uea_read)(DisasContext *ctx,
739 void (*uea_write)(DisasContext *ctx,
741 #if !defined(CONFIG_USER_ONLY)
743 void (*oea_read)(DisasContext *ctx,
745 void (*oea_write)(DisasContext *ctx,
747 void (*hea_read)(DisasContext *opaque,
749 void (*hea_write)(DisasContext *opaque,
752 #if defined(CONFIG_KVM)
755 target_ulong initial_value)
759 spr = &env->spr_cb[num];
760 if (spr->name != NULL || env->spr[num] != 0x00000000 ||
761 #if !defined(CONFIG_USER_ONLY)
762 spr->oea_read != NULL || spr->oea_write != NULL ||
764 spr->uea_read != NULL || spr->uea_write != NULL) {
765 printf("Error: Trying to register SPR %d (%03x) twice !\n", num, num);
768 #if defined(PPC_DEBUG_SPR)
769 printf("*** register spr %d (%03x) %s val " TARGET_FMT_lx "\n", num, num,
770 name, initial_value);
773 spr->uea_read = uea_read;
774 spr->uea_write = uea_write;
775 #if !defined(CONFIG_USER_ONLY)
776 spr->oea_read = oea_read;
777 spr->oea_write = oea_write;
778 spr->hea_read = hea_read;
779 spr->hea_write = hea_write;
781 #if defined(CONFIG_KVM)
782 spr->one_reg_id = one_reg_id,
784 env->spr[num] = spr->default_value = initial_value;
787 /* Generic PowerPC SPRs */
788 static void gen_spr_generic(CPUPPCState *env)
790 /* Integer processing */
791 spr_register(env, SPR_XER, "XER",
792 &spr_read_xer, &spr_write_xer,
793 &spr_read_xer, &spr_write_xer,
796 spr_register(env, SPR_LR, "LR",
797 &spr_read_lr, &spr_write_lr,
798 &spr_read_lr, &spr_write_lr,
800 spr_register(env, SPR_CTR, "CTR",
801 &spr_read_ctr, &spr_write_ctr,
802 &spr_read_ctr, &spr_write_ctr,
804 /* Interrupt processing */
805 spr_register(env, SPR_SRR0, "SRR0",
806 SPR_NOACCESS, SPR_NOACCESS,
807 &spr_read_generic, &spr_write_generic,
809 spr_register(env, SPR_SRR1, "SRR1",
810 SPR_NOACCESS, SPR_NOACCESS,
811 &spr_read_generic, &spr_write_generic,
813 /* Processor control */
814 spr_register(env, SPR_SPRG0, "SPRG0",
815 SPR_NOACCESS, SPR_NOACCESS,
816 &spr_read_generic, &spr_write_generic,
818 spr_register(env, SPR_SPRG1, "SPRG1",
819 SPR_NOACCESS, SPR_NOACCESS,
820 &spr_read_generic, &spr_write_generic,
822 spr_register(env, SPR_SPRG2, "SPRG2",
823 SPR_NOACCESS, SPR_NOACCESS,
824 &spr_read_generic, &spr_write_generic,
826 spr_register(env, SPR_SPRG3, "SPRG3",
827 SPR_NOACCESS, SPR_NOACCESS,
828 &spr_read_generic, &spr_write_generic,
832 /* SPR common to all non-embedded PowerPC, including 601 */
833 static void gen_spr_ne_601(CPUPPCState *env)
835 /* Exception processing */
836 spr_register_kvm(env, SPR_DSISR, "DSISR",
837 SPR_NOACCESS, SPR_NOACCESS,
838 &spr_read_generic, &spr_write_generic,
839 KVM_REG_PPC_DSISR, 0x00000000);
840 spr_register_kvm(env, SPR_DAR, "DAR",
841 SPR_NOACCESS, SPR_NOACCESS,
842 &spr_read_generic, &spr_write_generic,
843 KVM_REG_PPC_DAR, 0x00000000);
845 spr_register(env, SPR_DECR, "DECR",
846 SPR_NOACCESS, SPR_NOACCESS,
847 &spr_read_decr, &spr_write_decr,
851 /* Storage Description Register 1 */
852 static void gen_spr_sdr1(CPUPPCState *env)
854 #ifndef CONFIG_USER_ONLY
855 if (env->has_hv_mode) {
857 * SDR1 is a hypervisor resource on CPUs which have a
860 spr_register_hv(env, SPR_SDR1, "SDR1",
861 SPR_NOACCESS, SPR_NOACCESS,
862 SPR_NOACCESS, SPR_NOACCESS,
863 &spr_read_generic, &spr_write_sdr1,
866 spr_register(env, SPR_SDR1, "SDR1",
867 SPR_NOACCESS, SPR_NOACCESS,
868 &spr_read_generic, &spr_write_sdr1,
875 static void gen_low_BATs(CPUPPCState *env)
877 #if !defined(CONFIG_USER_ONLY)
878 spr_register(env, SPR_IBAT0U, "IBAT0U",
879 SPR_NOACCESS, SPR_NOACCESS,
880 &spr_read_ibat, &spr_write_ibatu,
882 spr_register(env, SPR_IBAT0L, "IBAT0L",
883 SPR_NOACCESS, SPR_NOACCESS,
884 &spr_read_ibat, &spr_write_ibatl,
886 spr_register(env, SPR_IBAT1U, "IBAT1U",
887 SPR_NOACCESS, SPR_NOACCESS,
888 &spr_read_ibat, &spr_write_ibatu,
890 spr_register(env, SPR_IBAT1L, "IBAT1L",
891 SPR_NOACCESS, SPR_NOACCESS,
892 &spr_read_ibat, &spr_write_ibatl,
894 spr_register(env, SPR_IBAT2U, "IBAT2U",
895 SPR_NOACCESS, SPR_NOACCESS,
896 &spr_read_ibat, &spr_write_ibatu,
898 spr_register(env, SPR_IBAT2L, "IBAT2L",
899 SPR_NOACCESS, SPR_NOACCESS,
900 &spr_read_ibat, &spr_write_ibatl,
902 spr_register(env, SPR_IBAT3U, "IBAT3U",
903 SPR_NOACCESS, SPR_NOACCESS,
904 &spr_read_ibat, &spr_write_ibatu,
906 spr_register(env, SPR_IBAT3L, "IBAT3L",
907 SPR_NOACCESS, SPR_NOACCESS,
908 &spr_read_ibat, &spr_write_ibatl,
910 spr_register(env, SPR_DBAT0U, "DBAT0U",
911 SPR_NOACCESS, SPR_NOACCESS,
912 &spr_read_dbat, &spr_write_dbatu,
914 spr_register(env, SPR_DBAT0L, "DBAT0L",
915 SPR_NOACCESS, SPR_NOACCESS,
916 &spr_read_dbat, &spr_write_dbatl,
918 spr_register(env, SPR_DBAT1U, "DBAT1U",
919 SPR_NOACCESS, SPR_NOACCESS,
920 &spr_read_dbat, &spr_write_dbatu,
922 spr_register(env, SPR_DBAT1L, "DBAT1L",
923 SPR_NOACCESS, SPR_NOACCESS,
924 &spr_read_dbat, &spr_write_dbatl,
926 spr_register(env, SPR_DBAT2U, "DBAT2U",
927 SPR_NOACCESS, SPR_NOACCESS,
928 &spr_read_dbat, &spr_write_dbatu,
930 spr_register(env, SPR_DBAT2L, "DBAT2L",
931 SPR_NOACCESS, SPR_NOACCESS,
932 &spr_read_dbat, &spr_write_dbatl,
934 spr_register(env, SPR_DBAT3U, "DBAT3U",
935 SPR_NOACCESS, SPR_NOACCESS,
936 &spr_read_dbat, &spr_write_dbatu,
938 spr_register(env, SPR_DBAT3L, "DBAT3L",
939 SPR_NOACCESS, SPR_NOACCESS,
940 &spr_read_dbat, &spr_write_dbatl,
947 static void gen_high_BATs(CPUPPCState *env)
949 #if !defined(CONFIG_USER_ONLY)
950 spr_register(env, SPR_IBAT4U, "IBAT4U",
951 SPR_NOACCESS, SPR_NOACCESS,
952 &spr_read_ibat_h, &spr_write_ibatu_h,
954 spr_register(env, SPR_IBAT4L, "IBAT4L",
955 SPR_NOACCESS, SPR_NOACCESS,
956 &spr_read_ibat_h, &spr_write_ibatl_h,
958 spr_register(env, SPR_IBAT5U, "IBAT5U",
959 SPR_NOACCESS, SPR_NOACCESS,
960 &spr_read_ibat_h, &spr_write_ibatu_h,
962 spr_register(env, SPR_IBAT5L, "IBAT5L",
963 SPR_NOACCESS, SPR_NOACCESS,
964 &spr_read_ibat_h, &spr_write_ibatl_h,
966 spr_register(env, SPR_IBAT6U, "IBAT6U",
967 SPR_NOACCESS, SPR_NOACCESS,
968 &spr_read_ibat_h, &spr_write_ibatu_h,
970 spr_register(env, SPR_IBAT6L, "IBAT6L",
971 SPR_NOACCESS, SPR_NOACCESS,
972 &spr_read_ibat_h, &spr_write_ibatl_h,
974 spr_register(env, SPR_IBAT7U, "IBAT7U",
975 SPR_NOACCESS, SPR_NOACCESS,
976 &spr_read_ibat_h, &spr_write_ibatu_h,
978 spr_register(env, SPR_IBAT7L, "IBAT7L",
979 SPR_NOACCESS, SPR_NOACCESS,
980 &spr_read_ibat_h, &spr_write_ibatl_h,
982 spr_register(env, SPR_DBAT4U, "DBAT4U",
983 SPR_NOACCESS, SPR_NOACCESS,
984 &spr_read_dbat_h, &spr_write_dbatu_h,
986 spr_register(env, SPR_DBAT4L, "DBAT4L",
987 SPR_NOACCESS, SPR_NOACCESS,
988 &spr_read_dbat_h, &spr_write_dbatl_h,
990 spr_register(env, SPR_DBAT5U, "DBAT5U",
991 SPR_NOACCESS, SPR_NOACCESS,
992 &spr_read_dbat_h, &spr_write_dbatu_h,
994 spr_register(env, SPR_DBAT5L, "DBAT5L",
995 SPR_NOACCESS, SPR_NOACCESS,
996 &spr_read_dbat_h, &spr_write_dbatl_h,
998 spr_register(env, SPR_DBAT6U, "DBAT6U",
999 SPR_NOACCESS, SPR_NOACCESS,
1000 &spr_read_dbat_h, &spr_write_dbatu_h,
1002 spr_register(env, SPR_DBAT6L, "DBAT6L",
1003 SPR_NOACCESS, SPR_NOACCESS,
1004 &spr_read_dbat_h, &spr_write_dbatl_h,
1006 spr_register(env, SPR_DBAT7U, "DBAT7U",
1007 SPR_NOACCESS, SPR_NOACCESS,
1008 &spr_read_dbat_h, &spr_write_dbatu_h,
1010 spr_register(env, SPR_DBAT7L, "DBAT7L",
1011 SPR_NOACCESS, SPR_NOACCESS,
1012 &spr_read_dbat_h, &spr_write_dbatl_h,
1018 /* Generic PowerPC time base */
1019 static void gen_tbl(CPUPPCState *env)
1021 spr_register(env, SPR_VTBL, "TBL",
1022 &spr_read_tbl, SPR_NOACCESS,
1023 &spr_read_tbl, SPR_NOACCESS,
1025 spr_register(env, SPR_TBL, "TBL",
1026 &spr_read_tbl, SPR_NOACCESS,
1027 &spr_read_tbl, &spr_write_tbl,
1029 spr_register(env, SPR_VTBU, "TBU",
1030 &spr_read_tbu, SPR_NOACCESS,
1031 &spr_read_tbu, SPR_NOACCESS,
1033 spr_register(env, SPR_TBU, "TBU",
1034 &spr_read_tbu, SPR_NOACCESS,
1035 &spr_read_tbu, &spr_write_tbu,
1039 /* Softare table search registers */
1040 static void gen_6xx_7xx_soft_tlb(CPUPPCState *env, int nb_tlbs, int nb_ways)
1042 #if !defined(CONFIG_USER_ONLY)
1043 env->nb_tlb = nb_tlbs;
1044 env->nb_ways = nb_ways;
1046 env->tlb_type = TLB_6XX;
1047 spr_register(env, SPR_DMISS, "DMISS",
1048 SPR_NOACCESS, SPR_NOACCESS,
1049 &spr_read_generic, SPR_NOACCESS,
1051 spr_register(env, SPR_DCMP, "DCMP",
1052 SPR_NOACCESS, SPR_NOACCESS,
1053 &spr_read_generic, SPR_NOACCESS,
1055 spr_register(env, SPR_HASH1, "HASH1",
1056 SPR_NOACCESS, SPR_NOACCESS,
1057 &spr_read_generic, SPR_NOACCESS,
1059 spr_register(env, SPR_HASH2, "HASH2",
1060 SPR_NOACCESS, SPR_NOACCESS,
1061 &spr_read_generic, SPR_NOACCESS,
1063 spr_register(env, SPR_IMISS, "IMISS",
1064 SPR_NOACCESS, SPR_NOACCESS,
1065 &spr_read_generic, SPR_NOACCESS,
1067 spr_register(env, SPR_ICMP, "ICMP",
1068 SPR_NOACCESS, SPR_NOACCESS,
1069 &spr_read_generic, SPR_NOACCESS,
1071 spr_register(env, SPR_RPA, "RPA",
1072 SPR_NOACCESS, SPR_NOACCESS,
1073 &spr_read_generic, &spr_write_generic,
1078 /* SPR common to MPC755 and G2 */
1079 static void gen_spr_G2_755(CPUPPCState *env)
1082 spr_register(env, SPR_SPRG4, "SPRG4",
1083 SPR_NOACCESS, SPR_NOACCESS,
1084 &spr_read_generic, &spr_write_generic,
1086 spr_register(env, SPR_SPRG5, "SPRG5",
1087 SPR_NOACCESS, SPR_NOACCESS,
1088 &spr_read_generic, &spr_write_generic,
1090 spr_register(env, SPR_SPRG6, "SPRG6",
1091 SPR_NOACCESS, SPR_NOACCESS,
1092 &spr_read_generic, &spr_write_generic,
1094 spr_register(env, SPR_SPRG7, "SPRG7",
1095 SPR_NOACCESS, SPR_NOACCESS,
1096 &spr_read_generic, &spr_write_generic,
1100 /* SPR common to all 7xx PowerPC implementations */
1101 static void gen_spr_7xx(CPUPPCState *env)
1104 /* XXX : not implemented */
1105 spr_register_kvm(env, SPR_DABR, "DABR",
1106 SPR_NOACCESS, SPR_NOACCESS,
1107 &spr_read_generic, &spr_write_generic,
1108 KVM_REG_PPC_DABR, 0x00000000);
1109 /* XXX : not implemented */
1110 spr_register(env, SPR_IABR, "IABR",
1111 SPR_NOACCESS, SPR_NOACCESS,
1112 &spr_read_generic, &spr_write_generic,
1114 /* Cache management */
1115 /* XXX : not implemented */
1116 spr_register(env, SPR_ICTC, "ICTC",
1117 SPR_NOACCESS, SPR_NOACCESS,
1118 &spr_read_generic, &spr_write_generic,
1120 /* Performance monitors */
1121 /* XXX : not implemented */
1122 spr_register(env, SPR_7XX_MMCR0, "MMCR0",
1123 SPR_NOACCESS, SPR_NOACCESS,
1124 &spr_read_generic, &spr_write_generic,
1126 /* XXX : not implemented */
1127 spr_register(env, SPR_7XX_MMCR1, "MMCR1",
1128 SPR_NOACCESS, SPR_NOACCESS,
1129 &spr_read_generic, &spr_write_generic,
1131 /* XXX : not implemented */
1132 spr_register(env, SPR_7XX_PMC1, "PMC1",
1133 SPR_NOACCESS, SPR_NOACCESS,
1134 &spr_read_generic, &spr_write_generic,
1136 /* XXX : not implemented */
1137 spr_register(env, SPR_7XX_PMC2, "PMC2",
1138 SPR_NOACCESS, SPR_NOACCESS,
1139 &spr_read_generic, &spr_write_generic,
1141 /* XXX : not implemented */
1142 spr_register(env, SPR_7XX_PMC3, "PMC3",
1143 SPR_NOACCESS, SPR_NOACCESS,
1144 &spr_read_generic, &spr_write_generic,
1146 /* XXX : not implemented */
1147 spr_register(env, SPR_7XX_PMC4, "PMC4",
1148 SPR_NOACCESS, SPR_NOACCESS,
1149 &spr_read_generic, &spr_write_generic,
1151 /* XXX : not implemented */
1152 spr_register(env, SPR_7XX_SIAR, "SIAR",
1153 SPR_NOACCESS, SPR_NOACCESS,
1154 &spr_read_generic, SPR_NOACCESS,
1156 /* XXX : not implemented */
1157 spr_register(env, SPR_7XX_UMMCR0, "UMMCR0",
1158 &spr_read_ureg, SPR_NOACCESS,
1159 &spr_read_ureg, SPR_NOACCESS,
1161 /* XXX : not implemented */
1162 spr_register(env, SPR_7XX_UMMCR1, "UMMCR1",
1163 &spr_read_ureg, SPR_NOACCESS,
1164 &spr_read_ureg, SPR_NOACCESS,
1166 /* XXX : not implemented */
1167 spr_register(env, SPR_7XX_UPMC1, "UPMC1",
1168 &spr_read_ureg, SPR_NOACCESS,
1169 &spr_read_ureg, SPR_NOACCESS,
1171 /* XXX : not implemented */
1172 spr_register(env, SPR_7XX_UPMC2, "UPMC2",
1173 &spr_read_ureg, SPR_NOACCESS,
1174 &spr_read_ureg, SPR_NOACCESS,
1176 /* XXX : not implemented */
1177 spr_register(env, SPR_7XX_UPMC3, "UPMC3",
1178 &spr_read_ureg, SPR_NOACCESS,
1179 &spr_read_ureg, SPR_NOACCESS,
1181 /* XXX : not implemented */
1182 spr_register(env, SPR_7XX_UPMC4, "UPMC4",
1183 &spr_read_ureg, SPR_NOACCESS,
1184 &spr_read_ureg, SPR_NOACCESS,
1186 /* XXX : not implemented */
1187 spr_register(env, SPR_7XX_USIAR, "USIAR",
1188 &spr_read_ureg, SPR_NOACCESS,
1189 &spr_read_ureg, SPR_NOACCESS,
1191 /* External access control */
1192 /* XXX : not implemented */
1193 spr_register(env, SPR_EAR, "EAR",
1194 SPR_NOACCESS, SPR_NOACCESS,
1195 &spr_read_generic, &spr_write_generic,
1200 #ifndef CONFIG_USER_ONLY
1201 static void spr_write_amr(DisasContext *ctx, int sprn, int gprn)
1203 TCGv t0 = tcg_temp_new();
1204 TCGv t1 = tcg_temp_new();
1205 TCGv t2 = tcg_temp_new();
1208 * Note, the HV=1 PR=0 case is handled earlier by simply using
1209 * spr_write_generic for HV mode in the SPR table
1212 /* Build insertion mask into t1 based on context */
1214 gen_load_spr(t1, SPR_UAMOR);
1216 gen_load_spr(t1, SPR_AMOR);
1219 /* Mask new bits into t2 */
1220 tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]);
1222 /* Load AMR and clear new bits in t0 */
1223 gen_load_spr(t0, SPR_AMR);
1224 tcg_gen_andc_tl(t0, t0, t1);
1226 /* Or'in new bits and write it out */
1227 tcg_gen_or_tl(t0, t0, t2);
1228 gen_store_spr(SPR_AMR, t0);
1229 spr_store_dump_spr(SPR_AMR);
1236 static void spr_write_uamor(DisasContext *ctx, int sprn, int gprn)
1238 TCGv t0 = tcg_temp_new();
1239 TCGv t1 = tcg_temp_new();
1240 TCGv t2 = tcg_temp_new();
1243 * Note, the HV=1 case is handled earlier by simply using
1244 * spr_write_generic for HV mode in the SPR table
1247 /* Build insertion mask into t1 based on context */
1248 gen_load_spr(t1, SPR_AMOR);
1250 /* Mask new bits into t2 */
1251 tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]);
1253 /* Load AMR and clear new bits in t0 */
1254 gen_load_spr(t0, SPR_UAMOR);
1255 tcg_gen_andc_tl(t0, t0, t1);
1257 /* Or'in new bits and write it out */
1258 tcg_gen_or_tl(t0, t0, t2);
1259 gen_store_spr(SPR_UAMOR, t0);
1260 spr_store_dump_spr(SPR_UAMOR);
1267 static void spr_write_iamr(DisasContext *ctx, int sprn, int gprn)
1269 TCGv t0 = tcg_temp_new();
1270 TCGv t1 = tcg_temp_new();
1271 TCGv t2 = tcg_temp_new();
1274 * Note, the HV=1 case is handled earlier by simply using
1275 * spr_write_generic for HV mode in the SPR table
1278 /* Build insertion mask into t1 based on context */
1279 gen_load_spr(t1, SPR_AMOR);
1281 /* Mask new bits into t2 */
1282 tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]);
1284 /* Load AMR and clear new bits in t0 */
1285 gen_load_spr(t0, SPR_IAMR);
1286 tcg_gen_andc_tl(t0, t0, t1);
1288 /* Or'in new bits and write it out */
1289 tcg_gen_or_tl(t0, t0, t2);
1290 gen_store_spr(SPR_IAMR, t0);
1291 spr_store_dump_spr(SPR_IAMR);
1297 #endif /* CONFIG_USER_ONLY */
1299 static void gen_spr_amr(CPUPPCState *env)
1301 #ifndef CONFIG_USER_ONLY
1303 * Virtual Page Class Key protection
1305 * The AMR is accessible either via SPR 13 or SPR 29. 13 is
1306 * userspace accessible, 29 is privileged. So we only need to set
1307 * the kvm ONE_REG id on one of them, we use 29
1309 spr_register(env, SPR_UAMR, "UAMR",
1310 &spr_read_generic, &spr_write_amr,
1311 &spr_read_generic, &spr_write_amr,
1313 spr_register_kvm_hv(env, SPR_AMR, "AMR",
1314 SPR_NOACCESS, SPR_NOACCESS,
1315 &spr_read_generic, &spr_write_amr,
1316 &spr_read_generic, &spr_write_generic,
1317 KVM_REG_PPC_AMR, 0);
1318 spr_register_kvm_hv(env, SPR_UAMOR, "UAMOR",
1319 SPR_NOACCESS, SPR_NOACCESS,
1320 &spr_read_generic, &spr_write_uamor,
1321 &spr_read_generic, &spr_write_generic,
1322 KVM_REG_PPC_UAMOR, 0);
1323 spr_register_hv(env, SPR_AMOR, "AMOR",
1324 SPR_NOACCESS, SPR_NOACCESS,
1325 SPR_NOACCESS, SPR_NOACCESS,
1326 &spr_read_generic, &spr_write_generic,
1328 #endif /* !CONFIG_USER_ONLY */
1331 static void gen_spr_iamr(CPUPPCState *env)
1333 #ifndef CONFIG_USER_ONLY
1334 spr_register_kvm_hv(env, SPR_IAMR, "IAMR",
1335 SPR_NOACCESS, SPR_NOACCESS,
1336 &spr_read_generic, &spr_write_iamr,
1337 &spr_read_generic, &spr_write_generic,
1338 KVM_REG_PPC_IAMR, 0);
1339 #endif /* !CONFIG_USER_ONLY */
1341 #endif /* TARGET_PPC64 */
1343 #ifndef CONFIG_USER_ONLY
1344 static void spr_read_thrm(DisasContext *ctx, int gprn, int sprn)
1346 gen_helper_fixup_thrm(cpu_env);
1347 gen_load_spr(cpu_gpr[gprn], sprn);
1348 spr_load_dump_spr(sprn);
1350 #endif /* !CONFIG_USER_ONLY */
1352 static void gen_spr_thrm(CPUPPCState *env)
1354 /* Thermal management */
1355 /* XXX : not implemented */
1356 spr_register(env, SPR_THRM1, "THRM1",
1357 SPR_NOACCESS, SPR_NOACCESS,
1358 &spr_read_thrm, &spr_write_generic,
1360 /* XXX : not implemented */
1361 spr_register(env, SPR_THRM2, "THRM2",
1362 SPR_NOACCESS, SPR_NOACCESS,
1363 &spr_read_thrm, &spr_write_generic,
1365 /* XXX : not implemented */
1366 spr_register(env, SPR_THRM3, "THRM3",
1367 SPR_NOACCESS, SPR_NOACCESS,
1368 &spr_read_thrm, &spr_write_generic,
1372 /* SPR specific to PowerPC 604 implementation */
1373 static void gen_spr_604(CPUPPCState *env)
1375 /* Processor identification */
1376 spr_register(env, SPR_PIR, "PIR",
1377 SPR_NOACCESS, SPR_NOACCESS,
1378 &spr_read_generic, &spr_write_pir,
1381 /* XXX : not implemented */
1382 spr_register(env, SPR_IABR, "IABR",
1383 SPR_NOACCESS, SPR_NOACCESS,
1384 &spr_read_generic, &spr_write_generic,
1386 /* XXX : not implemented */
1387 spr_register_kvm(env, SPR_DABR, "DABR",
1388 SPR_NOACCESS, SPR_NOACCESS,
1389 &spr_read_generic, &spr_write_generic,
1390 KVM_REG_PPC_DABR, 0x00000000);
1391 /* Performance counters */
1392 /* XXX : not implemented */
1393 spr_register(env, SPR_7XX_MMCR0, "MMCR0",
1394 SPR_NOACCESS, SPR_NOACCESS,
1395 &spr_read_generic, &spr_write_generic,
1397 /* XXX : not implemented */
1398 spr_register(env, SPR_7XX_PMC1, "PMC1",
1399 SPR_NOACCESS, SPR_NOACCESS,
1400 &spr_read_generic, &spr_write_generic,
1402 /* XXX : not implemented */
1403 spr_register(env, SPR_7XX_PMC2, "PMC2",
1404 SPR_NOACCESS, SPR_NOACCESS,
1405 &spr_read_generic, &spr_write_generic,
1407 /* XXX : not implemented */
1408 spr_register(env, SPR_7XX_SIAR, "SIAR",
1409 SPR_NOACCESS, SPR_NOACCESS,
1410 &spr_read_generic, SPR_NOACCESS,
1412 /* XXX : not implemented */
1413 spr_register(env, SPR_SDA, "SDA",
1414 SPR_NOACCESS, SPR_NOACCESS,
1415 &spr_read_generic, SPR_NOACCESS,
1417 /* External access control */
1418 /* XXX : not implemented */
1419 spr_register(env, SPR_EAR, "EAR",
1420 SPR_NOACCESS, SPR_NOACCESS,
1421 &spr_read_generic, &spr_write_generic,
1425 /* SPR specific to PowerPC 603 implementation */
1426 static void gen_spr_603(CPUPPCState *env)
1428 /* External access control */
1429 /* XXX : not implemented */
1430 spr_register(env, SPR_EAR, "EAR",
1431 SPR_NOACCESS, SPR_NOACCESS,
1432 &spr_read_generic, &spr_write_generic,
1435 /* XXX : not implemented */
1436 spr_register(env, SPR_IABR, "IABR",
1437 SPR_NOACCESS, SPR_NOACCESS,
1438 &spr_read_generic, &spr_write_generic,
1443 /* SPR specific to PowerPC G2 implementation */
1444 static void gen_spr_G2(CPUPPCState *env)
1446 /* Memory base address */
1448 /* XXX : not implemented */
1449 spr_register(env, SPR_MBAR, "MBAR",
1450 SPR_NOACCESS, SPR_NOACCESS,
1451 &spr_read_generic, &spr_write_generic,
1453 /* Exception processing */
1454 spr_register(env, SPR_BOOKE_CSRR0, "CSRR0",
1455 SPR_NOACCESS, SPR_NOACCESS,
1456 &spr_read_generic, &spr_write_generic,
1458 spr_register(env, SPR_BOOKE_CSRR1, "CSRR1",
1459 SPR_NOACCESS, SPR_NOACCESS,
1460 &spr_read_generic, &spr_write_generic,
1463 /* XXX : not implemented */
1464 spr_register(env, SPR_DABR, "DABR",
1465 SPR_NOACCESS, SPR_NOACCESS,
1466 &spr_read_generic, &spr_write_generic,
1468 /* XXX : not implemented */
1469 spr_register(env, SPR_DABR2, "DABR2",
1470 SPR_NOACCESS, SPR_NOACCESS,
1471 &spr_read_generic, &spr_write_generic,
1473 /* XXX : not implemented */
1474 spr_register(env, SPR_IABR, "IABR",
1475 SPR_NOACCESS, SPR_NOACCESS,
1476 &spr_read_generic, &spr_write_generic,
1478 /* XXX : not implemented */
1479 spr_register(env, SPR_IABR2, "IABR2",
1480 SPR_NOACCESS, SPR_NOACCESS,
1481 &spr_read_generic, &spr_write_generic,
1483 /* XXX : not implemented */
1484 spr_register(env, SPR_IBCR, "IBCR",
1485 SPR_NOACCESS, SPR_NOACCESS,
1486 &spr_read_generic, &spr_write_generic,
1488 /* XXX : not implemented */
1489 spr_register(env, SPR_DBCR, "DBCR",
1490 SPR_NOACCESS, SPR_NOACCESS,
1491 &spr_read_generic, &spr_write_generic,
1495 /* SPR specific to PowerPC 602 implementation */
1496 static void gen_spr_602(CPUPPCState *env)
1499 /* XXX : not implemented */
1500 spr_register(env, SPR_SER, "SER",
1501 SPR_NOACCESS, SPR_NOACCESS,
1502 &spr_read_generic, &spr_write_generic,
1504 /* XXX : not implemented */
1505 spr_register(env, SPR_SEBR, "SEBR",
1506 SPR_NOACCESS, SPR_NOACCESS,
1507 &spr_read_generic, &spr_write_generic,
1509 /* XXX : not implemented */
1510 spr_register(env, SPR_ESASRR, "ESASRR",
1511 SPR_NOACCESS, SPR_NOACCESS,
1512 &spr_read_generic, &spr_write_generic,
1514 /* Floating point status */
1515 /* XXX : not implemented */
1516 spr_register(env, SPR_SP, "SP",
1517 SPR_NOACCESS, SPR_NOACCESS,
1518 &spr_read_generic, &spr_write_generic,
1520 /* XXX : not implemented */
1521 spr_register(env, SPR_LT, "LT",
1522 SPR_NOACCESS, SPR_NOACCESS,
1523 &spr_read_generic, &spr_write_generic,
1525 /* Watchdog timer */
1526 /* XXX : not implemented */
1527 spr_register(env, SPR_TCR, "TCR",
1528 SPR_NOACCESS, SPR_NOACCESS,
1529 &spr_read_generic, &spr_write_generic,
1531 /* Interrupt base */
1532 spr_register(env, SPR_IBR, "IBR",
1533 SPR_NOACCESS, SPR_NOACCESS,
1534 &spr_read_generic, &spr_write_generic,
1536 /* XXX : not implemented */
1537 spr_register(env, SPR_IABR, "IABR",
1538 SPR_NOACCESS, SPR_NOACCESS,
1539 &spr_read_generic, &spr_write_generic,
1543 /* SPR specific to PowerPC 601 implementation */
1544 static void gen_spr_601(CPUPPCState *env)
1546 /* Multiplication/division register */
1548 spr_register(env, SPR_MQ, "MQ",
1549 &spr_read_generic, &spr_write_generic,
1550 &spr_read_generic, &spr_write_generic,
1553 spr_register(env, SPR_601_RTCU, "RTCU",
1554 SPR_NOACCESS, SPR_NOACCESS,
1555 SPR_NOACCESS, &spr_write_601_rtcu,
1557 spr_register(env, SPR_601_VRTCU, "RTCU",
1558 &spr_read_601_rtcu, SPR_NOACCESS,
1559 &spr_read_601_rtcu, SPR_NOACCESS,
1561 spr_register(env, SPR_601_RTCL, "RTCL",
1562 SPR_NOACCESS, SPR_NOACCESS,
1563 SPR_NOACCESS, &spr_write_601_rtcl,
1565 spr_register(env, SPR_601_VRTCL, "RTCL",
1566 &spr_read_601_rtcl, SPR_NOACCESS,
1567 &spr_read_601_rtcl, SPR_NOACCESS,
1571 spr_register(env, SPR_601_UDECR, "UDECR",
1572 &spr_read_decr, SPR_NOACCESS,
1573 &spr_read_decr, SPR_NOACCESS,
1576 /* External access control */
1577 /* XXX : not implemented */
1578 spr_register(env, SPR_EAR, "EAR",
1579 SPR_NOACCESS, SPR_NOACCESS,
1580 &spr_read_generic, &spr_write_generic,
1582 /* Memory management */
1583 #if !defined(CONFIG_USER_ONLY)
1584 spr_register(env, SPR_IBAT0U, "IBAT0U",
1585 SPR_NOACCESS, SPR_NOACCESS,
1586 &spr_read_601_ubat, &spr_write_601_ubatu,
1588 spr_register(env, SPR_IBAT0L, "IBAT0L",
1589 SPR_NOACCESS, SPR_NOACCESS,
1590 &spr_read_601_ubat, &spr_write_601_ubatl,
1592 spr_register(env, SPR_IBAT1U, "IBAT1U",
1593 SPR_NOACCESS, SPR_NOACCESS,
1594 &spr_read_601_ubat, &spr_write_601_ubatu,
1596 spr_register(env, SPR_IBAT1L, "IBAT1L",
1597 SPR_NOACCESS, SPR_NOACCESS,
1598 &spr_read_601_ubat, &spr_write_601_ubatl,
1600 spr_register(env, SPR_IBAT2U, "IBAT2U",
1601 SPR_NOACCESS, SPR_NOACCESS,
1602 &spr_read_601_ubat, &spr_write_601_ubatu,
1604 spr_register(env, SPR_IBAT2L, "IBAT2L",
1605 SPR_NOACCESS, SPR_NOACCESS,
1606 &spr_read_601_ubat, &spr_write_601_ubatl,
1608 spr_register(env, SPR_IBAT3U, "IBAT3U",
1609 SPR_NOACCESS, SPR_NOACCESS,
1610 &spr_read_601_ubat, &spr_write_601_ubatu,
1612 spr_register(env, SPR_IBAT3L, "IBAT3L",
1613 SPR_NOACCESS, SPR_NOACCESS,
1614 &spr_read_601_ubat, &spr_write_601_ubatl,
1620 static void gen_spr_74xx(CPUPPCState *env)
1622 /* Processor identification */
1623 spr_register(env, SPR_PIR, "PIR",
1624 SPR_NOACCESS, SPR_NOACCESS,
1625 &spr_read_generic, &spr_write_pir,
1627 /* XXX : not implemented */
1628 spr_register(env, SPR_74XX_MMCR2, "MMCR2",
1629 SPR_NOACCESS, SPR_NOACCESS,
1630 &spr_read_generic, &spr_write_generic,
1632 /* XXX : not implemented */
1633 spr_register(env, SPR_74XX_UMMCR2, "UMMCR2",
1634 &spr_read_ureg, SPR_NOACCESS,
1635 &spr_read_ureg, SPR_NOACCESS,
1637 /* XXX: not implemented */
1638 spr_register(env, SPR_BAMR, "BAMR",
1639 SPR_NOACCESS, SPR_NOACCESS,
1640 &spr_read_generic, &spr_write_generic,
1642 /* XXX : not implemented */
1643 spr_register(env, SPR_MSSCR0, "MSSCR0",
1644 SPR_NOACCESS, SPR_NOACCESS,
1645 &spr_read_generic, &spr_write_generic,
1647 /* Hardware implementation registers */
1648 /* XXX : not implemented */
1649 spr_register(env, SPR_HID0, "HID0",
1650 SPR_NOACCESS, SPR_NOACCESS,
1651 &spr_read_generic, &spr_write_generic,
1653 /* XXX : not implemented */
1654 spr_register(env, SPR_HID1, "HID1",
1655 SPR_NOACCESS, SPR_NOACCESS,
1656 &spr_read_generic, &spr_write_generic,
1659 spr_register(env, SPR_VRSAVE, "VRSAVE",
1660 &spr_read_generic, &spr_write_generic,
1661 &spr_read_generic, &spr_write_generic,
1663 /* XXX : not implemented */
1664 spr_register(env, SPR_L2CR, "L2CR",
1665 SPR_NOACCESS, SPR_NOACCESS,
1666 &spr_read_generic, spr_access_nop,
1668 /* Not strictly an SPR */
1669 vscr_init(env, 0x00010000);
1672 static void gen_l3_ctrl(CPUPPCState *env)
1675 /* XXX : not implemented */
1676 spr_register(env, SPR_L3CR, "L3CR",
1677 SPR_NOACCESS, SPR_NOACCESS,
1678 &spr_read_generic, &spr_write_generic,
1681 /* XXX : not implemented */
1682 spr_register(env, SPR_L3ITCR0, "L3ITCR0",
1683 SPR_NOACCESS, SPR_NOACCESS,
1684 &spr_read_generic, &spr_write_generic,
1687 /* XXX : not implemented */
1688 spr_register(env, SPR_L3PM, "L3PM",
1689 SPR_NOACCESS, SPR_NOACCESS,
1690 &spr_read_generic, &spr_write_generic,
1694 static void gen_74xx_soft_tlb(CPUPPCState *env, int nb_tlbs, int nb_ways)
1696 #if !defined(CONFIG_USER_ONLY)
1697 env->nb_tlb = nb_tlbs;
1698 env->nb_ways = nb_ways;
1700 env->tlb_type = TLB_6XX;
1701 /* XXX : not implemented */
1702 spr_register(env, SPR_PTEHI, "PTEHI",
1703 SPR_NOACCESS, SPR_NOACCESS,
1704 &spr_read_generic, &spr_write_generic,
1706 /* XXX : not implemented */
1707 spr_register(env, SPR_PTELO, "PTELO",
1708 SPR_NOACCESS, SPR_NOACCESS,
1709 &spr_read_generic, &spr_write_generic,
1711 /* XXX : not implemented */
1712 spr_register(env, SPR_TLBMISS, "TLBMISS",
1713 SPR_NOACCESS, SPR_NOACCESS,
1714 &spr_read_generic, &spr_write_generic,
1719 #if !defined(CONFIG_USER_ONLY)
1720 static void spr_write_e500_l1csr0(DisasContext *ctx, int sprn, int gprn)
1722 TCGv t0 = tcg_temp_new();
1724 tcg_gen_andi_tl(t0, cpu_gpr[gprn], L1CSR0_DCE | L1CSR0_CPE);
1725 gen_store_spr(sprn, t0);
1729 static void spr_write_e500_l1csr1(DisasContext *ctx, int sprn, int gprn)
1731 TCGv t0 = tcg_temp_new();
1733 tcg_gen_andi_tl(t0, cpu_gpr[gprn], L1CSR1_ICE | L1CSR1_CPE);
1734 gen_store_spr(sprn, t0);
1738 static void spr_write_booke206_mmucsr0(DisasContext *ctx, int sprn, int gprn)
1740 gen_helper_booke206_tlbflush(cpu_env, cpu_gpr[gprn]);
1743 static void spr_write_booke_pid(DisasContext *ctx, int sprn, int gprn)
1745 TCGv_i32 t0 = tcg_const_i32(sprn);
1746 gen_helper_booke_setpid(cpu_env, t0, cpu_gpr[gprn]);
1747 tcg_temp_free_i32(t0);
1749 static void spr_write_eplc(DisasContext *ctx, int sprn, int gprn)
1751 gen_helper_booke_set_eplc(cpu_env, cpu_gpr[gprn]);
1753 static void spr_write_epsc(DisasContext *ctx, int sprn, int gprn)
1755 gen_helper_booke_set_epsc(cpu_env, cpu_gpr[gprn]);
1760 static void gen_spr_usprg3(CPUPPCState *env)
1762 spr_register(env, SPR_USPRG3, "USPRG3",
1763 &spr_read_ureg, SPR_NOACCESS,
1764 &spr_read_ureg, SPR_NOACCESS,
1768 static void gen_spr_usprgh(CPUPPCState *env)
1770 spr_register(env, SPR_USPRG4, "USPRG4",
1771 &spr_read_ureg, SPR_NOACCESS,
1772 &spr_read_ureg, SPR_NOACCESS,
1774 spr_register(env, SPR_USPRG5, "USPRG5",
1775 &spr_read_ureg, SPR_NOACCESS,
1776 &spr_read_ureg, SPR_NOACCESS,
1778 spr_register(env, SPR_USPRG6, "USPRG6",
1779 &spr_read_ureg, SPR_NOACCESS,
1780 &spr_read_ureg, SPR_NOACCESS,
1782 spr_register(env, SPR_USPRG7, "USPRG7",
1783 &spr_read_ureg, SPR_NOACCESS,
1784 &spr_read_ureg, SPR_NOACCESS,
1788 /* PowerPC BookE SPR */
1789 static void gen_spr_BookE(CPUPPCState *env, uint64_t ivor_mask)
1791 const char *ivor_names[64] = {
1792 "IVOR0", "IVOR1", "IVOR2", "IVOR3",
1793 "IVOR4", "IVOR5", "IVOR6", "IVOR7",
1794 "IVOR8", "IVOR9", "IVOR10", "IVOR11",
1795 "IVOR12", "IVOR13", "IVOR14", "IVOR15",
1796 "IVOR16", "IVOR17", "IVOR18", "IVOR19",
1797 "IVOR20", "IVOR21", "IVOR22", "IVOR23",
1798 "IVOR24", "IVOR25", "IVOR26", "IVOR27",
1799 "IVOR28", "IVOR29", "IVOR30", "IVOR31",
1800 "IVOR32", "IVOR33", "IVOR34", "IVOR35",
1801 "IVOR36", "IVOR37", "IVOR38", "IVOR39",
1802 "IVOR40", "IVOR41", "IVOR42", "IVOR43",
1803 "IVOR44", "IVOR45", "IVOR46", "IVOR47",
1804 "IVOR48", "IVOR49", "IVOR50", "IVOR51",
1805 "IVOR52", "IVOR53", "IVOR54", "IVOR55",
1806 "IVOR56", "IVOR57", "IVOR58", "IVOR59",
1807 "IVOR60", "IVOR61", "IVOR62", "IVOR63",
1809 #define SPR_BOOKE_IVORxx (-1)
1810 int ivor_sprn[64] = {
1811 SPR_BOOKE_IVOR0, SPR_BOOKE_IVOR1, SPR_BOOKE_IVOR2, SPR_BOOKE_IVOR3,
1812 SPR_BOOKE_IVOR4, SPR_BOOKE_IVOR5, SPR_BOOKE_IVOR6, SPR_BOOKE_IVOR7,
1813 SPR_BOOKE_IVOR8, SPR_BOOKE_IVOR9, SPR_BOOKE_IVOR10, SPR_BOOKE_IVOR11,
1814 SPR_BOOKE_IVOR12, SPR_BOOKE_IVOR13, SPR_BOOKE_IVOR14, SPR_BOOKE_IVOR15,
1815 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1816 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1817 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1818 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1819 SPR_BOOKE_IVOR32, SPR_BOOKE_IVOR33, SPR_BOOKE_IVOR34, SPR_BOOKE_IVOR35,
1820 SPR_BOOKE_IVOR36, SPR_BOOKE_IVOR37, SPR_BOOKE_IVOR38, SPR_BOOKE_IVOR39,
1821 SPR_BOOKE_IVOR40, SPR_BOOKE_IVOR41, SPR_BOOKE_IVOR42, SPR_BOOKE_IVORxx,
1822 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1823 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1824 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1825 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1826 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1830 /* Interrupt processing */
1831 spr_register(env, SPR_BOOKE_CSRR0, "CSRR0",
1832 SPR_NOACCESS, SPR_NOACCESS,
1833 &spr_read_generic, &spr_write_generic,
1835 spr_register(env, SPR_BOOKE_CSRR1, "CSRR1",
1836 SPR_NOACCESS, SPR_NOACCESS,
1837 &spr_read_generic, &spr_write_generic,
1840 /* XXX : not implemented */
1841 spr_register(env, SPR_BOOKE_IAC1, "IAC1",
1842 SPR_NOACCESS, SPR_NOACCESS,
1843 &spr_read_generic, &spr_write_generic,
1845 /* XXX : not implemented */
1846 spr_register(env, SPR_BOOKE_IAC2, "IAC2",
1847 SPR_NOACCESS, SPR_NOACCESS,
1848 &spr_read_generic, &spr_write_generic,
1850 /* XXX : not implemented */
1851 spr_register(env, SPR_BOOKE_DAC1, "DAC1",
1852 SPR_NOACCESS, SPR_NOACCESS,
1853 &spr_read_generic, &spr_write_generic,
1855 /* XXX : not implemented */
1856 spr_register(env, SPR_BOOKE_DAC2, "DAC2",
1857 SPR_NOACCESS, SPR_NOACCESS,
1858 &spr_read_generic, &spr_write_generic,
1860 /* XXX : not implemented */
1861 spr_register(env, SPR_BOOKE_DBCR0, "DBCR0",
1862 SPR_NOACCESS, SPR_NOACCESS,
1863 &spr_read_generic, &spr_write_40x_dbcr0,
1865 /* XXX : not implemented */
1866 spr_register(env, SPR_BOOKE_DBCR1, "DBCR1",
1867 SPR_NOACCESS, SPR_NOACCESS,
1868 &spr_read_generic, &spr_write_generic,
1870 /* XXX : not implemented */
1871 spr_register(env, SPR_BOOKE_DBCR2, "DBCR2",
1872 SPR_NOACCESS, SPR_NOACCESS,
1873 &spr_read_generic, &spr_write_generic,
1875 spr_register(env, SPR_BOOKE_DSRR0, "DSRR0",
1876 SPR_NOACCESS, SPR_NOACCESS,
1877 &spr_read_generic, &spr_write_generic,
1879 spr_register(env, SPR_BOOKE_DSRR1, "DSRR1",
1880 SPR_NOACCESS, SPR_NOACCESS,
1881 &spr_read_generic, &spr_write_generic,
1883 /* XXX : not implemented */
1884 spr_register(env, SPR_BOOKE_DBSR, "DBSR",
1885 SPR_NOACCESS, SPR_NOACCESS,
1886 &spr_read_generic, &spr_write_clear,
1888 spr_register(env, SPR_BOOKE_DEAR, "DEAR",
1889 SPR_NOACCESS, SPR_NOACCESS,
1890 &spr_read_generic, &spr_write_generic,
1892 spr_register(env, SPR_BOOKE_ESR, "ESR",
1893 SPR_NOACCESS, SPR_NOACCESS,
1894 &spr_read_generic, &spr_write_generic,
1896 spr_register(env, SPR_BOOKE_IVPR, "IVPR",
1897 SPR_NOACCESS, SPR_NOACCESS,
1898 &spr_read_generic, &spr_write_excp_prefix,
1900 /* Exception vectors */
1901 for (i = 0; i < 64; i++) {
1902 if (ivor_mask & (1ULL << i)) {
1903 if (ivor_sprn[i] == SPR_BOOKE_IVORxx) {
1904 fprintf(stderr, "ERROR: IVOR %d SPR is not defined\n", i);
1907 spr_register(env, ivor_sprn[i], ivor_names[i],
1908 SPR_NOACCESS, SPR_NOACCESS,
1909 &spr_read_generic, &spr_write_excp_vector,
1913 spr_register(env, SPR_BOOKE_PID, "PID",
1914 SPR_NOACCESS, SPR_NOACCESS,
1915 &spr_read_generic, &spr_write_booke_pid,
1917 spr_register(env, SPR_BOOKE_TCR, "TCR",
1918 SPR_NOACCESS, SPR_NOACCESS,
1919 &spr_read_generic, &spr_write_booke_tcr,
1921 spr_register(env, SPR_BOOKE_TSR, "TSR",
1922 SPR_NOACCESS, SPR_NOACCESS,
1923 &spr_read_generic, &spr_write_booke_tsr,
1926 spr_register(env, SPR_DECR, "DECR",
1927 SPR_NOACCESS, SPR_NOACCESS,
1928 &spr_read_decr, &spr_write_decr,
1930 spr_register(env, SPR_BOOKE_DECAR, "DECAR",
1931 SPR_NOACCESS, SPR_NOACCESS,
1932 SPR_NOACCESS, &spr_write_generic,
1935 spr_register(env, SPR_USPRG0, "USPRG0",
1936 &spr_read_generic, &spr_write_generic,
1937 &spr_read_generic, &spr_write_generic,
1939 spr_register(env, SPR_SPRG4, "SPRG4",
1940 SPR_NOACCESS, SPR_NOACCESS,
1941 &spr_read_generic, &spr_write_generic,
1943 spr_register(env, SPR_SPRG5, "SPRG5",
1944 SPR_NOACCESS, SPR_NOACCESS,
1945 &spr_read_generic, &spr_write_generic,
1947 spr_register(env, SPR_SPRG6, "SPRG6",
1948 SPR_NOACCESS, SPR_NOACCESS,
1949 &spr_read_generic, &spr_write_generic,
1951 spr_register(env, SPR_SPRG7, "SPRG7",
1952 SPR_NOACCESS, SPR_NOACCESS,
1953 &spr_read_generic, &spr_write_generic,
1955 spr_register(env, SPR_BOOKE_SPRG8, "SPRG8",
1956 SPR_NOACCESS, SPR_NOACCESS,
1957 &spr_read_generic, &spr_write_generic,
1959 spr_register(env, SPR_BOOKE_SPRG9, "SPRG9",
1960 SPR_NOACCESS, SPR_NOACCESS,
1961 &spr_read_generic, &spr_write_generic,
1965 static inline uint32_t gen_tlbncfg(uint32_t assoc, uint32_t minsize,
1966 uint32_t maxsize, uint32_t flags,
1969 return (assoc << TLBnCFG_ASSOC_SHIFT) |
1970 (minsize << TLBnCFG_MINSIZE_SHIFT) |
1971 (maxsize << TLBnCFG_MAXSIZE_SHIFT) |
1975 /* BookE 2.06 storage control registers */
1976 static void gen_spr_BookE206(CPUPPCState *env, uint32_t mas_mask,
1977 uint32_t *tlbncfg, uint32_t mmucfg)
1979 #if !defined(CONFIG_USER_ONLY)
1980 const char *mas_names[8] = {
1981 "MAS0", "MAS1", "MAS2", "MAS3", "MAS4", "MAS5", "MAS6", "MAS7",
1984 SPR_BOOKE_MAS0, SPR_BOOKE_MAS1, SPR_BOOKE_MAS2, SPR_BOOKE_MAS3,
1985 SPR_BOOKE_MAS4, SPR_BOOKE_MAS5, SPR_BOOKE_MAS6, SPR_BOOKE_MAS7,
1989 /* TLB assist registers */
1990 /* XXX : not implemented */
1991 for (i = 0; i < 8; i++) {
1992 void (*uea_write)(DisasContext *ctx, int sprn, int gprn) =
1993 &spr_write_generic32;
1994 if (i == 2 && (mas_mask & (1 << i)) && (env->insns_flags & PPC_64B)) {
1995 uea_write = &spr_write_generic;
1997 if (mas_mask & (1 << i)) {
1998 spr_register(env, mas_sprn[i], mas_names[i],
1999 SPR_NOACCESS, SPR_NOACCESS,
2000 &spr_read_generic, uea_write,
2004 if (env->nb_pids > 1) {
2005 /* XXX : not implemented */
2006 spr_register(env, SPR_BOOKE_PID1, "PID1",
2007 SPR_NOACCESS, SPR_NOACCESS,
2008 &spr_read_generic, &spr_write_booke_pid,
2011 if (env->nb_pids > 2) {
2012 /* XXX : not implemented */
2013 spr_register(env, SPR_BOOKE_PID2, "PID2",
2014 SPR_NOACCESS, SPR_NOACCESS,
2015 &spr_read_generic, &spr_write_booke_pid,
2019 spr_register(env, SPR_BOOKE_EPLC, "EPLC",
2020 SPR_NOACCESS, SPR_NOACCESS,
2021 &spr_read_generic, &spr_write_eplc,
2023 spr_register(env, SPR_BOOKE_EPSC, "EPSC",
2024 SPR_NOACCESS, SPR_NOACCESS,
2025 &spr_read_generic, &spr_write_epsc,
2028 /* XXX : not implemented */
2029 spr_register(env, SPR_MMUCFG, "MMUCFG",
2030 SPR_NOACCESS, SPR_NOACCESS,
2031 &spr_read_generic, SPR_NOACCESS,
2033 switch (env->nb_ways) {
2035 spr_register(env, SPR_BOOKE_TLB3CFG, "TLB3CFG",
2036 SPR_NOACCESS, SPR_NOACCESS,
2037 &spr_read_generic, SPR_NOACCESS,
2041 spr_register(env, SPR_BOOKE_TLB2CFG, "TLB2CFG",
2042 SPR_NOACCESS, SPR_NOACCESS,
2043 &spr_read_generic, SPR_NOACCESS,
2047 spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG",
2048 SPR_NOACCESS, SPR_NOACCESS,
2049 &spr_read_generic, SPR_NOACCESS,
2053 spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG",
2054 SPR_NOACCESS, SPR_NOACCESS,
2055 &spr_read_generic, SPR_NOACCESS,
2064 gen_spr_usprgh(env);
2067 /* SPR specific to PowerPC 440 implementation */
2068 static void gen_spr_440(CPUPPCState *env)
2071 /* XXX : not implemented */
2072 spr_register(env, SPR_440_DNV0, "DNV0",
2073 SPR_NOACCESS, SPR_NOACCESS,
2074 &spr_read_generic, &spr_write_generic,
2076 /* XXX : not implemented */
2077 spr_register(env, SPR_440_DNV1, "DNV1",
2078 SPR_NOACCESS, SPR_NOACCESS,
2079 &spr_read_generic, &spr_write_generic,
2081 /* XXX : not implemented */
2082 spr_register(env, SPR_440_DNV2, "DNV2",
2083 SPR_NOACCESS, SPR_NOACCESS,
2084 &spr_read_generic, &spr_write_generic,
2086 /* XXX : not implemented */
2087 spr_register(env, SPR_440_DNV3, "DNV3",
2088 SPR_NOACCESS, SPR_NOACCESS,
2089 &spr_read_generic, &spr_write_generic,
2091 /* XXX : not implemented */
2092 spr_register(env, SPR_440_DTV0, "DTV0",
2093 SPR_NOACCESS, SPR_NOACCESS,
2094 &spr_read_generic, &spr_write_generic,
2096 /* XXX : not implemented */
2097 spr_register(env, SPR_440_DTV1, "DTV1",
2098 SPR_NOACCESS, SPR_NOACCESS,
2099 &spr_read_generic, &spr_write_generic,
2101 /* XXX : not implemented */
2102 spr_register(env, SPR_440_DTV2, "DTV2",
2103 SPR_NOACCESS, SPR_NOACCESS,
2104 &spr_read_generic, &spr_write_generic,
2106 /* XXX : not implemented */
2107 spr_register(env, SPR_440_DTV3, "DTV3",
2108 SPR_NOACCESS, SPR_NOACCESS,
2109 &spr_read_generic, &spr_write_generic,
2111 /* XXX : not implemented */
2112 spr_register(env, SPR_440_DVLIM, "DVLIM",
2113 SPR_NOACCESS, SPR_NOACCESS,
2114 &spr_read_generic, &spr_write_generic,
2116 /* XXX : not implemented */
2117 spr_register(env, SPR_440_INV0, "INV0",
2118 SPR_NOACCESS, SPR_NOACCESS,
2119 &spr_read_generic, &spr_write_generic,
2121 /* XXX : not implemented */
2122 spr_register(env, SPR_440_INV1, "INV1",
2123 SPR_NOACCESS, SPR_NOACCESS,
2124 &spr_read_generic, &spr_write_generic,
2126 /* XXX : not implemented */
2127 spr_register(env, SPR_440_INV2, "INV2",
2128 SPR_NOACCESS, SPR_NOACCESS,
2129 &spr_read_generic, &spr_write_generic,
2131 /* XXX : not implemented */
2132 spr_register(env, SPR_440_INV3, "INV3",
2133 SPR_NOACCESS, SPR_NOACCESS,
2134 &spr_read_generic, &spr_write_generic,
2136 /* XXX : not implemented */
2137 spr_register(env, SPR_440_ITV0, "ITV0",
2138 SPR_NOACCESS, SPR_NOACCESS,
2139 &spr_read_generic, &spr_write_generic,
2141 /* XXX : not implemented */
2142 spr_register(env, SPR_440_ITV1, "ITV1",
2143 SPR_NOACCESS, SPR_NOACCESS,
2144 &spr_read_generic, &spr_write_generic,
2146 /* XXX : not implemented */
2147 spr_register(env, SPR_440_ITV2, "ITV2",
2148 SPR_NOACCESS, SPR_NOACCESS,
2149 &spr_read_generic, &spr_write_generic,
2151 /* XXX : not implemented */
2152 spr_register(env, SPR_440_ITV3, "ITV3",
2153 SPR_NOACCESS, SPR_NOACCESS,
2154 &spr_read_generic, &spr_write_generic,
2156 /* XXX : not implemented */
2157 spr_register(env, SPR_440_IVLIM, "IVLIM",
2158 SPR_NOACCESS, SPR_NOACCESS,
2159 &spr_read_generic, &spr_write_generic,
2162 /* XXX : not implemented */
2163 spr_register(env, SPR_BOOKE_DCDBTRH, "DCDBTRH",
2164 SPR_NOACCESS, SPR_NOACCESS,
2165 &spr_read_generic, SPR_NOACCESS,
2167 /* XXX : not implemented */
2168 spr_register(env, SPR_BOOKE_DCDBTRL, "DCDBTRL",
2169 SPR_NOACCESS, SPR_NOACCESS,
2170 &spr_read_generic, SPR_NOACCESS,
2172 /* XXX : not implemented */
2173 spr_register(env, SPR_BOOKE_ICDBDR, "ICDBDR",
2174 SPR_NOACCESS, SPR_NOACCESS,
2175 &spr_read_generic, SPR_NOACCESS,
2177 /* XXX : not implemented */
2178 spr_register(env, SPR_BOOKE_ICDBTRH, "ICDBTRH",
2179 SPR_NOACCESS, SPR_NOACCESS,
2180 &spr_read_generic, SPR_NOACCESS,
2182 /* XXX : not implemented */
2183 spr_register(env, SPR_BOOKE_ICDBTRL, "ICDBTRL",
2184 SPR_NOACCESS, SPR_NOACCESS,
2185 &spr_read_generic, SPR_NOACCESS,
2187 /* XXX : not implemented */
2188 spr_register(env, SPR_440_DBDR, "DBDR",
2189 SPR_NOACCESS, SPR_NOACCESS,
2190 &spr_read_generic, &spr_write_generic,
2192 /* Processor control */
2193 spr_register(env, SPR_4xx_CCR0, "CCR0",
2194 SPR_NOACCESS, SPR_NOACCESS,
2195 &spr_read_generic, &spr_write_generic,
2197 spr_register(env, SPR_440_RSTCFG, "RSTCFG",
2198 SPR_NOACCESS, SPR_NOACCESS,
2199 &spr_read_generic, SPR_NOACCESS,
2201 /* Storage control */
2202 spr_register(env, SPR_440_MMUCR, "MMUCR",
2203 SPR_NOACCESS, SPR_NOACCESS,
2204 &spr_read_generic, &spr_write_generic,
2208 /* SPR shared between PowerPC 40x implementations */
2209 static void gen_spr_40x(CPUPPCState *env)
2212 /* not emulated, as QEMU do not emulate caches */
2213 spr_register(env, SPR_40x_DCCR, "DCCR",
2214 SPR_NOACCESS, SPR_NOACCESS,
2215 &spr_read_generic, &spr_write_generic,
2217 /* not emulated, as QEMU do not emulate caches */
2218 spr_register(env, SPR_40x_ICCR, "ICCR",
2219 SPR_NOACCESS, SPR_NOACCESS,
2220 &spr_read_generic, &spr_write_generic,
2222 /* not emulated, as QEMU do not emulate caches */
2223 spr_register(env, SPR_BOOKE_ICDBDR, "ICDBDR",
2224 SPR_NOACCESS, SPR_NOACCESS,
2225 &spr_read_generic, SPR_NOACCESS,
2228 spr_register(env, SPR_40x_DEAR, "DEAR",
2229 SPR_NOACCESS, SPR_NOACCESS,
2230 &spr_read_generic, &spr_write_generic,
2232 spr_register(env, SPR_40x_ESR, "ESR",
2233 SPR_NOACCESS, SPR_NOACCESS,
2234 &spr_read_generic, &spr_write_generic,
2236 spr_register(env, SPR_40x_EVPR, "EVPR",
2237 SPR_NOACCESS, SPR_NOACCESS,
2238 &spr_read_generic, &spr_write_excp_prefix,
2240 spr_register(env, SPR_40x_SRR2, "SRR2",
2241 &spr_read_generic, &spr_write_generic,
2242 &spr_read_generic, &spr_write_generic,
2244 spr_register(env, SPR_40x_SRR3, "SRR3",
2245 &spr_read_generic, &spr_write_generic,
2246 &spr_read_generic, &spr_write_generic,
2249 spr_register(env, SPR_40x_PIT, "PIT",
2250 SPR_NOACCESS, SPR_NOACCESS,
2251 &spr_read_40x_pit, &spr_write_40x_pit,
2253 spr_register(env, SPR_40x_TCR, "TCR",
2254 SPR_NOACCESS, SPR_NOACCESS,
2255 &spr_read_generic, &spr_write_booke_tcr,
2257 spr_register(env, SPR_40x_TSR, "TSR",
2258 SPR_NOACCESS, SPR_NOACCESS,
2259 &spr_read_generic, &spr_write_booke_tsr,
2263 /* SPR specific to PowerPC 405 implementation */
2264 static void gen_spr_405(CPUPPCState *env)
2267 spr_register(env, SPR_40x_PID, "PID",
2268 SPR_NOACCESS, SPR_NOACCESS,
2269 &spr_read_generic, &spr_write_generic,
2271 spr_register(env, SPR_4xx_CCR0, "CCR0",
2272 SPR_NOACCESS, SPR_NOACCESS,
2273 &spr_read_generic, &spr_write_generic,
2275 /* Debug interface */
2276 /* XXX : not implemented */
2277 spr_register(env, SPR_40x_DBCR0, "DBCR0",
2278 SPR_NOACCESS, SPR_NOACCESS,
2279 &spr_read_generic, &spr_write_40x_dbcr0,
2281 /* XXX : not implemented */
2282 spr_register(env, SPR_405_DBCR1, "DBCR1",
2283 SPR_NOACCESS, SPR_NOACCESS,
2284 &spr_read_generic, &spr_write_generic,
2286 /* XXX : not implemented */
2287 spr_register(env, SPR_40x_DBSR, "DBSR",
2288 SPR_NOACCESS, SPR_NOACCESS,
2289 &spr_read_generic, &spr_write_clear,
2290 /* Last reset was system reset */
2292 /* XXX : not implemented */
2293 spr_register(env, SPR_40x_DAC1, "DAC1",
2294 SPR_NOACCESS, SPR_NOACCESS,
2295 &spr_read_generic, &spr_write_generic,
2297 spr_register(env, SPR_40x_DAC2, "DAC2",
2298 SPR_NOACCESS, SPR_NOACCESS,
2299 &spr_read_generic, &spr_write_generic,
2301 /* XXX : not implemented */
2302 spr_register(env, SPR_405_DVC1, "DVC1",
2303 SPR_NOACCESS, SPR_NOACCESS,
2304 &spr_read_generic, &spr_write_generic,
2306 /* XXX : not implemented */
2307 spr_register(env, SPR_405_DVC2, "DVC2",
2308 SPR_NOACCESS, SPR_NOACCESS,
2309 &spr_read_generic, &spr_write_generic,
2311 /* XXX : not implemented */
2312 spr_register(env, SPR_40x_IAC1, "IAC1",
2313 SPR_NOACCESS, SPR_NOACCESS,
2314 &spr_read_generic, &spr_write_generic,
2316 spr_register(env, SPR_40x_IAC2, "IAC2",
2317 SPR_NOACCESS, SPR_NOACCESS,
2318 &spr_read_generic, &spr_write_generic,
2320 /* XXX : not implemented */
2321 spr_register(env, SPR_405_IAC3, "IAC3",
2322 SPR_NOACCESS, SPR_NOACCESS,
2323 &spr_read_generic, &spr_write_generic,
2325 /* XXX : not implemented */
2326 spr_register(env, SPR_405_IAC4, "IAC4",
2327 SPR_NOACCESS, SPR_NOACCESS,
2328 &spr_read_generic, &spr_write_generic,
2330 /* Storage control */
2331 /* XXX: TODO: not implemented */
2332 spr_register(env, SPR_405_SLER, "SLER",
2333 SPR_NOACCESS, SPR_NOACCESS,
2334 &spr_read_generic, &spr_write_40x_sler,
2336 spr_register(env, SPR_40x_ZPR, "ZPR",
2337 SPR_NOACCESS, SPR_NOACCESS,
2338 &spr_read_generic, &spr_write_generic,
2340 /* XXX : not implemented */
2341 spr_register(env, SPR_405_SU0R, "SU0R",
2342 SPR_NOACCESS, SPR_NOACCESS,
2343 &spr_read_generic, &spr_write_generic,
2346 spr_register(env, SPR_USPRG0, "USPRG0",
2347 &spr_read_ureg, SPR_NOACCESS,
2348 &spr_read_ureg, SPR_NOACCESS,
2350 spr_register(env, SPR_SPRG4, "SPRG4",
2351 SPR_NOACCESS, SPR_NOACCESS,
2352 &spr_read_generic, &spr_write_generic,
2354 spr_register(env, SPR_SPRG5, "SPRG5",
2355 SPR_NOACCESS, SPR_NOACCESS,
2356 spr_read_generic, &spr_write_generic,
2358 spr_register(env, SPR_SPRG6, "SPRG6",
2359 SPR_NOACCESS, SPR_NOACCESS,
2360 spr_read_generic, &spr_write_generic,
2362 spr_register(env, SPR_SPRG7, "SPRG7",
2363 SPR_NOACCESS, SPR_NOACCESS,
2364 spr_read_generic, &spr_write_generic,
2366 gen_spr_usprgh(env);
2369 /* SPR shared between PowerPC 401 & 403 implementations */
2370 static void gen_spr_401_403(CPUPPCState *env)
2373 spr_register(env, SPR_403_VTBL, "TBL",
2374 &spr_read_tbl, SPR_NOACCESS,
2375 &spr_read_tbl, SPR_NOACCESS,
2377 spr_register(env, SPR_403_TBL, "TBL",
2378 SPR_NOACCESS, SPR_NOACCESS,
2379 SPR_NOACCESS, &spr_write_tbl,
2381 spr_register(env, SPR_403_VTBU, "TBU",
2382 &spr_read_tbu, SPR_NOACCESS,
2383 &spr_read_tbu, SPR_NOACCESS,
2385 spr_register(env, SPR_403_TBU, "TBU",
2386 SPR_NOACCESS, SPR_NOACCESS,
2387 SPR_NOACCESS, &spr_write_tbu,
2390 /* not emulated, as QEMU do not emulate caches */
2391 spr_register(env, SPR_403_CDBCR, "CDBCR",
2392 SPR_NOACCESS, SPR_NOACCESS,
2393 &spr_read_generic, &spr_write_generic,
2397 /* SPR specific to PowerPC 401 implementation */
2398 static void gen_spr_401(CPUPPCState *env)
2400 /* Debug interface */
2401 /* XXX : not implemented */
2402 spr_register(env, SPR_40x_DBCR0, "DBCR",
2403 SPR_NOACCESS, SPR_NOACCESS,
2404 &spr_read_generic, &spr_write_40x_dbcr0,
2406 /* XXX : not implemented */
2407 spr_register(env, SPR_40x_DBSR, "DBSR",
2408 SPR_NOACCESS, SPR_NOACCESS,
2409 &spr_read_generic, &spr_write_clear,
2410 /* Last reset was system reset */
2412 /* XXX : not implemented */
2413 spr_register(env, SPR_40x_DAC1, "DAC",
2414 SPR_NOACCESS, SPR_NOACCESS,
2415 &spr_read_generic, &spr_write_generic,
2417 /* XXX : not implemented */
2418 spr_register(env, SPR_40x_IAC1, "IAC",
2419 SPR_NOACCESS, SPR_NOACCESS,
2420 &spr_read_generic, &spr_write_generic,
2422 /* Storage control */
2423 /* XXX: TODO: not implemented */
2424 spr_register(env, SPR_405_SLER, "SLER",
2425 SPR_NOACCESS, SPR_NOACCESS,
2426 &spr_read_generic, &spr_write_40x_sler,
2428 /* not emulated, as QEMU never does speculative access */
2429 spr_register(env, SPR_40x_SGR, "SGR",
2430 SPR_NOACCESS, SPR_NOACCESS,
2431 &spr_read_generic, &spr_write_generic,
2433 /* not emulated, as QEMU do not emulate caches */
2434 spr_register(env, SPR_40x_DCWR, "DCWR",
2435 SPR_NOACCESS, SPR_NOACCESS,
2436 &spr_read_generic, &spr_write_generic,
2440 static void gen_spr_401x2(CPUPPCState *env)
2443 spr_register(env, SPR_40x_PID, "PID",
2444 SPR_NOACCESS, SPR_NOACCESS,
2445 &spr_read_generic, &spr_write_generic,
2447 spr_register(env, SPR_40x_ZPR, "ZPR",
2448 SPR_NOACCESS, SPR_NOACCESS,
2449 &spr_read_generic, &spr_write_generic,
2453 /* SPR specific to PowerPC 403 implementation */
2454 static void gen_spr_403(CPUPPCState *env)
2456 /* Debug interface */
2457 /* XXX : not implemented */
2458 spr_register(env, SPR_40x_DBCR0, "DBCR0",
2459 SPR_NOACCESS, SPR_NOACCESS,
2460 &spr_read_generic, &spr_write_40x_dbcr0,
2462 /* XXX : not implemented */
2463 spr_register(env, SPR_40x_DBSR, "DBSR",
2464 SPR_NOACCESS, SPR_NOACCESS,
2465 &spr_read_generic, &spr_write_clear,
2466 /* Last reset was system reset */
2468 /* XXX : not implemented */
2469 spr_register(env, SPR_40x_DAC1, "DAC1",
2470 SPR_NOACCESS, SPR_NOACCESS,
2471 &spr_read_generic, &spr_write_generic,
2473 /* XXX : not implemented */
2474 spr_register(env, SPR_40x_DAC2, "DAC2",
2475 SPR_NOACCESS, SPR_NOACCESS,
2476 &spr_read_generic, &spr_write_generic,
2478 /* XXX : not implemented */
2479 spr_register(env, SPR_40x_IAC1, "IAC1",
2480 SPR_NOACCESS, SPR_NOACCESS,
2481 &spr_read_generic, &spr_write_generic,
2483 /* XXX : not implemented */
2484 spr_register(env, SPR_40x_IAC2, "IAC2",
2485 SPR_NOACCESS, SPR_NOACCESS,
2486 &spr_read_generic, &spr_write_generic,
2490 static void gen_spr_403_real(CPUPPCState *env)
2492 spr_register(env, SPR_403_PBL1, "PBL1",
2493 SPR_NOACCESS, SPR_NOACCESS,
2494 &spr_read_403_pbr, &spr_write_403_pbr,
2496 spr_register(env, SPR_403_PBU1, "PBU1",
2497 SPR_NOACCESS, SPR_NOACCESS,
2498 &spr_read_403_pbr, &spr_write_403_pbr,
2500 spr_register(env, SPR_403_PBL2, "PBL2",
2501 SPR_NOACCESS, SPR_NOACCESS,
2502 &spr_read_403_pbr, &spr_write_403_pbr,
2504 spr_register(env, SPR_403_PBU2, "PBU2",
2505 SPR_NOACCESS, SPR_NOACCESS,
2506 &spr_read_403_pbr, &spr_write_403_pbr,
2510 static void gen_spr_403_mmu(CPUPPCState *env)
2513 spr_register(env, SPR_40x_PID, "PID",
2514 SPR_NOACCESS, SPR_NOACCESS,
2515 &spr_read_generic, &spr_write_generic,
2517 spr_register(env, SPR_40x_ZPR, "ZPR",
2518 SPR_NOACCESS, SPR_NOACCESS,
2519 &spr_read_generic, &spr_write_generic,
2523 /* SPR specific to PowerPC compression coprocessor extension */
2524 static void gen_spr_compress(CPUPPCState *env)
2526 /* XXX : not implemented */
2527 spr_register(env, SPR_401_SKR, "SKR",
2528 SPR_NOACCESS, SPR_NOACCESS,
2529 &spr_read_generic, &spr_write_generic,
2533 static void gen_spr_5xx_8xx(CPUPPCState *env)
2535 /* Exception processing */
2536 spr_register_kvm(env, SPR_DSISR, "DSISR",
2537 SPR_NOACCESS, SPR_NOACCESS,
2538 &spr_read_generic, &spr_write_generic,
2539 KVM_REG_PPC_DSISR, 0x00000000);
2540 spr_register_kvm(env, SPR_DAR, "DAR",
2541 SPR_NOACCESS, SPR_NOACCESS,
2542 &spr_read_generic, &spr_write_generic,
2543 KVM_REG_PPC_DAR, 0x00000000);
2545 spr_register(env, SPR_DECR, "DECR",
2546 SPR_NOACCESS, SPR_NOACCESS,
2547 &spr_read_decr, &spr_write_decr,
2549 /* XXX : not implemented */
2550 spr_register(env, SPR_MPC_EIE, "EIE",
2551 SPR_NOACCESS, SPR_NOACCESS,
2552 &spr_read_generic, &spr_write_generic,
2554 /* XXX : not implemented */
2555 spr_register(env, SPR_MPC_EID, "EID",
2556 SPR_NOACCESS, SPR_NOACCESS,
2557 &spr_read_generic, &spr_write_generic,
2559 /* XXX : not implemented */
2560 spr_register(env, SPR_MPC_NRI, "NRI",
2561 SPR_NOACCESS, SPR_NOACCESS,
2562 &spr_read_generic, &spr_write_generic,
2564 /* XXX : not implemented */
2565 spr_register(env, SPR_MPC_CMPA, "CMPA",
2566 SPR_NOACCESS, SPR_NOACCESS,
2567 &spr_read_generic, &spr_write_generic,
2569 /* XXX : not implemented */
2570 spr_register(env, SPR_MPC_CMPB, "CMPB",
2571 SPR_NOACCESS, SPR_NOACCESS,
2572 &spr_read_generic, &spr_write_generic,
2574 /* XXX : not implemented */
2575 spr_register(env, SPR_MPC_CMPC, "CMPC",
2576 SPR_NOACCESS, SPR_NOACCESS,
2577 &spr_read_generic, &spr_write_generic,
2579 /* XXX : not implemented */
2580 spr_register(env, SPR_MPC_CMPD, "CMPD",
2581 SPR_NOACCESS, SPR_NOACCESS,
2582 &spr_read_generic, &spr_write_generic,
2584 /* XXX : not implemented */
2585 spr_register(env, SPR_MPC_ECR, "ECR",
2586 SPR_NOACCESS, SPR_NOACCESS,
2587 &spr_read_generic, &spr_write_generic,
2589 /* XXX : not implemented */
2590 spr_register(env, SPR_MPC_DER, "DER",
2591 SPR_NOACCESS, SPR_NOACCESS,
2592 &spr_read_generic, &spr_write_generic,
2594 /* XXX : not implemented */
2595 spr_register(env, SPR_MPC_COUNTA, "COUNTA",
2596 SPR_NOACCESS, SPR_NOACCESS,
2597 &spr_read_generic, &spr_write_generic,
2599 /* XXX : not implemented */
2600 spr_register(env, SPR_MPC_COUNTB, "COUNTB",
2601 SPR_NOACCESS, SPR_NOACCESS,
2602 &spr_read_generic, &spr_write_generic,
2604 /* XXX : not implemented */
2605 spr_register(env, SPR_MPC_CMPE, "CMPE",
2606 SPR_NOACCESS, SPR_NOACCESS,
2607 &spr_read_generic, &spr_write_generic,
2609 /* XXX : not implemented */
2610 spr_register(env, SPR_MPC_CMPF, "CMPF",
2611 SPR_NOACCESS, SPR_NOACCESS,
2612 &spr_read_generic, &spr_write_generic,
2614 /* XXX : not implemented */
2615 spr_register(env, SPR_MPC_CMPG, "CMPG",
2616 SPR_NOACCESS, SPR_NOACCESS,
2617 &spr_read_generic, &spr_write_generic,
2619 /* XXX : not implemented */
2620 spr_register(env, SPR_MPC_CMPH, "CMPH",
2621 SPR_NOACCESS, SPR_NOACCESS,
2622 &spr_read_generic, &spr_write_generic,
2624 /* XXX : not implemented */
2625 spr_register(env, SPR_MPC_LCTRL1, "LCTRL1",
2626 SPR_NOACCESS, SPR_NOACCESS,
2627 &spr_read_generic, &spr_write_generic,
2629 /* XXX : not implemented */
2630 spr_register(env, SPR_MPC_LCTRL2, "LCTRL2",
2631 SPR_NOACCESS, SPR_NOACCESS,
2632 &spr_read_generic, &spr_write_generic,
2634 /* XXX : not implemented */
2635 spr_register(env, SPR_MPC_BAR, "BAR",
2636 SPR_NOACCESS, SPR_NOACCESS,
2637 &spr_read_generic, &spr_write_generic,
2639 /* XXX : not implemented */
2640 spr_register(env, SPR_MPC_DPDR, "DPDR",
2641 SPR_NOACCESS, SPR_NOACCESS,
2642 &spr_read_generic, &spr_write_generic,
2644 /* XXX : not implemented */
2645 spr_register(env, SPR_MPC_IMMR, "IMMR",
2646 SPR_NOACCESS, SPR_NOACCESS,
2647 &spr_read_generic, &spr_write_generic,
2651 static void gen_spr_5xx(CPUPPCState *env)
2653 /* XXX : not implemented */
2654 spr_register(env, SPR_RCPU_MI_GRA, "MI_GRA",
2655 SPR_NOACCESS, SPR_NOACCESS,
2656 &spr_read_generic, &spr_write_generic,
2658 /* XXX : not implemented */
2659 spr_register(env, SPR_RCPU_L2U_GRA, "L2U_GRA",
2660 SPR_NOACCESS, SPR_NOACCESS,
2661 &spr_read_generic, &spr_write_generic,
2663 /* XXX : not implemented */
2664 spr_register(env, SPR_RPCU_BBCMCR, "L2U_BBCMCR",
2665 SPR_NOACCESS, SPR_NOACCESS,
2666 &spr_read_generic, &spr_write_generic,
2668 /* XXX : not implemented */
2669 spr_register(env, SPR_RCPU_L2U_MCR, "L2U_MCR",
2670 SPR_NOACCESS, SPR_NOACCESS,
2671 &spr_read_generic, &spr_write_generic,
2673 /* XXX : not implemented */
2674 spr_register(env, SPR_RCPU_MI_RBA0, "MI_RBA0",
2675 SPR_NOACCESS, SPR_NOACCESS,
2676 &spr_read_generic, &spr_write_generic,
2678 /* XXX : not implemented */
2679 spr_register(env, SPR_RCPU_MI_RBA1, "MI_RBA1",
2680 SPR_NOACCESS, SPR_NOACCESS,
2681 &spr_read_generic, &spr_write_generic,
2683 /* XXX : not implemented */
2684 spr_register(env, SPR_RCPU_MI_RBA2, "MI_RBA2",
2685 SPR_NOACCESS, SPR_NOACCESS,
2686 &spr_read_generic, &spr_write_generic,
2688 /* XXX : not implemented */
2689 spr_register(env, SPR_RCPU_MI_RBA3, "MI_RBA3",
2690 SPR_NOACCESS, SPR_NOACCESS,
2691 &spr_read_generic, &spr_write_generic,
2693 /* XXX : not implemented */
2694 spr_register(env, SPR_RCPU_L2U_RBA0, "L2U_RBA0",
2695 SPR_NOACCESS, SPR_NOACCESS,
2696 &spr_read_generic, &spr_write_generic,
2698 /* XXX : not implemented */
2699 spr_register(env, SPR_RCPU_L2U_RBA1, "L2U_RBA1",
2700 SPR_NOACCESS, SPR_NOACCESS,
2701 &spr_read_generic, &spr_write_generic,
2703 /* XXX : not implemented */
2704 spr_register(env, SPR_RCPU_L2U_RBA2, "L2U_RBA2",
2705 SPR_NOACCESS, SPR_NOACCESS,
2706 &spr_read_generic, &spr_write_generic,
2708 /* XXX : not implemented */
2709 spr_register(env, SPR_RCPU_L2U_RBA3, "L2U_RBA3",
2710 SPR_NOACCESS, SPR_NOACCESS,
2711 &spr_read_generic, &spr_write_generic,
2713 /* XXX : not implemented */
2714 spr_register(env, SPR_RCPU_MI_RA0, "MI_RA0",
2715 SPR_NOACCESS, SPR_NOACCESS,
2716 &spr_read_generic, &spr_write_generic,
2718 /* XXX : not implemented */
2719 spr_register(env, SPR_RCPU_MI_RA1, "MI_RA1",
2720 SPR_NOACCESS, SPR_NOACCESS,
2721 &spr_read_generic, &spr_write_generic,
2723 /* XXX : not implemented */
2724 spr_register(env, SPR_RCPU_MI_RA2, "MI_RA2",
2725 SPR_NOACCESS, SPR_NOACCESS,
2726 &spr_read_generic, &spr_write_generic,
2728 /* XXX : not implemented */
2729 spr_register(env, SPR_RCPU_MI_RA3, "MI_RA3",
2730 SPR_NOACCESS, SPR_NOACCESS,
2731 &spr_read_generic, &spr_write_generic,
2733 /* XXX : not implemented */
2734 spr_register(env, SPR_RCPU_L2U_RA0, "L2U_RA0",
2735 SPR_NOACCESS, SPR_NOACCESS,
2736 &spr_read_generic, &spr_write_generic,
2738 /* XXX : not implemented */
2739 spr_register(env, SPR_RCPU_L2U_RA1, "L2U_RA1",
2740 SPR_NOACCESS, SPR_NOACCESS,
2741 &spr_read_generic, &spr_write_generic,
2743 /* XXX : not implemented */
2744 spr_register(env, SPR_RCPU_L2U_RA2, "L2U_RA2",
2745 SPR_NOACCESS, SPR_NOACCESS,
2746 &spr_read_generic, &spr_write_generic,
2748 /* XXX : not implemented */
2749 spr_register(env, SPR_RCPU_L2U_RA3, "L2U_RA3",
2750 SPR_NOACCESS, SPR_NOACCESS,
2751 &spr_read_generic, &spr_write_generic,
2753 /* XXX : not implemented */
2754 spr_register(env, SPR_RCPU_FPECR, "FPECR",
2755 SPR_NOACCESS, SPR_NOACCESS,
2756 &spr_read_generic, &spr_write_generic,
2760 static void gen_spr_8xx(CPUPPCState *env)
2762 /* XXX : not implemented */
2763 spr_register(env, SPR_MPC_IC_CST, "IC_CST",
2764 SPR_NOACCESS, SPR_NOACCESS,
2765 &spr_read_generic, &spr_write_generic,
2767 /* XXX : not implemented */
2768 spr_register(env, SPR_MPC_IC_ADR, "IC_ADR",
2769 SPR_NOACCESS, SPR_NOACCESS,
2770 &spr_read_generic, &spr_write_generic,
2772 /* XXX : not implemented */
2773 spr_register(env, SPR_MPC_IC_DAT, "IC_DAT",
2774 SPR_NOACCESS, SPR_NOACCESS,
2775 &spr_read_generic, &spr_write_generic,
2777 /* XXX : not implemented */
2778 spr_register(env, SPR_MPC_DC_CST, "DC_CST",
2779 SPR_NOACCESS, SPR_NOACCESS,
2780 &spr_read_generic, &spr_write_generic,
2782 /* XXX : not implemented */
2783 spr_register(env, SPR_MPC_DC_ADR, "DC_ADR",
2784 SPR_NOACCESS, SPR_NOACCESS,
2785 &spr_read_generic, &spr_write_generic,
2787 /* XXX : not implemented */
2788 spr_register(env, SPR_MPC_DC_DAT, "DC_DAT",
2789 SPR_NOACCESS, SPR_NOACCESS,
2790 &spr_read_generic, &spr_write_generic,
2792 /* XXX : not implemented */
2793 spr_register(env, SPR_MPC_MI_CTR, "MI_CTR",
2794 SPR_NOACCESS, SPR_NOACCESS,
2795 &spr_read_generic, &spr_write_generic,
2797 /* XXX : not implemented */
2798 spr_register(env, SPR_MPC_MI_AP, "MI_AP",
2799 SPR_NOACCESS, SPR_NOACCESS,
2800 &spr_read_generic, &spr_write_generic,
2802 /* XXX : not implemented */
2803 spr_register(env, SPR_MPC_MI_EPN, "MI_EPN",
2804 SPR_NOACCESS, SPR_NOACCESS,
2805 &spr_read_generic, &spr_write_generic,
2807 /* XXX : not implemented */
2808 spr_register(env, SPR_MPC_MI_TWC, "MI_TWC",
2809 SPR_NOACCESS, SPR_NOACCESS,
2810 &spr_read_generic, &spr_write_generic,
2812 /* XXX : not implemented */
2813 spr_register(env, SPR_MPC_MI_RPN, "MI_RPN",
2814 SPR_NOACCESS, SPR_NOACCESS,
2815 &spr_read_generic, &spr_write_generic,
2817 /* XXX : not implemented */
2818 spr_register(env, SPR_MPC_MI_DBCAM, "MI_DBCAM",
2819 SPR_NOACCESS, SPR_NOACCESS,
2820 &spr_read_generic, &spr_write_generic,
2822 /* XXX : not implemented */
2823 spr_register(env, SPR_MPC_MI_DBRAM0, "MI_DBRAM0",
2824 SPR_NOACCESS, SPR_NOACCESS,
2825 &spr_read_generic, &spr_write_generic,
2827 /* XXX : not implemented */
2828 spr_register(env, SPR_MPC_MI_DBRAM1, "MI_DBRAM1",
2829 SPR_NOACCESS, SPR_NOACCESS,
2830 &spr_read_generic, &spr_write_generic,
2832 /* XXX : not implemented */
2833 spr_register(env, SPR_MPC_MD_CTR, "MD_CTR",
2834 SPR_NOACCESS, SPR_NOACCESS,
2835 &spr_read_generic, &spr_write_generic,
2837 /* XXX : not implemented */
2838 spr_register(env, SPR_MPC_MD_CASID, "MD_CASID",
2839 SPR_NOACCESS, SPR_NOACCESS,
2840 &spr_read_generic, &spr_write_generic,
2842 /* XXX : not implemented */
2843 spr_register(env, SPR_MPC_MD_AP, "MD_AP",
2844 SPR_NOACCESS, SPR_NOACCESS,
2845 &spr_read_generic, &spr_write_generic,
2847 /* XXX : not implemented */
2848 spr_register(env, SPR_MPC_MD_EPN, "MD_EPN",
2849 SPR_NOACCESS, SPR_NOACCESS,
2850 &spr_read_generic, &spr_write_generic,
2852 /* XXX : not implemented */
2853 spr_register(env, SPR_MPC_MD_TWB, "MD_TWB",
2854 SPR_NOACCESS, SPR_NOACCESS,
2855 &spr_read_generic, &spr_write_generic,
2857 /* XXX : not implemented */
2858 spr_register(env, SPR_MPC_MD_TWC, "MD_TWC",
2859 SPR_NOACCESS, SPR_NOACCESS,
2860 &spr_read_generic, &spr_write_generic,
2862 /* XXX : not implemented */
2863 spr_register(env, SPR_MPC_MD_RPN, "MD_RPN",
2864 SPR_NOACCESS, SPR_NOACCESS,
2865 &spr_read_generic, &spr_write_generic,
2867 /* XXX : not implemented */
2868 spr_register(env, SPR_MPC_MD_TW, "MD_TW",
2869 SPR_NOACCESS, SPR_NOACCESS,
2870 &spr_read_generic, &spr_write_generic,
2872 /* XXX : not implemented */
2873 spr_register(env, SPR_MPC_MD_DBCAM, "MD_DBCAM",
2874 SPR_NOACCESS, SPR_NOACCESS,
2875 &spr_read_generic, &spr_write_generic,
2877 /* XXX : not implemented */
2878 spr_register(env, SPR_MPC_MD_DBRAM0, "MD_DBRAM0",
2879 SPR_NOACCESS, SPR_NOACCESS,
2880 &spr_read_generic, &spr_write_generic,
2882 /* XXX : not implemented */
2883 spr_register(env, SPR_MPC_MD_DBRAM1, "MD_DBRAM1",
2884 SPR_NOACCESS, SPR_NOACCESS,
2885 &spr_read_generic, &spr_write_generic,
2890 * AMR => SPR 29 (Power 2.04)
2891 * CTRL => SPR 136 (Power 2.04)
2892 * CTRL => SPR 152 (Power 2.04)
2893 * SCOMC => SPR 276 (64 bits ?)
2894 * SCOMD => SPR 277 (64 bits ?)
2895 * TBU40 => SPR 286 (Power 2.04 hypv)
2896 * HSPRG0 => SPR 304 (Power 2.04 hypv)
2897 * HSPRG1 => SPR 305 (Power 2.04 hypv)
2898 * HDSISR => SPR 306 (Power 2.04 hypv)
2899 * HDAR => SPR 307 (Power 2.04 hypv)
2900 * PURR => SPR 309 (Power 2.04 hypv)
2901 * HDEC => SPR 310 (Power 2.04 hypv)
2902 * HIOR => SPR 311 (hypv)
2903 * RMOR => SPR 312 (970)
2904 * HRMOR => SPR 313 (Power 2.04 hypv)
2905 * HSRR0 => SPR 314 (Power 2.04 hypv)
2906 * HSRR1 => SPR 315 (Power 2.04 hypv)
2907 * LPIDR => SPR 317 (970)
2908 * EPR => SPR 702 (Power 2.04 emb)
2909 * perf => 768-783 (Power 2.04)
2910 * perf => 784-799 (Power 2.04)
2911 * PPR => SPR 896 (Power 2.04)
2912 * DABRX => 1015 (Power 2.04 hypv)
2913 * FPECR => SPR 1022 (?)
2914 * ... and more (thermal management, performance counters, ...)
2917 /*****************************************************************************/
2918 /* Exception vectors models */
2919 static void init_excp_4xx_real(CPUPPCState *env)
2921 #if !defined(CONFIG_USER_ONLY)
2922 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000100;
2923 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
2924 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
2925 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
2926 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
2927 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
2928 env->excp_vectors[POWERPC_EXCP_PIT] = 0x00001000;
2929 env->excp_vectors[POWERPC_EXCP_FIT] = 0x00001010;
2930 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001020;
2931 env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000;
2932 env->ivor_mask = 0x0000FFF0UL;
2933 env->ivpr_mask = 0xFFFF0000UL;
2934 /* Hardware reset vector */
2935 env->hreset_vector = 0xFFFFFFFCUL;
2939 static void init_excp_4xx_softmmu(CPUPPCState *env)
2941 #if !defined(CONFIG_USER_ONLY)
2942 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000100;
2943 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
2944 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
2945 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
2946 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
2947 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
2948 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
2949 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
2950 env->excp_vectors[POWERPC_EXCP_PIT] = 0x00001000;
2951 env->excp_vectors[POWERPC_EXCP_FIT] = 0x00001010;
2952 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001020;
2953 env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001100;
2954 env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001200;
2955 env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000;
2956 env->ivor_mask = 0x0000FFF0UL;
2957 env->ivpr_mask = 0xFFFF0000UL;
2958 /* Hardware reset vector */
2959 env->hreset_vector = 0xFFFFFFFCUL;
2963 static void init_excp_MPC5xx(CPUPPCState *env)
2965 #if !defined(CONFIG_USER_ONLY)
2966 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
2967 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
2968 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
2969 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
2970 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
2971 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000900;
2972 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
2973 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
2974 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
2975 env->excp_vectors[POWERPC_EXCP_FPA] = 0x00000E00;
2976 env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001000;
2977 env->excp_vectors[POWERPC_EXCP_DABR] = 0x00001C00;
2978 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001C00;
2979 env->excp_vectors[POWERPC_EXCP_MEXTBR] = 0x00001E00;
2980 env->excp_vectors[POWERPC_EXCP_NMEXTBR] = 0x00001F00;
2981 env->ivor_mask = 0x0000FFF0UL;
2982 env->ivpr_mask = 0xFFFF0000UL;
2983 /* Hardware reset vector */
2984 env->hreset_vector = 0x00000100UL;
2988 static void init_excp_MPC8xx(CPUPPCState *env)
2990 #if !defined(CONFIG_USER_ONLY)
2991 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
2992 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
2993 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
2994 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
2995 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
2996 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
2997 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
2998 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000900;
2999 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3000 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3001 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3002 env->excp_vectors[POWERPC_EXCP_FPA] = 0x00000E00;
3003 env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001000;
3004 env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001100;
3005 env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001200;
3006 env->excp_vectors[POWERPC_EXCP_ITLBE] = 0x00001300;
3007 env->excp_vectors[POWERPC_EXCP_DTLBE] = 0x00001400;
3008 env->excp_vectors[POWERPC_EXCP_DABR] = 0x00001C00;
3009 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001C00;
3010 env->excp_vectors[POWERPC_EXCP_MEXTBR] = 0x00001E00;
3011 env->excp_vectors[POWERPC_EXCP_NMEXTBR] = 0x00001F00;
3012 env->ivor_mask = 0x0000FFF0UL;
3013 env->ivpr_mask = 0xFFFF0000UL;
3014 /* Hardware reset vector */
3015 env->hreset_vector = 0x00000100UL;
3019 static void init_excp_G2(CPUPPCState *env)
3021 #if !defined(CONFIG_USER_ONLY)
3022 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3023 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3024 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3025 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3026 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3027 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3028 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3029 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3030 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3031 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000A00;
3032 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3033 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3034 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
3035 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
3036 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
3037 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3038 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3039 /* Hardware reset vector */
3040 env->hreset_vector = 0x00000100UL;
3044 static void init_excp_e200(CPUPPCState *env, target_ulong ivpr_mask)
3046 #if !defined(CONFIG_USER_ONLY)
3047 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000FFC;
3048 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000000;
3049 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000000;
3050 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000000;
3051 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000000;
3052 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000000;
3053 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000000;
3054 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000000;
3055 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000000;
3056 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000000;
3057 env->excp_vectors[POWERPC_EXCP_APU] = 0x00000000;
3058 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000000;
3059 env->excp_vectors[POWERPC_EXCP_FIT] = 0x00000000;
3060 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00000000;
3061 env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00000000;
3062 env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00000000;
3063 env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00000000;
3064 env->excp_vectors[POWERPC_EXCP_SPEU] = 0x00000000;
3065 env->excp_vectors[POWERPC_EXCP_EFPDI] = 0x00000000;
3066 env->excp_vectors[POWERPC_EXCP_EFPRI] = 0x00000000;
3067 env->ivor_mask = 0x0000FFF7UL;
3068 env->ivpr_mask = ivpr_mask;
3069 /* Hardware reset vector */
3070 env->hreset_vector = 0xFFFFFFFCUL;
3074 static void init_excp_BookE(CPUPPCState *env)
3076 #if !defined(CONFIG_USER_ONLY)
3077 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000000;
3078 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000000;
3079 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000000;
3080 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000000;
3081 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000000;
3082 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000000;
3083 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000000;
3084 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000000;
3085 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000000;
3086 env->excp_vectors[POWERPC_EXCP_APU] = 0x00000000;
3087 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000000;
3088 env->excp_vectors[POWERPC_EXCP_FIT] = 0x00000000;
3089 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00000000;
3090 env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00000000;
3091 env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00000000;
3092 env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00000000;
3093 env->ivor_mask = 0x0000FFF0UL;
3094 env->ivpr_mask = 0xFFFF0000UL;
3095 /* Hardware reset vector */
3096 env->hreset_vector = 0xFFFFFFFCUL;
3100 static void init_excp_601(CPUPPCState *env)
3102 #if !defined(CONFIG_USER_ONLY)
3103 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3104 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3105 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3106 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3107 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3108 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3109 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3110 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3111 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3112 env->excp_vectors[POWERPC_EXCP_IO] = 0x00000A00;
3113 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3114 env->excp_vectors[POWERPC_EXCP_RUNM] = 0x00002000;
3115 /* Hardware reset vector */
3116 env->hreset_vector = 0x00000100UL;
3120 static void init_excp_602(CPUPPCState *env)
3122 #if !defined(CONFIG_USER_ONLY)
3123 /* XXX: exception prefix has a special behavior on 602 */
3124 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3125 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3126 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3127 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3128 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3129 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3130 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3131 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3132 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3133 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3134 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3135 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
3136 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
3137 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
3138 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3139 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3140 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001500;
3141 env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001600;
3142 /* Hardware reset vector */
3143 env->hreset_vector = 0x00000100UL;
3147 static void init_excp_603(CPUPPCState *env)
3149 #if !defined(CONFIG_USER_ONLY)
3150 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3151 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3152 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3153 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3154 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3155 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3156 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3157 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3158 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3159 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3160 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3161 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
3162 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
3163 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
3164 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3165 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3166 /* Hardware reset vector */
3167 env->hreset_vector = 0x00000100UL;
3171 static void init_excp_604(CPUPPCState *env)
3173 #if !defined(CONFIG_USER_ONLY)
3174 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3175 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3176 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3177 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3178 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3179 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3180 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3181 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3182 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3183 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3184 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3185 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3186 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3187 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3188 /* Hardware reset vector */
3189 env->hreset_vector = 0x00000100UL;
3193 static void init_excp_7x0(CPUPPCState *env)
3195 #if !defined(CONFIG_USER_ONLY)
3196 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3197 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3198 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3199 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3200 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3201 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3202 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3203 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3204 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3205 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3206 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3207 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3208 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3209 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3210 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
3211 /* Hardware reset vector */
3212 env->hreset_vector = 0x00000100UL;
3216 static void init_excp_750cl(CPUPPCState *env)
3218 #if !defined(CONFIG_USER_ONLY)
3219 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3220 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3221 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3222 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3223 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3224 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3225 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3226 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3227 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3228 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3229 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3230 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3231 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3232 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3233 /* Hardware reset vector */
3234 env->hreset_vector = 0x00000100UL;
3238 static void init_excp_750cx(CPUPPCState *env)
3240 #if !defined(CONFIG_USER_ONLY)
3241 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3242 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3243 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3244 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3245 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3246 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3247 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3248 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3249 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3250 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3251 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3252 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3253 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3254 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
3255 /* Hardware reset vector */
3256 env->hreset_vector = 0x00000100UL;
3260 /* XXX: Check if this is correct */
3261 static void init_excp_7x5(CPUPPCState *env)
3263 #if !defined(CONFIG_USER_ONLY)
3264 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3265 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3266 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3267 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3268 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3269 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3270 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3271 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3272 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3273 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3274 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3275 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3276 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
3277 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
3278 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
3279 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3280 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3281 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
3282 /* Hardware reset vector */
3283 env->hreset_vector = 0x00000100UL;
3287 static void init_excp_7400(CPUPPCState *env)
3289 #if !defined(CONFIG_USER_ONLY)
3290 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3291 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3292 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3293 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3294 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3295 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3296 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3297 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3298 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3299 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3300 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3301 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3302 env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
3303 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3304 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3305 env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600;
3306 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
3307 /* Hardware reset vector */
3308 env->hreset_vector = 0x00000100UL;
3312 static void init_excp_7450(CPUPPCState *env)
3314 #if !defined(CONFIG_USER_ONLY)
3315 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3316 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3317 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3318 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3319 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3320 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3321 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3322 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3323 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3324 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3325 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3326 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3327 env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
3328 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
3329 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
3330 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
3331 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3332 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3333 env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600;
3334 /* Hardware reset vector */
3335 env->hreset_vector = 0x00000100UL;
3339 #if defined(TARGET_PPC64)
3340 static void init_excp_970(CPUPPCState *env)
3342 #if !defined(CONFIG_USER_ONLY)
3343 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3344 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3345 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3346 env->excp_vectors[POWERPC_EXCP_DSEG] = 0x00000380;
3347 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3348 env->excp_vectors[POWERPC_EXCP_ISEG] = 0x00000480;
3349 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3350 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3351 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3352 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3353 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3354 env->excp_vectors[POWERPC_EXCP_HDECR] = 0x00000980;
3355 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3356 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3357 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3358 env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
3359 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3360 env->excp_vectors[POWERPC_EXCP_MAINT] = 0x00001600;
3361 env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001700;
3362 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001800;
3363 /* Hardware reset vector */
3364 env->hreset_vector = 0x0000000000000100ULL;
3368 static void init_excp_POWER7(CPUPPCState *env)
3370 #if !defined(CONFIG_USER_ONLY)
3371 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3372 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3373 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3374 env->excp_vectors[POWERPC_EXCP_DSEG] = 0x00000380;
3375 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3376 env->excp_vectors[POWERPC_EXCP_ISEG] = 0x00000480;
3377 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3378 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3379 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3380 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3381 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3382 env->excp_vectors[POWERPC_EXCP_HDECR] = 0x00000980;
3383 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3384 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3385 env->excp_vectors[POWERPC_EXCP_HDSI] = 0x00000E00;
3386 env->excp_vectors[POWERPC_EXCP_HISI] = 0x00000E20;
3387 env->excp_vectors[POWERPC_EXCP_HV_EMU] = 0x00000E40;
3388 env->excp_vectors[POWERPC_EXCP_HV_MAINT] = 0x00000E60;
3389 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3390 env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
3391 env->excp_vectors[POWERPC_EXCP_VSXU] = 0x00000F40;
3392 /* Hardware reset vector */
3393 env->hreset_vector = 0x0000000000000100ULL;
3397 static void init_excp_POWER8(CPUPPCState *env)
3399 init_excp_POWER7(env);
3401 #if !defined(CONFIG_USER_ONLY)
3402 env->excp_vectors[POWERPC_EXCP_SDOOR] = 0x00000A00;
3403 env->excp_vectors[POWERPC_EXCP_FU] = 0x00000F60;
3404 env->excp_vectors[POWERPC_EXCP_HV_FU] = 0x00000F80;
3405 env->excp_vectors[POWERPC_EXCP_SDOOR_HV] = 0x00000E80;
3409 static void init_excp_POWER9(CPUPPCState *env)
3411 init_excp_POWER8(env);
3413 #if !defined(CONFIG_USER_ONLY)
3414 env->excp_vectors[POWERPC_EXCP_HVIRT] = 0x00000EA0;
3415 env->excp_vectors[POWERPC_EXCP_SYSCALL_VECTORED] = 0x00000000;
3419 static void init_excp_POWER10(CPUPPCState *env)
3421 init_excp_POWER9(env);
3426 /*****************************************************************************/
3427 /* Power management enable checks */
3428 static int check_pow_none(CPUPPCState *env)
3433 static int check_pow_nocheck(CPUPPCState *env)
3438 static int check_pow_hid0(CPUPPCState *env)
3440 if (env->spr[SPR_HID0] & 0x00E00000) {
3447 static int check_pow_hid0_74xx(CPUPPCState *env)
3449 if (env->spr[SPR_HID0] & 0x00600000) {
3456 static bool ppc_cpu_interrupts_big_endian_always(PowerPCCPU *cpu)
3462 static bool ppc_cpu_interrupts_big_endian_lpcr(PowerPCCPU *cpu)
3464 return !(cpu->env.spr[SPR_LPCR] & LPCR_ILE);
3468 /*****************************************************************************/
3469 /* PowerPC implementations definitions */
3471 #define POWERPC_FAMILY(_name) \
3473 glue(glue(ppc_, _name), _cpu_family_class_init)(ObjectClass *, void *); \
3475 static const TypeInfo \
3476 glue(glue(ppc_, _name), _cpu_family_type_info) = { \
3477 .name = stringify(_name) "-family-" TYPE_POWERPC_CPU, \
3478 .parent = TYPE_POWERPC_CPU, \
3480 .class_init = glue(glue(ppc_, _name), _cpu_family_class_init), \
3483 static void glue(glue(ppc_, _name), _cpu_family_register_types)(void) \
3485 type_register_static( \
3486 &glue(glue(ppc_, _name), _cpu_family_type_info)); \
3489 type_init(glue(glue(ppc_, _name), _cpu_family_register_types)) \
3491 static void glue(glue(ppc_, _name), _cpu_family_class_init)
3493 static void init_proc_401(CPUPPCState *env)
3496 gen_spr_401_403(env);
3498 init_excp_4xx_real(env);
3499 env->dcache_line_size = 32;
3500 env->icache_line_size = 32;
3501 /* Allocate hardware IRQ controller */
3502 ppc40x_irq_init(env_archcpu(env));
3504 SET_FIT_PERIOD(12, 16, 20, 24);
3505 SET_WDT_PERIOD(16, 20, 24, 28);
3508 POWERPC_FAMILY(401)(ObjectClass *oc, void *data)
3510 DeviceClass *dc = DEVICE_CLASS(oc);
3511 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3513 dc->desc = "PowerPC 401";
3514 pcc->init_proc = init_proc_401;
3515 pcc->check_pow = check_pow_nocheck;
3516 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3517 PPC_WRTEE | PPC_DCR |
3518 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3520 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3521 PPC_4xx_COMMON | PPC_40x_EXCP;
3522 pcc->msr_mask = (1ull << MSR_KEY) |
3531 pcc->mmu_model = POWERPC_MMU_REAL;
3532 pcc->excp_model = POWERPC_EXCP_40x;
3533 pcc->bus_model = PPC_FLAGS_INPUT_401;
3534 pcc->bfd_mach = bfd_mach_ppc_403;
3535 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3536 POWERPC_FLAG_BUS_CLK;
3539 static void init_proc_401x2(CPUPPCState *env)
3542 gen_spr_401_403(env);
3544 gen_spr_compress(env);
3545 /* Memory management */
3546 #if !defined(CONFIG_USER_ONLY)
3550 env->tlb_type = TLB_EMB;
3552 init_excp_4xx_softmmu(env);
3553 env->dcache_line_size = 32;
3554 env->icache_line_size = 32;
3555 /* Allocate hardware IRQ controller */
3556 ppc40x_irq_init(env_archcpu(env));
3558 SET_FIT_PERIOD(12, 16, 20, 24);
3559 SET_WDT_PERIOD(16, 20, 24, 28);
3562 POWERPC_FAMILY(401x2)(ObjectClass *oc, void *data)
3564 DeviceClass *dc = DEVICE_CLASS(oc);
3565 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3567 dc->desc = "PowerPC 401x2";
3568 pcc->init_proc = init_proc_401x2;
3569 pcc->check_pow = check_pow_nocheck;
3570 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
3571 PPC_DCR | PPC_WRTEE |
3572 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3573 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3574 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3575 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3576 PPC_4xx_COMMON | PPC_40x_EXCP;
3577 pcc->msr_mask = (1ull << 20) |
3589 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3590 pcc->excp_model = POWERPC_EXCP_40x;
3591 pcc->bus_model = PPC_FLAGS_INPUT_401;
3592 pcc->bfd_mach = bfd_mach_ppc_403;
3593 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3594 POWERPC_FLAG_BUS_CLK;
3597 static void init_proc_401x3(CPUPPCState *env)
3600 gen_spr_401_403(env);
3603 gen_spr_compress(env);
3604 init_excp_4xx_softmmu(env);
3605 env->dcache_line_size = 32;
3606 env->icache_line_size = 32;
3607 /* Allocate hardware IRQ controller */
3608 ppc40x_irq_init(env_archcpu(env));
3610 SET_FIT_PERIOD(12, 16, 20, 24);
3611 SET_WDT_PERIOD(16, 20, 24, 28);
3614 POWERPC_FAMILY(401x3)(ObjectClass *oc, void *data)
3616 DeviceClass *dc = DEVICE_CLASS(oc);
3617 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3619 dc->desc = "PowerPC 401x3";
3620 pcc->init_proc = init_proc_401x3;
3621 pcc->check_pow = check_pow_nocheck;
3622 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
3623 PPC_DCR | PPC_WRTEE |
3624 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3625 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3626 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3627 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3628 PPC_4xx_COMMON | PPC_40x_EXCP;
3629 pcc->msr_mask = (1ull << 20) |
3642 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3643 pcc->excp_model = POWERPC_EXCP_40x;
3644 pcc->bus_model = PPC_FLAGS_INPUT_401;
3645 pcc->bfd_mach = bfd_mach_ppc_403;
3646 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3647 POWERPC_FLAG_BUS_CLK;
3650 static void init_proc_IOP480(CPUPPCState *env)
3653 gen_spr_401_403(env);
3655 gen_spr_compress(env);
3656 /* Memory management */
3657 #if !defined(CONFIG_USER_ONLY)
3661 env->tlb_type = TLB_EMB;
3663 init_excp_4xx_softmmu(env);
3664 env->dcache_line_size = 32;
3665 env->icache_line_size = 32;
3666 /* Allocate hardware IRQ controller */
3667 ppc40x_irq_init(env_archcpu(env));
3669 SET_FIT_PERIOD(8, 12, 16, 20);
3670 SET_WDT_PERIOD(16, 20, 24, 28);
3673 POWERPC_FAMILY(IOP480)(ObjectClass *oc, void *data)
3675 DeviceClass *dc = DEVICE_CLASS(oc);
3676 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3678 dc->desc = "IOP480";
3679 pcc->init_proc = init_proc_IOP480;
3680 pcc->check_pow = check_pow_nocheck;
3681 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3682 PPC_DCR | PPC_WRTEE |
3683 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3684 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3685 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3686 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3687 PPC_4xx_COMMON | PPC_40x_EXCP;
3688 pcc->msr_mask = (1ull << 20) |
3700 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3701 pcc->excp_model = POWERPC_EXCP_40x;
3702 pcc->bus_model = PPC_FLAGS_INPUT_401;
3703 pcc->bfd_mach = bfd_mach_ppc_403;
3704 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3705 POWERPC_FLAG_BUS_CLK;
3708 static void init_proc_403(CPUPPCState *env)
3711 gen_spr_401_403(env);
3713 gen_spr_403_real(env);
3714 init_excp_4xx_real(env);
3715 env->dcache_line_size = 32;
3716 env->icache_line_size = 32;
3717 /* Allocate hardware IRQ controller */
3718 ppc40x_irq_init(env_archcpu(env));
3720 SET_FIT_PERIOD(8, 12, 16, 20);
3721 SET_WDT_PERIOD(16, 20, 24, 28);
3724 POWERPC_FAMILY(403)(ObjectClass *oc, void *data)
3726 DeviceClass *dc = DEVICE_CLASS(oc);
3727 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3729 dc->desc = "PowerPC 403";
3730 pcc->init_proc = init_proc_403;
3731 pcc->check_pow = check_pow_nocheck;
3732 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3733 PPC_DCR | PPC_WRTEE |
3734 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3736 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3737 PPC_4xx_COMMON | PPC_40x_EXCP;
3738 pcc->msr_mask = (1ull << MSR_POW) |
3747 pcc->mmu_model = POWERPC_MMU_REAL;
3748 pcc->excp_model = POWERPC_EXCP_40x;
3749 pcc->bus_model = PPC_FLAGS_INPUT_401;
3750 pcc->bfd_mach = bfd_mach_ppc_403;
3751 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_PX |
3752 POWERPC_FLAG_BUS_CLK;
3755 static void init_proc_403GCX(CPUPPCState *env)
3758 gen_spr_401_403(env);
3760 gen_spr_403_real(env);
3761 gen_spr_403_mmu(env);
3762 /* Bus access control */
3763 /* not emulated, as QEMU never does speculative access */
3764 spr_register(env, SPR_40x_SGR, "SGR",
3765 SPR_NOACCESS, SPR_NOACCESS,
3766 &spr_read_generic, &spr_write_generic,
3768 /* not emulated, as QEMU do not emulate caches */
3769 spr_register(env, SPR_40x_DCWR, "DCWR",
3770 SPR_NOACCESS, SPR_NOACCESS,
3771 &spr_read_generic, &spr_write_generic,
3773 /* Memory management */
3774 #if !defined(CONFIG_USER_ONLY)
3778 env->tlb_type = TLB_EMB;
3780 init_excp_4xx_softmmu(env);
3781 env->dcache_line_size = 32;
3782 env->icache_line_size = 32;
3783 /* Allocate hardware IRQ controller */
3784 ppc40x_irq_init(env_archcpu(env));
3786 SET_FIT_PERIOD(8, 12, 16, 20);
3787 SET_WDT_PERIOD(16, 20, 24, 28);
3790 POWERPC_FAMILY(403GCX)(ObjectClass *oc, void *data)
3792 DeviceClass *dc = DEVICE_CLASS(oc);
3793 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3795 dc->desc = "PowerPC 403 GCX";
3796 pcc->init_proc = init_proc_403GCX;
3797 pcc->check_pow = check_pow_nocheck;
3798 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3799 PPC_DCR | PPC_WRTEE |
3800 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3802 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3803 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3804 PPC_4xx_COMMON | PPC_40x_EXCP;
3805 pcc->msr_mask = (1ull << MSR_POW) |
3814 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3815 pcc->excp_model = POWERPC_EXCP_40x;
3816 pcc->bus_model = PPC_FLAGS_INPUT_401;
3817 pcc->bfd_mach = bfd_mach_ppc_403;
3818 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_PX |
3819 POWERPC_FLAG_BUS_CLK;
3822 static void init_proc_405(CPUPPCState *env)
3828 /* Bus access control */
3829 /* not emulated, as QEMU never does speculative access */
3830 spr_register(env, SPR_40x_SGR, "SGR",
3831 SPR_NOACCESS, SPR_NOACCESS,
3832 &spr_read_generic, &spr_write_generic,
3834 /* not emulated, as QEMU do not emulate caches */
3835 spr_register(env, SPR_40x_DCWR, "DCWR",
3836 SPR_NOACCESS, SPR_NOACCESS,
3837 &spr_read_generic, &spr_write_generic,
3839 /* Memory management */
3840 #if !defined(CONFIG_USER_ONLY)
3844 env->tlb_type = TLB_EMB;
3846 init_excp_4xx_softmmu(env);
3847 env->dcache_line_size = 32;
3848 env->icache_line_size = 32;
3849 /* Allocate hardware IRQ controller */
3850 ppc40x_irq_init(env_archcpu(env));
3852 SET_FIT_PERIOD(8, 12, 16, 20);
3853 SET_WDT_PERIOD(16, 20, 24, 28);
3856 POWERPC_FAMILY(405)(ObjectClass *oc, void *data)
3858 DeviceClass *dc = DEVICE_CLASS(oc);
3859 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3861 dc->desc = "PowerPC 405";
3862 pcc->init_proc = init_proc_405;
3863 pcc->check_pow = check_pow_nocheck;
3864 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
3865 PPC_DCR | PPC_WRTEE |
3866 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3867 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3868 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3869 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3870 PPC_4xx_COMMON | PPC_405_MAC | PPC_40x_EXCP;
3871 pcc->msr_mask = (1ull << MSR_POW) |
3880 pcc->mmu_model = POWERPC_MMU_SOFT_4xx;
3881 pcc->excp_model = POWERPC_EXCP_40x;
3882 pcc->bus_model = PPC_FLAGS_INPUT_405;
3883 pcc->bfd_mach = bfd_mach_ppc_403;
3884 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
3885 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
3888 static void init_proc_440EP(CPUPPCState *env)
3892 gen_spr_BookE(env, 0x000000000000FFFFULL);
3894 gen_spr_usprgh(env);
3895 /* Processor identification */
3896 spr_register(env, SPR_BOOKE_PIR, "PIR",
3897 SPR_NOACCESS, SPR_NOACCESS,
3898 &spr_read_generic, &spr_write_pir,
3900 /* XXX : not implemented */
3901 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
3902 SPR_NOACCESS, SPR_NOACCESS,
3903 &spr_read_generic, &spr_write_generic,
3905 /* XXX : not implemented */
3906 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
3907 SPR_NOACCESS, SPR_NOACCESS,
3908 &spr_read_generic, &spr_write_generic,
3910 /* XXX : not implemented */
3911 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
3912 SPR_NOACCESS, SPR_NOACCESS,
3913 &spr_read_generic, &spr_write_generic,
3915 /* XXX : not implemented */
3916 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
3917 SPR_NOACCESS, SPR_NOACCESS,
3918 &spr_read_generic, &spr_write_generic,
3920 /* XXX : not implemented */
3921 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
3922 SPR_NOACCESS, SPR_NOACCESS,
3923 &spr_read_generic, &spr_write_generic,
3925 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
3926 SPR_NOACCESS, SPR_NOACCESS,
3927 &spr_read_generic, &spr_write_generic,
3929 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
3930 SPR_NOACCESS, SPR_NOACCESS,
3931 &spr_read_generic, &spr_write_generic,
3933 /* XXX : not implemented */
3934 spr_register(env, SPR_440_CCR1, "CCR1",
3935 SPR_NOACCESS, SPR_NOACCESS,
3936 &spr_read_generic, &spr_write_generic,
3938 /* Memory management */
3939 #if !defined(CONFIG_USER_ONLY)
3943 env->tlb_type = TLB_EMB;
3945 init_excp_BookE(env);
3946 env->dcache_line_size = 32;
3947 env->icache_line_size = 32;
3948 ppc40x_irq_init(env_archcpu(env));
3950 SET_FIT_PERIOD(12, 16, 20, 24);
3951 SET_WDT_PERIOD(20, 24, 28, 32);
3954 POWERPC_FAMILY(440EP)(ObjectClass *oc, void *data)
3956 DeviceClass *dc = DEVICE_CLASS(oc);
3957 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3959 dc->desc = "PowerPC 440 EP";
3960 pcc->init_proc = init_proc_440EP;
3961 pcc->check_pow = check_pow_nocheck;
3962 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3963 PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL |
3964 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
3966 PPC_DCR | PPC_WRTEE | PPC_RFMCI |
3967 PPC_CACHE | PPC_CACHE_ICBI |
3968 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3969 PPC_MEM_TLBSYNC | PPC_MFTB |
3970 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
3972 pcc->msr_mask = (1ull << MSR_POW) |
3984 pcc->mmu_model = POWERPC_MMU_BOOKE;
3985 pcc->excp_model = POWERPC_EXCP_BOOKE;
3986 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
3987 pcc->bfd_mach = bfd_mach_ppc_403;
3988 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
3989 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
3992 POWERPC_FAMILY(460EX)(ObjectClass *oc, void *data)
3994 DeviceClass *dc = DEVICE_CLASS(oc);
3995 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3997 dc->desc = "PowerPC 460 EX";
3998 pcc->init_proc = init_proc_440EP;
3999 pcc->check_pow = check_pow_nocheck;
4000 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4001 PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL |
4002 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
4004 PPC_DCR | PPC_DCRX | PPC_WRTEE | PPC_RFMCI |
4005 PPC_CACHE | PPC_CACHE_ICBI |
4006 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4007 PPC_MEM_TLBSYNC | PPC_MFTB |
4008 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4010 pcc->msr_mask = (1ull << MSR_POW) |
4022 pcc->mmu_model = POWERPC_MMU_BOOKE;
4023 pcc->excp_model = POWERPC_EXCP_BOOKE;
4024 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4025 pcc->bfd_mach = bfd_mach_ppc_403;
4026 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4027 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
4030 static void init_proc_440GP(CPUPPCState *env)
4034 gen_spr_BookE(env, 0x000000000000FFFFULL);
4036 gen_spr_usprgh(env);
4037 /* Processor identification */
4038 spr_register(env, SPR_BOOKE_PIR, "PIR",
4039 SPR_NOACCESS, SPR_NOACCESS,
4040 &spr_read_generic, &spr_write_pir,
4042 /* XXX : not implemented */
4043 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4044 SPR_NOACCESS, SPR_NOACCESS,
4045 &spr_read_generic, &spr_write_generic,
4047 /* XXX : not implemented */
4048 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4049 SPR_NOACCESS, SPR_NOACCESS,
4050 &spr_read_generic, &spr_write_generic,
4052 /* XXX : not implemented */
4053 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
4054 SPR_NOACCESS, SPR_NOACCESS,
4055 &spr_read_generic, &spr_write_generic,
4057 /* XXX : not implemented */
4058 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
4059 SPR_NOACCESS, SPR_NOACCESS,
4060 &spr_read_generic, &spr_write_generic,
4062 /* Memory management */
4063 #if !defined(CONFIG_USER_ONLY)
4067 env->tlb_type = TLB_EMB;
4069 init_excp_BookE(env);
4070 env->dcache_line_size = 32;
4071 env->icache_line_size = 32;
4072 /* XXX: TODO: allocate internal IRQ controller */
4074 SET_FIT_PERIOD(12, 16, 20, 24);
4075 SET_WDT_PERIOD(20, 24, 28, 32);
4078 POWERPC_FAMILY(440GP)(ObjectClass *oc, void *data)
4080 DeviceClass *dc = DEVICE_CLASS(oc);
4081 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4083 dc->desc = "PowerPC 440 GP";
4084 pcc->init_proc = init_proc_440GP;
4085 pcc->check_pow = check_pow_nocheck;
4086 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4087 PPC_DCR | PPC_DCRX | PPC_WRTEE | PPC_MFAPIDI |
4088 PPC_CACHE | PPC_CACHE_ICBI |
4089 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4090 PPC_MEM_TLBSYNC | PPC_TLBIVA | PPC_MFTB |
4091 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4093 pcc->msr_mask = (1ull << MSR_POW) |
4105 pcc->mmu_model = POWERPC_MMU_BOOKE;
4106 pcc->excp_model = POWERPC_EXCP_BOOKE;
4107 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4108 pcc->bfd_mach = bfd_mach_ppc_403;
4109 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4110 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
4113 static void init_proc_440x4(CPUPPCState *env)
4117 gen_spr_BookE(env, 0x000000000000FFFFULL);
4119 gen_spr_usprgh(env);
4120 /* Processor identification */
4121 spr_register(env, SPR_BOOKE_PIR, "PIR",
4122 SPR_NOACCESS, SPR_NOACCESS,
4123 &spr_read_generic, &spr_write_pir,
4125 /* XXX : not implemented */
4126 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4127 SPR_NOACCESS, SPR_NOACCESS,
4128 &spr_read_generic, &spr_write_generic,
4130 /* XXX : not implemented */
4131 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4132 SPR_NOACCESS, SPR_NOACCESS,
4133 &spr_read_generic, &spr_write_generic,
4135 /* XXX : not implemented */
4136 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
4137 SPR_NOACCESS, SPR_NOACCESS,
4138 &spr_read_generic, &spr_write_generic,
4140 /* XXX : not implemented */
4141 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
4142 SPR_NOACCESS, SPR_NOACCESS,
4143 &spr_read_generic, &spr_write_generic,
4145 /* Memory management */
4146 #if !defined(CONFIG_USER_ONLY)
4150 env->tlb_type = TLB_EMB;
4152 init_excp_BookE(env);
4153 env->dcache_line_size = 32;
4154 env->icache_line_size = 32;
4155 /* XXX: TODO: allocate internal IRQ controller */
4157 SET_FIT_PERIOD(12, 16, 20, 24);
4158 SET_WDT_PERIOD(20, 24, 28, 32);
4161 POWERPC_FAMILY(440x4)(ObjectClass *oc, void *data)
4163 DeviceClass *dc = DEVICE_CLASS(oc);
4164 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4166 dc->desc = "PowerPC 440x4";
4167 pcc->init_proc = init_proc_440x4;
4168 pcc->check_pow = check_pow_nocheck;
4169 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4170 PPC_DCR | PPC_WRTEE |
4171 PPC_CACHE | PPC_CACHE_ICBI |
4172 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4173 PPC_MEM_TLBSYNC | PPC_MFTB |
4174 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4176 pcc->msr_mask = (1ull << MSR_POW) |
4188 pcc->mmu_model = POWERPC_MMU_BOOKE;
4189 pcc->excp_model = POWERPC_EXCP_BOOKE;
4190 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4191 pcc->bfd_mach = bfd_mach_ppc_403;
4192 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4193 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
4196 static void init_proc_440x5(CPUPPCState *env)
4200 gen_spr_BookE(env, 0x000000000000FFFFULL);
4202 gen_spr_usprgh(env);
4203 /* Processor identification */
4204 spr_register(env, SPR_BOOKE_PIR, "PIR",
4205 SPR_NOACCESS, SPR_NOACCESS,
4206 &spr_read_generic, &spr_write_pir,
4208 /* XXX : not implemented */
4209 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4210 SPR_NOACCESS, SPR_NOACCESS,
4211 &spr_read_generic, &spr_write_generic,
4213 /* XXX : not implemented */
4214 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4215 SPR_NOACCESS, SPR_NOACCESS,
4216 &spr_read_generic, &spr_write_generic,
4218 /* XXX : not implemented */
4219 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
4220 SPR_NOACCESS, SPR_NOACCESS,
4221 &spr_read_generic, &spr_write_generic,
4223 /* XXX : not implemented */
4224 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
4225 SPR_NOACCESS, SPR_NOACCESS,
4226 &spr_read_generic, &spr_write_generic,
4228 /* XXX : not implemented */
4229 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
4230 SPR_NOACCESS, SPR_NOACCESS,
4231 &spr_read_generic, &spr_write_generic,
4233 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
4234 SPR_NOACCESS, SPR_NOACCESS,
4235 &spr_read_generic, &spr_write_generic,
4237 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
4238 SPR_NOACCESS, SPR_NOACCESS,
4239 &spr_read_generic, &spr_write_generic,
4241 /* XXX : not implemented */
4242 spr_register(env, SPR_440_CCR1, "CCR1",
4243 SPR_NOACCESS, SPR_NOACCESS,
4244 &spr_read_generic, &spr_write_generic,
4246 /* Memory management */
4247 #if !defined(CONFIG_USER_ONLY)
4251 env->tlb_type = TLB_EMB;
4253 init_excp_BookE(env);
4254 env->dcache_line_size = 32;
4255 env->icache_line_size = 32;
4256 ppc40x_irq_init(env_archcpu(env));
4258 SET_FIT_PERIOD(12, 16, 20, 24);
4259 SET_WDT_PERIOD(20, 24, 28, 32);
4262 POWERPC_FAMILY(440x5)(ObjectClass *oc, void *data)
4264 DeviceClass *dc = DEVICE_CLASS(oc);
4265 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4267 dc->desc = "PowerPC 440x5";
4268 pcc->init_proc = init_proc_440x5;
4269 pcc->check_pow = check_pow_nocheck;
4270 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4271 PPC_DCR | PPC_WRTEE | PPC_RFMCI |
4272 PPC_CACHE | PPC_CACHE_ICBI |
4273 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4274 PPC_MEM_TLBSYNC | PPC_MFTB |
4275 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4277 pcc->msr_mask = (1ull << MSR_POW) |
4289 pcc->mmu_model = POWERPC_MMU_BOOKE;
4290 pcc->excp_model = POWERPC_EXCP_BOOKE;
4291 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4292 pcc->bfd_mach = bfd_mach_ppc_403;
4293 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4294 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
4297 POWERPC_FAMILY(440x5wDFPU)(ObjectClass *oc, void *data)
4299 DeviceClass *dc = DEVICE_CLASS(oc);
4300 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4302 dc->desc = "PowerPC 440x5 with double precision FPU";
4303 pcc->init_proc = init_proc_440x5;
4304 pcc->check_pow = check_pow_nocheck;
4305 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4306 PPC_FLOAT | PPC_FLOAT_FSQRT |
4308 PPC_DCR | PPC_WRTEE | PPC_RFMCI |
4309 PPC_CACHE | PPC_CACHE_ICBI |
4310 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4311 PPC_MEM_TLBSYNC | PPC_MFTB |
4312 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4314 pcc->insns_flags2 = PPC2_FP_CVT_S64;
4315 pcc->msr_mask = (1ull << MSR_POW) |
4327 pcc->mmu_model = POWERPC_MMU_BOOKE;
4328 pcc->excp_model = POWERPC_EXCP_BOOKE;
4329 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4330 pcc->bfd_mach = bfd_mach_ppc_403;
4331 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4332 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
4335 static void init_proc_MPC5xx(CPUPPCState *env)
4339 gen_spr_5xx_8xx(env);
4341 init_excp_MPC5xx(env);
4342 env->dcache_line_size = 32;
4343 env->icache_line_size = 32;
4344 /* XXX: TODO: allocate internal IRQ controller */
4347 POWERPC_FAMILY(MPC5xx)(ObjectClass *oc, void *data)
4349 DeviceClass *dc = DEVICE_CLASS(oc);
4350 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4352 dc->desc = "Freescale 5xx cores (aka RCPU)";
4353 pcc->init_proc = init_proc_MPC5xx;
4354 pcc->check_pow = check_pow_none;
4355 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4356 PPC_MEM_EIEIO | PPC_MEM_SYNC |
4357 PPC_CACHE_ICBI | PPC_FLOAT | PPC_FLOAT_STFIWX |
4359 pcc->msr_mask = (1ull << MSR_ILE) |
4371 pcc->mmu_model = POWERPC_MMU_REAL;
4372 pcc->excp_model = POWERPC_EXCP_603;
4373 pcc->bus_model = PPC_FLAGS_INPUT_RCPU;
4374 pcc->bfd_mach = bfd_mach_ppc_505;
4375 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
4376 POWERPC_FLAG_BUS_CLK;
4379 static void init_proc_MPC8xx(CPUPPCState *env)
4383 gen_spr_5xx_8xx(env);
4385 init_excp_MPC8xx(env);
4386 env->dcache_line_size = 32;
4387 env->icache_line_size = 32;
4388 /* XXX: TODO: allocate internal IRQ controller */
4391 POWERPC_FAMILY(MPC8xx)(ObjectClass *oc, void *data)
4393 DeviceClass *dc = DEVICE_CLASS(oc);
4394 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4396 dc->desc = "Freescale 8xx cores (aka PowerQUICC)";
4397 pcc->init_proc = init_proc_MPC8xx;
4398 pcc->check_pow = check_pow_none;
4399 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4400 PPC_MEM_EIEIO | PPC_MEM_SYNC |
4401 PPC_CACHE_ICBI | PPC_MFTB;
4402 pcc->msr_mask = (1ull << MSR_ILE) |
4414 pcc->mmu_model = POWERPC_MMU_MPC8xx;
4415 pcc->excp_model = POWERPC_EXCP_603;
4416 pcc->bus_model = PPC_FLAGS_INPUT_RCPU;
4417 pcc->bfd_mach = bfd_mach_ppc_860;
4418 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
4419 POWERPC_FLAG_BUS_CLK;
4422 /* Freescale 82xx cores (aka PowerQUICC-II) */
4424 static void init_proc_G2(CPUPPCState *env)
4426 gen_spr_ne_601(env);
4428 gen_spr_G2_755(env);
4432 /* External access control */
4433 /* XXX : not implemented */
4434 spr_register(env, SPR_EAR, "EAR",
4435 SPR_NOACCESS, SPR_NOACCESS,
4436 &spr_read_generic, &spr_write_generic,
4438 /* Hardware implementation register */
4439 /* XXX : not implemented */
4440 spr_register(env, SPR_HID0, "HID0",
4441 SPR_NOACCESS, SPR_NOACCESS,
4442 &spr_read_generic, &spr_write_generic,
4444 /* XXX : not implemented */
4445 spr_register(env, SPR_HID1, "HID1",
4446 SPR_NOACCESS, SPR_NOACCESS,
4447 &spr_read_generic, &spr_write_generic,
4449 /* XXX : not implemented */
4450 spr_register(env, SPR_HID2, "HID2",
4451 SPR_NOACCESS, SPR_NOACCESS,
4452 &spr_read_generic, &spr_write_generic,
4454 /* Memory management */
4457 gen_6xx_7xx_soft_tlb(env, 64, 2);
4459 env->dcache_line_size = 32;
4460 env->icache_line_size = 32;
4461 /* Allocate hardware IRQ controller */
4462 ppc6xx_irq_init(env_archcpu(env));
4465 POWERPC_FAMILY(G2)(ObjectClass *oc, void *data)
4467 DeviceClass *dc = DEVICE_CLASS(oc);
4468 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4470 dc->desc = "PowerPC G2";
4471 pcc->init_proc = init_proc_G2;
4472 pcc->check_pow = check_pow_hid0;
4473 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4474 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4476 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4477 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4478 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4479 PPC_SEGMENT | PPC_EXTERN;
4480 pcc->msr_mask = (1ull << MSR_POW) |
4481 (1ull << MSR_TGPR) |
4495 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4496 pcc->excp_model = POWERPC_EXCP_G2;
4497 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4498 pcc->bfd_mach = bfd_mach_ppc_ec603e;
4499 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4500 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
4503 static void init_proc_G2LE(CPUPPCState *env)
4505 gen_spr_ne_601(env);
4507 gen_spr_G2_755(env);
4511 /* External access control */
4512 /* XXX : not implemented */
4513 spr_register(env, SPR_EAR, "EAR",
4514 SPR_NOACCESS, SPR_NOACCESS,
4515 &spr_read_generic, &spr_write_generic,
4517 /* Hardware implementation register */
4518 /* XXX : not implemented */
4519 spr_register(env, SPR_HID0, "HID0",
4520 SPR_NOACCESS, SPR_NOACCESS,
4521 &spr_read_generic, &spr_write_generic,
4523 /* XXX : not implemented */
4524 spr_register(env, SPR_HID1, "HID1",
4525 SPR_NOACCESS, SPR_NOACCESS,
4526 &spr_read_generic, &spr_write_generic,
4528 /* XXX : not implemented */
4529 spr_register(env, SPR_HID2, "HID2",
4530 SPR_NOACCESS, SPR_NOACCESS,
4531 &spr_read_generic, &spr_write_generic,
4534 /* Memory management */
4537 gen_6xx_7xx_soft_tlb(env, 64, 2);
4539 env->dcache_line_size = 32;
4540 env->icache_line_size = 32;
4541 /* Allocate hardware IRQ controller */
4542 ppc6xx_irq_init(env_archcpu(env));
4545 POWERPC_FAMILY(G2LE)(ObjectClass *oc, void *data)
4547 DeviceClass *dc = DEVICE_CLASS(oc);
4548 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4550 dc->desc = "PowerPC G2LE";
4551 pcc->init_proc = init_proc_G2LE;
4552 pcc->check_pow = check_pow_hid0;
4553 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4554 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4556 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4557 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4558 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4559 PPC_SEGMENT | PPC_EXTERN;
4560 pcc->msr_mask = (1ull << MSR_POW) |
4561 (1ull << MSR_TGPR) |
4577 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4578 pcc->excp_model = POWERPC_EXCP_G2;
4579 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4580 pcc->bfd_mach = bfd_mach_ppc_ec603e;
4581 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4582 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
4585 static void init_proc_e200(CPUPPCState *env)
4589 gen_spr_BookE(env, 0x000000070000FFFFULL);
4590 /* XXX : not implemented */
4591 spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
4592 &spr_read_spefscr, &spr_write_spefscr,
4593 &spr_read_spefscr, &spr_write_spefscr,
4595 /* Memory management */
4596 gen_spr_BookE206(env, 0x0000005D, NULL, 0);
4597 /* XXX : not implemented */
4598 spr_register(env, SPR_HID0, "HID0",
4599 SPR_NOACCESS, SPR_NOACCESS,
4600 &spr_read_generic, &spr_write_generic,
4602 /* XXX : not implemented */
4603 spr_register(env, SPR_HID1, "HID1",
4604 SPR_NOACCESS, SPR_NOACCESS,
4605 &spr_read_generic, &spr_write_generic,
4607 /* XXX : not implemented */
4608 spr_register(env, SPR_Exxx_ALTCTXCR, "ALTCTXCR",
4609 SPR_NOACCESS, SPR_NOACCESS,
4610 &spr_read_generic, &spr_write_generic,
4612 /* XXX : not implemented */
4613 spr_register(env, SPR_Exxx_BUCSR, "BUCSR",
4614 SPR_NOACCESS, SPR_NOACCESS,
4615 &spr_read_generic, &spr_write_generic,
4617 /* XXX : not implemented */
4618 spr_register(env, SPR_Exxx_CTXCR, "CTXCR",
4619 SPR_NOACCESS, SPR_NOACCESS,
4620 &spr_read_generic, &spr_write_generic,
4622 /* XXX : not implemented */
4623 spr_register(env, SPR_Exxx_DBCNT, "DBCNT",
4624 SPR_NOACCESS, SPR_NOACCESS,
4625 &spr_read_generic, &spr_write_generic,
4627 /* XXX : not implemented */
4628 spr_register(env, SPR_Exxx_DBCR3, "DBCR3",
4629 SPR_NOACCESS, SPR_NOACCESS,
4630 &spr_read_generic, &spr_write_generic,
4632 /* XXX : not implemented */
4633 spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0",
4634 &spr_read_generic, SPR_NOACCESS,
4635 &spr_read_generic, SPR_NOACCESS,
4637 /* XXX : not implemented */
4638 spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0",
4639 SPR_NOACCESS, SPR_NOACCESS,
4640 &spr_read_generic, &spr_write_generic,
4642 /* XXX : not implemented */
4643 spr_register(env, SPR_Exxx_L1FINV0, "L1FINV0",
4644 SPR_NOACCESS, SPR_NOACCESS,
4645 &spr_read_generic, &spr_write_generic,
4647 /* XXX : not implemented */
4648 spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG",
4649 SPR_NOACCESS, SPR_NOACCESS,
4650 &spr_read_generic, &spr_write_generic,
4652 /* XXX : not implemented */
4653 spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG",
4654 SPR_NOACCESS, SPR_NOACCESS,
4655 &spr_read_generic, &spr_write_generic,
4657 /* XXX : not implemented */
4658 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4659 SPR_NOACCESS, SPR_NOACCESS,
4660 &spr_read_generic, &spr_write_generic,
4662 /* XXX : not implemented */
4663 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4664 SPR_NOACCESS, SPR_NOACCESS,
4665 &spr_read_generic, &spr_write_generic,
4667 /* XXX : not implemented */
4668 spr_register(env, SPR_MMUCSR0, "MMUCSR0",
4669 SPR_NOACCESS, SPR_NOACCESS,
4670 &spr_read_generic, &spr_write_generic,
4671 0x00000000); /* TOFIX */
4672 spr_register(env, SPR_BOOKE_DSRR0, "DSRR0",
4673 SPR_NOACCESS, SPR_NOACCESS,
4674 &spr_read_generic, &spr_write_generic,
4676 spr_register(env, SPR_BOOKE_DSRR1, "DSRR1",
4677 SPR_NOACCESS, SPR_NOACCESS,
4678 &spr_read_generic, &spr_write_generic,
4680 #if !defined(CONFIG_USER_ONLY)
4684 env->tlb_type = TLB_EMB;
4686 init_excp_e200(env, 0xFFFF0000UL);
4687 env->dcache_line_size = 32;
4688 env->icache_line_size = 32;
4689 /* XXX: TODO: allocate internal IRQ controller */
4692 POWERPC_FAMILY(e200)(ObjectClass *oc, void *data)
4694 DeviceClass *dc = DEVICE_CLASS(oc);
4695 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4697 dc->desc = "e200 core";
4698 pcc->init_proc = init_proc_e200;
4699 pcc->check_pow = check_pow_hid0;
4701 * XXX: unimplemented instructions:
4708 * all SPE multiply-accumulate instructions
4710 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
4711 PPC_SPE | PPC_SPE_SINGLE |
4712 PPC_WRTEE | PPC_RFDI |
4713 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
4714 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4715 PPC_MEM_TLBSYNC | PPC_TLBIVAX |
4717 pcc->msr_mask = (1ull << MSR_UCLE) |
4731 pcc->mmu_model = POWERPC_MMU_BOOKE206;
4732 pcc->excp_model = POWERPC_EXCP_BOOKE;
4733 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4734 pcc->bfd_mach = bfd_mach_ppc_860;
4735 pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
4736 POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
4737 POWERPC_FLAG_BUS_CLK;
4740 static void init_proc_e300(CPUPPCState *env)
4742 gen_spr_ne_601(env);
4747 /* hardware implementation registers */
4748 /* XXX : not implemented */
4749 spr_register(env, SPR_HID0, "HID0",
4750 SPR_NOACCESS, SPR_NOACCESS,
4751 &spr_read_generic, &spr_write_generic,
4753 /* XXX : not implemented */
4754 spr_register(env, SPR_HID1, "HID1",
4755 SPR_NOACCESS, SPR_NOACCESS,
4756 &spr_read_generic, &spr_write_generic,
4758 /* XXX : not implemented */
4759 spr_register(env, SPR_HID2, "HID2",
4760 SPR_NOACCESS, SPR_NOACCESS,
4761 &spr_read_generic, &spr_write_generic,
4764 /* XXX : not implemented */
4765 spr_register(env, SPR_DABR, "DABR",
4766 SPR_NOACCESS, SPR_NOACCESS,
4767 &spr_read_generic, &spr_write_generic,
4769 /* XXX : not implemented */
4770 spr_register(env, SPR_DABR2, "DABR2",
4771 SPR_NOACCESS, SPR_NOACCESS,
4772 &spr_read_generic, &spr_write_generic,
4774 /* XXX : not implemented */
4775 spr_register(env, SPR_IABR2, "IABR2",
4776 SPR_NOACCESS, SPR_NOACCESS,
4777 &spr_read_generic, &spr_write_generic,
4779 /* XXX : not implemented */
4780 spr_register(env, SPR_IBCR, "IBCR",
4781 SPR_NOACCESS, SPR_NOACCESS,
4782 &spr_read_generic, &spr_write_generic,
4784 /* XXX : not implemented */
4785 spr_register(env, SPR_DBCR, "DBCR",
4786 SPR_NOACCESS, SPR_NOACCESS,
4787 &spr_read_generic, &spr_write_generic,
4789 /* Memory management */
4792 gen_6xx_7xx_soft_tlb(env, 64, 2);
4794 env->dcache_line_size = 32;
4795 env->icache_line_size = 32;
4796 /* Allocate hardware IRQ controller */
4797 ppc6xx_irq_init(env_archcpu(env));
4800 POWERPC_FAMILY(e300)(ObjectClass *oc, void *data)
4802 DeviceClass *dc = DEVICE_CLASS(oc);
4803 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4805 dc->desc = "e300 core";
4806 pcc->init_proc = init_proc_e300;
4807 pcc->check_pow = check_pow_hid0;
4808 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4809 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4811 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4812 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4813 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4814 PPC_SEGMENT | PPC_EXTERN;
4815 pcc->msr_mask = (1ull << MSR_POW) |
4816 (1ull << MSR_TGPR) |
4832 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4833 pcc->excp_model = POWERPC_EXCP_603;
4834 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4835 pcc->bfd_mach = bfd_mach_ppc_603;
4836 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4837 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
4840 #if !defined(CONFIG_USER_ONLY)
4841 static void spr_write_mas73(DisasContext *ctx, int sprn, int gprn)
4843 TCGv val = tcg_temp_new();
4844 tcg_gen_ext32u_tl(val, cpu_gpr[gprn]);
4845 gen_store_spr(SPR_BOOKE_MAS3, val);
4846 tcg_gen_shri_tl(val, cpu_gpr[gprn], 32);
4847 gen_store_spr(SPR_BOOKE_MAS7, val);
4851 static void spr_read_mas73(DisasContext *ctx, int gprn, int sprn)
4853 TCGv mas7 = tcg_temp_new();
4854 TCGv mas3 = tcg_temp_new();
4855 gen_load_spr(mas7, SPR_BOOKE_MAS7);
4856 tcg_gen_shli_tl(mas7, mas7, 32);
4857 gen_load_spr(mas3, SPR_BOOKE_MAS3);
4858 tcg_gen_or_tl(cpu_gpr[gprn], mas3, mas7);
4859 tcg_temp_free(mas3);
4860 tcg_temp_free(mas7);
4865 enum fsl_e500_version {
4873 static void init_proc_e500(CPUPPCState *env, int version)
4875 uint32_t tlbncfg[2];
4877 uint64_t ivpr_mask = 0xFFFF0000ULL;
4878 uint32_t l1cfg0 = 0x3800 /* 8 ways */
4879 | 0x0020; /* 32 kb */
4880 uint32_t l1cfg1 = 0x3800 /* 8 ways */
4881 | 0x0020; /* 32 kb */
4882 uint32_t mmucfg = 0;
4883 #if !defined(CONFIG_USER_ONLY)
4890 * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't
4891 * complain when accessing them.
4892 * gen_spr_BookE(env, 0x0000000F0000FD7FULL);
4898 ivor_mask = 0x0000000F0000FFFFULL;
4902 ivor_mask = 0x000003FE0000FFFFULL;
4905 ivor_mask = 0x000003FF0000FFFFULL;
4908 gen_spr_BookE(env, ivor_mask);
4909 gen_spr_usprg3(env);
4910 /* Processor identification */
4911 spr_register(env, SPR_BOOKE_PIR, "PIR",
4912 SPR_NOACCESS, SPR_NOACCESS,
4913 &spr_read_generic, &spr_write_pir,
4915 /* XXX : not implemented */
4916 spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
4917 &spr_read_spefscr, &spr_write_spefscr,
4918 &spr_read_spefscr, &spr_write_spefscr,
4920 #if !defined(CONFIG_USER_ONLY)
4921 /* Memory management */
4927 tlbncfg[0] = gen_tlbncfg(2, 1, 1, 0, 256);
4928 tlbncfg[1] = gen_tlbncfg(16, 1, 9, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16);
4931 tlbncfg[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4932 tlbncfg[1] = gen_tlbncfg(16, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16);
4936 tlbncfg[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4937 tlbncfg[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 64);
4942 tlbncfg[0] = 0x08052400;
4943 tlbncfg[1] = 0x40028040;
4946 cpu_abort(env_cpu(env), "Unknown CPU: " TARGET_FMT_lx "\n",
4954 env->dcache_line_size = 32;
4955 env->icache_line_size = 32;
4959 env->dcache_line_size = 64;
4960 env->icache_line_size = 64;
4961 l1cfg0 |= 0x1000000; /* 64 byte cache block size */
4962 l1cfg1 |= 0x1000000; /* 64 byte cache block size */
4965 env->dcache_line_size = 32;
4966 env->icache_line_size = 32;
4967 l1cfg0 |= 0x0F83820;
4968 l1cfg1 |= 0x0B83820;
4971 cpu_abort(env_cpu(env), "Unknown CPU: " TARGET_FMT_lx "\n",
4974 gen_spr_BookE206(env, 0x000000DF, tlbncfg, mmucfg);
4975 /* XXX : not implemented */
4976 spr_register(env, SPR_HID0, "HID0",
4977 SPR_NOACCESS, SPR_NOACCESS,
4978 &spr_read_generic, &spr_write_generic,
4980 /* XXX : not implemented */
4981 spr_register(env, SPR_HID1, "HID1",
4982 SPR_NOACCESS, SPR_NOACCESS,
4983 &spr_read_generic, &spr_write_generic,
4985 /* XXX : not implemented */
4986 spr_register(env, SPR_Exxx_BBEAR, "BBEAR",
4987 SPR_NOACCESS, SPR_NOACCESS,
4988 &spr_read_generic, &spr_write_generic,
4990 /* XXX : not implemented */
4991 spr_register(env, SPR_Exxx_BBTAR, "BBTAR",
4992 SPR_NOACCESS, SPR_NOACCESS,
4993 &spr_read_generic, &spr_write_generic,
4995 /* XXX : not implemented */
4996 spr_register(env, SPR_Exxx_MCAR, "MCAR",
4997 SPR_NOACCESS, SPR_NOACCESS,
4998 &spr_read_generic, &spr_write_generic,
5000 /* XXX : not implemented */
5001 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
5002 SPR_NOACCESS, SPR_NOACCESS,
5003 &spr_read_generic, &spr_write_generic,
5005 /* XXX : not implemented */
5006 spr_register(env, SPR_Exxx_NPIDR, "NPIDR",
5007 SPR_NOACCESS, SPR_NOACCESS,
5008 &spr_read_generic, &spr_write_generic,
5010 /* XXX : not implemented */
5011 spr_register(env, SPR_Exxx_BUCSR, "BUCSR",
5012 SPR_NOACCESS, SPR_NOACCESS,
5013 &spr_read_generic, &spr_write_generic,
5015 /* XXX : not implemented */
5016 spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0",
5017 &spr_read_generic, SPR_NOACCESS,
5018 &spr_read_generic, SPR_NOACCESS,
5020 spr_register(env, SPR_Exxx_L1CFG1, "L1CFG1",
5021 &spr_read_generic, SPR_NOACCESS,
5022 &spr_read_generic, SPR_NOACCESS,
5024 spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0",
5025 SPR_NOACCESS, SPR_NOACCESS,
5026 &spr_read_generic, &spr_write_e500_l1csr0,
5028 spr_register(env, SPR_Exxx_L1CSR1, "L1CSR1",
5029 SPR_NOACCESS, SPR_NOACCESS,
5030 &spr_read_generic, &spr_write_e500_l1csr1,
5032 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
5033 SPR_NOACCESS, SPR_NOACCESS,
5034 &spr_read_generic, &spr_write_generic,
5036 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
5037 SPR_NOACCESS, SPR_NOACCESS,
5038 &spr_read_generic, &spr_write_generic,
5040 spr_register(env, SPR_MMUCSR0, "MMUCSR0",
5041 SPR_NOACCESS, SPR_NOACCESS,
5042 &spr_read_generic, &spr_write_booke206_mmucsr0,
5044 spr_register(env, SPR_BOOKE_EPR, "EPR",
5045 SPR_NOACCESS, SPR_NOACCESS,
5046 &spr_read_generic, SPR_NOACCESS,
5048 /* XXX better abstract into Emb.xxx features */
5049 if ((version == fsl_e5500) || (version == fsl_e6500)) {
5050 spr_register(env, SPR_BOOKE_EPCR, "EPCR",
5051 SPR_NOACCESS, SPR_NOACCESS,
5052 &spr_read_generic, &spr_write_generic,
5054 spr_register(env, SPR_BOOKE_MAS7_MAS3, "MAS7_MAS3",
5055 SPR_NOACCESS, SPR_NOACCESS,
5056 &spr_read_mas73, &spr_write_mas73,
5058 ivpr_mask = (target_ulong)~0xFFFFULL;
5061 if (version == fsl_e6500) {
5062 /* Thread identification */
5063 spr_register(env, SPR_TIR, "TIR",
5064 SPR_NOACCESS, SPR_NOACCESS,
5065 &spr_read_generic, SPR_NOACCESS,
5067 spr_register(env, SPR_BOOKE_TLB0PS, "TLB0PS",
5068 SPR_NOACCESS, SPR_NOACCESS,
5069 &spr_read_generic, SPR_NOACCESS,
5071 spr_register(env, SPR_BOOKE_TLB1PS, "TLB1PS",
5072 SPR_NOACCESS, SPR_NOACCESS,
5073 &spr_read_generic, SPR_NOACCESS,
5077 #if !defined(CONFIG_USER_ONLY)
5079 env->tlb_type = TLB_MAS;
5080 for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
5081 env->nb_tlb += booke206_tlb_size(env, i);
5085 init_excp_e200(env, ivpr_mask);
5086 /* Allocate hardware IRQ controller */
5087 ppce500_irq_init(env_archcpu(env));
5090 static void init_proc_e500v1(CPUPPCState *env)
5092 init_proc_e500(env, fsl_e500v1);
5095 POWERPC_FAMILY(e500v1)(ObjectClass *oc, void *data)
5097 DeviceClass *dc = DEVICE_CLASS(oc);
5098 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5100 dc->desc = "e500v1 core";
5101 pcc->init_proc = init_proc_e500v1;
5102 pcc->check_pow = check_pow_hid0;
5103 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
5104 PPC_SPE | PPC_SPE_SINGLE |
5105 PPC_WRTEE | PPC_RFDI |
5106 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5107 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5108 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
5109 pcc->insns_flags2 = PPC2_BOOKE206;
5110 pcc->msr_mask = (1ull << MSR_UCLE) |
5124 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5125 pcc->excp_model = POWERPC_EXCP_BOOKE;
5126 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5127 pcc->bfd_mach = bfd_mach_ppc_860;
5128 pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
5129 POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
5130 POWERPC_FLAG_BUS_CLK;
5133 static void init_proc_e500v2(CPUPPCState *env)
5135 init_proc_e500(env, fsl_e500v2);
5138 POWERPC_FAMILY(e500v2)(ObjectClass *oc, void *data)
5140 DeviceClass *dc = DEVICE_CLASS(oc);
5141 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5143 dc->desc = "e500v2 core";
5144 pcc->init_proc = init_proc_e500v2;
5145 pcc->check_pow = check_pow_hid0;
5146 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
5147 PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE |
5148 PPC_WRTEE | PPC_RFDI |
5149 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5150 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5151 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
5152 pcc->insns_flags2 = PPC2_BOOKE206;
5153 pcc->msr_mask = (1ull << MSR_UCLE) |
5167 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5168 pcc->excp_model = POWERPC_EXCP_BOOKE;
5169 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5170 pcc->bfd_mach = bfd_mach_ppc_860;
5171 pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
5172 POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
5173 POWERPC_FLAG_BUS_CLK;
5176 static void init_proc_e500mc(CPUPPCState *env)
5178 init_proc_e500(env, fsl_e500mc);
5181 POWERPC_FAMILY(e500mc)(ObjectClass *oc, void *data)
5183 DeviceClass *dc = DEVICE_CLASS(oc);
5184 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5186 dc->desc = "e500mc core";
5187 pcc->init_proc = init_proc_e500mc;
5188 pcc->check_pow = check_pow_none;
5189 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
5190 PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
5191 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5192 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5193 PPC_FLOAT | PPC_FLOAT_FRES |
5194 PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
5195 PPC_FLOAT_STFIWX | PPC_WAIT |
5196 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
5197 pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL;
5198 pcc->msr_mask = (1ull << MSR_GS) |
5199 (1ull << MSR_UCLE) |
5212 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5213 pcc->excp_model = POWERPC_EXCP_BOOKE;
5214 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5215 /* FIXME: figure out the correct flag for e500mc */
5216 pcc->bfd_mach = bfd_mach_ppc_e500;
5217 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
5218 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
5222 static void init_proc_e5500(CPUPPCState *env)
5224 init_proc_e500(env, fsl_e5500);
5227 POWERPC_FAMILY(e5500)(ObjectClass *oc, void *data)
5229 DeviceClass *dc = DEVICE_CLASS(oc);
5230 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5232 dc->desc = "e5500 core";
5233 pcc->init_proc = init_proc_e5500;
5234 pcc->check_pow = check_pow_none;
5235 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
5236 PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
5237 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5238 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5239 PPC_FLOAT | PPC_FLOAT_FRES |
5240 PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
5241 PPC_FLOAT_STFIWX | PPC_WAIT |
5242 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC |
5243 PPC_64B | PPC_POPCNTB | PPC_POPCNTWD;
5244 pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_PERM_ISA206 |
5246 pcc->msr_mask = (1ull << MSR_CM) |
5248 (1ull << MSR_UCLE) |
5261 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5262 pcc->excp_model = POWERPC_EXCP_BOOKE;
5263 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5264 /* FIXME: figure out the correct flag for e5500 */
5265 pcc->bfd_mach = bfd_mach_ppc_e500;
5266 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
5267 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
5270 static void init_proc_e6500(CPUPPCState *env)
5272 init_proc_e500(env, fsl_e6500);
5275 POWERPC_FAMILY(e6500)(ObjectClass *oc, void *data)
5277 DeviceClass *dc = DEVICE_CLASS(oc);
5278 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5280 dc->desc = "e6500 core";
5281 pcc->init_proc = init_proc_e6500;
5282 pcc->check_pow = check_pow_none;
5283 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
5284 PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
5285 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5286 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5287 PPC_FLOAT | PPC_FLOAT_FRES |
5288 PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
5289 PPC_FLOAT_STFIWX | PPC_WAIT |
5290 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC |
5291 PPC_64B | PPC_POPCNTB | PPC_POPCNTWD | PPC_ALTIVEC;
5292 pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_PERM_ISA206 |
5293 PPC2_FP_CVT_S64 | PPC2_ATOMIC_ISA206;
5294 pcc->msr_mask = (1ull << MSR_CM) |
5296 (1ull << MSR_UCLE) |
5310 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5311 pcc->excp_model = POWERPC_EXCP_BOOKE;
5312 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5313 pcc->bfd_mach = bfd_mach_ppc_e500;
5314 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
5315 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_VRE;
5320 /* Non-embedded PowerPC */
5322 #define POWERPC_MSRR_601 (0x0000000000001040ULL)
5324 static void init_proc_601(CPUPPCState *env)
5326 gen_spr_ne_601(env);
5329 /* Hardware implementation registers */
5330 /* XXX : not implemented */
5331 spr_register(env, SPR_HID0, "HID0",
5332 SPR_NOACCESS, SPR_NOACCESS,
5333 &spr_read_generic, &spr_write_hid0_601,
5335 /* XXX : not implemented */
5336 spr_register(env, SPR_HID1, "HID1",
5337 SPR_NOACCESS, SPR_NOACCESS,
5338 &spr_read_generic, &spr_write_generic,
5340 /* XXX : not implemented */
5341 spr_register(env, SPR_601_HID2, "HID2",
5342 SPR_NOACCESS, SPR_NOACCESS,
5343 &spr_read_generic, &spr_write_generic,
5345 /* XXX : not implemented */
5346 spr_register(env, SPR_601_HID5, "HID5",
5347 SPR_NOACCESS, SPR_NOACCESS,
5348 &spr_read_generic, &spr_write_generic,
5350 /* Memory management */
5353 * XXX: beware that dcache line size is 64
5354 * but dcbz uses 32 bytes "sectors"
5355 * XXX: this breaks clcs instruction !
5357 env->dcache_line_size = 32;
5358 env->icache_line_size = 64;
5359 /* Allocate hardware IRQ controller */
5360 ppc6xx_irq_init(env_archcpu(env));
5363 POWERPC_FAMILY(601)(ObjectClass *oc, void *data)
5365 DeviceClass *dc = DEVICE_CLASS(oc);
5366 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5368 dc->desc = "PowerPC 601";
5369 pcc->init_proc = init_proc_601;
5370 pcc->check_pow = check_pow_none;
5371 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
5373 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5374 PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
5375 PPC_SEGMENT | PPC_EXTERN;
5376 pcc->msr_mask = (1ull << MSR_EE) |
5386 pcc->mmu_model = POWERPC_MMU_601;
5387 #if defined(CONFIG_SOFTMMU)
5388 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5390 pcc->excp_model = POWERPC_EXCP_601;
5391 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5392 pcc->bfd_mach = bfd_mach_ppc_601;
5393 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK;
5396 #define POWERPC_MSRR_601v (0x0000000000001040ULL)
5398 static void init_proc_601v(CPUPPCState *env)
5401 /* XXX : not implemented */
5402 spr_register(env, SPR_601_HID15, "HID15",
5403 SPR_NOACCESS, SPR_NOACCESS,
5404 &spr_read_generic, &spr_write_generic,
5408 POWERPC_FAMILY(601v)(ObjectClass *oc, void *data)
5410 DeviceClass *dc = DEVICE_CLASS(oc);
5411 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5413 dc->desc = "PowerPC 601v";
5414 pcc->init_proc = init_proc_601v;
5415 pcc->check_pow = check_pow_none;
5416 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
5418 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5419 PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
5420 PPC_SEGMENT | PPC_EXTERN;
5421 pcc->msr_mask = (1ull << MSR_EE) |
5431 pcc->mmu_model = POWERPC_MMU_601;
5432 #if defined(CONFIG_SOFTMMU)
5433 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5435 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5436 pcc->bfd_mach = bfd_mach_ppc_601;
5437 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK;
5440 static void init_proc_602(CPUPPCState *env)
5442 gen_spr_ne_601(env);
5447 /* hardware implementation registers */
5448 /* XXX : not implemented */
5449 spr_register(env, SPR_HID0, "HID0",
5450 SPR_NOACCESS, SPR_NOACCESS,
5451 &spr_read_generic, &spr_write_generic,
5453 /* XXX : not implemented */
5454 spr_register(env, SPR_HID1, "HID1",
5455 SPR_NOACCESS, SPR_NOACCESS,
5456 &spr_read_generic, &spr_write_generic,
5458 /* Memory management */
5460 gen_6xx_7xx_soft_tlb(env, 64, 2);
5462 env->dcache_line_size = 32;
5463 env->icache_line_size = 32;
5464 /* Allocate hardware IRQ controller */
5465 ppc6xx_irq_init(env_archcpu(env));
5468 POWERPC_FAMILY(602)(ObjectClass *oc, void *data)
5470 DeviceClass *dc = DEVICE_CLASS(oc);
5471 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5473 dc->desc = "PowerPC 602";
5474 pcc->init_proc = init_proc_602;
5475 pcc->check_pow = check_pow_hid0;
5476 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5477 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5478 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5479 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5480 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5481 PPC_MEM_TLBIE | PPC_6xx_TLB | PPC_MEM_TLBSYNC |
5482 PPC_SEGMENT | PPC_602_SPEC;
5483 pcc->msr_mask = (1ull << MSR_VSX) |
5486 (1ull << MSR_TGPR) |
5501 /* XXX: 602 MMU is quite specific. Should add a special case */
5502 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
5503 pcc->excp_model = POWERPC_EXCP_602;
5504 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5505 pcc->bfd_mach = bfd_mach_ppc_602;
5506 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
5507 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
5510 static void init_proc_603(CPUPPCState *env)
5512 gen_spr_ne_601(env);
5517 /* hardware implementation registers */
5518 /* XXX : not implemented */
5519 spr_register(env, SPR_HID0, "HID0",
5520 SPR_NOACCESS, SPR_NOACCESS,
5521 &spr_read_generic, &spr_write_generic,
5523 /* XXX : not implemented */
5524 spr_register(env, SPR_HID1, "HID1",
5525 SPR_NOACCESS, SPR_NOACCESS,
5526 &spr_read_generic, &spr_write_generic,
5528 /* Memory management */
5530 gen_6xx_7xx_soft_tlb(env, 64, 2);
5532 env->dcache_line_size = 32;
5533 env->icache_line_size = 32;
5534 /* Allocate hardware IRQ controller */
5535 ppc6xx_irq_init(env_archcpu(env));
5538 POWERPC_FAMILY(603)(ObjectClass *oc, void *data)
5540 DeviceClass *dc = DEVICE_CLASS(oc);
5541 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5543 dc->desc = "PowerPC 603";
5544 pcc->init_proc = init_proc_603;
5545 pcc->check_pow = check_pow_hid0;
5546 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5547 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5548 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5549 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5550 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5551 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
5552 PPC_SEGMENT | PPC_EXTERN;
5553 pcc->msr_mask = (1ull << MSR_POW) |
5554 (1ull << MSR_TGPR) |
5569 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
5570 pcc->excp_model = POWERPC_EXCP_603;
5571 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5572 pcc->bfd_mach = bfd_mach_ppc_603;
5573 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
5574 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
5577 static void init_proc_603E(CPUPPCState *env)
5579 gen_spr_ne_601(env);
5584 /* hardware implementation registers */
5585 /* XXX : not implemented */
5586 spr_register(env, SPR_HID0, "HID0",
5587 SPR_NOACCESS, SPR_NOACCESS,
5588 &spr_read_generic, &spr_write_generic,
5590 /* XXX : not implemented */
5591 spr_register(env, SPR_HID1, "HID1",
5592 SPR_NOACCESS, SPR_NOACCESS,
5593 &spr_read_generic, &spr_write_generic,
5595 /* Memory management */
5597 gen_6xx_7xx_soft_tlb(env, 64, 2);
5599 env->dcache_line_size = 32;
5600 env->icache_line_size = 32;
5601 /* Allocate hardware IRQ controller */
5602 ppc6xx_irq_init(env_archcpu(env));
5605 POWERPC_FAMILY(603E)(ObjectClass *oc, void *data)
5607 DeviceClass *dc = DEVICE_CLASS(oc);
5608 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5610 dc->desc = "PowerPC 603e";
5611 pcc->init_proc = init_proc_603E;
5612 pcc->check_pow = check_pow_hid0;
5613 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5614 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5615 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5616 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5617 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5618 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
5619 PPC_SEGMENT | PPC_EXTERN;
5620 pcc->msr_mask = (1ull << MSR_POW) |
5621 (1ull << MSR_TGPR) |
5636 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
5637 pcc->excp_model = POWERPC_EXCP_603E;
5638 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5639 pcc->bfd_mach = bfd_mach_ppc_ec603e;
5640 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
5641 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
5644 static void init_proc_604(CPUPPCState *env)
5646 gen_spr_ne_601(env);
5651 /* Hardware implementation registers */
5652 /* XXX : not implemented */
5653 spr_register(env, SPR_HID0, "HID0",
5654 SPR_NOACCESS, SPR_NOACCESS,
5655 &spr_read_generic, &spr_write_generic,
5657 /* Memory management */
5660 env->dcache_line_size = 32;
5661 env->icache_line_size = 32;
5662 /* Allocate hardware IRQ controller */
5663 ppc6xx_irq_init(env_archcpu(env));
5666 POWERPC_FAMILY(604)(ObjectClass *oc, void *data)
5668 DeviceClass *dc = DEVICE_CLASS(oc);
5669 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5671 dc->desc = "PowerPC 604";
5672 pcc->init_proc = init_proc_604;
5673 pcc->check_pow = check_pow_nocheck;
5674 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5675 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5676 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5677 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5678 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5679 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5680 PPC_SEGMENT | PPC_EXTERN;
5681 pcc->msr_mask = (1ull << MSR_POW) |
5697 pcc->mmu_model = POWERPC_MMU_32B;
5698 #if defined(CONFIG_SOFTMMU)
5699 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5701 pcc->excp_model = POWERPC_EXCP_604;
5702 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5703 pcc->bfd_mach = bfd_mach_ppc_604;
5704 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5705 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
5708 static void init_proc_604E(CPUPPCState *env)
5710 gen_spr_ne_601(env);
5713 /* XXX : not implemented */
5714 spr_register(env, SPR_7XX_MMCR1, "MMCR1",
5715 SPR_NOACCESS, SPR_NOACCESS,
5716 &spr_read_generic, &spr_write_generic,
5718 /* XXX : not implemented */
5719 spr_register(env, SPR_7XX_PMC3, "PMC3",
5720 SPR_NOACCESS, SPR_NOACCESS,
5721 &spr_read_generic, &spr_write_generic,
5723 /* XXX : not implemented */
5724 spr_register(env, SPR_7XX_PMC4, "PMC4",
5725 SPR_NOACCESS, SPR_NOACCESS,
5726 &spr_read_generic, &spr_write_generic,
5730 /* Hardware implementation registers */
5731 /* XXX : not implemented */
5732 spr_register(env, SPR_HID0, "HID0",
5733 SPR_NOACCESS, SPR_NOACCESS,
5734 &spr_read_generic, &spr_write_generic,
5736 /* XXX : not implemented */
5737 spr_register(env, SPR_HID1, "HID1",
5738 SPR_NOACCESS, SPR_NOACCESS,
5739 &spr_read_generic, &spr_write_generic,
5741 /* Memory management */
5744 env->dcache_line_size = 32;
5745 env->icache_line_size = 32;
5746 /* Allocate hardware IRQ controller */
5747 ppc6xx_irq_init(env_archcpu(env));
5750 POWERPC_FAMILY(604E)(ObjectClass *oc, void *data)
5752 DeviceClass *dc = DEVICE_CLASS(oc);
5753 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5755 dc->desc = "PowerPC 604E";
5756 pcc->init_proc = init_proc_604E;
5757 pcc->check_pow = check_pow_nocheck;
5758 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5759 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5760 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5761 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5762 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5763 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5764 PPC_SEGMENT | PPC_EXTERN;
5765 pcc->msr_mask = (1ull << MSR_POW) |
5781 pcc->mmu_model = POWERPC_MMU_32B;
5782 #if defined(CONFIG_SOFTMMU)
5783 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5785 pcc->excp_model = POWERPC_EXCP_604;
5786 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5787 pcc->bfd_mach = bfd_mach_ppc_604;
5788 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5789 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
5792 static void init_proc_740(CPUPPCState *env)
5794 gen_spr_ne_601(env);
5799 /* Thermal management */
5801 /* Hardware implementation registers */
5802 /* XXX : not implemented */
5803 spr_register(env, SPR_HID0, "HID0",
5804 SPR_NOACCESS, SPR_NOACCESS,
5805 &spr_read_generic, &spr_write_generic,
5807 /* XXX : not implemented */
5808 spr_register(env, SPR_HID1, "HID1",
5809 SPR_NOACCESS, SPR_NOACCESS,
5810 &spr_read_generic, &spr_write_generic,
5812 /* Memory management */
5815 env->dcache_line_size = 32;
5816 env->icache_line_size = 32;
5817 /* Allocate hardware IRQ controller */
5818 ppc6xx_irq_init(env_archcpu(env));
5821 POWERPC_FAMILY(740)(ObjectClass *oc, void *data)
5823 DeviceClass *dc = DEVICE_CLASS(oc);
5824 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5826 dc->desc = "PowerPC 740";
5827 pcc->init_proc = init_proc_740;
5828 pcc->check_pow = check_pow_hid0;
5829 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5830 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5831 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5832 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5833 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5834 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5835 PPC_SEGMENT | PPC_EXTERN;
5836 pcc->msr_mask = (1ull << MSR_POW) |
5852 pcc->mmu_model = POWERPC_MMU_32B;
5853 #if defined(CONFIG_SOFTMMU)
5854 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5856 pcc->excp_model = POWERPC_EXCP_7x0;
5857 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5858 pcc->bfd_mach = bfd_mach_ppc_750;
5859 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5860 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
5863 static void init_proc_750(CPUPPCState *env)
5865 gen_spr_ne_601(env);
5868 /* XXX : not implemented */
5869 spr_register(env, SPR_L2CR, "L2CR",
5870 SPR_NOACCESS, SPR_NOACCESS,
5871 &spr_read_generic, spr_access_nop,
5875 /* Thermal management */
5877 /* Hardware implementation registers */
5878 /* XXX : not implemented */
5879 spr_register(env, SPR_HID0, "HID0",
5880 SPR_NOACCESS, SPR_NOACCESS,
5881 &spr_read_generic, &spr_write_generic,
5883 /* XXX : not implemented */
5884 spr_register(env, SPR_HID1, "HID1",
5885 SPR_NOACCESS, SPR_NOACCESS,
5886 &spr_read_generic, &spr_write_generic,
5888 /* Memory management */
5891 * XXX: high BATs are also present but are known to be bugged on
5895 env->dcache_line_size = 32;
5896 env->icache_line_size = 32;
5897 /* Allocate hardware IRQ controller */
5898 ppc6xx_irq_init(env_archcpu(env));
5901 POWERPC_FAMILY(750)(ObjectClass *oc, void *data)
5903 DeviceClass *dc = DEVICE_CLASS(oc);
5904 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5906 dc->desc = "PowerPC 750";
5907 pcc->init_proc = init_proc_750;
5908 pcc->check_pow = check_pow_hid0;
5909 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5910 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5911 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5912 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5913 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5914 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5915 PPC_SEGMENT | PPC_EXTERN;
5916 pcc->msr_mask = (1ull << MSR_POW) |
5932 pcc->mmu_model = POWERPC_MMU_32B;
5933 #if defined(CONFIG_SOFTMMU)
5934 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5936 pcc->excp_model = POWERPC_EXCP_7x0;
5937 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5938 pcc->bfd_mach = bfd_mach_ppc_750;
5939 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5940 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
5943 static void init_proc_750cl(CPUPPCState *env)
5945 gen_spr_ne_601(env);
5948 /* XXX : not implemented */
5949 spr_register(env, SPR_L2CR, "L2CR",
5950 SPR_NOACCESS, SPR_NOACCESS,
5951 &spr_read_generic, spr_access_nop,
5955 /* Thermal management */
5956 /* Those registers are fake on 750CL */
5957 spr_register(env, SPR_THRM1, "THRM1",
5958 SPR_NOACCESS, SPR_NOACCESS,
5959 &spr_read_generic, &spr_write_generic,
5961 spr_register(env, SPR_THRM2, "THRM2",
5962 SPR_NOACCESS, SPR_NOACCESS,
5963 &spr_read_generic, &spr_write_generic,
5965 spr_register(env, SPR_THRM3, "THRM3",
5966 SPR_NOACCESS, SPR_NOACCESS,
5967 &spr_read_generic, &spr_write_generic,
5969 /* XXX: not implemented */
5970 spr_register(env, SPR_750_TDCL, "TDCL",
5971 SPR_NOACCESS, SPR_NOACCESS,
5972 &spr_read_generic, &spr_write_generic,
5974 spr_register(env, SPR_750_TDCH, "TDCH",
5975 SPR_NOACCESS, SPR_NOACCESS,
5976 &spr_read_generic, &spr_write_generic,
5979 /* XXX : not implemented */
5980 spr_register(env, SPR_750_WPAR, "WPAR",
5981 SPR_NOACCESS, SPR_NOACCESS,
5982 &spr_read_generic, &spr_write_generic,
5984 spr_register(env, SPR_750_DMAL, "DMAL",
5985 SPR_NOACCESS, SPR_NOACCESS,
5986 &spr_read_generic, &spr_write_generic,
5988 spr_register(env, SPR_750_DMAU, "DMAU",
5989 SPR_NOACCESS, SPR_NOACCESS,
5990 &spr_read_generic, &spr_write_generic,
5992 /* Hardware implementation registers */
5993 /* XXX : not implemented */
5994 spr_register(env, SPR_HID0, "HID0",
5995 SPR_NOACCESS, SPR_NOACCESS,
5996 &spr_read_generic, &spr_write_generic,
5998 /* XXX : not implemented */
5999 spr_register(env, SPR_HID1, "HID1",
6000 SPR_NOACCESS, SPR_NOACCESS,
6001 &spr_read_generic, &spr_write_generic,
6003 /* XXX : not implemented */
6004 spr_register(env, SPR_750CL_HID2, "HID2",
6005 SPR_NOACCESS, SPR_NOACCESS,
6006 &spr_read_generic, &spr_write_generic,
6008 /* XXX : not implemented */
6009 spr_register(env, SPR_750CL_HID4, "HID4",
6010 SPR_NOACCESS, SPR_NOACCESS,
6011 &spr_read_generic, &spr_write_generic,
6013 /* Quantization registers */
6014 /* XXX : not implemented */
6015 spr_register(env, SPR_750_GQR0, "GQR0",
6016 SPR_NOACCESS, SPR_NOACCESS,
6017 &spr_read_generic, &spr_write_generic,
6019 /* XXX : not implemented */
6020 spr_register(env, SPR_750_GQR1, "GQR1",
6021 SPR_NOACCESS, SPR_NOACCESS,
6022 &spr_read_generic, &spr_write_generic,
6024 /* XXX : not implemented */
6025 spr_register(env, SPR_750_GQR2, "GQR2",
6026 SPR_NOACCESS, SPR_NOACCESS,
6027 &spr_read_generic, &spr_write_generic,
6029 /* XXX : not implemented */
6030 spr_register(env, SPR_750_GQR3, "GQR3",
6031 SPR_NOACCESS, SPR_NOACCESS,
6032 &spr_read_generic, &spr_write_generic,
6034 /* XXX : not implemented */
6035 spr_register(env, SPR_750_GQR4, "GQR4",
6036 SPR_NOACCESS, SPR_NOACCESS,
6037 &spr_read_generic, &spr_write_generic,
6039 /* XXX : not implemented */
6040 spr_register(env, SPR_750_GQR5, "GQR5",
6041 SPR_NOACCESS, SPR_NOACCESS,
6042 &spr_read_generic, &spr_write_generic,
6044 /* XXX : not implemented */
6045 spr_register(env, SPR_750_GQR6, "GQR6",
6046 SPR_NOACCESS, SPR_NOACCESS,
6047 &spr_read_generic, &spr_write_generic,
6049 /* XXX : not implemented */
6050 spr_register(env, SPR_750_GQR7, "GQR7",
6051 SPR_NOACCESS, SPR_NOACCESS,
6052 &spr_read_generic, &spr_write_generic,
6054 /* Memory management */
6056 /* PowerPC 750cl has 8 DBATs and 8 IBATs */
6058 init_excp_750cl(env);
6059 env->dcache_line_size = 32;
6060 env->icache_line_size = 32;
6061 /* Allocate hardware IRQ controller */
6062 ppc6xx_irq_init(env_archcpu(env));
6065 POWERPC_FAMILY(750cl)(ObjectClass *oc, void *data)
6067 DeviceClass *dc = DEVICE_CLASS(oc);
6068 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6070 dc->desc = "PowerPC 750 CL";
6071 pcc->init_proc = init_proc_750cl;
6072 pcc->check_pow = check_pow_hid0;
6074 * XXX: not implemented:
6075 * cache lock instructions:
6077 * floating point paired instructions
6112 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6113 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6114 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6115 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6116 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6117 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6118 PPC_SEGMENT | PPC_EXTERN;
6119 pcc->msr_mask = (1ull << MSR_POW) |
6135 pcc->mmu_model = POWERPC_MMU_32B;
6136 #if defined(CONFIG_SOFTMMU)
6137 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6139 pcc->excp_model = POWERPC_EXCP_7x0;
6140 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6141 pcc->bfd_mach = bfd_mach_ppc_750;
6142 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6143 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
6146 static void init_proc_750cx(CPUPPCState *env)
6148 gen_spr_ne_601(env);
6151 /* XXX : not implemented */
6152 spr_register(env, SPR_L2CR, "L2CR",
6153 SPR_NOACCESS, SPR_NOACCESS,
6154 &spr_read_generic, spr_access_nop,
6158 /* Thermal management */
6160 /* This register is not implemented but is present for compatibility */
6161 spr_register(env, SPR_SDA, "SDA",
6162 SPR_NOACCESS, SPR_NOACCESS,
6163 &spr_read_generic, &spr_write_generic,
6165 /* Hardware implementation registers */
6166 /* XXX : not implemented */
6167 spr_register(env, SPR_HID0, "HID0",
6168 SPR_NOACCESS, SPR_NOACCESS,
6169 &spr_read_generic, &spr_write_generic,
6171 /* XXX : not implemented */
6172 spr_register(env, SPR_HID1, "HID1",
6173 SPR_NOACCESS, SPR_NOACCESS,
6174 &spr_read_generic, &spr_write_generic,
6176 /* Memory management */
6178 /* PowerPC 750cx has 8 DBATs and 8 IBATs */
6180 init_excp_750cx(env);
6181 env->dcache_line_size = 32;
6182 env->icache_line_size = 32;
6183 /* Allocate hardware IRQ controller */
6184 ppc6xx_irq_init(env_archcpu(env));
6187 POWERPC_FAMILY(750cx)(ObjectClass *oc, void *data)
6189 DeviceClass *dc = DEVICE_CLASS(oc);
6190 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6192 dc->desc = "PowerPC 750CX";
6193 pcc->init_proc = init_proc_750cx;
6194 pcc->check_pow = check_pow_hid0;
6195 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6196 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6197 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6198 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6199 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6200 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6201 PPC_SEGMENT | PPC_EXTERN;
6202 pcc->msr_mask = (1ull << MSR_POW) |
6218 pcc->mmu_model = POWERPC_MMU_32B;
6219 #if defined(CONFIG_SOFTMMU)
6220 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6222 pcc->excp_model = POWERPC_EXCP_7x0;
6223 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6224 pcc->bfd_mach = bfd_mach_ppc_750;
6225 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6226 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
6229 static void init_proc_750fx(CPUPPCState *env)
6231 gen_spr_ne_601(env);
6234 /* XXX : not implemented */
6235 spr_register(env, SPR_L2CR, "L2CR",
6236 SPR_NOACCESS, SPR_NOACCESS,
6237 &spr_read_generic, spr_access_nop,
6241 /* Thermal management */
6243 /* XXX : not implemented */
6244 spr_register(env, SPR_750_THRM4, "THRM4",
6245 SPR_NOACCESS, SPR_NOACCESS,
6246 &spr_read_generic, &spr_write_generic,
6248 /* Hardware implementation registers */
6249 /* XXX : not implemented */
6250 spr_register(env, SPR_HID0, "HID0",
6251 SPR_NOACCESS, SPR_NOACCESS,
6252 &spr_read_generic, &spr_write_generic,
6254 /* XXX : not implemented */
6255 spr_register(env, SPR_HID1, "HID1",
6256 SPR_NOACCESS, SPR_NOACCESS,
6257 &spr_read_generic, &spr_write_generic,
6259 /* XXX : not implemented */
6260 spr_register(env, SPR_750FX_HID2, "HID2",
6261 SPR_NOACCESS, SPR_NOACCESS,
6262 &spr_read_generic, &spr_write_generic,
6264 /* Memory management */
6266 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6269 env->dcache_line_size = 32;
6270 env->icache_line_size = 32;
6271 /* Allocate hardware IRQ controller */
6272 ppc6xx_irq_init(env_archcpu(env));
6275 POWERPC_FAMILY(750fx)(ObjectClass *oc, void *data)
6277 DeviceClass *dc = DEVICE_CLASS(oc);
6278 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6280 dc->desc = "PowerPC 750FX";
6281 pcc->init_proc = init_proc_750fx;
6282 pcc->check_pow = check_pow_hid0;
6283 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6284 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6285 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6286 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6287 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6288 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6289 PPC_SEGMENT | PPC_EXTERN;
6290 pcc->msr_mask = (1ull << MSR_POW) |
6306 pcc->mmu_model = POWERPC_MMU_32B;
6307 #if defined(CONFIG_SOFTMMU)
6308 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6310 pcc->excp_model = POWERPC_EXCP_7x0;
6311 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6312 pcc->bfd_mach = bfd_mach_ppc_750;
6313 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6314 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
6317 static void init_proc_750gx(CPUPPCState *env)
6319 gen_spr_ne_601(env);
6322 /* XXX : not implemented (XXX: different from 750fx) */
6323 spr_register(env, SPR_L2CR, "L2CR",
6324 SPR_NOACCESS, SPR_NOACCESS,
6325 &spr_read_generic, spr_access_nop,
6329 /* Thermal management */
6331 /* XXX : not implemented */
6332 spr_register(env, SPR_750_THRM4, "THRM4",
6333 SPR_NOACCESS, SPR_NOACCESS,
6334 &spr_read_generic, &spr_write_generic,
6336 /* Hardware implementation registers */
6337 /* XXX : not implemented (XXX: different from 750fx) */
6338 spr_register(env, SPR_HID0, "HID0",
6339 SPR_NOACCESS, SPR_NOACCESS,
6340 &spr_read_generic, &spr_write_generic,
6342 /* XXX : not implemented */
6343 spr_register(env, SPR_HID1, "HID1",
6344 SPR_NOACCESS, SPR_NOACCESS,
6345 &spr_read_generic, &spr_write_generic,
6347 /* XXX : not implemented (XXX: different from 750fx) */
6348 spr_register(env, SPR_750FX_HID2, "HID2",
6349 SPR_NOACCESS, SPR_NOACCESS,
6350 &spr_read_generic, &spr_write_generic,
6352 /* Memory management */
6354 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6357 env->dcache_line_size = 32;
6358 env->icache_line_size = 32;
6359 /* Allocate hardware IRQ controller */
6360 ppc6xx_irq_init(env_archcpu(env));
6363 POWERPC_FAMILY(750gx)(ObjectClass *oc, void *data)
6365 DeviceClass *dc = DEVICE_CLASS(oc);
6366 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6368 dc->desc = "PowerPC 750GX";
6369 pcc->init_proc = init_proc_750gx;
6370 pcc->check_pow = check_pow_hid0;
6371 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6372 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6373 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6374 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6375 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6376 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6377 PPC_SEGMENT | PPC_EXTERN;
6378 pcc->msr_mask = (1ull << MSR_POW) |
6394 pcc->mmu_model = POWERPC_MMU_32B;
6395 #if defined(CONFIG_SOFTMMU)
6396 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6398 pcc->excp_model = POWERPC_EXCP_7x0;
6399 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6400 pcc->bfd_mach = bfd_mach_ppc_750;
6401 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6402 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
6405 static void init_proc_745(CPUPPCState *env)
6407 gen_spr_ne_601(env);
6410 gen_spr_G2_755(env);
6413 /* Thermal management */
6415 /* Hardware implementation registers */
6416 /* XXX : not implemented */
6417 spr_register(env, SPR_HID0, "HID0",
6418 SPR_NOACCESS, SPR_NOACCESS,
6419 &spr_read_generic, &spr_write_generic,
6421 /* XXX : not implemented */
6422 spr_register(env, SPR_HID1, "HID1",
6423 SPR_NOACCESS, SPR_NOACCESS,
6424 &spr_read_generic, &spr_write_generic,
6426 /* XXX : not implemented */
6427 spr_register(env, SPR_HID2, "HID2",
6428 SPR_NOACCESS, SPR_NOACCESS,
6429 &spr_read_generic, &spr_write_generic,
6431 /* Memory management */
6434 gen_6xx_7xx_soft_tlb(env, 64, 2);
6436 env->dcache_line_size = 32;
6437 env->icache_line_size = 32;
6438 /* Allocate hardware IRQ controller */
6439 ppc6xx_irq_init(env_archcpu(env));
6442 POWERPC_FAMILY(745)(ObjectClass *oc, void *data)
6444 DeviceClass *dc = DEVICE_CLASS(oc);
6445 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6447 dc->desc = "PowerPC 745";
6448 pcc->init_proc = init_proc_745;
6449 pcc->check_pow = check_pow_hid0;
6450 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6451 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6452 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6453 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6454 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6455 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
6456 PPC_SEGMENT | PPC_EXTERN;
6457 pcc->msr_mask = (1ull << MSR_POW) |
6473 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
6474 pcc->excp_model = POWERPC_EXCP_7x5;
6475 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6476 pcc->bfd_mach = bfd_mach_ppc_750;
6477 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6478 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
6481 static void init_proc_755(CPUPPCState *env)
6483 gen_spr_ne_601(env);
6486 gen_spr_G2_755(env);
6489 /* L2 cache control */
6490 /* XXX : not implemented */
6491 spr_register(env, SPR_L2CR, "L2CR",
6492 SPR_NOACCESS, SPR_NOACCESS,
6493 &spr_read_generic, spr_access_nop,
6495 /* XXX : not implemented */
6496 spr_register(env, SPR_L2PMCR, "L2PMCR",
6497 SPR_NOACCESS, SPR_NOACCESS,
6498 &spr_read_generic, &spr_write_generic,
6500 /* Thermal management */
6502 /* Hardware implementation registers */
6503 /* XXX : not implemented */
6504 spr_register(env, SPR_HID0, "HID0",
6505 SPR_NOACCESS, SPR_NOACCESS,
6506 &spr_read_generic, &spr_write_generic,
6508 /* XXX : not implemented */
6509 spr_register(env, SPR_HID1, "HID1",
6510 SPR_NOACCESS, SPR_NOACCESS,
6511 &spr_read_generic, &spr_write_generic,
6513 /* XXX : not implemented */
6514 spr_register(env, SPR_HID2, "HID2",
6515 SPR_NOACCESS, SPR_NOACCESS,
6516 &spr_read_generic, &spr_write_generic,
6518 /* Memory management */
6521 gen_6xx_7xx_soft_tlb(env, 64, 2);
6523 env->dcache_line_size = 32;
6524 env->icache_line_size = 32;
6525 /* Allocate hardware IRQ controller */
6526 ppc6xx_irq_init(env_archcpu(env));
6529 POWERPC_FAMILY(755)(ObjectClass *oc, void *data)
6531 DeviceClass *dc = DEVICE_CLASS(oc);
6532 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6534 dc->desc = "PowerPC 755";
6535 pcc->init_proc = init_proc_755;
6536 pcc->check_pow = check_pow_hid0;
6537 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6538 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6539 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6540 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6541 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6542 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
6543 PPC_SEGMENT | PPC_EXTERN;
6544 pcc->msr_mask = (1ull << MSR_POW) |
6560 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
6561 pcc->excp_model = POWERPC_EXCP_7x5;
6562 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6563 pcc->bfd_mach = bfd_mach_ppc_750;
6564 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6565 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
6568 static void init_proc_7400(CPUPPCState *env)
6570 gen_spr_ne_601(env);
6575 /* 74xx specific SPR */
6577 /* XXX : not implemented */
6578 spr_register(env, SPR_UBAMR, "UBAMR",
6579 &spr_read_ureg, SPR_NOACCESS,
6580 &spr_read_ureg, SPR_NOACCESS,
6582 /* XXX: this seems not implemented on all revisions. */
6583 /* XXX : not implemented */
6584 spr_register(env, SPR_MSSCR1, "MSSCR1",
6585 SPR_NOACCESS, SPR_NOACCESS,
6586 &spr_read_generic, &spr_write_generic,
6588 /* Thermal management */
6590 /* Memory management */
6592 init_excp_7400(env);
6593 env->dcache_line_size = 32;
6594 env->icache_line_size = 32;
6595 /* Allocate hardware IRQ controller */
6596 ppc6xx_irq_init(env_archcpu(env));
6599 POWERPC_FAMILY(7400)(ObjectClass *oc, void *data)
6601 DeviceClass *dc = DEVICE_CLASS(oc);
6602 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6604 dc->desc = "PowerPC 7400 (aka G4)";
6605 pcc->init_proc = init_proc_7400;
6606 pcc->check_pow = check_pow_hid0;
6607 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6608 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6609 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6611 PPC_CACHE | PPC_CACHE_ICBI |
6612 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6613 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6614 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6616 PPC_SEGMENT | PPC_EXTERN |
6618 pcc->msr_mask = (1ull << MSR_VR) |
6635 pcc->mmu_model = POWERPC_MMU_32B;
6636 #if defined(CONFIG_SOFTMMU)
6637 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6639 pcc->excp_model = POWERPC_EXCP_74xx;
6640 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6641 pcc->bfd_mach = bfd_mach_ppc_7400;
6642 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6643 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6644 POWERPC_FLAG_BUS_CLK;
6647 static void init_proc_7410(CPUPPCState *env)
6649 gen_spr_ne_601(env);
6654 /* 74xx specific SPR */
6656 /* XXX : not implemented */
6657 spr_register(env, SPR_UBAMR, "UBAMR",
6658 &spr_read_ureg, SPR_NOACCESS,
6659 &spr_read_ureg, SPR_NOACCESS,
6661 /* Thermal management */
6664 /* XXX : not implemented */
6665 spr_register(env, SPR_L2PMCR, "L2PMCR",
6666 SPR_NOACCESS, SPR_NOACCESS,
6667 &spr_read_generic, &spr_write_generic,
6670 /* XXX : not implemented */
6671 spr_register(env, SPR_LDSTDB, "LDSTDB",
6672 SPR_NOACCESS, SPR_NOACCESS,
6673 &spr_read_generic, &spr_write_generic,
6675 /* Memory management */
6677 init_excp_7400(env);
6678 env->dcache_line_size = 32;
6679 env->icache_line_size = 32;
6680 /* Allocate hardware IRQ controller */
6681 ppc6xx_irq_init(env_archcpu(env));
6684 POWERPC_FAMILY(7410)(ObjectClass *oc, void *data)
6686 DeviceClass *dc = DEVICE_CLASS(oc);
6687 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6689 dc->desc = "PowerPC 7410 (aka G4)";
6690 pcc->init_proc = init_proc_7410;
6691 pcc->check_pow = check_pow_hid0;
6692 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6693 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6694 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6696 PPC_CACHE | PPC_CACHE_ICBI |
6697 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6698 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6699 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6701 PPC_SEGMENT | PPC_EXTERN |
6703 pcc->msr_mask = (1ull << MSR_VR) |
6720 pcc->mmu_model = POWERPC_MMU_32B;
6721 #if defined(CONFIG_SOFTMMU)
6722 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6724 pcc->excp_model = POWERPC_EXCP_74xx;
6725 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6726 pcc->bfd_mach = bfd_mach_ppc_7400;
6727 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6728 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6729 POWERPC_FLAG_BUS_CLK;
6732 static void init_proc_7440(CPUPPCState *env)
6734 gen_spr_ne_601(env);
6739 /* 74xx specific SPR */
6741 /* XXX : not implemented */
6742 spr_register(env, SPR_UBAMR, "UBAMR",
6743 &spr_read_ureg, SPR_NOACCESS,
6744 &spr_read_ureg, SPR_NOACCESS,
6747 /* XXX : not implemented */
6748 spr_register(env, SPR_LDSTCR, "LDSTCR",
6749 SPR_NOACCESS, SPR_NOACCESS,
6750 &spr_read_generic, &spr_write_generic,
6753 /* XXX : not implemented */
6754 spr_register(env, SPR_ICTRL, "ICTRL",
6755 SPR_NOACCESS, SPR_NOACCESS,
6756 &spr_read_generic, &spr_write_generic,
6759 /* XXX : not implemented */
6760 spr_register(env, SPR_MSSSR0, "MSSSR0",
6761 SPR_NOACCESS, SPR_NOACCESS,
6762 &spr_read_generic, &spr_write_generic,
6765 /* XXX : not implemented */
6766 spr_register(env, SPR_7XX_PMC5, "PMC5",
6767 SPR_NOACCESS, SPR_NOACCESS,
6768 &spr_read_generic, &spr_write_generic,
6770 /* XXX : not implemented */
6771 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
6772 &spr_read_ureg, SPR_NOACCESS,
6773 &spr_read_ureg, SPR_NOACCESS,
6775 /* XXX : not implemented */
6776 spr_register(env, SPR_7XX_PMC6, "PMC6",
6777 SPR_NOACCESS, SPR_NOACCESS,
6778 &spr_read_generic, &spr_write_generic,
6780 /* XXX : not implemented */
6781 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
6782 &spr_read_ureg, SPR_NOACCESS,
6783 &spr_read_ureg, SPR_NOACCESS,
6785 /* Memory management */
6787 gen_74xx_soft_tlb(env, 128, 2);
6788 init_excp_7450(env);
6789 env->dcache_line_size = 32;
6790 env->icache_line_size = 32;
6791 /* Allocate hardware IRQ controller */
6792 ppc6xx_irq_init(env_archcpu(env));
6795 POWERPC_FAMILY(7440)(ObjectClass *oc, void *data)
6797 DeviceClass *dc = DEVICE_CLASS(oc);
6798 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6800 dc->desc = "PowerPC 7440 (aka G4)";
6801 pcc->init_proc = init_proc_7440;
6802 pcc->check_pow = check_pow_hid0_74xx;
6803 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6804 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6805 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6807 PPC_CACHE | PPC_CACHE_ICBI |
6808 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6809 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6810 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6811 PPC_MEM_TLBIA | PPC_74xx_TLB |
6812 PPC_SEGMENT | PPC_EXTERN |
6814 pcc->msr_mask = (1ull << MSR_VR) |
6831 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
6832 pcc->excp_model = POWERPC_EXCP_74xx;
6833 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6834 pcc->bfd_mach = bfd_mach_ppc_7400;
6835 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6836 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6837 POWERPC_FLAG_BUS_CLK;
6840 static void init_proc_7450(CPUPPCState *env)
6842 gen_spr_ne_601(env);
6847 /* 74xx specific SPR */
6849 /* Level 3 cache control */
6852 /* XXX : not implemented */
6853 spr_register(env, SPR_L3ITCR1, "L3ITCR1",
6854 SPR_NOACCESS, SPR_NOACCESS,
6855 &spr_read_generic, &spr_write_generic,
6858 /* XXX : not implemented */
6859 spr_register(env, SPR_L3ITCR2, "L3ITCR2",
6860 SPR_NOACCESS, SPR_NOACCESS,
6861 &spr_read_generic, &spr_write_generic,
6864 /* XXX : not implemented */
6865 spr_register(env, SPR_L3ITCR3, "L3ITCR3",
6866 SPR_NOACCESS, SPR_NOACCESS,
6867 &spr_read_generic, &spr_write_generic,
6870 /* XXX : not implemented */
6871 spr_register(env, SPR_L3OHCR, "L3OHCR",
6872 SPR_NOACCESS, SPR_NOACCESS,
6873 &spr_read_generic, &spr_write_generic,
6875 /* XXX : not implemented */
6876 spr_register(env, SPR_UBAMR, "UBAMR",
6877 &spr_read_ureg, SPR_NOACCESS,
6878 &spr_read_ureg, SPR_NOACCESS,
6881 /* XXX : not implemented */
6882 spr_register(env, SPR_LDSTCR, "LDSTCR",
6883 SPR_NOACCESS, SPR_NOACCESS,
6884 &spr_read_generic, &spr_write_generic,
6887 /* XXX : not implemented */
6888 spr_register(env, SPR_ICTRL, "ICTRL",
6889 SPR_NOACCESS, SPR_NOACCESS,
6890 &spr_read_generic, &spr_write_generic,
6893 /* XXX : not implemented */
6894 spr_register(env, SPR_MSSSR0, "MSSSR0",
6895 SPR_NOACCESS, SPR_NOACCESS,
6896 &spr_read_generic, &spr_write_generic,
6899 /* XXX : not implemented */
6900 spr_register(env, SPR_7XX_PMC5, "PMC5",
6901 SPR_NOACCESS, SPR_NOACCESS,
6902 &spr_read_generic, &spr_write_generic,
6904 /* XXX : not implemented */
6905 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
6906 &spr_read_ureg, SPR_NOACCESS,
6907 &spr_read_ureg, SPR_NOACCESS,
6909 /* XXX : not implemented */
6910 spr_register(env, SPR_7XX_PMC6, "PMC6",
6911 SPR_NOACCESS, SPR_NOACCESS,
6912 &spr_read_generic, &spr_write_generic,
6914 /* XXX : not implemented */
6915 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
6916 &spr_read_ureg, SPR_NOACCESS,
6917 &spr_read_ureg, SPR_NOACCESS,
6919 /* Memory management */
6921 gen_74xx_soft_tlb(env, 128, 2);
6922 init_excp_7450(env);
6923 env->dcache_line_size = 32;
6924 env->icache_line_size = 32;
6925 /* Allocate hardware IRQ controller */
6926 ppc6xx_irq_init(env_archcpu(env));
6929 POWERPC_FAMILY(7450)(ObjectClass *oc, void *data)
6931 DeviceClass *dc = DEVICE_CLASS(oc);
6932 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6934 dc->desc = "PowerPC 7450 (aka G4)";
6935 pcc->init_proc = init_proc_7450;
6936 pcc->check_pow = check_pow_hid0_74xx;
6937 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6938 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6939 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6941 PPC_CACHE | PPC_CACHE_ICBI |
6942 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6943 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6944 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6945 PPC_MEM_TLBIA | PPC_74xx_TLB |
6946 PPC_SEGMENT | PPC_EXTERN |
6948 pcc->msr_mask = (1ull << MSR_VR) |
6965 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
6966 pcc->excp_model = POWERPC_EXCP_74xx;
6967 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6968 pcc->bfd_mach = bfd_mach_ppc_7400;
6969 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6970 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6971 POWERPC_FLAG_BUS_CLK;
6974 static void init_proc_7445(CPUPPCState *env)
6976 gen_spr_ne_601(env);
6981 /* 74xx specific SPR */
6984 /* XXX : not implemented */
6985 spr_register(env, SPR_LDSTCR, "LDSTCR",
6986 SPR_NOACCESS, SPR_NOACCESS,
6987 &spr_read_generic, &spr_write_generic,
6990 /* XXX : not implemented */
6991 spr_register(env, SPR_ICTRL, "ICTRL",
6992 SPR_NOACCESS, SPR_NOACCESS,
6993 &spr_read_generic, &spr_write_generic,
6996 /* XXX : not implemented */
6997 spr_register(env, SPR_MSSSR0, "MSSSR0",
6998 SPR_NOACCESS, SPR_NOACCESS,
6999 &spr_read_generic, &spr_write_generic,
7002 /* XXX : not implemented */
7003 spr_register(env, SPR_7XX_PMC5, "PMC5",
7004 SPR_NOACCESS, SPR_NOACCESS,
7005 &spr_read_generic, &spr_write_generic,
7007 /* XXX : not implemented */
7008 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
7009 &spr_read_ureg, SPR_NOACCESS,
7010 &spr_read_ureg, SPR_NOACCESS,
7012 /* XXX : not implemented */
7013 spr_register(env, SPR_7XX_PMC6, "PMC6",
7014 SPR_NOACCESS, SPR_NOACCESS,
7015 &spr_read_generic, &spr_write_generic,
7017 /* XXX : not implemented */
7018 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
7019 &spr_read_ureg, SPR_NOACCESS,
7020 &spr_read_ureg, SPR_NOACCESS,
7023 spr_register(env, SPR_SPRG4, "SPRG4",
7024 SPR_NOACCESS, SPR_NOACCESS,
7025 &spr_read_generic, &spr_write_generic,
7027 spr_register(env, SPR_USPRG4, "USPRG4",
7028 &spr_read_ureg, SPR_NOACCESS,
7029 &spr_read_ureg, SPR_NOACCESS,
7031 spr_register(env, SPR_SPRG5, "SPRG5",
7032 SPR_NOACCESS, SPR_NOACCESS,
7033 &spr_read_generic, &spr_write_generic,
7035 spr_register(env, SPR_USPRG5, "USPRG5",
7036 &spr_read_ureg, SPR_NOACCESS,
7037 &spr_read_ureg, SPR_NOACCESS,
7039 spr_register(env, SPR_SPRG6, "SPRG6",
7040 SPR_NOACCESS, SPR_NOACCESS,
7041 &spr_read_generic, &spr_write_generic,
7043 spr_register(env, SPR_USPRG6, "USPRG6",
7044 &spr_read_ureg, SPR_NOACCESS,
7045 &spr_read_ureg, SPR_NOACCESS,
7047 spr_register(env, SPR_SPRG7, "SPRG7",
7048 SPR_NOACCESS, SPR_NOACCESS,
7049 &spr_read_generic, &spr_write_generic,
7051 spr_register(env, SPR_USPRG7, "USPRG7",
7052 &spr_read_ureg, SPR_NOACCESS,
7053 &spr_read_ureg, SPR_NOACCESS,
7055 /* Memory management */
7058 gen_74xx_soft_tlb(env, 128, 2);
7059 init_excp_7450(env);
7060 env->dcache_line_size = 32;
7061 env->icache_line_size = 32;
7062 /* Allocate hardware IRQ controller */
7063 ppc6xx_irq_init(env_archcpu(env));
7066 POWERPC_FAMILY(7445)(ObjectClass *oc, void *data)
7068 DeviceClass *dc = DEVICE_CLASS(oc);
7069 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7071 dc->desc = "PowerPC 7445 (aka G4)";
7072 pcc->init_proc = init_proc_7445;
7073 pcc->check_pow = check_pow_hid0_74xx;
7074 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7075 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7076 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7078 PPC_CACHE | PPC_CACHE_ICBI |
7079 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7080 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7081 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7082 PPC_MEM_TLBIA | PPC_74xx_TLB |
7083 PPC_SEGMENT | PPC_EXTERN |
7085 pcc->msr_mask = (1ull << MSR_VR) |
7102 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
7103 pcc->excp_model = POWERPC_EXCP_74xx;
7104 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7105 pcc->bfd_mach = bfd_mach_ppc_7400;
7106 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7107 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7108 POWERPC_FLAG_BUS_CLK;
7111 static void init_proc_7455(CPUPPCState *env)
7113 gen_spr_ne_601(env);
7118 /* 74xx specific SPR */
7120 /* Level 3 cache control */
7123 /* XXX : not implemented */
7124 spr_register(env, SPR_LDSTCR, "LDSTCR",
7125 SPR_NOACCESS, SPR_NOACCESS,
7126 &spr_read_generic, &spr_write_generic,
7129 /* XXX : not implemented */
7130 spr_register(env, SPR_ICTRL, "ICTRL",
7131 SPR_NOACCESS, SPR_NOACCESS,
7132 &spr_read_generic, &spr_write_generic,
7135 /* XXX : not implemented */
7136 spr_register(env, SPR_MSSSR0, "MSSSR0",
7137 SPR_NOACCESS, SPR_NOACCESS,
7138 &spr_read_generic, &spr_write_generic,
7141 /* XXX : not implemented */
7142 spr_register(env, SPR_7XX_PMC5, "PMC5",
7143 SPR_NOACCESS, SPR_NOACCESS,
7144 &spr_read_generic, &spr_write_generic,
7146 /* XXX : not implemented */
7147 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
7148 &spr_read_ureg, SPR_NOACCESS,
7149 &spr_read_ureg, SPR_NOACCESS,
7151 /* XXX : not implemented */
7152 spr_register(env, SPR_7XX_PMC6, "PMC6",
7153 SPR_NOACCESS, SPR_NOACCESS,
7154 &spr_read_generic, &spr_write_generic,
7156 /* XXX : not implemented */
7157 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
7158 &spr_read_ureg, SPR_NOACCESS,
7159 &spr_read_ureg, SPR_NOACCESS,
7162 spr_register(env, SPR_SPRG4, "SPRG4",
7163 SPR_NOACCESS, SPR_NOACCESS,
7164 &spr_read_generic, &spr_write_generic,
7166 spr_register(env, SPR_USPRG4, "USPRG4",
7167 &spr_read_ureg, SPR_NOACCESS,
7168 &spr_read_ureg, SPR_NOACCESS,
7170 spr_register(env, SPR_SPRG5, "SPRG5",
7171 SPR_NOACCESS, SPR_NOACCESS,
7172 &spr_read_generic, &spr_write_generic,
7174 spr_register(env, SPR_USPRG5, "USPRG5",
7175 &spr_read_ureg, SPR_NOACCESS,
7176 &spr_read_ureg, SPR_NOACCESS,
7178 spr_register(env, SPR_SPRG6, "SPRG6",
7179 SPR_NOACCESS, SPR_NOACCESS,
7180 &spr_read_generic, &spr_write_generic,
7182 spr_register(env, SPR_USPRG6, "USPRG6",
7183 &spr_read_ureg, SPR_NOACCESS,
7184 &spr_read_ureg, SPR_NOACCESS,
7186 spr_register(env, SPR_SPRG7, "SPRG7",
7187 SPR_NOACCESS, SPR_NOACCESS,
7188 &spr_read_generic, &spr_write_generic,
7190 spr_register(env, SPR_USPRG7, "USPRG7",
7191 &spr_read_ureg, SPR_NOACCESS,
7192 &spr_read_ureg, SPR_NOACCESS,
7194 /* Memory management */
7197 gen_74xx_soft_tlb(env, 128, 2);
7198 init_excp_7450(env);
7199 env->dcache_line_size = 32;
7200 env->icache_line_size = 32;
7201 /* Allocate hardware IRQ controller */
7202 ppc6xx_irq_init(env_archcpu(env));
7205 POWERPC_FAMILY(7455)(ObjectClass *oc, void *data)
7207 DeviceClass *dc = DEVICE_CLASS(oc);
7208 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7210 dc->desc = "PowerPC 7455 (aka G4)";
7211 pcc->init_proc = init_proc_7455;
7212 pcc->check_pow = check_pow_hid0_74xx;
7213 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7214 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7215 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7217 PPC_CACHE | PPC_CACHE_ICBI |
7218 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7219 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7220 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7221 PPC_MEM_TLBIA | PPC_74xx_TLB |
7222 PPC_SEGMENT | PPC_EXTERN |
7224 pcc->msr_mask = (1ull << MSR_VR) |
7241 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
7242 pcc->excp_model = POWERPC_EXCP_74xx;
7243 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7244 pcc->bfd_mach = bfd_mach_ppc_7400;
7245 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7246 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7247 POWERPC_FLAG_BUS_CLK;
7250 static void init_proc_7457(CPUPPCState *env)
7252 gen_spr_ne_601(env);
7257 /* 74xx specific SPR */
7259 /* Level 3 cache control */
7262 /* XXX : not implemented */
7263 spr_register(env, SPR_L3ITCR1, "L3ITCR1",
7264 SPR_NOACCESS, SPR_NOACCESS,
7265 &spr_read_generic, &spr_write_generic,
7268 /* XXX : not implemented */
7269 spr_register(env, SPR_L3ITCR2, "L3ITCR2",
7270 SPR_NOACCESS, SPR_NOACCESS,
7271 &spr_read_generic, &spr_write_generic,
7274 /* XXX : not implemented */
7275 spr_register(env, SPR_L3ITCR3, "L3ITCR3",
7276 SPR_NOACCESS, SPR_NOACCESS,
7277 &spr_read_generic, &spr_write_generic,
7280 /* XXX : not implemented */
7281 spr_register(env, SPR_L3OHCR, "L3OHCR",
7282 SPR_NOACCESS, SPR_NOACCESS,
7283 &spr_read_generic, &spr_write_generic,
7286 /* XXX : not implemented */
7287 spr_register(env, SPR_LDSTCR, "LDSTCR",
7288 SPR_NOACCESS, SPR_NOACCESS,
7289 &spr_read_generic, &spr_write_generic,
7292 /* XXX : not implemented */
7293 spr_register(env, SPR_ICTRL, "ICTRL",
7294 SPR_NOACCESS, SPR_NOACCESS,
7295 &spr_read_generic, &spr_write_generic,
7298 /* XXX : not implemented */
7299 spr_register(env, SPR_MSSSR0, "MSSSR0",
7300 SPR_NOACCESS, SPR_NOACCESS,
7301 &spr_read_generic, &spr_write_generic,
7304 /* XXX : not implemented */
7305 spr_register(env, SPR_7XX_PMC5, "PMC5",
7306 SPR_NOACCESS, SPR_NOACCESS,
7307 &spr_read_generic, &spr_write_generic,
7309 /* XXX : not implemented */
7310 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
7311 &spr_read_ureg, SPR_NOACCESS,
7312 &spr_read_ureg, SPR_NOACCESS,
7314 /* XXX : not implemented */
7315 spr_register(env, SPR_7XX_PMC6, "PMC6",
7316 SPR_NOACCESS, SPR_NOACCESS,
7317 &spr_read_generic, &spr_write_generic,
7319 /* XXX : not implemented */
7320 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
7321 &spr_read_ureg, SPR_NOACCESS,
7322 &spr_read_ureg, SPR_NOACCESS,
7325 spr_register(env, SPR_SPRG4, "SPRG4",
7326 SPR_NOACCESS, SPR_NOACCESS,
7327 &spr_read_generic, &spr_write_generic,
7329 spr_register(env, SPR_USPRG4, "USPRG4",
7330 &spr_read_ureg, SPR_NOACCESS,
7331 &spr_read_ureg, SPR_NOACCESS,
7333 spr_register(env, SPR_SPRG5, "SPRG5",
7334 SPR_NOACCESS, SPR_NOACCESS,
7335 &spr_read_generic, &spr_write_generic,
7337 spr_register(env, SPR_USPRG5, "USPRG5",
7338 &spr_read_ureg, SPR_NOACCESS,
7339 &spr_read_ureg, SPR_NOACCESS,
7341 spr_register(env, SPR_SPRG6, "SPRG6",
7342 SPR_NOACCESS, SPR_NOACCESS,
7343 &spr_read_generic, &spr_write_generic,
7345 spr_register(env, SPR_USPRG6, "USPRG6",
7346 &spr_read_ureg, SPR_NOACCESS,
7347 &spr_read_ureg, SPR_NOACCESS,
7349 spr_register(env, SPR_SPRG7, "SPRG7",
7350 SPR_NOACCESS, SPR_NOACCESS,
7351 &spr_read_generic, &spr_write_generic,
7353 spr_register(env, SPR_USPRG7, "USPRG7",
7354 &spr_read_ureg, SPR_NOACCESS,
7355 &spr_read_ureg, SPR_NOACCESS,
7357 /* Memory management */
7360 gen_74xx_soft_tlb(env, 128, 2);
7361 init_excp_7450(env);
7362 env->dcache_line_size = 32;
7363 env->icache_line_size = 32;
7364 /* Allocate hardware IRQ controller */
7365 ppc6xx_irq_init(env_archcpu(env));
7368 POWERPC_FAMILY(7457)(ObjectClass *oc, void *data)
7370 DeviceClass *dc = DEVICE_CLASS(oc);
7371 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7373 dc->desc = "PowerPC 7457 (aka G4)";
7374 pcc->init_proc = init_proc_7457;
7375 pcc->check_pow = check_pow_hid0_74xx;
7376 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7377 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7378 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7380 PPC_CACHE | PPC_CACHE_ICBI |
7381 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7382 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7383 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7384 PPC_MEM_TLBIA | PPC_74xx_TLB |
7385 PPC_SEGMENT | PPC_EXTERN |
7387 pcc->msr_mask = (1ull << MSR_VR) |
7404 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
7405 pcc->excp_model = POWERPC_EXCP_74xx;
7406 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7407 pcc->bfd_mach = bfd_mach_ppc_7400;
7408 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7409 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7410 POWERPC_FLAG_BUS_CLK;
7413 static void init_proc_e600(CPUPPCState *env)
7415 gen_spr_ne_601(env);
7420 /* 74xx specific SPR */
7422 /* XXX : not implemented */
7423 spr_register(env, SPR_UBAMR, "UBAMR",
7424 &spr_read_ureg, SPR_NOACCESS,
7425 &spr_read_ureg, SPR_NOACCESS,
7427 /* XXX : not implemented */
7428 spr_register(env, SPR_LDSTCR, "LDSTCR",
7429 SPR_NOACCESS, SPR_NOACCESS,
7430 &spr_read_generic, &spr_write_generic,
7432 /* XXX : not implemented */
7433 spr_register(env, SPR_ICTRL, "ICTRL",
7434 SPR_NOACCESS, SPR_NOACCESS,
7435 &spr_read_generic, &spr_write_generic,
7437 /* XXX : not implemented */
7438 spr_register(env, SPR_MSSSR0, "MSSSR0",
7439 SPR_NOACCESS, SPR_NOACCESS,
7440 &spr_read_generic, &spr_write_generic,
7442 /* XXX : not implemented */
7443 spr_register(env, SPR_7XX_PMC5, "PMC5",
7444 SPR_NOACCESS, SPR_NOACCESS,
7445 &spr_read_generic, &spr_write_generic,
7447 /* XXX : not implemented */
7448 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
7449 &spr_read_ureg, SPR_NOACCESS,
7450 &spr_read_ureg, SPR_NOACCESS,
7452 /* XXX : not implemented */
7453 spr_register(env, SPR_7XX_PMC6, "PMC6",
7454 SPR_NOACCESS, SPR_NOACCESS,
7455 &spr_read_generic, &spr_write_generic,
7457 /* XXX : not implemented */
7458 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
7459 &spr_read_ureg, SPR_NOACCESS,
7460 &spr_read_ureg, SPR_NOACCESS,
7463 spr_register(env, SPR_SPRG4, "SPRG4",
7464 SPR_NOACCESS, SPR_NOACCESS,
7465 &spr_read_generic, &spr_write_generic,
7467 spr_register(env, SPR_USPRG4, "USPRG4",
7468 &spr_read_ureg, SPR_NOACCESS,
7469 &spr_read_ureg, SPR_NOACCESS,
7471 spr_register(env, SPR_SPRG5, "SPRG5",
7472 SPR_NOACCESS, SPR_NOACCESS,
7473 &spr_read_generic, &spr_write_generic,
7475 spr_register(env, SPR_USPRG5, "USPRG5",
7476 &spr_read_ureg, SPR_NOACCESS,
7477 &spr_read_ureg, SPR_NOACCESS,
7479 spr_register(env, SPR_SPRG6, "SPRG6",
7480 SPR_NOACCESS, SPR_NOACCESS,
7481 &spr_read_generic, &spr_write_generic,
7483 spr_register(env, SPR_USPRG6, "USPRG6",
7484 &spr_read_ureg, SPR_NOACCESS,
7485 &spr_read_ureg, SPR_NOACCESS,
7487 spr_register(env, SPR_SPRG7, "SPRG7",
7488 SPR_NOACCESS, SPR_NOACCESS,
7489 &spr_read_generic, &spr_write_generic,
7491 spr_register(env, SPR_USPRG7, "USPRG7",
7492 &spr_read_ureg, SPR_NOACCESS,
7493 &spr_read_ureg, SPR_NOACCESS,
7495 /* Memory management */
7498 gen_74xx_soft_tlb(env, 128, 2);
7499 init_excp_7450(env);
7500 env->dcache_line_size = 32;
7501 env->icache_line_size = 32;
7502 /* Allocate hardware IRQ controller */
7503 ppc6xx_irq_init(env_archcpu(env));
7506 POWERPC_FAMILY(e600)(ObjectClass *oc, void *data)
7508 DeviceClass *dc = DEVICE_CLASS(oc);
7509 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7511 dc->desc = "PowerPC e600";
7512 pcc->init_proc = init_proc_e600;
7513 pcc->check_pow = check_pow_hid0_74xx;
7514 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7515 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7516 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7518 PPC_CACHE | PPC_CACHE_ICBI |
7519 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7520 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7521 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7522 PPC_MEM_TLBIA | PPC_74xx_TLB |
7523 PPC_SEGMENT | PPC_EXTERN |
7525 pcc->insns_flags2 = PPC_NONE;
7526 pcc->msr_mask = (1ull << MSR_VR) |
7543 pcc->mmu_model = POWERPC_MMU_32B;
7544 #if defined(CONFIG_SOFTMMU)
7545 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
7547 pcc->excp_model = POWERPC_EXCP_74xx;
7548 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7549 pcc->bfd_mach = bfd_mach_ppc_7400;
7550 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7551 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7552 POWERPC_FLAG_BUS_CLK;
7555 #if defined(TARGET_PPC64)
7556 #if defined(CONFIG_USER_ONLY)
7557 #define POWERPC970_HID5_INIT 0x00000080
7559 #define POWERPC970_HID5_INIT 0x00000000
7562 static void gen_fscr_facility_check(DisasContext *ctx, int facility_sprn,
7563 int bit, int sprn, int cause)
7565 TCGv_i32 t1 = tcg_const_i32(bit);
7566 TCGv_i32 t2 = tcg_const_i32(sprn);
7567 TCGv_i32 t3 = tcg_const_i32(cause);
7569 gen_helper_fscr_facility_check(cpu_env, t1, t2, t3);
7571 tcg_temp_free_i32(t3);
7572 tcg_temp_free_i32(t2);
7573 tcg_temp_free_i32(t1);
7576 static void gen_msr_facility_check(DisasContext *ctx, int facility_sprn,
7577 int bit, int sprn, int cause)
7579 TCGv_i32 t1 = tcg_const_i32(bit);
7580 TCGv_i32 t2 = tcg_const_i32(sprn);
7581 TCGv_i32 t3 = tcg_const_i32(cause);
7583 gen_helper_msr_facility_check(cpu_env, t1, t2, t3);
7585 tcg_temp_free_i32(t3);
7586 tcg_temp_free_i32(t2);
7587 tcg_temp_free_i32(t1);
7590 static void spr_read_prev_upper32(DisasContext *ctx, int gprn, int sprn)
7592 TCGv spr_up = tcg_temp_new();
7593 TCGv spr = tcg_temp_new();
7595 gen_load_spr(spr, sprn - 1);
7596 tcg_gen_shri_tl(spr_up, spr, 32);
7597 tcg_gen_ext32u_tl(cpu_gpr[gprn], spr_up);
7600 tcg_temp_free(spr_up);
7603 static void spr_write_prev_upper32(DisasContext *ctx, int sprn, int gprn)
7605 TCGv spr = tcg_temp_new();
7607 gen_load_spr(spr, sprn - 1);
7608 tcg_gen_deposit_tl(spr, spr, cpu_gpr[gprn], 32, 32);
7609 gen_store_spr(sprn - 1, spr);
7614 static int check_pow_970(CPUPPCState *env)
7616 if (env->spr[SPR_HID0] & (HID0_DEEPNAP | HID0_DOZE | HID0_NAP)) {
7623 static void gen_spr_970_hid(CPUPPCState *env)
7625 /* Hardware implementation registers */
7626 /* XXX : not implemented */
7627 spr_register(env, SPR_HID0, "HID0",
7628 SPR_NOACCESS, SPR_NOACCESS,
7629 &spr_read_generic, &spr_write_clear,
7631 spr_register(env, SPR_HID1, "HID1",
7632 SPR_NOACCESS, SPR_NOACCESS,
7633 &spr_read_generic, &spr_write_generic,
7635 spr_register(env, SPR_970_HID5, "HID5",
7636 SPR_NOACCESS, SPR_NOACCESS,
7637 &spr_read_generic, &spr_write_generic,
7638 POWERPC970_HID5_INIT);
7641 static void gen_spr_970_hior(CPUPPCState *env)
7643 spr_register(env, SPR_HIOR, "SPR_HIOR",
7644 SPR_NOACCESS, SPR_NOACCESS,
7645 &spr_read_hior, &spr_write_hior,
7649 static void gen_spr_book3s_ctrl(CPUPPCState *env)
7651 spr_register(env, SPR_CTRL, "SPR_CTRL",
7652 SPR_NOACCESS, SPR_NOACCESS,
7653 SPR_NOACCESS, &spr_write_generic,
7655 spr_register(env, SPR_UCTRL, "SPR_UCTRL",
7656 &spr_read_ureg, SPR_NOACCESS,
7657 &spr_read_ureg, SPR_NOACCESS,
7661 static void gen_spr_book3s_altivec(CPUPPCState *env)
7663 if (!(env->insns_flags & PPC_ALTIVEC)) {
7667 spr_register_kvm(env, SPR_VRSAVE, "VRSAVE",
7668 &spr_read_generic, &spr_write_generic,
7669 &spr_read_generic, &spr_write_generic,
7670 KVM_REG_PPC_VRSAVE, 0x00000000);
7673 * Can't find information on what this should be on reset. This
7674 * value is the one used by 74xx processors.
7676 vscr_init(env, 0x00010000);
7679 static void gen_spr_book3s_dbg(CPUPPCState *env)
7682 * TODO: different specs define different scopes for these,
7683 * will have to address this:
7684 * 970: super/write and super/read
7685 * powerisa 2.03..2.04: hypv/write and super/read.
7686 * powerisa 2.05 and newer: hypv/write and hypv/read.
7688 spr_register_kvm(env, SPR_DABR, "DABR",
7689 SPR_NOACCESS, SPR_NOACCESS,
7690 &spr_read_generic, &spr_write_generic,
7691 KVM_REG_PPC_DABR, 0x00000000);
7692 spr_register_kvm(env, SPR_DABRX, "DABRX",
7693 SPR_NOACCESS, SPR_NOACCESS,
7694 &spr_read_generic, &spr_write_generic,
7695 KVM_REG_PPC_DABRX, 0x00000000);
7698 static void gen_spr_book3s_207_dbg(CPUPPCState *env)
7700 spr_register_kvm_hv(env, SPR_DAWR, "DAWR",
7701 SPR_NOACCESS, SPR_NOACCESS,
7702 SPR_NOACCESS, SPR_NOACCESS,
7703 &spr_read_generic, &spr_write_generic,
7704 KVM_REG_PPC_DAWR, 0x00000000);
7705 spr_register_kvm_hv(env, SPR_DAWRX, "DAWRX",
7706 SPR_NOACCESS, SPR_NOACCESS,
7707 SPR_NOACCESS, SPR_NOACCESS,
7708 &spr_read_generic, &spr_write_generic,
7709 KVM_REG_PPC_DAWRX, 0x00000000);
7710 spr_register_kvm_hv(env, SPR_CIABR, "CIABR",
7711 SPR_NOACCESS, SPR_NOACCESS,
7712 SPR_NOACCESS, SPR_NOACCESS,
7713 &spr_read_generic, &spr_write_generic,
7714 KVM_REG_PPC_CIABR, 0x00000000);
7717 static void gen_spr_970_dbg(CPUPPCState *env)
7720 spr_register(env, SPR_IABR, "IABR",
7721 SPR_NOACCESS, SPR_NOACCESS,
7722 &spr_read_generic, &spr_write_generic,
7726 static void gen_spr_book3s_pmu_sup(CPUPPCState *env)
7728 spr_register_kvm(env, SPR_POWER_MMCR0, "MMCR0",
7729 SPR_NOACCESS, SPR_NOACCESS,
7730 &spr_read_generic, &spr_write_generic,
7731 KVM_REG_PPC_MMCR0, 0x00000000);
7732 spr_register_kvm(env, SPR_POWER_MMCR1, "MMCR1",
7733 SPR_NOACCESS, SPR_NOACCESS,
7734 &spr_read_generic, &spr_write_generic,
7735 KVM_REG_PPC_MMCR1, 0x00000000);
7736 spr_register_kvm(env, SPR_POWER_MMCRA, "MMCRA",
7737 SPR_NOACCESS, SPR_NOACCESS,
7738 &spr_read_generic, &spr_write_generic,
7739 KVM_REG_PPC_MMCRA, 0x00000000);
7740 spr_register_kvm(env, SPR_POWER_PMC1, "PMC1",
7741 SPR_NOACCESS, SPR_NOACCESS,
7742 &spr_read_generic, &spr_write_generic,
7743 KVM_REG_PPC_PMC1, 0x00000000);
7744 spr_register_kvm(env, SPR_POWER_PMC2, "PMC2",
7745 SPR_NOACCESS, SPR_NOACCESS,
7746 &spr_read_generic, &spr_write_generic,
7747 KVM_REG_PPC_PMC2, 0x00000000);
7748 spr_register_kvm(env, SPR_POWER_PMC3, "PMC3",
7749 SPR_NOACCESS, SPR_NOACCESS,
7750 &spr_read_generic, &spr_write_generic,
7751 KVM_REG_PPC_PMC3, 0x00000000);
7752 spr_register_kvm(env, SPR_POWER_PMC4, "PMC4",
7753 SPR_NOACCESS, SPR_NOACCESS,
7754 &spr_read_generic, &spr_write_generic,
7755 KVM_REG_PPC_PMC4, 0x00000000);
7756 spr_register_kvm(env, SPR_POWER_PMC5, "PMC5",
7757 SPR_NOACCESS, SPR_NOACCESS,
7758 &spr_read_generic, &spr_write_generic,
7759 KVM_REG_PPC_PMC5, 0x00000000);
7760 spr_register_kvm(env, SPR_POWER_PMC6, "PMC6",
7761 SPR_NOACCESS, SPR_NOACCESS,
7762 &spr_read_generic, &spr_write_generic,
7763 KVM_REG_PPC_PMC6, 0x00000000);
7764 spr_register_kvm(env, SPR_POWER_SIAR, "SIAR",
7765 SPR_NOACCESS, SPR_NOACCESS,
7766 &spr_read_generic, &spr_write_generic,
7767 KVM_REG_PPC_SIAR, 0x00000000);
7768 spr_register_kvm(env, SPR_POWER_SDAR, "SDAR",
7769 SPR_NOACCESS, SPR_NOACCESS,
7770 &spr_read_generic, &spr_write_generic,
7771 KVM_REG_PPC_SDAR, 0x00000000);
7774 static void gen_spr_book3s_pmu_user(CPUPPCState *env)
7776 spr_register(env, SPR_POWER_UMMCR0, "UMMCR0",
7777 &spr_read_ureg, SPR_NOACCESS,
7778 &spr_read_ureg, &spr_write_ureg,
7780 spr_register(env, SPR_POWER_UMMCR1, "UMMCR1",
7781 &spr_read_ureg, SPR_NOACCESS,
7782 &spr_read_ureg, &spr_write_ureg,
7784 spr_register(env, SPR_POWER_UMMCRA, "UMMCRA",
7785 &spr_read_ureg, SPR_NOACCESS,
7786 &spr_read_ureg, &spr_write_ureg,
7788 spr_register(env, SPR_POWER_UPMC1, "UPMC1",
7789 &spr_read_ureg, SPR_NOACCESS,
7790 &spr_read_ureg, &spr_write_ureg,
7792 spr_register(env, SPR_POWER_UPMC2, "UPMC2",
7793 &spr_read_ureg, SPR_NOACCESS,
7794 &spr_read_ureg, &spr_write_ureg,
7796 spr_register(env, SPR_POWER_UPMC3, "UPMC3",
7797 &spr_read_ureg, SPR_NOACCESS,
7798 &spr_read_ureg, &spr_write_ureg,
7800 spr_register(env, SPR_POWER_UPMC4, "UPMC4",
7801 &spr_read_ureg, SPR_NOACCESS,
7802 &spr_read_ureg, &spr_write_ureg,
7804 spr_register(env, SPR_POWER_UPMC5, "UPMC5",
7805 &spr_read_ureg, SPR_NOACCESS,
7806 &spr_read_ureg, &spr_write_ureg,
7808 spr_register(env, SPR_POWER_UPMC6, "UPMC6",
7809 &spr_read_ureg, SPR_NOACCESS,
7810 &spr_read_ureg, &spr_write_ureg,
7812 spr_register(env, SPR_POWER_USIAR, "USIAR",
7813 &spr_read_ureg, SPR_NOACCESS,
7814 &spr_read_ureg, &spr_write_ureg,
7816 spr_register(env, SPR_POWER_USDAR, "USDAR",
7817 &spr_read_ureg, SPR_NOACCESS,
7818 &spr_read_ureg, &spr_write_ureg,
7822 static void gen_spr_970_pmu_sup(CPUPPCState *env)
7824 spr_register_kvm(env, SPR_970_PMC7, "PMC7",
7825 SPR_NOACCESS, SPR_NOACCESS,
7826 &spr_read_generic, &spr_write_generic,
7827 KVM_REG_PPC_PMC7, 0x00000000);
7828 spr_register_kvm(env, SPR_970_PMC8, "PMC8",
7829 SPR_NOACCESS, SPR_NOACCESS,
7830 &spr_read_generic, &spr_write_generic,
7831 KVM_REG_PPC_PMC8, 0x00000000);
7834 static void gen_spr_970_pmu_user(CPUPPCState *env)
7836 spr_register(env, SPR_970_UPMC7, "UPMC7",
7837 &spr_read_ureg, SPR_NOACCESS,
7838 &spr_read_ureg, &spr_write_ureg,
7840 spr_register(env, SPR_970_UPMC8, "UPMC8",
7841 &spr_read_ureg, SPR_NOACCESS,
7842 &spr_read_ureg, &spr_write_ureg,
7846 static void gen_spr_power8_pmu_sup(CPUPPCState *env)
7848 spr_register_kvm(env, SPR_POWER_MMCR2, "MMCR2",
7849 SPR_NOACCESS, SPR_NOACCESS,
7850 &spr_read_generic, &spr_write_generic,
7851 KVM_REG_PPC_MMCR2, 0x00000000);
7852 spr_register_kvm(env, SPR_POWER_MMCRS, "MMCRS",
7853 SPR_NOACCESS, SPR_NOACCESS,
7854 &spr_read_generic, &spr_write_generic,
7855 KVM_REG_PPC_MMCRS, 0x00000000);
7856 spr_register_kvm(env, SPR_POWER_SIER, "SIER",
7857 SPR_NOACCESS, SPR_NOACCESS,
7858 &spr_read_generic, &spr_write_generic,
7859 KVM_REG_PPC_SIER, 0x00000000);
7860 spr_register_kvm(env, SPR_POWER_SPMC1, "SPMC1",
7861 SPR_NOACCESS, SPR_NOACCESS,
7862 &spr_read_generic, &spr_write_generic,
7863 KVM_REG_PPC_SPMC1, 0x00000000);
7864 spr_register_kvm(env, SPR_POWER_SPMC2, "SPMC2",
7865 SPR_NOACCESS, SPR_NOACCESS,
7866 &spr_read_generic, &spr_write_generic,
7867 KVM_REG_PPC_SPMC2, 0x00000000);
7868 spr_register_kvm(env, SPR_TACR, "TACR",
7869 SPR_NOACCESS, SPR_NOACCESS,
7870 &spr_read_generic, &spr_write_generic,
7871 KVM_REG_PPC_TACR, 0x00000000);
7872 spr_register_kvm(env, SPR_TCSCR, "TCSCR",
7873 SPR_NOACCESS, SPR_NOACCESS,
7874 &spr_read_generic, &spr_write_generic,
7875 KVM_REG_PPC_TCSCR, 0x00000000);
7876 spr_register_kvm(env, SPR_CSIGR, "CSIGR",
7877 SPR_NOACCESS, SPR_NOACCESS,
7878 &spr_read_generic, &spr_write_generic,
7879 KVM_REG_PPC_CSIGR, 0x00000000);
7882 static void gen_spr_power8_pmu_user(CPUPPCState *env)
7884 spr_register(env, SPR_POWER_UMMCR2, "UMMCR2",
7885 &spr_read_ureg, SPR_NOACCESS,
7886 &spr_read_ureg, &spr_write_ureg,
7888 spr_register(env, SPR_POWER_USIER, "USIER",
7889 &spr_read_generic, SPR_NOACCESS,
7890 &spr_read_generic, &spr_write_generic,
7894 static void gen_spr_power5p_ear(CPUPPCState *env)
7896 /* External access control */
7897 spr_register(env, SPR_EAR, "EAR",
7898 SPR_NOACCESS, SPR_NOACCESS,
7899 &spr_read_generic, &spr_write_generic,
7903 static void gen_spr_power5p_tb(CPUPPCState *env)
7905 /* TBU40 (High 40 bits of the Timebase register */
7906 spr_register_hv(env, SPR_TBU40, "TBU40",
7907 SPR_NOACCESS, SPR_NOACCESS,
7908 SPR_NOACCESS, SPR_NOACCESS,
7909 SPR_NOACCESS, &spr_write_tbu40,
7913 #if !defined(CONFIG_USER_ONLY)
7914 static void spr_write_hmer(DisasContext *ctx, int sprn, int gprn)
7916 TCGv hmer = tcg_temp_new();
7918 gen_load_spr(hmer, sprn);
7919 tcg_gen_and_tl(hmer, cpu_gpr[gprn], hmer);
7920 gen_store_spr(sprn, hmer);
7921 spr_store_dump_spr(sprn);
7922 tcg_temp_free(hmer);
7925 static void spr_write_lpcr(DisasContext *ctx, int sprn, int gprn)
7927 gen_helper_store_lpcr(cpu_env, cpu_gpr[gprn]);
7929 #endif /* !defined(CONFIG_USER_ONLY) */
7931 static void gen_spr_970_lpar(CPUPPCState *env)
7933 #if !defined(CONFIG_USER_ONLY)
7935 * PPC970: HID4 covers things later controlled by the LPCR and
7936 * RMOR in later CPUs, but with a different encoding. We only
7937 * support the 970 in "Apple mode" which has all hypervisor
7938 * facilities disabled by strapping, so we can basically just
7941 spr_register(env, SPR_970_HID4, "HID4",
7942 SPR_NOACCESS, SPR_NOACCESS,
7943 &spr_read_generic, &spr_write_generic,
7948 static void gen_spr_power5p_lpar(CPUPPCState *env)
7950 #if !defined(CONFIG_USER_ONLY)
7951 /* Logical partitionning */
7952 spr_register_kvm_hv(env, SPR_LPCR, "LPCR",
7953 SPR_NOACCESS, SPR_NOACCESS,
7954 SPR_NOACCESS, SPR_NOACCESS,
7955 &spr_read_generic, &spr_write_lpcr,
7956 KVM_REG_PPC_LPCR, LPCR_LPES0 | LPCR_LPES1);
7957 spr_register_hv(env, SPR_HDEC, "HDEC",
7958 SPR_NOACCESS, SPR_NOACCESS,
7959 SPR_NOACCESS, SPR_NOACCESS,
7960 &spr_read_hdecr, &spr_write_hdecr, 0);
7964 static void gen_spr_book3s_ids(CPUPPCState *env)
7966 /* FIXME: Will need to deal with thread vs core only SPRs */
7968 /* Processor identification */
7969 spr_register_hv(env, SPR_PIR, "PIR",
7970 SPR_NOACCESS, SPR_NOACCESS,
7971 &spr_read_generic, SPR_NOACCESS,
7972 &spr_read_generic, NULL,
7974 spr_register_hv(env, SPR_HID0, "HID0",
7975 SPR_NOACCESS, SPR_NOACCESS,
7976 SPR_NOACCESS, SPR_NOACCESS,
7977 &spr_read_generic, &spr_write_generic,
7979 spr_register_hv(env, SPR_TSCR, "TSCR",
7980 SPR_NOACCESS, SPR_NOACCESS,
7981 SPR_NOACCESS, SPR_NOACCESS,
7982 &spr_read_generic, &spr_write_generic,
7984 spr_register_hv(env, SPR_HMER, "HMER",
7985 SPR_NOACCESS, SPR_NOACCESS,
7986 SPR_NOACCESS, SPR_NOACCESS,
7987 &spr_read_generic, &spr_write_hmer,
7989 spr_register_hv(env, SPR_HMEER, "HMEER",
7990 SPR_NOACCESS, SPR_NOACCESS,
7991 SPR_NOACCESS, SPR_NOACCESS,
7992 &spr_read_generic, &spr_write_generic,
7994 spr_register_hv(env, SPR_TFMR, "TFMR",
7995 SPR_NOACCESS, SPR_NOACCESS,
7996 SPR_NOACCESS, SPR_NOACCESS,
7997 &spr_read_generic, &spr_write_generic,
7999 spr_register_hv(env, SPR_LPIDR, "LPIDR",
8000 SPR_NOACCESS, SPR_NOACCESS,
8001 SPR_NOACCESS, SPR_NOACCESS,
8002 &spr_read_generic, &spr_write_lpidr,
8004 spr_register_hv(env, SPR_HFSCR, "HFSCR",
8005 SPR_NOACCESS, SPR_NOACCESS,
8006 SPR_NOACCESS, SPR_NOACCESS,
8007 &spr_read_generic, &spr_write_generic,
8009 spr_register_hv(env, SPR_MMCRC, "MMCRC",
8010 SPR_NOACCESS, SPR_NOACCESS,
8011 SPR_NOACCESS, SPR_NOACCESS,
8012 &spr_read_generic, &spr_write_generic,
8014 spr_register_hv(env, SPR_MMCRH, "MMCRH",
8015 SPR_NOACCESS, SPR_NOACCESS,
8016 SPR_NOACCESS, SPR_NOACCESS,
8017 &spr_read_generic, &spr_write_generic,
8019 spr_register_hv(env, SPR_HSPRG0, "HSPRG0",
8020 SPR_NOACCESS, SPR_NOACCESS,
8021 SPR_NOACCESS, SPR_NOACCESS,
8022 &spr_read_generic, &spr_write_generic,
8024 spr_register_hv(env, SPR_HSPRG1, "HSPRG1",
8025 SPR_NOACCESS, SPR_NOACCESS,
8026 SPR_NOACCESS, SPR_NOACCESS,
8027 &spr_read_generic, &spr_write_generic,
8029 spr_register_hv(env, SPR_HSRR0, "HSRR0",
8030 SPR_NOACCESS, SPR_NOACCESS,
8031 SPR_NOACCESS, SPR_NOACCESS,
8032 &spr_read_generic, &spr_write_generic,
8034 spr_register_hv(env, SPR_HSRR1, "HSRR1",
8035 SPR_NOACCESS, SPR_NOACCESS,
8036 SPR_NOACCESS, SPR_NOACCESS,
8037 &spr_read_generic, &spr_write_generic,
8039 spr_register_hv(env, SPR_HDAR, "HDAR",
8040 SPR_NOACCESS, SPR_NOACCESS,
8041 SPR_NOACCESS, SPR_NOACCESS,
8042 &spr_read_generic, &spr_write_generic,
8044 spr_register_hv(env, SPR_HDSISR, "HDSISR",
8045 SPR_NOACCESS, SPR_NOACCESS,
8046 SPR_NOACCESS, SPR_NOACCESS,
8047 &spr_read_generic, &spr_write_generic,
8049 spr_register_hv(env, SPR_HRMOR, "HRMOR",
8050 SPR_NOACCESS, SPR_NOACCESS,
8051 SPR_NOACCESS, SPR_NOACCESS,
8052 &spr_read_generic, &spr_write_generic,
8056 static void gen_spr_rmor(CPUPPCState *env)
8058 spr_register_hv(env, SPR_RMOR, "RMOR",
8059 SPR_NOACCESS, SPR_NOACCESS,
8060 SPR_NOACCESS, SPR_NOACCESS,
8061 &spr_read_generic, &spr_write_generic,
8065 static void gen_spr_power8_ids(CPUPPCState *env)
8067 /* Thread identification */
8068 spr_register(env, SPR_TIR, "TIR",
8069 SPR_NOACCESS, SPR_NOACCESS,
8070 &spr_read_generic, SPR_NOACCESS,
8074 static void gen_spr_book3s_purr(CPUPPCState *env)
8076 #if !defined(CONFIG_USER_ONLY)
8077 /* PURR & SPURR: Hack - treat these as aliases for the TB for now */
8078 spr_register_kvm_hv(env, SPR_PURR, "PURR",
8079 &spr_read_purr, SPR_NOACCESS,
8080 &spr_read_purr, SPR_NOACCESS,
8081 &spr_read_purr, &spr_write_purr,
8082 KVM_REG_PPC_PURR, 0x00000000);
8083 spr_register_kvm_hv(env, SPR_SPURR, "SPURR",
8084 &spr_read_purr, SPR_NOACCESS,
8085 &spr_read_purr, SPR_NOACCESS,
8086 &spr_read_purr, &spr_write_purr,
8087 KVM_REG_PPC_SPURR, 0x00000000);
8091 static void gen_spr_power6_dbg(CPUPPCState *env)
8093 #if !defined(CONFIG_USER_ONLY)
8094 spr_register(env, SPR_CFAR, "SPR_CFAR",
8095 SPR_NOACCESS, SPR_NOACCESS,
8096 &spr_read_cfar, &spr_write_cfar,
8101 static void gen_spr_power5p_common(CPUPPCState *env)
8103 spr_register_kvm(env, SPR_PPR, "PPR",
8104 &spr_read_generic, &spr_write_generic,
8105 &spr_read_generic, &spr_write_generic,
8106 KVM_REG_PPC_PPR, 0x00000000);
8109 static void gen_spr_power6_common(CPUPPCState *env)
8111 #if !defined(CONFIG_USER_ONLY)
8112 spr_register_kvm(env, SPR_DSCR, "SPR_DSCR",
8113 SPR_NOACCESS, SPR_NOACCESS,
8114 &spr_read_generic, &spr_write_generic,
8115 KVM_REG_PPC_DSCR, 0x00000000);
8118 * Register PCR to report POWERPC_EXCP_PRIV_REG instead of
8119 * POWERPC_EXCP_INVAL_SPR in userspace. Permit hypervisor access.
8121 spr_register_hv(env, SPR_PCR, "PCR",
8122 SPR_NOACCESS, SPR_NOACCESS,
8123 SPR_NOACCESS, SPR_NOACCESS,
8124 &spr_read_generic, &spr_write_pcr,
8128 static void spr_read_tar(DisasContext *ctx, int gprn, int sprn)
8130 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_TAR, sprn, FSCR_IC_TAR);
8131 spr_read_generic(ctx, gprn, sprn);
8134 static void spr_write_tar(DisasContext *ctx, int sprn, int gprn)
8136 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_TAR, sprn, FSCR_IC_TAR);
8137 spr_write_generic(ctx, sprn, gprn);
8140 static void gen_spr_power8_tce_address_control(CPUPPCState *env)
8142 spr_register_kvm(env, SPR_TAR, "TAR",
8143 &spr_read_tar, &spr_write_tar,
8144 &spr_read_generic, &spr_write_generic,
8145 KVM_REG_PPC_TAR, 0x00000000);
8148 static void spr_read_tm(DisasContext *ctx, int gprn, int sprn)
8150 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8151 spr_read_generic(ctx, gprn, sprn);
8154 static void spr_write_tm(DisasContext *ctx, int sprn, int gprn)
8156 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8157 spr_write_generic(ctx, sprn, gprn);
8160 static void spr_read_tm_upper32(DisasContext *ctx, int gprn, int sprn)
8162 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8163 spr_read_prev_upper32(ctx, gprn, sprn);
8166 static void spr_write_tm_upper32(DisasContext *ctx, int sprn, int gprn)
8168 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8169 spr_write_prev_upper32(ctx, sprn, gprn);
8172 static void gen_spr_power8_tm(CPUPPCState *env)
8174 spr_register_kvm(env, SPR_TFHAR, "TFHAR",
8175 &spr_read_tm, &spr_write_tm,
8176 &spr_read_tm, &spr_write_tm,
8177 KVM_REG_PPC_TFHAR, 0x00000000);
8178 spr_register_kvm(env, SPR_TFIAR, "TFIAR",
8179 &spr_read_tm, &spr_write_tm,
8180 &spr_read_tm, &spr_write_tm,
8181 KVM_REG_PPC_TFIAR, 0x00000000);
8182 spr_register_kvm(env, SPR_TEXASR, "TEXASR",
8183 &spr_read_tm, &spr_write_tm,
8184 &spr_read_tm, &spr_write_tm,
8185 KVM_REG_PPC_TEXASR, 0x00000000);
8186 spr_register(env, SPR_TEXASRU, "TEXASRU",
8187 &spr_read_tm_upper32, &spr_write_tm_upper32,
8188 &spr_read_tm_upper32, &spr_write_tm_upper32,
8192 static void spr_read_ebb(DisasContext *ctx, int gprn, int sprn)
8194 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8195 spr_read_generic(ctx, gprn, sprn);
8198 static void spr_write_ebb(DisasContext *ctx, int sprn, int gprn)
8200 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8201 spr_write_generic(ctx, sprn, gprn);
8204 static void spr_read_ebb_upper32(DisasContext *ctx, int gprn, int sprn)
8206 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8207 spr_read_prev_upper32(ctx, gprn, sprn);
8210 static void spr_write_ebb_upper32(DisasContext *ctx, int sprn, int gprn)
8212 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8213 spr_write_prev_upper32(ctx, sprn, gprn);
8216 static void gen_spr_power8_ebb(CPUPPCState *env)
8218 spr_register(env, SPR_BESCRS, "BESCRS",
8219 &spr_read_ebb, &spr_write_ebb,
8220 &spr_read_generic, &spr_write_generic,
8222 spr_register(env, SPR_BESCRSU, "BESCRSU",
8223 &spr_read_ebb_upper32, &spr_write_ebb_upper32,
8224 &spr_read_prev_upper32, &spr_write_prev_upper32,
8226 spr_register(env, SPR_BESCRR, "BESCRR",
8227 &spr_read_ebb, &spr_write_ebb,
8228 &spr_read_generic, &spr_write_generic,
8230 spr_register(env, SPR_BESCRRU, "BESCRRU",
8231 &spr_read_ebb_upper32, &spr_write_ebb_upper32,
8232 &spr_read_prev_upper32, &spr_write_prev_upper32,
8234 spr_register_kvm(env, SPR_EBBHR, "EBBHR",
8235 &spr_read_ebb, &spr_write_ebb,
8236 &spr_read_generic, &spr_write_generic,
8237 KVM_REG_PPC_EBBHR, 0x00000000);
8238 spr_register_kvm(env, SPR_EBBRR, "EBBRR",
8239 &spr_read_ebb, &spr_write_ebb,
8240 &spr_read_generic, &spr_write_generic,
8241 KVM_REG_PPC_EBBRR, 0x00000000);
8242 spr_register_kvm(env, SPR_BESCR, "BESCR",
8243 &spr_read_ebb, &spr_write_ebb,
8244 &spr_read_generic, &spr_write_generic,
8245 KVM_REG_PPC_BESCR, 0x00000000);
8248 /* Virtual Time Base */
8249 static void gen_spr_vtb(CPUPPCState *env)
8251 spr_register_kvm_hv(env, SPR_VTB, "VTB",
8252 SPR_NOACCESS, SPR_NOACCESS,
8253 &spr_read_vtb, SPR_NOACCESS,
8254 &spr_read_vtb, &spr_write_vtb,
8255 KVM_REG_PPC_VTB, 0x00000000);
8258 static void gen_spr_power8_fscr(CPUPPCState *env)
8260 #if defined(CONFIG_USER_ONLY)
8261 target_ulong initval = 1ULL << FSCR_TAR;
8263 target_ulong initval = 0;
8265 spr_register_kvm(env, SPR_FSCR, "FSCR",
8266 SPR_NOACCESS, SPR_NOACCESS,
8267 &spr_read_generic, &spr_write_generic,
8268 KVM_REG_PPC_FSCR, initval);
8271 static void gen_spr_power8_pspb(CPUPPCState *env)
8273 spr_register_kvm(env, SPR_PSPB, "PSPB",
8274 SPR_NOACCESS, SPR_NOACCESS,
8275 &spr_read_generic, &spr_write_generic32,
8276 KVM_REG_PPC_PSPB, 0);
8279 static void gen_spr_power8_dpdes(CPUPPCState *env)
8281 #if !defined(CONFIG_USER_ONLY)
8282 /* Directed Privileged Door-bell Exception State, used for IPI */
8283 spr_register_kvm_hv(env, SPR_DPDES, "DPDES",
8284 SPR_NOACCESS, SPR_NOACCESS,
8285 &spr_read_dpdes, SPR_NOACCESS,
8286 &spr_read_dpdes, &spr_write_dpdes,
8287 KVM_REG_PPC_DPDES, 0x00000000);
8291 static void gen_spr_power8_ic(CPUPPCState *env)
8293 #if !defined(CONFIG_USER_ONLY)
8294 spr_register_hv(env, SPR_IC, "IC",
8295 SPR_NOACCESS, SPR_NOACCESS,
8296 &spr_read_generic, SPR_NOACCESS,
8297 &spr_read_generic, &spr_write_generic,
8302 static void gen_spr_power8_book4(CPUPPCState *env)
8304 /* Add a number of P8 book4 registers */
8305 #if !defined(CONFIG_USER_ONLY)
8306 spr_register_kvm(env, SPR_ACOP, "ACOP",
8307 SPR_NOACCESS, SPR_NOACCESS,
8308 &spr_read_generic, &spr_write_generic,
8309 KVM_REG_PPC_ACOP, 0);
8310 spr_register_kvm(env, SPR_BOOKS_PID, "PID",
8311 SPR_NOACCESS, SPR_NOACCESS,
8312 &spr_read_generic, &spr_write_pidr,
8313 KVM_REG_PPC_PID, 0);
8314 spr_register_kvm(env, SPR_WORT, "WORT",
8315 SPR_NOACCESS, SPR_NOACCESS,
8316 &spr_read_generic, &spr_write_generic,
8317 KVM_REG_PPC_WORT, 0);
8321 static void gen_spr_power7_book4(CPUPPCState *env)
8323 /* Add a number of P7 book4 registers */
8324 #if !defined(CONFIG_USER_ONLY)
8325 spr_register_kvm(env, SPR_ACOP, "ACOP",
8326 SPR_NOACCESS, SPR_NOACCESS,
8327 &spr_read_generic, &spr_write_generic,
8328 KVM_REG_PPC_ACOP, 0);
8329 spr_register_kvm(env, SPR_BOOKS_PID, "PID",
8330 SPR_NOACCESS, SPR_NOACCESS,
8331 &spr_read_generic, &spr_write_generic,
8332 KVM_REG_PPC_PID, 0);
8336 static void gen_spr_power8_rpr(CPUPPCState *env)
8338 #if !defined(CONFIG_USER_ONLY)
8339 spr_register_hv(env, SPR_RPR, "RPR",
8340 SPR_NOACCESS, SPR_NOACCESS,
8341 SPR_NOACCESS, SPR_NOACCESS,
8342 &spr_read_generic, &spr_write_generic,
8343 0x00000103070F1F3F);
8347 static void gen_spr_power9_mmu(CPUPPCState *env)
8349 #if !defined(CONFIG_USER_ONLY)
8350 /* Partition Table Control */
8351 spr_register_kvm_hv(env, SPR_PTCR, "PTCR",
8352 SPR_NOACCESS, SPR_NOACCESS,
8353 SPR_NOACCESS, SPR_NOACCESS,
8354 &spr_read_generic, &spr_write_ptcr,
8355 KVM_REG_PPC_PTCR, 0x00000000);
8356 /* Address Segment Descriptor Register */
8357 spr_register_hv(env, SPR_ASDR, "ASDR",
8358 SPR_NOACCESS, SPR_NOACCESS,
8359 SPR_NOACCESS, SPR_NOACCESS,
8360 &spr_read_generic, &spr_write_generic,
8361 0x0000000000000000);
8365 static void init_proc_book3s_common(CPUPPCState *env)
8367 gen_spr_ne_601(env);
8369 gen_spr_usprg3(env);
8370 gen_spr_book3s_altivec(env);
8371 gen_spr_book3s_pmu_sup(env);
8372 gen_spr_book3s_pmu_user(env);
8373 gen_spr_book3s_ctrl(env);
8376 static void init_proc_970(CPUPPCState *env)
8378 /* Common Registers */
8379 init_proc_book3s_common(env);
8381 gen_spr_book3s_dbg(env);
8383 /* 970 Specific Registers */
8384 gen_spr_970_hid(env);
8385 gen_spr_970_hior(env);
8387 gen_spr_970_pmu_sup(env);
8388 gen_spr_970_pmu_user(env);
8389 gen_spr_970_lpar(env);
8390 gen_spr_970_dbg(env);
8393 env->dcache_line_size = 128;
8394 env->icache_line_size = 128;
8396 /* Allocate hardware IRQ controller */
8398 ppc970_irq_init(env_archcpu(env));
8401 POWERPC_FAMILY(970)(ObjectClass *oc, void *data)
8403 DeviceClass *dc = DEVICE_CLASS(oc);
8404 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8406 dc->desc = "PowerPC 970";
8407 pcc->init_proc = init_proc_970;
8408 pcc->check_pow = check_pow_970;
8409 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
8410 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8411 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
8413 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8414 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8415 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
8416 PPC_64B | PPC_ALTIVEC |
8417 PPC_SEGMENT_64B | PPC_SLBI;
8418 pcc->insns_flags2 = PPC2_FP_CVT_S64;
8419 pcc->msr_mask = (1ull << MSR_SF) |
8434 pcc->mmu_model = POWERPC_MMU_64B;
8435 #if defined(CONFIG_SOFTMMU)
8436 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
8437 pcc->hash64_opts = &ppc_hash64_opts_basic;
8439 pcc->excp_model = POWERPC_EXCP_970;
8440 pcc->bus_model = PPC_FLAGS_INPUT_970;
8441 pcc->bfd_mach = bfd_mach_ppc64;
8442 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8443 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8444 POWERPC_FLAG_BUS_CLK;
8445 pcc->l1_dcache_size = 0x8000;
8446 pcc->l1_icache_size = 0x10000;
8449 static void init_proc_power5plus(CPUPPCState *env)
8451 /* Common Registers */
8452 init_proc_book3s_common(env);
8454 gen_spr_book3s_dbg(env);
8456 /* POWER5+ Specific Registers */
8457 gen_spr_970_hid(env);
8458 gen_spr_970_hior(env);
8460 gen_spr_970_pmu_sup(env);
8461 gen_spr_970_pmu_user(env);
8462 gen_spr_power5p_common(env);
8463 gen_spr_power5p_lpar(env);
8464 gen_spr_power5p_ear(env);
8465 gen_spr_power5p_tb(env);
8468 env->dcache_line_size = 128;
8469 env->icache_line_size = 128;
8471 /* Allocate hardware IRQ controller */
8473 ppc970_irq_init(env_archcpu(env));
8476 POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data)
8478 DeviceClass *dc = DEVICE_CLASS(oc);
8479 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8481 dc->fw_name = "PowerPC,POWER5";
8482 dc->desc = "POWER5+";
8483 pcc->init_proc = init_proc_power5plus;
8484 pcc->check_pow = check_pow_970;
8485 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
8486 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8487 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
8489 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8490 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8491 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
8493 PPC_SEGMENT_64B | PPC_SLBI;
8494 pcc->insns_flags2 = PPC2_FP_CVT_S64;
8495 pcc->msr_mask = (1ull << MSR_SF) |
8510 pcc->lpcr_mask = LPCR_RMLS | LPCR_ILE | LPCR_LPES0 | LPCR_LPES1 |
8511 LPCR_RMI | LPCR_HDICE;
8512 pcc->mmu_model = POWERPC_MMU_2_03;
8513 #if defined(CONFIG_SOFTMMU)
8514 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
8515 pcc->hash64_opts = &ppc_hash64_opts_basic;
8516 pcc->lrg_decr_bits = 32;
8518 pcc->excp_model = POWERPC_EXCP_970;
8519 pcc->bus_model = PPC_FLAGS_INPUT_970;
8520 pcc->bfd_mach = bfd_mach_ppc64;
8521 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8522 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8523 POWERPC_FLAG_BUS_CLK;
8524 pcc->l1_dcache_size = 0x8000;
8525 pcc->l1_icache_size = 0x10000;
8528 static void init_proc_POWER7(CPUPPCState *env)
8530 /* Common Registers */
8531 init_proc_book3s_common(env);
8533 gen_spr_book3s_dbg(env);
8535 /* POWER7 Specific Registers */
8536 gen_spr_book3s_ids(env);
8539 gen_spr_book3s_purr(env);
8540 gen_spr_power5p_common(env);
8541 gen_spr_power5p_lpar(env);
8542 gen_spr_power5p_ear(env);
8543 gen_spr_power5p_tb(env);
8544 gen_spr_power6_common(env);
8545 gen_spr_power6_dbg(env);
8546 gen_spr_power7_book4(env);
8549 env->dcache_line_size = 128;
8550 env->icache_line_size = 128;
8552 /* Allocate hardware IRQ controller */
8553 init_excp_POWER7(env);
8554 ppcPOWER7_irq_init(env_archcpu(env));
8557 static bool ppc_pvr_match_power7(PowerPCCPUClass *pcc, uint32_t pvr)
8559 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7P_BASE) {
8562 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7_BASE) {
8568 static bool cpu_has_work_POWER7(CPUState *cs)
8570 PowerPCCPU *cpu = POWERPC_CPU(cs);
8571 CPUPPCState *env = &cpu->env;
8574 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
8577 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
8578 (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) {
8581 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
8582 (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) {
8585 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
8586 (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
8589 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
8590 (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
8593 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
8598 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
8602 POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
8604 DeviceClass *dc = DEVICE_CLASS(oc);
8605 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8606 CPUClass *cc = CPU_CLASS(oc);
8608 dc->fw_name = "PowerPC,POWER7";
8609 dc->desc = "POWER7";
8610 pcc->pvr_match = ppc_pvr_match_power7;
8611 pcc->pcr_mask = PCR_VEC_DIS | PCR_VSX_DIS | PCR_COMPAT_2_05;
8612 pcc->pcr_supported = PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
8613 pcc->init_proc = init_proc_POWER7;
8614 pcc->check_pow = check_pow_nocheck;
8615 cc->has_work = cpu_has_work_POWER7;
8616 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
8617 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8618 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
8619 PPC_FLOAT_FRSQRTES |
8622 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8623 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8624 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
8625 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
8626 PPC_SEGMENT_64B | PPC_SLBI |
8627 PPC_POPCNTB | PPC_POPCNTWD |
8629 pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
8630 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
8631 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
8632 PPC2_FP_TST_ISA206 | PPC2_FP_CVT_S64 |
8634 pcc->msr_mask = (1ull << MSR_SF) |
8650 pcc->lpcr_mask = LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_DPFD |
8651 LPCR_VRMASD | LPCR_RMLS | LPCR_ILE |
8652 LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2 |
8653 LPCR_MER | LPCR_TC |
8654 LPCR_LPES0 | LPCR_LPES1 | LPCR_HDICE;
8655 pcc->lpcr_pm = LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2;
8656 pcc->mmu_model = POWERPC_MMU_2_06;
8657 #if defined(CONFIG_SOFTMMU)
8658 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
8659 pcc->hash64_opts = &ppc_hash64_opts_POWER7;
8660 pcc->lrg_decr_bits = 32;
8662 pcc->excp_model = POWERPC_EXCP_POWER7;
8663 pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
8664 pcc->bfd_mach = bfd_mach_ppc64;
8665 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8666 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8667 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
8669 pcc->l1_dcache_size = 0x8000;
8670 pcc->l1_icache_size = 0x8000;
8671 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
8674 static void init_proc_POWER8(CPUPPCState *env)
8676 /* Common Registers */
8677 init_proc_book3s_common(env);
8679 gen_spr_book3s_207_dbg(env);
8681 /* POWER8 Specific Registers */
8682 gen_spr_book3s_ids(env);
8686 gen_spr_book3s_purr(env);
8687 gen_spr_power5p_common(env);
8688 gen_spr_power5p_lpar(env);
8689 gen_spr_power5p_ear(env);
8690 gen_spr_power5p_tb(env);
8691 gen_spr_power6_common(env);
8692 gen_spr_power6_dbg(env);
8693 gen_spr_power8_tce_address_control(env);
8694 gen_spr_power8_ids(env);
8695 gen_spr_power8_ebb(env);
8696 gen_spr_power8_fscr(env);
8697 gen_spr_power8_pmu_sup(env);
8698 gen_spr_power8_pmu_user(env);
8699 gen_spr_power8_tm(env);
8700 gen_spr_power8_pspb(env);
8701 gen_spr_power8_dpdes(env);
8703 gen_spr_power8_ic(env);
8704 gen_spr_power8_book4(env);
8705 gen_spr_power8_rpr(env);
8708 env->dcache_line_size = 128;
8709 env->icache_line_size = 128;
8711 /* Allocate hardware IRQ controller */
8712 init_excp_POWER8(env);
8713 ppcPOWER7_irq_init(env_archcpu(env));
8716 static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, uint32_t pvr)
8718 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8NVL_BASE) {
8721 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8E_BASE) {
8724 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8_BASE) {
8730 static bool cpu_has_work_POWER8(CPUState *cs)
8732 PowerPCCPU *cpu = POWERPC_CPU(cs);
8733 CPUPPCState *env = &cpu->env;
8736 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
8739 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
8740 (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) {
8743 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
8744 (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) {
8747 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
8748 (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
8751 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
8752 (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
8755 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
8756 (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) {
8759 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
8760 (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) {
8763 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
8768 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
8772 POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
8774 DeviceClass *dc = DEVICE_CLASS(oc);
8775 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8776 CPUClass *cc = CPU_CLASS(oc);
8778 dc->fw_name = "PowerPC,POWER8";
8779 dc->desc = "POWER8";
8780 pcc->pvr_match = ppc_pvr_match_power8;
8781 pcc->pcr_mask = PCR_TM_DIS | PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
8782 pcc->pcr_supported = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
8783 pcc->init_proc = init_proc_POWER8;
8784 pcc->check_pow = check_pow_nocheck;
8785 cc->has_work = cpu_has_work_POWER8;
8786 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
8787 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8788 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
8789 PPC_FLOAT_FRSQRTES |
8792 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8793 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8794 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
8795 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
8796 PPC_SEGMENT_64B | PPC_SLBI |
8797 PPC_POPCNTB | PPC_POPCNTWD |
8799 pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
8800 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
8801 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
8802 PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
8803 PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
8804 PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
8805 PPC2_TM | PPC2_PM_ISA206;
8806 pcc->msr_mask = (1ull << MSR_SF) |
8826 pcc->lpcr_mask = LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV |
8827 LPCR_DPFD | LPCR_VRMASD | LPCR_RMLS | LPCR_ILE |
8828 LPCR_AIL | LPCR_ONL | LPCR_P8_PECE0 | LPCR_P8_PECE1 |
8829 LPCR_P8_PECE2 | LPCR_P8_PECE3 | LPCR_P8_PECE4 |
8830 LPCR_MER | LPCR_TC | LPCR_LPES0 | LPCR_HDICE;
8831 pcc->lpcr_pm = LPCR_P8_PECE0 | LPCR_P8_PECE1 | LPCR_P8_PECE2 |
8832 LPCR_P8_PECE3 | LPCR_P8_PECE4;
8833 pcc->mmu_model = POWERPC_MMU_2_07;
8834 #if defined(CONFIG_SOFTMMU)
8835 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
8836 pcc->hash64_opts = &ppc_hash64_opts_POWER7;
8837 pcc->lrg_decr_bits = 32;
8838 pcc->n_host_threads = 8;
8840 pcc->excp_model = POWERPC_EXCP_POWER8;
8841 pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
8842 pcc->bfd_mach = bfd_mach_ppc64;
8843 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8844 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8845 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
8846 POWERPC_FLAG_VSX | POWERPC_FLAG_TM;
8847 pcc->l1_dcache_size = 0x8000;
8848 pcc->l1_icache_size = 0x8000;
8849 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
8852 #ifdef CONFIG_SOFTMMU
8854 * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
8855 * Encoded as array of int_32s in the form:
8856 * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
8858 * y -> radix mode supported page size (encoded as a shift)
8860 static struct ppc_radix_page_info POWER9_radix_page_info = {
8863 0x0000000c, /* 4K - enc: 0x0 */
8864 0xa0000010, /* 64K - enc: 0x5 */
8865 0x20000015, /* 2M - enc: 0x1 */
8866 0x4000001e /* 1G - enc: 0x2 */
8869 #endif /* CONFIG_SOFTMMU */
8871 static void init_proc_POWER9(CPUPPCState *env)
8873 /* Common Registers */
8874 init_proc_book3s_common(env);
8875 gen_spr_book3s_207_dbg(env);
8877 /* POWER8 Specific Registers */
8878 gen_spr_book3s_ids(env);
8881 gen_spr_book3s_purr(env);
8882 gen_spr_power5p_common(env);
8883 gen_spr_power5p_lpar(env);
8884 gen_spr_power5p_ear(env);
8885 gen_spr_power5p_tb(env);
8886 gen_spr_power6_common(env);
8887 gen_spr_power6_dbg(env);
8888 gen_spr_power8_tce_address_control(env);
8889 gen_spr_power8_ids(env);
8890 gen_spr_power8_ebb(env);
8891 gen_spr_power8_fscr(env);
8892 gen_spr_power8_pmu_sup(env);
8893 gen_spr_power8_pmu_user(env);
8894 gen_spr_power8_tm(env);
8895 gen_spr_power8_pspb(env);
8896 gen_spr_power8_dpdes(env);
8898 gen_spr_power8_ic(env);
8899 gen_spr_power8_book4(env);
8900 gen_spr_power8_rpr(env);
8901 gen_spr_power9_mmu(env);
8903 /* POWER9 Specific registers */
8904 spr_register_kvm(env, SPR_TIDR, "TIDR", NULL, NULL,
8905 spr_read_generic, spr_write_generic,
8906 KVM_REG_PPC_TIDR, 0);
8908 /* FIXME: Filter fields properly based on privilege level */
8909 spr_register_kvm_hv(env, SPR_PSSCR, "PSSCR", NULL, NULL, NULL, NULL,
8910 spr_read_generic, spr_write_generic,
8911 KVM_REG_PPC_PSSCR, 0);
8914 env->dcache_line_size = 128;
8915 env->icache_line_size = 128;
8917 /* Allocate hardware IRQ controller */
8918 init_excp_POWER9(env);
8919 ppcPOWER9_irq_init(env_archcpu(env));
8922 static bool ppc_pvr_match_power9(PowerPCCPUClass *pcc, uint32_t pvr)
8924 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER9_BASE) {
8930 static bool cpu_has_work_POWER9(CPUState *cs)
8932 PowerPCCPU *cpu = POWERPC_CPU(cs);
8933 CPUPPCState *env = &cpu->env;
8936 uint64_t psscr = env->spr[SPR_PSSCR];
8938 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
8942 /* If EC is clear, just return true on any pending interrupt */
8943 if (!(psscr & PSSCR_EC)) {
8946 /* External Exception */
8947 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
8948 (env->spr[SPR_LPCR] & LPCR_EEE)) {
8949 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
8950 if (heic == 0 || !msr_hv || msr_pr) {
8954 /* Decrementer Exception */
8955 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
8956 (env->spr[SPR_LPCR] & LPCR_DEE)) {
8959 /* Machine Check or Hypervisor Maintenance Exception */
8960 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK |
8961 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) {
8964 /* Privileged Doorbell Exception */
8965 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
8966 (env->spr[SPR_LPCR] & LPCR_PDEE)) {
8969 /* Hypervisor Doorbell Exception */
8970 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
8971 (env->spr[SPR_LPCR] & LPCR_HDEE)) {
8974 /* Hypervisor virtualization exception */
8975 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) &&
8976 (env->spr[SPR_LPCR] & LPCR_HVEE)) {
8979 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
8984 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
8988 POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
8990 DeviceClass *dc = DEVICE_CLASS(oc);
8991 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8992 CPUClass *cc = CPU_CLASS(oc);
8994 dc->fw_name = "PowerPC,POWER9";
8995 dc->desc = "POWER9";
8996 pcc->pvr_match = ppc_pvr_match_power9;
8997 pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07;
8998 pcc->pcr_supported = PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 |
9000 pcc->init_proc = init_proc_POWER9;
9001 pcc->check_pow = check_pow_nocheck;
9002 cc->has_work = cpu_has_work_POWER9;
9003 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
9004 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
9005 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
9006 PPC_FLOAT_FRSQRTES |
9009 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
9010 PPC_MEM_SYNC | PPC_MEM_EIEIO |
9012 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
9013 PPC_SEGMENT_64B | PPC_SLBI |
9014 PPC_POPCNTB | PPC_POPCNTWD |
9016 pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
9017 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
9018 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
9019 PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
9020 PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
9021 PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
9022 PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL;
9023 pcc->msr_mask = (1ull << MSR_SF) |
9041 pcc->lpcr_mask = LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD |
9042 (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL |
9043 LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR | LPCR_LD |
9044 (LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE | LPCR_EEE |
9045 LPCR_DEE | LPCR_OEE))
9046 | LPCR_MER | LPCR_GTSE | LPCR_TC |
9047 LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE | LPCR_HDICE;
9048 pcc->lpcr_pm = LPCR_PDEE | LPCR_HDEE | LPCR_EEE | LPCR_DEE | LPCR_OEE;
9049 pcc->mmu_model = POWERPC_MMU_3_00;
9050 #if defined(CONFIG_SOFTMMU)
9051 pcc->handle_mmu_fault = ppc64_v3_handle_mmu_fault;
9052 /* segment page size remain the same */
9053 pcc->hash64_opts = &ppc_hash64_opts_POWER7;
9054 pcc->radix_page_info = &POWER9_radix_page_info;
9055 pcc->lrg_decr_bits = 56;
9056 pcc->n_host_threads = 4;
9058 pcc->excp_model = POWERPC_EXCP_POWER9;
9059 pcc->bus_model = PPC_FLAGS_INPUT_POWER9;
9060 pcc->bfd_mach = bfd_mach_ppc64;
9061 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
9062 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
9063 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
9064 POWERPC_FLAG_VSX | POWERPC_FLAG_TM | POWERPC_FLAG_SCV;
9065 pcc->l1_dcache_size = 0x8000;
9066 pcc->l1_icache_size = 0x8000;
9067 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
9070 #ifdef CONFIG_SOFTMMU
9072 * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
9073 * Encoded as array of int_32s in the form:
9074 * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
9076 * y -> radix mode supported page size (encoded as a shift)
9078 static struct ppc_radix_page_info POWER10_radix_page_info = {
9081 0x0000000c, /* 4K - enc: 0x0 */
9082 0xa0000010, /* 64K - enc: 0x5 */
9083 0x20000015, /* 2M - enc: 0x1 */
9084 0x4000001e /* 1G - enc: 0x2 */
9087 #endif /* CONFIG_SOFTMMU */
9089 static void init_proc_POWER10(CPUPPCState *env)
9091 /* Common Registers */
9092 init_proc_book3s_common(env);
9093 gen_spr_book3s_207_dbg(env);
9095 /* POWER8 Specific Registers */
9096 gen_spr_book3s_ids(env);
9099 gen_spr_book3s_purr(env);
9100 gen_spr_power5p_common(env);
9101 gen_spr_power5p_lpar(env);
9102 gen_spr_power5p_ear(env);
9103 gen_spr_power6_common(env);
9104 gen_spr_power6_dbg(env);
9105 gen_spr_power8_tce_address_control(env);
9106 gen_spr_power8_ids(env);
9107 gen_spr_power8_ebb(env);
9108 gen_spr_power8_fscr(env);
9109 gen_spr_power8_pmu_sup(env);
9110 gen_spr_power8_pmu_user(env);
9111 gen_spr_power8_tm(env);
9112 gen_spr_power8_pspb(env);
9114 gen_spr_power8_ic(env);
9115 gen_spr_power8_book4(env);
9116 gen_spr_power8_rpr(env);
9117 gen_spr_power9_mmu(env);
9119 /* FIXME: Filter fields properly based on privilege level */
9120 spr_register_kvm_hv(env, SPR_PSSCR, "PSSCR", NULL, NULL, NULL, NULL,
9121 spr_read_generic, spr_write_generic,
9122 KVM_REG_PPC_PSSCR, 0);
9125 env->dcache_line_size = 128;
9126 env->icache_line_size = 128;
9128 /* Allocate hardware IRQ controller */
9129 init_excp_POWER10(env);
9130 ppcPOWER9_irq_init(env_archcpu(env));
9133 static bool ppc_pvr_match_power10(PowerPCCPUClass *pcc, uint32_t pvr)
9135 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER10_BASE) {
9141 static bool cpu_has_work_POWER10(CPUState *cs)
9143 PowerPCCPU *cpu = POWERPC_CPU(cs);
9144 CPUPPCState *env = &cpu->env;
9147 uint64_t psscr = env->spr[SPR_PSSCR];
9149 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
9153 /* If EC is clear, just return true on any pending interrupt */
9154 if (!(psscr & PSSCR_EC)) {
9157 /* External Exception */
9158 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
9159 (env->spr[SPR_LPCR] & LPCR_EEE)) {
9160 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
9161 if (heic == 0 || !msr_hv || msr_pr) {
9165 /* Decrementer Exception */
9166 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
9167 (env->spr[SPR_LPCR] & LPCR_DEE)) {
9170 /* Machine Check or Hypervisor Maintenance Exception */
9171 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK |
9172 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) {
9175 /* Privileged Doorbell Exception */
9176 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
9177 (env->spr[SPR_LPCR] & LPCR_PDEE)) {
9180 /* Hypervisor Doorbell Exception */
9181 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
9182 (env->spr[SPR_LPCR] & LPCR_HDEE)) {
9185 /* Hypervisor virtualization exception */
9186 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) &&
9187 (env->spr[SPR_LPCR] & LPCR_HVEE)) {
9190 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
9195 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
9199 POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data)
9201 DeviceClass *dc = DEVICE_CLASS(oc);
9202 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
9203 CPUClass *cc = CPU_CLASS(oc);
9205 dc->fw_name = "PowerPC,POWER10";
9206 dc->desc = "POWER10";
9207 pcc->pvr_match = ppc_pvr_match_power10;
9208 pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07 |
9210 pcc->pcr_supported = PCR_COMPAT_3_10 | PCR_COMPAT_3_00 | PCR_COMPAT_2_07 |
9211 PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
9212 pcc->init_proc = init_proc_POWER10;
9213 pcc->check_pow = check_pow_nocheck;
9214 cc->has_work = cpu_has_work_POWER10;
9215 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
9216 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
9217 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
9218 PPC_FLOAT_FRSQRTES |
9221 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
9222 PPC_MEM_SYNC | PPC_MEM_EIEIO |
9224 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
9225 PPC_SEGMENT_64B | PPC_SLBI |
9226 PPC_POPCNTB | PPC_POPCNTWD |
9228 pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
9229 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
9230 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
9231 PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
9232 PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
9233 PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
9234 PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL | PPC2_ISA310;
9235 pcc->msr_mask = (1ull << MSR_SF) |
9253 pcc->lpcr_mask = LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD |
9254 (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL |
9255 LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR | LPCR_LD |
9256 (LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE | LPCR_EEE |
9257 LPCR_DEE | LPCR_OEE))
9258 | LPCR_MER | LPCR_GTSE | LPCR_TC |
9259 LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE | LPCR_HDICE;
9260 pcc->lpcr_pm = LPCR_PDEE | LPCR_HDEE | LPCR_EEE | LPCR_DEE | LPCR_OEE;
9261 pcc->mmu_model = POWERPC_MMU_3_00;
9262 #if defined(CONFIG_SOFTMMU)
9263 pcc->handle_mmu_fault = ppc64_v3_handle_mmu_fault;
9264 /* segment page size remain the same */
9265 pcc->hash64_opts = &ppc_hash64_opts_POWER7;
9266 pcc->radix_page_info = &POWER10_radix_page_info;
9267 pcc->lrg_decr_bits = 56;
9269 pcc->excp_model = POWERPC_EXCP_POWER9;
9270 pcc->bus_model = PPC_FLAGS_INPUT_POWER9;
9271 pcc->bfd_mach = bfd_mach_ppc64;
9272 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
9273 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
9274 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
9275 POWERPC_FLAG_VSX | POWERPC_FLAG_TM;
9276 pcc->l1_dcache_size = 0x8000;
9277 pcc->l1_icache_size = 0x8000;
9278 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
9281 #if !defined(CONFIG_USER_ONLY)
9282 void cpu_ppc_set_vhyp(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp)
9284 CPUPPCState *env = &cpu->env;
9289 * With a virtual hypervisor mode we never allow the CPU to go
9290 * hypervisor mode itself
9292 env->msr_mask &= ~MSR_HVB;
9295 #endif /* !defined(CONFIG_USER_ONLY) */
9297 #endif /* defined(TARGET_PPC64) */
9299 /*****************************************************************************/
9300 /* Generic CPU instantiation routine */
9301 static void init_ppc_proc(PowerPCCPU *cpu)
9303 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
9304 CPUPPCState *env = &cpu->env;
9305 #if !defined(CONFIG_USER_ONLY)
9308 env->irq_inputs = NULL;
9309 /* Set all exception vectors to an invalid address */
9310 for (i = 0; i < POWERPC_EXCP_NB; i++) {
9311 env->excp_vectors[i] = (target_ulong)(-1ULL);
9313 env->ivor_mask = 0x00000000;
9314 env->ivpr_mask = 0x00000000;
9315 /* Default MMU definitions */
9319 env->tlb_type = TLB_NONE;
9321 /* Register SPR common to all PowerPC implementations */
9322 gen_spr_generic(env);
9323 spr_register(env, SPR_PVR, "PVR",
9324 /* Linux permits userspace to read PVR */
9325 #if defined(CONFIG_LINUX_USER)
9331 &spr_read_generic, SPR_NOACCESS,
9333 /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
9334 if (pcc->svr != POWERPC_SVR_NONE) {
9335 if (pcc->svr & POWERPC_SVR_E500) {
9336 spr_register(env, SPR_E500_SVR, "SVR",
9337 SPR_NOACCESS, SPR_NOACCESS,
9338 &spr_read_generic, SPR_NOACCESS,
9339 pcc->svr & ~POWERPC_SVR_E500);
9341 spr_register(env, SPR_SVR, "SVR",
9342 SPR_NOACCESS, SPR_NOACCESS,
9343 &spr_read_generic, SPR_NOACCESS,
9347 /* PowerPC implementation specific initialisations (SPRs, timers, ...) */
9348 (*pcc->init_proc)(env);
9350 #if !defined(CONFIG_USER_ONLY)
9351 ppc_gdb_gen_spr_xml(cpu);
9354 /* MSR bits & flags consistency checks */
9355 if (env->msr_mask & (1 << 25)) {
9356 switch (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
9357 case POWERPC_FLAG_SPE:
9358 case POWERPC_FLAG_VRE:
9361 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9362 "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n");
9365 } else if (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
9366 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9367 "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n");
9370 if (env->msr_mask & (1 << 17)) {
9371 switch (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
9372 case POWERPC_FLAG_TGPR:
9373 case POWERPC_FLAG_CE:
9376 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9377 "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n");
9380 } else if (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
9381 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9382 "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n");
9385 if (env->msr_mask & (1 << 10)) {
9386 switch (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
9387 POWERPC_FLAG_UBLE)) {
9388 case POWERPC_FLAG_SE:
9389 case POWERPC_FLAG_DWE:
9390 case POWERPC_FLAG_UBLE:
9393 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9394 "Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE or "
9395 "POWERPC_FLAG_UBLE\n");
9398 } else if (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
9399 POWERPC_FLAG_UBLE)) {
9400 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9401 "Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE nor "
9402 "POWERPC_FLAG_UBLE\n");
9405 if (env->msr_mask & (1 << 9)) {
9406 switch (env->flags & (POWERPC_FLAG_BE | POWERPC_FLAG_DE)) {
9407 case POWERPC_FLAG_BE:
9408 case POWERPC_FLAG_DE:
9411 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9412 "Should define POWERPC_FLAG_BE or POWERPC_FLAG_DE\n");
9415 } else if (env->flags & (POWERPC_FLAG_BE | POWERPC_FLAG_DE)) {
9416 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9417 "Should not define POWERPC_FLAG_BE nor POWERPC_FLAG_DE\n");
9420 if (env->msr_mask & (1 << 2)) {
9421 switch (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
9422 case POWERPC_FLAG_PX:
9423 case POWERPC_FLAG_PMM:
9426 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9427 "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n");
9430 } else if (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
9431 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9432 "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
9435 if ((env->flags & (POWERPC_FLAG_RTC_CLK | POWERPC_FLAG_BUS_CLK)) == 0) {
9436 fprintf(stderr, "PowerPC flags inconsistency\n"
9437 "Should define the time-base and decrementer clock source\n");
9440 /* Allocate TLBs buffer when needed */
9441 #if !defined(CONFIG_USER_ONLY)
9442 if (env->nb_tlb != 0) {
9443 int nb_tlb = env->nb_tlb;
9444 if (env->id_tlbs != 0) {
9447 switch (env->tlb_type) {
9449 env->tlb.tlb6 = g_new0(ppc6xx_tlb_t, nb_tlb);
9452 env->tlb.tlbe = g_new0(ppcemb_tlb_t, nb_tlb);
9455 env->tlb.tlbm = g_new0(ppcmas_tlb_t, nb_tlb);
9458 /* Pre-compute some useful values */
9459 env->tlb_per_way = env->nb_tlb / env->nb_ways;
9461 if (env->irq_inputs == NULL) {
9462 warn_report("no internal IRQ controller registered."
9463 " Attempt QEMU to crash very soon !");
9466 if (env->check_pow == NULL) {
9467 warn_report("no power management check handler registered."
9468 " Attempt QEMU to crash very soon !");
9472 #if defined(PPC_DUMP_CPU)
9473 static void dump_ppc_sprs(CPUPPCState *env)
9476 #if !defined(CONFIG_USER_ONLY)
9482 printf("Special purpose registers:\n");
9483 for (i = 0; i < 32; i++) {
9484 for (j = 0; j < 32; j++) {
9486 spr = &env->spr_cb[n];
9487 uw = spr->uea_write != NULL && spr->uea_write != SPR_NOACCESS;
9488 ur = spr->uea_read != NULL && spr->uea_read != SPR_NOACCESS;
9489 #if !defined(CONFIG_USER_ONLY)
9490 sw = spr->oea_write != NULL && spr->oea_write != SPR_NOACCESS;
9491 sr = spr->oea_read != NULL && spr->oea_read != SPR_NOACCESS;
9492 if (sw || sr || uw || ur) {
9493 printf("SPR: %4d (%03x) %-8s s%c%c u%c%c\n",
9494 (i << 5) | j, (i << 5) | j, spr->name,
9495 sw ? 'w' : '-', sr ? 'r' : '-',
9496 uw ? 'w' : '-', ur ? 'r' : '-');
9500 printf("SPR: %4d (%03x) %-8s u%c%c\n",
9501 (i << 5) | j, (i << 5) | j, spr->name,
9502 uw ? 'w' : '-', ur ? 'r' : '-');
9512 /*****************************************************************************/
9516 PPC_DIRECT = 0, /* Opcode routine */
9517 PPC_INDIRECT = 1, /* Indirect opcode table */
9520 #define PPC_OPCODE_MASK 0x3
9522 static inline int is_indirect_opcode(void *handler)
9524 return ((uintptr_t)handler & PPC_OPCODE_MASK) == PPC_INDIRECT;
9527 static inline opc_handler_t **ind_table(void *handler)
9529 return (opc_handler_t **)((uintptr_t)handler & ~PPC_OPCODE_MASK);
9532 /* Instruction table creation */
9533 /* Opcodes tables creation */
9534 static void fill_new_table(opc_handler_t **table, int len)
9538 for (i = 0; i < len; i++) {
9539 table[i] = &invalid_handler;
9543 static int create_new_table(opc_handler_t **table, unsigned char idx)
9545 opc_handler_t **tmp;
9547 tmp = g_new(opc_handler_t *, PPC_CPU_INDIRECT_OPCODES_LEN);
9548 fill_new_table(tmp, PPC_CPU_INDIRECT_OPCODES_LEN);
9549 table[idx] = (opc_handler_t *)((uintptr_t)tmp | PPC_INDIRECT);
9554 static int insert_in_table(opc_handler_t **table, unsigned char idx,
9555 opc_handler_t *handler)
9557 if (table[idx] != &invalid_handler) {
9560 table[idx] = handler;
9565 static int register_direct_insn(opc_handler_t **ppc_opcodes,
9566 unsigned char idx, opc_handler_t *handler)
9568 if (insert_in_table(ppc_opcodes, idx, handler) < 0) {
9569 printf("*** ERROR: opcode %02x already assigned in main "
9570 "opcode table\n", idx);
9571 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9572 printf(" Registered handler '%s' - new handler '%s'\n",
9573 ppc_opcodes[idx]->oname, handler->oname);
9581 static int register_ind_in_table(opc_handler_t **table,
9582 unsigned char idx1, unsigned char idx2,
9583 opc_handler_t *handler)
9585 if (table[idx1] == &invalid_handler) {
9586 if (create_new_table(table, idx1) < 0) {
9587 printf("*** ERROR: unable to create indirect table "
9588 "idx=%02x\n", idx1);
9592 if (!is_indirect_opcode(table[idx1])) {
9593 printf("*** ERROR: idx %02x already assigned to a direct "
9595 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9596 printf(" Registered handler '%s' - new handler '%s'\n",
9597 ind_table(table[idx1])[idx2]->oname, handler->oname);
9602 if (handler != NULL &&
9603 insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) {
9604 printf("*** ERROR: opcode %02x already assigned in "
9605 "opcode table %02x\n", idx2, idx1);
9606 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9607 printf(" Registered handler '%s' - new handler '%s'\n",
9608 ind_table(table[idx1])[idx2]->oname, handler->oname);
9616 static int register_ind_insn(opc_handler_t **ppc_opcodes,
9617 unsigned char idx1, unsigned char idx2,
9618 opc_handler_t *handler)
9620 return register_ind_in_table(ppc_opcodes, idx1, idx2, handler);
9623 static int register_dblind_insn(opc_handler_t **ppc_opcodes,
9624 unsigned char idx1, unsigned char idx2,
9625 unsigned char idx3, opc_handler_t *handler)
9627 if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
9628 printf("*** ERROR: unable to join indirect table idx "
9629 "[%02x-%02x]\n", idx1, idx2);
9632 if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3,
9634 printf("*** ERROR: unable to insert opcode "
9635 "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
9642 static int register_trplind_insn(opc_handler_t **ppc_opcodes,
9643 unsigned char idx1, unsigned char idx2,
9644 unsigned char idx3, unsigned char idx4,
9645 opc_handler_t *handler)
9647 opc_handler_t **table;
9649 if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
9650 printf("*** ERROR: unable to join indirect table idx "
9651 "[%02x-%02x]\n", idx1, idx2);
9654 table = ind_table(ppc_opcodes[idx1]);
9655 if (register_ind_in_table(table, idx2, idx3, NULL) < 0) {
9656 printf("*** ERROR: unable to join 2nd-level indirect table idx "
9657 "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
9660 table = ind_table(table[idx2]);
9661 if (register_ind_in_table(table, idx3, idx4, handler) < 0) {
9662 printf("*** ERROR: unable to insert opcode "
9663 "[%02x-%02x-%02x-%02x]\n", idx1, idx2, idx3, idx4);
9668 static int register_insn(opc_handler_t **ppc_opcodes, opcode_t *insn)
9670 if (insn->opc2 != 0xFF) {
9671 if (insn->opc3 != 0xFF) {
9672 if (insn->opc4 != 0xFF) {
9673 if (register_trplind_insn(ppc_opcodes, insn->opc1, insn->opc2,
9674 insn->opc3, insn->opc4,
9675 &insn->handler) < 0) {
9679 if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2,
9680 insn->opc3, &insn->handler) < 0) {
9685 if (register_ind_insn(ppc_opcodes, insn->opc1,
9686 insn->opc2, &insn->handler) < 0) {
9691 if (register_direct_insn(ppc_opcodes, insn->opc1, &insn->handler) < 0) {
9699 static int test_opcode_table(opc_handler_t **table, int len)
9703 for (i = 0, count = 0; i < len; i++) {
9704 /* Consistency fixup */
9705 if (table[i] == NULL) {
9706 table[i] = &invalid_handler;
9708 if (table[i] != &invalid_handler) {
9709 if (is_indirect_opcode(table[i])) {
9710 tmp = test_opcode_table(ind_table(table[i]),
9711 PPC_CPU_INDIRECT_OPCODES_LEN);
9714 table[i] = &invalid_handler;
9727 static void fix_opcode_tables(opc_handler_t **ppc_opcodes)
9729 if (test_opcode_table(ppc_opcodes, PPC_CPU_OPCODES_LEN) == 0) {
9730 printf("*** WARNING: no opcode defined !\n");
9734 /*****************************************************************************/
9735 static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp)
9737 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
9740 fill_new_table(cpu->opcodes, PPC_CPU_OPCODES_LEN);
9741 for (opc = opcodes; opc < &opcodes[ARRAY_SIZE(opcodes)]; opc++) {
9742 if (((opc->handler.type & pcc->insns_flags) != 0) ||
9743 ((opc->handler.type2 & pcc->insns_flags2) != 0)) {
9744 if (register_insn(cpu->opcodes, opc) < 0) {
9745 error_setg(errp, "ERROR initializing PowerPC instruction "
9746 "0x%02x 0x%02x 0x%02x", opc->opc1, opc->opc2,
9752 fix_opcode_tables(cpu->opcodes);
9757 #if defined(PPC_DUMP_CPU)
9758 static void dump_ppc_insns(CPUPPCState *env)
9760 opc_handler_t **table, *handler;
9762 uint8_t opc1, opc2, opc3, opc4;
9764 printf("Instructions set:\n");
9765 /* opc1 is 6 bits long */
9766 for (opc1 = 0x00; opc1 < PPC_CPU_OPCODES_LEN; opc1++) {
9767 table = env->opcodes;
9768 handler = table[opc1];
9769 if (is_indirect_opcode(handler)) {
9770 /* opc2 is 5 bits long */
9771 for (opc2 = 0; opc2 < PPC_CPU_INDIRECT_OPCODES_LEN; opc2++) {
9772 table = env->opcodes;
9773 handler = env->opcodes[opc1];
9774 table = ind_table(handler);
9775 handler = table[opc2];
9776 if (is_indirect_opcode(handler)) {
9777 table = ind_table(handler);
9778 /* opc3 is 5 bits long */
9779 for (opc3 = 0; opc3 < PPC_CPU_INDIRECT_OPCODES_LEN;
9781 handler = table[opc3];
9782 if (is_indirect_opcode(handler)) {
9783 table = ind_table(handler);
9784 /* opc4 is 5 bits long */
9785 for (opc4 = 0; opc4 < PPC_CPU_INDIRECT_OPCODES_LEN;
9787 handler = table[opc4];
9788 if (handler->handler != &gen_invalid) {
9789 printf("INSN: %02x %02x %02x %02x -- "
9790 "(%02d %04d %02d) : %s\n",
9791 opc1, opc2, opc3, opc4,
9792 opc1, (opc3 << 5) | opc2, opc4,
9797 if (handler->handler != &gen_invalid) {
9798 /* Special hack to properly dump SPE insns */
9799 p = strchr(handler->oname, '_');
9801 printf("INSN: %02x %02x %02x (%02d %04d) : "
9803 opc1, opc2, opc3, opc1,
9808 if ((p - handler->oname) != strlen(q)
9809 || (memcmp(handler->oname, q, strlen(q))
9811 /* First instruction */
9812 printf("INSN: %02x %02x %02x"
9813 "(%02d %04d) : %.*s\n",
9814 opc1, opc2 << 1, opc3, opc1,
9815 (opc3 << 6) | (opc2 << 1),
9816 (int)(p - handler->oname),
9819 if (strcmp(p + 1, q) != 0) {
9820 /* Second instruction */
9821 printf("INSN: %02x %02x %02x "
9822 "(%02d %04d) : %s\n", opc1,
9823 (opc2 << 1) | 1, opc3, opc1,
9824 (opc3 << 6) | (opc2 << 1) | 1,
9832 if (handler->handler != &gen_invalid) {
9833 printf("INSN: %02x %02x -- (%02d %04d) : %s\n",
9834 opc1, opc2, opc1, opc2, handler->oname);
9839 if (handler->handler != &gen_invalid) {
9840 printf("INSN: %02x -- -- (%02d ----) : %s\n",
9841 opc1, opc1, handler->oname);
9848 static bool avr_need_swap(CPUPPCState *env)
9850 #ifdef HOST_WORDS_BIGENDIAN
9857 #if !defined(CONFIG_USER_ONLY)
9858 static int gdb_find_spr_idx(CPUPPCState *env, int n)
9862 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
9863 ppc_spr_t *spr = &env->spr_cb[i];
9865 if (spr->name && spr->gdb_id == n) {
9872 static int gdb_get_spr_reg(CPUPPCState *env, GByteArray *buf, int n)
9877 reg = gdb_find_spr_idx(env, n);
9882 len = TARGET_LONG_SIZE;
9883 gdb_get_regl(buf, env->spr[reg]);
9884 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, len), len);
9888 static int gdb_set_spr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
9893 reg = gdb_find_spr_idx(env, n);
9898 len = TARGET_LONG_SIZE;
9899 ppc_maybe_bswap_register(env, mem_buf, len);
9900 env->spr[reg] = ldn_p(mem_buf, len);
9906 static int gdb_get_float_reg(CPUPPCState *env, GByteArray *buf, int n)
9910 gdb_get_float64(buf, *cpu_fpr_ptr(env, n));
9911 mem_buf = gdb_get_reg_ptr(buf, 8);
9912 ppc_maybe_bswap_register(env, mem_buf, 8);
9916 gdb_get_reg32(buf, env->fpscr);
9917 mem_buf = gdb_get_reg_ptr(buf, 4);
9918 ppc_maybe_bswap_register(env, mem_buf, 4);
9924 static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
9927 ppc_maybe_bswap_register(env, mem_buf, 8);
9928 *cpu_fpr_ptr(env, n) = ldfq_p(mem_buf);
9932 ppc_maybe_bswap_register(env, mem_buf, 4);
9933 helper_store_fpscr(env, ldl_p(mem_buf), 0xffffffff);
9939 static int gdb_get_avr_reg(CPUPPCState *env, GByteArray *buf, int n)
9944 ppc_avr_t *avr = cpu_avr_ptr(env, n);
9945 if (!avr_need_swap(env)) {
9946 gdb_get_reg128(buf, avr->u64[0] , avr->u64[1]);
9948 gdb_get_reg128(buf, avr->u64[1] , avr->u64[0]);
9950 mem_buf = gdb_get_reg_ptr(buf, 16);
9951 ppc_maybe_bswap_register(env, mem_buf, 8);
9952 ppc_maybe_bswap_register(env, mem_buf + 8, 8);
9956 gdb_get_reg32(buf, helper_mfvscr(env));
9957 mem_buf = gdb_get_reg_ptr(buf, 4);
9958 ppc_maybe_bswap_register(env, mem_buf, 4);
9962 gdb_get_reg32(buf, (uint32_t)env->spr[SPR_VRSAVE]);
9963 mem_buf = gdb_get_reg_ptr(buf, 4);
9964 ppc_maybe_bswap_register(env, mem_buf, 4);
9970 static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
9973 ppc_avr_t *avr = cpu_avr_ptr(env, n);
9974 ppc_maybe_bswap_register(env, mem_buf, 8);
9975 ppc_maybe_bswap_register(env, mem_buf + 8, 8);
9976 if (!avr_need_swap(env)) {
9977 avr->u64[0] = ldq_p(mem_buf);
9978 avr->u64[1] = ldq_p(mem_buf + 8);
9980 avr->u64[1] = ldq_p(mem_buf);
9981 avr->u64[0] = ldq_p(mem_buf + 8);
9986 ppc_maybe_bswap_register(env, mem_buf, 4);
9987 helper_mtvscr(env, ldl_p(mem_buf));
9991 ppc_maybe_bswap_register(env, mem_buf, 4);
9992 env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf);
9998 static int gdb_get_spe_reg(CPUPPCState *env, GByteArray *buf, int n)
10001 #if defined(TARGET_PPC64)
10002 gdb_get_reg32(buf, env->gpr[n] >> 32);
10003 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
10005 gdb_get_reg32(buf, env->gprh[n]);
10010 gdb_get_reg64(buf, env->spe_acc);
10011 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
10015 gdb_get_reg32(buf, env->spe_fscr);
10016 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
10022 static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
10025 #if defined(TARGET_PPC64)
10026 target_ulong lo = (uint32_t)env->gpr[n];
10029 ppc_maybe_bswap_register(env, mem_buf, 4);
10031 hi = (target_ulong)ldl_p(mem_buf) << 32;
10032 env->gpr[n] = lo | hi;
10034 env->gprh[n] = ldl_p(mem_buf);
10039 ppc_maybe_bswap_register(env, mem_buf, 8);
10040 env->spe_acc = ldq_p(mem_buf);
10044 ppc_maybe_bswap_register(env, mem_buf, 4);
10045 env->spe_fscr = ldl_p(mem_buf);
10051 static int gdb_get_vsx_reg(CPUPPCState *env, GByteArray *buf, int n)
10054 gdb_get_reg64(buf, *cpu_vsrl_ptr(env, n));
10055 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
10061 static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
10064 ppc_maybe_bswap_register(env, mem_buf, 8);
10065 *cpu_vsrl_ptr(env, n) = ldq_p(mem_buf);
10071 static int ppc_fixup_cpu(PowerPCCPU *cpu)
10073 CPUPPCState *env = &cpu->env;
10076 * TCG doesn't (yet) emulate some groups of instructions that are
10077 * implemented on some otherwise supported CPUs (e.g. VSX and
10078 * decimal floating point instructions on POWER7). We remove
10079 * unsupported instruction groups from the cpu state's instruction
10080 * masks and hope the guest can cope. For at least the pseries
10081 * machine, the unavailability of these instructions can be
10082 * advertised to the guest via the device tree.
10084 if ((env->insns_flags & ~PPC_TCG_INSNS)
10085 || (env->insns_flags2 & ~PPC_TCG_INSNS2)) {
10086 warn_report("Disabling some instructions which are not "
10087 "emulated by TCG (0x%" PRIx64 ", 0x%" PRIx64 ")",
10088 env->insns_flags & ~PPC_TCG_INSNS,
10089 env->insns_flags2 & ~PPC_TCG_INSNS2);
10091 env->insns_flags &= PPC_TCG_INSNS;
10092 env->insns_flags2 &= PPC_TCG_INSNS2;
10096 static void ppc_cpu_realize(DeviceState *dev, Error **errp)
10098 CPUState *cs = CPU(dev);
10099 PowerPCCPU *cpu = POWERPC_CPU(dev);
10100 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
10101 Error *local_err = NULL;
10103 cpu_exec_realizefn(cs, &local_err);
10104 if (local_err != NULL) {
10105 error_propagate(errp, local_err);
10108 if (cpu->vcpu_id == UNASSIGNED_CPU_INDEX) {
10109 cpu->vcpu_id = cs->cpu_index;
10112 if (tcg_enabled()) {
10113 if (ppc_fixup_cpu(cpu) != 0) {
10114 error_setg(errp, "Unable to emulate selected CPU with TCG");
10119 create_ppc_opcodes(cpu, &local_err);
10120 if (local_err != NULL) {
10121 error_propagate(errp, local_err);
10124 init_ppc_proc(cpu);
10126 if (pcc->insns_flags & PPC_FLOAT) {
10127 gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
10128 33, "power-fpu.xml", 0);
10130 if (pcc->insns_flags & PPC_ALTIVEC) {
10131 gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
10132 34, "power-altivec.xml", 0);
10134 if (pcc->insns_flags & PPC_SPE) {
10135 gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
10136 34, "power-spe.xml", 0);
10138 if (pcc->insns_flags2 & PPC2_VSX) {
10139 gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg,
10140 32, "power-vsx.xml", 0);
10142 #ifndef CONFIG_USER_ONLY
10143 gdb_register_coprocessor(cs, gdb_get_spr_reg, gdb_set_spr_reg,
10144 pcc->gdb_num_sprs, "power-spr.xml", 0);
10146 qemu_init_vcpu(cs);
10148 pcc->parent_realize(dev, errp);
10150 #if defined(PPC_DUMP_CPU)
10152 CPUPPCState *env = &cpu->env;
10153 const char *mmu_model, *excp_model, *bus_model;
10154 switch (env->mmu_model) {
10155 case POWERPC_MMU_32B:
10156 mmu_model = "PowerPC 32";
10158 case POWERPC_MMU_SOFT_6xx:
10159 mmu_model = "PowerPC 6xx/7xx with software driven TLBs";
10161 case POWERPC_MMU_SOFT_74xx:
10162 mmu_model = "PowerPC 74xx with software driven TLBs";
10164 case POWERPC_MMU_SOFT_4xx:
10165 mmu_model = "PowerPC 4xx with software driven TLBs";
10167 case POWERPC_MMU_SOFT_4xx_Z:
10168 mmu_model = "PowerPC 4xx with software driven TLBs "
10169 "and zones protections";
10171 case POWERPC_MMU_REAL:
10172 mmu_model = "PowerPC real mode only";
10174 case POWERPC_MMU_MPC8xx:
10175 mmu_model = "PowerPC MPC8xx";
10177 case POWERPC_MMU_BOOKE:
10178 mmu_model = "PowerPC BookE";
10180 case POWERPC_MMU_BOOKE206:
10181 mmu_model = "PowerPC BookE 2.06";
10183 case POWERPC_MMU_601:
10184 mmu_model = "PowerPC 601";
10186 #if defined(TARGET_PPC64)
10187 case POWERPC_MMU_64B:
10188 mmu_model = "PowerPC 64";
10192 mmu_model = "Unknown or invalid";
10195 switch (env->excp_model) {
10196 case POWERPC_EXCP_STD:
10197 excp_model = "PowerPC";
10199 case POWERPC_EXCP_40x:
10200 excp_model = "PowerPC 40x";
10202 case POWERPC_EXCP_601:
10203 excp_model = "PowerPC 601";
10205 case POWERPC_EXCP_602:
10206 excp_model = "PowerPC 602";
10208 case POWERPC_EXCP_603:
10209 excp_model = "PowerPC 603";
10211 case POWERPC_EXCP_603E:
10212 excp_model = "PowerPC 603e";
10214 case POWERPC_EXCP_604:
10215 excp_model = "PowerPC 604";
10217 case POWERPC_EXCP_7x0:
10218 excp_model = "PowerPC 740/750";
10220 case POWERPC_EXCP_7x5:
10221 excp_model = "PowerPC 745/755";
10223 case POWERPC_EXCP_74xx:
10224 excp_model = "PowerPC 74xx";
10226 case POWERPC_EXCP_BOOKE:
10227 excp_model = "PowerPC BookE";
10229 #if defined(TARGET_PPC64)
10230 case POWERPC_EXCP_970:
10231 excp_model = "PowerPC 970";
10235 excp_model = "Unknown or invalid";
10238 switch (env->bus_model) {
10239 case PPC_FLAGS_INPUT_6xx:
10240 bus_model = "PowerPC 6xx";
10242 case PPC_FLAGS_INPUT_BookE:
10243 bus_model = "PowerPC BookE";
10245 case PPC_FLAGS_INPUT_405:
10246 bus_model = "PowerPC 405";
10248 case PPC_FLAGS_INPUT_401:
10249 bus_model = "PowerPC 401/403";
10251 case PPC_FLAGS_INPUT_RCPU:
10252 bus_model = "RCPU / MPC8xx";
10254 #if defined(TARGET_PPC64)
10255 case PPC_FLAGS_INPUT_970:
10256 bus_model = "PowerPC 970";
10260 bus_model = "Unknown or invalid";
10263 printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64 "\n"
10264 " MMU model : %s\n",
10265 object_class_get_name(OBJECT_CLASS(pcc)),
10266 pcc->pvr, pcc->msr_mask, mmu_model);
10267 #if !defined(CONFIG_USER_ONLY)
10268 if (env->tlb.tlb6) {
10269 printf(" %d %s TLB in %d ways\n",
10270 env->nb_tlb, env->id_tlbs ? "splitted" : "merged",
10274 printf(" Exceptions model : %s\n"
10275 " Bus model : %s\n",
10276 excp_model, bus_model);
10277 printf(" MSR features :\n");
10278 if (env->flags & POWERPC_FLAG_SPE) {
10279 printf(" signal processing engine enable"
10281 } else if (env->flags & POWERPC_FLAG_VRE) {
10282 printf(" vector processor enable\n");
10284 if (env->flags & POWERPC_FLAG_TGPR) {
10285 printf(" temporary GPRs\n");
10286 } else if (env->flags & POWERPC_FLAG_CE) {
10287 printf(" critical input enable\n");
10289 if (env->flags & POWERPC_FLAG_SE) {
10290 printf(" single-step trace mode\n");
10291 } else if (env->flags & POWERPC_FLAG_DWE) {
10292 printf(" debug wait enable\n");
10293 } else if (env->flags & POWERPC_FLAG_UBLE) {
10294 printf(" user BTB lock enable\n");
10296 if (env->flags & POWERPC_FLAG_BE) {
10297 printf(" branch-step trace mode\n");
10298 } else if (env->flags & POWERPC_FLAG_DE) {
10299 printf(" debug interrupt enable\n");
10301 if (env->flags & POWERPC_FLAG_PX) {
10302 printf(" inclusive protection\n");
10303 } else if (env->flags & POWERPC_FLAG_PMM) {
10304 printf(" performance monitor mark\n");
10306 if (env->flags == POWERPC_FLAG_NONE) {
10309 printf(" Time-base/decrementer clock source: %s\n",
10310 env->flags & POWERPC_FLAG_RTC_CLK ? "RTC clock" : "bus clock");
10311 dump_ppc_insns(env);
10312 dump_ppc_sprs(env);
10319 cpu_exec_unrealizefn(cs);
10322 static void ppc_cpu_unrealize(DeviceState *dev)
10324 PowerPCCPU *cpu = POWERPC_CPU(dev);
10325 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
10326 opc_handler_t **table, **table_2;
10329 pcc->parent_unrealize(dev);
10331 cpu_remove_sync(CPU(cpu));
10333 for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) {
10334 if (cpu->opcodes[i] == &invalid_handler) {
10337 if (is_indirect_opcode(cpu->opcodes[i])) {
10338 table = ind_table(cpu->opcodes[i]);
10339 for (j = 0; j < PPC_CPU_INDIRECT_OPCODES_LEN; j++) {
10340 if (table[j] == &invalid_handler) {
10343 if (is_indirect_opcode(table[j])) {
10344 table_2 = ind_table(table[j]);
10345 for (k = 0; k < PPC_CPU_INDIRECT_OPCODES_LEN; k++) {
10346 if (table_2[k] != &invalid_handler &&
10347 is_indirect_opcode(table_2[k])) {
10348 g_free((opc_handler_t *)((uintptr_t)table_2[k] &
10352 g_free((opc_handler_t *)((uintptr_t)table[j] &
10356 g_free((opc_handler_t *)((uintptr_t)cpu->opcodes[i] &
10362 static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b)
10364 ObjectClass *oc = (ObjectClass *)a;
10365 uint32_t pvr = *(uint32_t *)b;
10366 PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
10368 /* -cpu host does a PVR lookup during construction */
10369 if (unlikely(strcmp(object_class_get_name(oc),
10370 TYPE_HOST_POWERPC_CPU) == 0)) {
10374 return pcc->pvr == pvr ? 0 : -1;
10377 PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr)
10379 GSList *list, *item;
10380 PowerPCCPUClass *pcc = NULL;
10382 list = object_class_get_list(TYPE_POWERPC_CPU, false);
10383 item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr);
10384 if (item != NULL) {
10385 pcc = POWERPC_CPU_CLASS(item->data);
10387 g_slist_free(list);
10392 static gint ppc_cpu_compare_class_pvr_mask(gconstpointer a, gconstpointer b)
10394 ObjectClass *oc = (ObjectClass *)a;
10395 uint32_t pvr = *(uint32_t *)b;
10396 PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
10398 /* -cpu host does a PVR lookup during construction */
10399 if (unlikely(strcmp(object_class_get_name(oc),
10400 TYPE_HOST_POWERPC_CPU) == 0)) {
10404 if (pcc->pvr_match(pcc, pvr)) {
10411 PowerPCCPUClass *ppc_cpu_class_by_pvr_mask(uint32_t pvr)
10413 GSList *list, *item;
10414 PowerPCCPUClass *pcc = NULL;
10416 list = object_class_get_list(TYPE_POWERPC_CPU, true);
10417 item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr_mask);
10418 if (item != NULL) {
10419 pcc = POWERPC_CPU_CLASS(item->data);
10421 g_slist_free(list);
10426 static const char *ppc_cpu_lookup_alias(const char *alias)
10430 for (ai = 0; ppc_cpu_aliases[ai].alias != NULL; ai++) {
10431 if (strcmp(ppc_cpu_aliases[ai].alias, alias) == 0) {
10432 return ppc_cpu_aliases[ai].model;
10439 static ObjectClass *ppc_cpu_class_by_name(const char *name)
10441 char *cpu_model, *typename;
10447 * Lookup by PVR if cpu_model is valid 8 digit hex number (excl:
10448 * 0x prefix if present)
10450 if (!qemu_strtoul(name, &p, 16, &pvr)) {
10451 int len = p - name;
10452 len = (len == 10) && (name[1] == 'x') ? len - 2 : len;
10453 if ((len == 8) && (*p == '\0')) {
10454 return OBJECT_CLASS(ppc_cpu_class_by_pvr(pvr));
10458 cpu_model = g_ascii_strdown(name, -1);
10459 p = ppc_cpu_lookup_alias(cpu_model);
10462 cpu_model = g_strdup(p);
10465 typename = g_strdup_printf("%s" POWERPC_CPU_TYPE_SUFFIX, cpu_model);
10466 oc = object_class_by_name(typename);
10473 static void ppc_cpu_parse_featurestr(const char *type, char *features,
10476 Object *machine = qdev_get_machine();
10477 const PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(object_class_by_name(type));
10483 if (object_property_find(machine, "max-cpu-compat")) {
10486 char *s = features;
10487 Error *local_err = NULL;
10488 char *compat_str = NULL;
10491 * Backwards compatibility hack:
10493 * CPUs had a "compat=" property which didn't make sense for
10494 * anything except pseries. It was replaced by "max-cpu-compat"
10495 * machine option. This supports old command lines like
10496 * -cpu POWER8,compat=power7
10497 * By stripping the compat option and applying it to the machine
10498 * before passing it on to the cpu level parser.
10500 inpieces = g_strsplit(features, ",", 0);
10502 for (i = 0; inpieces[i]; i++) {
10503 if (g_str_has_prefix(inpieces[i], "compat=")) {
10504 warn_report_once("CPU 'compat' property is deprecated; "
10505 "use max-cpu-compat machine property instead");
10506 compat_str = inpieces[i];
10509 if ((i != 0) && (s != features)) {
10510 s = g_stpcpy(s, ",");
10512 s = g_stpcpy(s, inpieces[i]);
10516 char *v = compat_str + strlen("compat=");
10517 object_property_set_str(machine, "max-cpu-compat", v, &local_err);
10519 g_strfreev(inpieces);
10521 error_propagate(errp, local_err);
10526 /* do property processing with generic handler */
10527 pcc->parent_parse_features(type, features, errp);
10530 PowerPCCPUClass *ppc_cpu_get_family_class(PowerPCCPUClass *pcc)
10532 ObjectClass *oc = OBJECT_CLASS(pcc);
10534 while (oc && !object_class_is_abstract(oc)) {
10535 oc = object_class_get_parent(oc);
10539 return POWERPC_CPU_CLASS(oc);
10542 /* Sort by PVR, ordering special case "host" last. */
10543 static gint ppc_cpu_list_compare(gconstpointer a, gconstpointer b)
10545 ObjectClass *oc_a = (ObjectClass *)a;
10546 ObjectClass *oc_b = (ObjectClass *)b;
10547 PowerPCCPUClass *pcc_a = POWERPC_CPU_CLASS(oc_a);
10548 PowerPCCPUClass *pcc_b = POWERPC_CPU_CLASS(oc_b);
10549 const char *name_a = object_class_get_name(oc_a);
10550 const char *name_b = object_class_get_name(oc_b);
10552 if (strcmp(name_a, TYPE_HOST_POWERPC_CPU) == 0) {
10554 } else if (strcmp(name_b, TYPE_HOST_POWERPC_CPU) == 0) {
10557 /* Avoid an integer overflow during subtraction */
10558 if (pcc_a->pvr < pcc_b->pvr) {
10560 } else if (pcc_a->pvr > pcc_b->pvr) {
10568 static void ppc_cpu_list_entry(gpointer data, gpointer user_data)
10570 ObjectClass *oc = data;
10571 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
10572 DeviceClass *family = DEVICE_CLASS(ppc_cpu_get_family_class(pcc));
10573 const char *typename = object_class_get_name(oc);
10577 if (unlikely(strcmp(typename, TYPE_HOST_POWERPC_CPU) == 0)) {
10581 name = g_strndup(typename,
10582 strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX));
10583 qemu_printf("PowerPC %-16s PVR %08x\n", name, pcc->pvr);
10584 for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
10585 PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
10586 ObjectClass *alias_oc = ppc_cpu_class_by_name(alias->model);
10588 if (alias_oc != oc) {
10592 * If running with KVM, we might update the family alias later, so
10593 * avoid printing the wrong alias here and use "preferred" instead
10595 if (strcmp(alias->alias, family->desc) == 0) {
10596 qemu_printf("PowerPC %-16s (alias for preferred %s CPU)\n",
10597 alias->alias, family->desc);
10599 qemu_printf("PowerPC %-16s (alias for %s)\n",
10600 alias->alias, name);
10606 void ppc_cpu_list(void)
10610 list = object_class_get_list(TYPE_POWERPC_CPU, false);
10611 list = g_slist_sort(list, ppc_cpu_list_compare);
10612 g_slist_foreach(list, ppc_cpu_list_entry, NULL);
10613 g_slist_free(list);
10617 qemu_printf("PowerPC %-16s\n", "host");
10621 static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
10623 ObjectClass *oc = data;
10624 CpuDefinitionInfoList **first = user_data;
10625 const char *typename;
10626 CpuDefinitionInfoList *entry;
10627 CpuDefinitionInfo *info;
10629 typename = object_class_get_name(oc);
10630 info = g_malloc0(sizeof(*info));
10631 info->name = g_strndup(typename,
10632 strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX));
10634 entry = g_malloc0(sizeof(*entry));
10635 entry->value = info;
10636 entry->next = *first;
10640 CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
10642 CpuDefinitionInfoList *cpu_list = NULL;
10646 list = object_class_get_list(TYPE_POWERPC_CPU, false);
10647 g_slist_foreach(list, ppc_cpu_defs_entry, &cpu_list);
10648 g_slist_free(list);
10650 for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
10651 PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
10653 CpuDefinitionInfoList *entry;
10654 CpuDefinitionInfo *info;
10656 oc = ppc_cpu_class_by_name(alias->model);
10661 info = g_malloc0(sizeof(*info));
10662 info->name = g_strdup(alias->alias);
10663 info->q_typename = g_strdup(object_class_get_name(oc));
10665 entry = g_malloc0(sizeof(*entry));
10666 entry->value = info;
10667 entry->next = cpu_list;
10674 static void ppc_cpu_set_pc(CPUState *cs, vaddr value)
10676 PowerPCCPU *cpu = POWERPC_CPU(cs);
10678 cpu->env.nip = value;
10681 static bool ppc_cpu_has_work(CPUState *cs)
10683 PowerPCCPU *cpu = POWERPC_CPU(cs);
10684 CPUPPCState *env = &cpu->env;
10686 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
10689 static void ppc_cpu_reset(DeviceState *dev)
10691 CPUState *s = CPU(dev);
10692 PowerPCCPU *cpu = POWERPC_CPU(s);
10693 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
10694 CPUPPCState *env = &cpu->env;
10698 pcc->parent_reset(dev);
10700 msr = (target_ulong)0;
10701 msr |= (target_ulong)MSR_HVB;
10702 msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
10703 msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
10704 msr |= (target_ulong)1 << MSR_EP;
10705 #if defined(DO_SINGLE_STEP) && 0
10706 /* Single step trace mode */
10707 msr |= (target_ulong)1 << MSR_SE;
10708 msr |= (target_ulong)1 << MSR_BE;
10710 #if defined(CONFIG_USER_ONLY)
10711 msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
10712 msr |= (target_ulong)1 << MSR_FE0; /* Allow floating point exceptions */
10713 msr |= (target_ulong)1 << MSR_FE1;
10714 msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
10715 msr |= (target_ulong)1 << MSR_VSX; /* Allow VSX usage */
10716 msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
10717 msr |= (target_ulong)1 << MSR_PR;
10718 #if defined(TARGET_PPC64)
10719 msr |= (target_ulong)1 << MSR_TM; /* Transactional memory */
10721 #if !defined(TARGET_WORDS_BIGENDIAN)
10722 msr |= (target_ulong)1 << MSR_LE; /* Little-endian user mode */
10723 if (!((env->msr_mask >> MSR_LE) & 1)) {
10724 fprintf(stderr, "Selected CPU does not support little-endian.\n");
10730 #if defined(TARGET_PPC64)
10731 if (env->mmu_model & POWERPC_MMU_64) {
10732 msr |= (1ULL << MSR_SF);
10736 hreg_store_msr(env, msr, 1);
10738 #if !defined(CONFIG_USER_ONLY)
10739 env->nip = env->hreset_vector | env->excp_prefix;
10740 if (env->mmu_model != POWERPC_MMU_REAL) {
10741 ppc_tlb_invalidate_all(env);
10745 hreg_compute_hflags(env);
10746 env->reserve_addr = (target_ulong)-1ULL;
10747 /* Be sure no exception or interrupt is pending */
10748 env->pending_interrupts = 0;
10749 s->exception_index = POWERPC_EXCP_NONE;
10750 env->error_code = 0;
10751 ppc_irq_reset(cpu);
10753 /* tininess for underflow is detected before rounding */
10754 set_float_detect_tininess(float_tininess_before_rounding,
10757 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
10758 ppc_spr_t *spr = &env->spr_cb[i];
10763 env->spr[i] = spr->default_value;
10767 #ifndef CONFIG_USER_ONLY
10768 static bool ppc_cpu_is_big_endian(CPUState *cs)
10770 PowerPCCPU *cpu = POWERPC_CPU(cs);
10771 CPUPPCState *env = &cpu->env;
10773 cpu_synchronize_state(cs);
10778 static void ppc_cpu_exec_enter(CPUState *cs)
10780 PowerPCCPU *cpu = POWERPC_CPU(cs);
10783 PPCVirtualHypervisorClass *vhc =
10784 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
10785 vhc->cpu_exec_enter(cpu->vhyp, cpu);
10789 static void ppc_cpu_exec_exit(CPUState *cs)
10791 PowerPCCPU *cpu = POWERPC_CPU(cs);
10794 PPCVirtualHypervisorClass *vhc =
10795 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
10796 vhc->cpu_exec_exit(cpu->vhyp, cpu);
10801 static void ppc_cpu_instance_init(Object *obj)
10803 PowerPCCPU *cpu = POWERPC_CPU(obj);
10804 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
10805 CPUPPCState *env = &cpu->env;
10807 cpu_set_cpustate_pointers(cpu);
10808 cpu->vcpu_id = UNASSIGNED_CPU_INDEX;
10810 env->msr_mask = pcc->msr_mask;
10811 env->mmu_model = pcc->mmu_model;
10812 env->excp_model = pcc->excp_model;
10813 env->bus_model = pcc->bus_model;
10814 env->insns_flags = pcc->insns_flags;
10815 env->insns_flags2 = pcc->insns_flags2;
10816 env->flags = pcc->flags;
10817 env->bfd_mach = pcc->bfd_mach;
10818 env->check_pow = pcc->check_pow;
10821 * Mark HV mode as supported if the CPU has an MSR_HV bit in the
10822 * msr_mask. The mask can later be cleared by PAPR mode but the hv
10823 * mode support will remain, thus enforcing that we cannot use
10824 * priv. instructions in guest in PAPR mode. For 970 we currently
10825 * simply don't set HV in msr_mask thus simulating an "Apple mode"
10826 * 970. If we ever want to support 970 HV mode, we'll have to add
10827 * a processor attribute of some sort.
10829 #if !defined(CONFIG_USER_ONLY)
10830 env->has_hv_mode = !!(env->msr_mask & MSR_HVB);
10833 ppc_hash64_init(cpu);
10836 static void ppc_cpu_instance_finalize(Object *obj)
10838 PowerPCCPU *cpu = POWERPC_CPU(obj);
10840 ppc_hash64_finalize(cpu);
10843 static bool ppc_pvr_match_default(PowerPCCPUClass *pcc, uint32_t pvr)
10845 return pcc->pvr == pvr;
10848 static gchar *ppc_gdb_arch_name(CPUState *cs)
10850 #if defined(TARGET_PPC64)
10851 return g_strdup("powerpc:common64");
10853 return g_strdup("powerpc:common");
10857 static void ppc_disas_set_info(CPUState *cs, disassemble_info *info)
10859 PowerPCCPU *cpu = POWERPC_CPU(cs);
10860 CPUPPCState *env = &cpu->env;
10862 if ((env->hflags >> MSR_LE) & 1) {
10863 info->endian = BFD_ENDIAN_LITTLE;
10865 info->mach = env->bfd_mach;
10866 if (!env->bfd_mach) {
10867 #ifdef TARGET_PPC64
10868 info->mach = bfd_mach_ppc64;
10870 info->mach = bfd_mach_ppc;
10873 info->disassembler_options = (char *)"any";
10874 info->print_insn = print_insn_ppc;
10876 info->cap_arch = CS_ARCH_PPC;
10877 #ifdef TARGET_PPC64
10878 info->cap_mode = CS_MODE_64;
10882 static Property ppc_cpu_properties[] = {
10883 DEFINE_PROP_BOOL("pre-2.8-migration", PowerPCCPU, pre_2_8_migration, false),
10884 DEFINE_PROP_BOOL("pre-2.10-migration", PowerPCCPU, pre_2_10_migration,
10886 DEFINE_PROP_BOOL("pre-3.0-migration", PowerPCCPU, pre_3_0_migration,
10888 DEFINE_PROP_END_OF_LIST(),
10891 static void ppc_cpu_class_init(ObjectClass *oc, void *data)
10893 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
10894 CPUClass *cc = CPU_CLASS(oc);
10895 DeviceClass *dc = DEVICE_CLASS(oc);
10897 device_class_set_parent_realize(dc, ppc_cpu_realize,
10898 &pcc->parent_realize);
10899 device_class_set_parent_unrealize(dc, ppc_cpu_unrealize,
10900 &pcc->parent_unrealize);
10901 pcc->pvr_match = ppc_pvr_match_default;
10902 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_always;
10903 device_class_set_props(dc, ppc_cpu_properties);
10905 device_class_set_parent_reset(dc, ppc_cpu_reset, &pcc->parent_reset);
10907 cc->class_by_name = ppc_cpu_class_by_name;
10908 pcc->parent_parse_features = cc->parse_features;
10909 cc->parse_features = ppc_cpu_parse_featurestr;
10910 cc->has_work = ppc_cpu_has_work;
10911 cc->do_interrupt = ppc_cpu_do_interrupt;
10912 cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt;
10913 cc->dump_state = ppc_cpu_dump_state;
10914 cc->dump_statistics = ppc_cpu_dump_statistics;
10915 cc->set_pc = ppc_cpu_set_pc;
10916 cc->gdb_read_register = ppc_cpu_gdb_read_register;
10917 cc->gdb_write_register = ppc_cpu_gdb_write_register;
10918 cc->do_unaligned_access = ppc_cpu_do_unaligned_access;
10919 #ifndef CONFIG_USER_ONLY
10920 cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
10921 cc->vmsd = &vmstate_ppc_cpu;
10923 #if defined(CONFIG_SOFTMMU)
10924 cc->write_elf64_note = ppc64_cpu_write_elf64_note;
10925 cc->write_elf32_note = ppc32_cpu_write_elf32_note;
10928 cc->gdb_num_core_regs = 71;
10929 #ifndef CONFIG_USER_ONLY
10930 cc->gdb_get_dynamic_xml = ppc_gdb_get_dynamic_xml;
10932 #ifdef USE_APPLE_GDB
10933 cc->gdb_read_register = ppc_cpu_gdb_read_register_apple;
10934 cc->gdb_write_register = ppc_cpu_gdb_write_register_apple;
10935 cc->gdb_num_core_regs = 71 + 32;
10938 cc->gdb_arch_name = ppc_gdb_arch_name;
10939 #if defined(TARGET_PPC64)
10940 cc->gdb_core_xml_file = "power64-core.xml";
10942 cc->gdb_core_xml_file = "power-core.xml";
10944 #ifndef CONFIG_USER_ONLY
10945 cc->virtio_is_big_endian = ppc_cpu_is_big_endian;
10948 cc->tcg_initialize = ppc_translate_init;
10949 cc->tlb_fill = ppc_cpu_tlb_fill;
10951 #ifndef CONFIG_USER_ONLY
10952 cc->cpu_exec_enter = ppc_cpu_exec_enter;
10953 cc->cpu_exec_exit = ppc_cpu_exec_exit;
10956 cc->disas_set_info = ppc_disas_set_info;
10958 dc->fw_name = "PowerPC,UNKNOWN";
10961 static const TypeInfo ppc_cpu_type_info = {
10962 .name = TYPE_POWERPC_CPU,
10963 .parent = TYPE_CPU,
10964 .instance_size = sizeof(PowerPCCPU),
10965 .instance_align = __alignof__(PowerPCCPU),
10966 .instance_init = ppc_cpu_instance_init,
10967 .instance_finalize = ppc_cpu_instance_finalize,
10969 .class_size = sizeof(PowerPCCPUClass),
10970 .class_init = ppc_cpu_class_init,
10973 #ifndef CONFIG_USER_ONLY
10974 static const TypeInfo ppc_vhyp_type_info = {
10975 .name = TYPE_PPC_VIRTUAL_HYPERVISOR,
10976 .parent = TYPE_INTERFACE,
10977 .class_size = sizeof(PPCVirtualHypervisorClass),
10981 static void ppc_cpu_register_types(void)
10983 type_register_static(&ppc_cpu_type_info);
10984 #ifndef CONFIG_USER_ONLY
10985 type_register_static(&ppc_vhyp_type_info);
10989 type_init(ppc_cpu_register_types)