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_e500_l2csr0(DisasContext *ctx, int sprn, int gprn)
1740 TCGv t0 = tcg_temp_new();
1742 tcg_gen_andi_tl(t0, cpu_gpr[gprn],
1743 ~(E500_L2CSR0_L2FI | E500_L2CSR0_L2FL | E500_L2CSR0_L2LFC));
1744 gen_store_spr(sprn, t0);
1748 static void spr_write_booke206_mmucsr0(DisasContext *ctx, int sprn, int gprn)
1750 gen_helper_booke206_tlbflush(cpu_env, cpu_gpr[gprn]);
1753 static void spr_write_booke_pid(DisasContext *ctx, int sprn, int gprn)
1755 TCGv_i32 t0 = tcg_const_i32(sprn);
1756 gen_helper_booke_setpid(cpu_env, t0, cpu_gpr[gprn]);
1757 tcg_temp_free_i32(t0);
1759 static void spr_write_eplc(DisasContext *ctx, int sprn, int gprn)
1761 gen_helper_booke_set_eplc(cpu_env, cpu_gpr[gprn]);
1763 static void spr_write_epsc(DisasContext *ctx, int sprn, int gprn)
1765 gen_helper_booke_set_epsc(cpu_env, cpu_gpr[gprn]);
1770 static void gen_spr_usprg3(CPUPPCState *env)
1772 spr_register(env, SPR_USPRG3, "USPRG3",
1773 &spr_read_ureg, SPR_NOACCESS,
1774 &spr_read_ureg, SPR_NOACCESS,
1778 static void gen_spr_usprgh(CPUPPCState *env)
1780 spr_register(env, SPR_USPRG4, "USPRG4",
1781 &spr_read_ureg, SPR_NOACCESS,
1782 &spr_read_ureg, SPR_NOACCESS,
1784 spr_register(env, SPR_USPRG5, "USPRG5",
1785 &spr_read_ureg, SPR_NOACCESS,
1786 &spr_read_ureg, SPR_NOACCESS,
1788 spr_register(env, SPR_USPRG6, "USPRG6",
1789 &spr_read_ureg, SPR_NOACCESS,
1790 &spr_read_ureg, SPR_NOACCESS,
1792 spr_register(env, SPR_USPRG7, "USPRG7",
1793 &spr_read_ureg, SPR_NOACCESS,
1794 &spr_read_ureg, SPR_NOACCESS,
1798 /* PowerPC BookE SPR */
1799 static void gen_spr_BookE(CPUPPCState *env, uint64_t ivor_mask)
1801 const char *ivor_names[64] = {
1802 "IVOR0", "IVOR1", "IVOR2", "IVOR3",
1803 "IVOR4", "IVOR5", "IVOR6", "IVOR7",
1804 "IVOR8", "IVOR9", "IVOR10", "IVOR11",
1805 "IVOR12", "IVOR13", "IVOR14", "IVOR15",
1806 "IVOR16", "IVOR17", "IVOR18", "IVOR19",
1807 "IVOR20", "IVOR21", "IVOR22", "IVOR23",
1808 "IVOR24", "IVOR25", "IVOR26", "IVOR27",
1809 "IVOR28", "IVOR29", "IVOR30", "IVOR31",
1810 "IVOR32", "IVOR33", "IVOR34", "IVOR35",
1811 "IVOR36", "IVOR37", "IVOR38", "IVOR39",
1812 "IVOR40", "IVOR41", "IVOR42", "IVOR43",
1813 "IVOR44", "IVOR45", "IVOR46", "IVOR47",
1814 "IVOR48", "IVOR49", "IVOR50", "IVOR51",
1815 "IVOR52", "IVOR53", "IVOR54", "IVOR55",
1816 "IVOR56", "IVOR57", "IVOR58", "IVOR59",
1817 "IVOR60", "IVOR61", "IVOR62", "IVOR63",
1819 #define SPR_BOOKE_IVORxx (-1)
1820 int ivor_sprn[64] = {
1821 SPR_BOOKE_IVOR0, SPR_BOOKE_IVOR1, SPR_BOOKE_IVOR2, SPR_BOOKE_IVOR3,
1822 SPR_BOOKE_IVOR4, SPR_BOOKE_IVOR5, SPR_BOOKE_IVOR6, SPR_BOOKE_IVOR7,
1823 SPR_BOOKE_IVOR8, SPR_BOOKE_IVOR9, SPR_BOOKE_IVOR10, SPR_BOOKE_IVOR11,
1824 SPR_BOOKE_IVOR12, SPR_BOOKE_IVOR13, SPR_BOOKE_IVOR14, SPR_BOOKE_IVOR15,
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,
1827 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1828 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1829 SPR_BOOKE_IVOR32, SPR_BOOKE_IVOR33, SPR_BOOKE_IVOR34, SPR_BOOKE_IVOR35,
1830 SPR_BOOKE_IVOR36, SPR_BOOKE_IVOR37, SPR_BOOKE_IVOR38, SPR_BOOKE_IVOR39,
1831 SPR_BOOKE_IVOR40, SPR_BOOKE_IVOR41, SPR_BOOKE_IVOR42, SPR_BOOKE_IVORxx,
1832 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1833 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1834 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1835 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1836 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1840 /* Interrupt processing */
1841 spr_register(env, SPR_BOOKE_CSRR0, "CSRR0",
1842 SPR_NOACCESS, SPR_NOACCESS,
1843 &spr_read_generic, &spr_write_generic,
1845 spr_register(env, SPR_BOOKE_CSRR1, "CSRR1",
1846 SPR_NOACCESS, SPR_NOACCESS,
1847 &spr_read_generic, &spr_write_generic,
1850 /* XXX : not implemented */
1851 spr_register(env, SPR_BOOKE_IAC1, "IAC1",
1852 SPR_NOACCESS, SPR_NOACCESS,
1853 &spr_read_generic, &spr_write_generic,
1855 /* XXX : not implemented */
1856 spr_register(env, SPR_BOOKE_IAC2, "IAC2",
1857 SPR_NOACCESS, SPR_NOACCESS,
1858 &spr_read_generic, &spr_write_generic,
1860 /* XXX : not implemented */
1861 spr_register(env, SPR_BOOKE_DAC1, "DAC1",
1862 SPR_NOACCESS, SPR_NOACCESS,
1863 &spr_read_generic, &spr_write_generic,
1865 /* XXX : not implemented */
1866 spr_register(env, SPR_BOOKE_DAC2, "DAC2",
1867 SPR_NOACCESS, SPR_NOACCESS,
1868 &spr_read_generic, &spr_write_generic,
1870 /* XXX : not implemented */
1871 spr_register(env, SPR_BOOKE_DBCR0, "DBCR0",
1872 SPR_NOACCESS, SPR_NOACCESS,
1873 &spr_read_generic, &spr_write_40x_dbcr0,
1875 /* XXX : not implemented */
1876 spr_register(env, SPR_BOOKE_DBCR1, "DBCR1",
1877 SPR_NOACCESS, SPR_NOACCESS,
1878 &spr_read_generic, &spr_write_generic,
1880 /* XXX : not implemented */
1881 spr_register(env, SPR_BOOKE_DBCR2, "DBCR2",
1882 SPR_NOACCESS, SPR_NOACCESS,
1883 &spr_read_generic, &spr_write_generic,
1885 spr_register(env, SPR_BOOKE_DSRR0, "DSRR0",
1886 SPR_NOACCESS, SPR_NOACCESS,
1887 &spr_read_generic, &spr_write_generic,
1889 spr_register(env, SPR_BOOKE_DSRR1, "DSRR1",
1890 SPR_NOACCESS, SPR_NOACCESS,
1891 &spr_read_generic, &spr_write_generic,
1893 /* XXX : not implemented */
1894 spr_register(env, SPR_BOOKE_DBSR, "DBSR",
1895 SPR_NOACCESS, SPR_NOACCESS,
1896 &spr_read_generic, &spr_write_clear,
1898 spr_register(env, SPR_BOOKE_DEAR, "DEAR",
1899 SPR_NOACCESS, SPR_NOACCESS,
1900 &spr_read_generic, &spr_write_generic,
1902 spr_register(env, SPR_BOOKE_ESR, "ESR",
1903 SPR_NOACCESS, SPR_NOACCESS,
1904 &spr_read_generic, &spr_write_generic,
1906 spr_register(env, SPR_BOOKE_IVPR, "IVPR",
1907 SPR_NOACCESS, SPR_NOACCESS,
1908 &spr_read_generic, &spr_write_excp_prefix,
1910 /* Exception vectors */
1911 for (i = 0; i < 64; i++) {
1912 if (ivor_mask & (1ULL << i)) {
1913 if (ivor_sprn[i] == SPR_BOOKE_IVORxx) {
1914 fprintf(stderr, "ERROR: IVOR %d SPR is not defined\n", i);
1917 spr_register(env, ivor_sprn[i], ivor_names[i],
1918 SPR_NOACCESS, SPR_NOACCESS,
1919 &spr_read_generic, &spr_write_excp_vector,
1923 spr_register(env, SPR_BOOKE_PID, "PID",
1924 SPR_NOACCESS, SPR_NOACCESS,
1925 &spr_read_generic, &spr_write_booke_pid,
1927 spr_register(env, SPR_BOOKE_TCR, "TCR",
1928 SPR_NOACCESS, SPR_NOACCESS,
1929 &spr_read_generic, &spr_write_booke_tcr,
1931 spr_register(env, SPR_BOOKE_TSR, "TSR",
1932 SPR_NOACCESS, SPR_NOACCESS,
1933 &spr_read_generic, &spr_write_booke_tsr,
1936 spr_register(env, SPR_DECR, "DECR",
1937 SPR_NOACCESS, SPR_NOACCESS,
1938 &spr_read_decr, &spr_write_decr,
1940 spr_register(env, SPR_BOOKE_DECAR, "DECAR",
1941 SPR_NOACCESS, SPR_NOACCESS,
1942 SPR_NOACCESS, &spr_write_generic,
1945 spr_register(env, SPR_USPRG0, "USPRG0",
1946 &spr_read_generic, &spr_write_generic,
1947 &spr_read_generic, &spr_write_generic,
1949 spr_register(env, SPR_SPRG4, "SPRG4",
1950 SPR_NOACCESS, SPR_NOACCESS,
1951 &spr_read_generic, &spr_write_generic,
1953 spr_register(env, SPR_SPRG5, "SPRG5",
1954 SPR_NOACCESS, SPR_NOACCESS,
1955 &spr_read_generic, &spr_write_generic,
1957 spr_register(env, SPR_SPRG6, "SPRG6",
1958 SPR_NOACCESS, SPR_NOACCESS,
1959 &spr_read_generic, &spr_write_generic,
1961 spr_register(env, SPR_SPRG7, "SPRG7",
1962 SPR_NOACCESS, SPR_NOACCESS,
1963 &spr_read_generic, &spr_write_generic,
1965 spr_register(env, SPR_BOOKE_SPRG8, "SPRG8",
1966 SPR_NOACCESS, SPR_NOACCESS,
1967 &spr_read_generic, &spr_write_generic,
1969 spr_register(env, SPR_BOOKE_SPRG9, "SPRG9",
1970 SPR_NOACCESS, SPR_NOACCESS,
1971 &spr_read_generic, &spr_write_generic,
1975 static inline uint32_t gen_tlbncfg(uint32_t assoc, uint32_t minsize,
1976 uint32_t maxsize, uint32_t flags,
1979 return (assoc << TLBnCFG_ASSOC_SHIFT) |
1980 (minsize << TLBnCFG_MINSIZE_SHIFT) |
1981 (maxsize << TLBnCFG_MAXSIZE_SHIFT) |
1985 /* BookE 2.06 storage control registers */
1986 static void gen_spr_BookE206(CPUPPCState *env, uint32_t mas_mask,
1987 uint32_t *tlbncfg, uint32_t mmucfg)
1989 #if !defined(CONFIG_USER_ONLY)
1990 const char *mas_names[8] = {
1991 "MAS0", "MAS1", "MAS2", "MAS3", "MAS4", "MAS5", "MAS6", "MAS7",
1994 SPR_BOOKE_MAS0, SPR_BOOKE_MAS1, SPR_BOOKE_MAS2, SPR_BOOKE_MAS3,
1995 SPR_BOOKE_MAS4, SPR_BOOKE_MAS5, SPR_BOOKE_MAS6, SPR_BOOKE_MAS7,
1999 /* TLB assist registers */
2000 /* XXX : not implemented */
2001 for (i = 0; i < 8; i++) {
2002 void (*uea_write)(DisasContext *ctx, int sprn, int gprn) =
2003 &spr_write_generic32;
2004 if (i == 2 && (mas_mask & (1 << i)) && (env->insns_flags & PPC_64B)) {
2005 uea_write = &spr_write_generic;
2007 if (mas_mask & (1 << i)) {
2008 spr_register(env, mas_sprn[i], mas_names[i],
2009 SPR_NOACCESS, SPR_NOACCESS,
2010 &spr_read_generic, uea_write,
2014 if (env->nb_pids > 1) {
2015 /* XXX : not implemented */
2016 spr_register(env, SPR_BOOKE_PID1, "PID1",
2017 SPR_NOACCESS, SPR_NOACCESS,
2018 &spr_read_generic, &spr_write_booke_pid,
2021 if (env->nb_pids > 2) {
2022 /* XXX : not implemented */
2023 spr_register(env, SPR_BOOKE_PID2, "PID2",
2024 SPR_NOACCESS, SPR_NOACCESS,
2025 &spr_read_generic, &spr_write_booke_pid,
2029 spr_register(env, SPR_BOOKE_EPLC, "EPLC",
2030 SPR_NOACCESS, SPR_NOACCESS,
2031 &spr_read_generic, &spr_write_eplc,
2033 spr_register(env, SPR_BOOKE_EPSC, "EPSC",
2034 SPR_NOACCESS, SPR_NOACCESS,
2035 &spr_read_generic, &spr_write_epsc,
2038 /* XXX : not implemented */
2039 spr_register(env, SPR_MMUCFG, "MMUCFG",
2040 SPR_NOACCESS, SPR_NOACCESS,
2041 &spr_read_generic, SPR_NOACCESS,
2043 switch (env->nb_ways) {
2045 spr_register(env, SPR_BOOKE_TLB3CFG, "TLB3CFG",
2046 SPR_NOACCESS, SPR_NOACCESS,
2047 &spr_read_generic, SPR_NOACCESS,
2051 spr_register(env, SPR_BOOKE_TLB2CFG, "TLB2CFG",
2052 SPR_NOACCESS, SPR_NOACCESS,
2053 &spr_read_generic, SPR_NOACCESS,
2057 spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG",
2058 SPR_NOACCESS, SPR_NOACCESS,
2059 &spr_read_generic, SPR_NOACCESS,
2063 spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG",
2064 SPR_NOACCESS, SPR_NOACCESS,
2065 &spr_read_generic, SPR_NOACCESS,
2074 gen_spr_usprgh(env);
2077 /* SPR specific to PowerPC 440 implementation */
2078 static void gen_spr_440(CPUPPCState *env)
2081 /* XXX : not implemented */
2082 spr_register(env, SPR_440_DNV0, "DNV0",
2083 SPR_NOACCESS, SPR_NOACCESS,
2084 &spr_read_generic, &spr_write_generic,
2086 /* XXX : not implemented */
2087 spr_register(env, SPR_440_DNV1, "DNV1",
2088 SPR_NOACCESS, SPR_NOACCESS,
2089 &spr_read_generic, &spr_write_generic,
2091 /* XXX : not implemented */
2092 spr_register(env, SPR_440_DNV2, "DNV2",
2093 SPR_NOACCESS, SPR_NOACCESS,
2094 &spr_read_generic, &spr_write_generic,
2096 /* XXX : not implemented */
2097 spr_register(env, SPR_440_DNV3, "DNV3",
2098 SPR_NOACCESS, SPR_NOACCESS,
2099 &spr_read_generic, &spr_write_generic,
2101 /* XXX : not implemented */
2102 spr_register(env, SPR_440_DTV0, "DTV0",
2103 SPR_NOACCESS, SPR_NOACCESS,
2104 &spr_read_generic, &spr_write_generic,
2106 /* XXX : not implemented */
2107 spr_register(env, SPR_440_DTV1, "DTV1",
2108 SPR_NOACCESS, SPR_NOACCESS,
2109 &spr_read_generic, &spr_write_generic,
2111 /* XXX : not implemented */
2112 spr_register(env, SPR_440_DTV2, "DTV2",
2113 SPR_NOACCESS, SPR_NOACCESS,
2114 &spr_read_generic, &spr_write_generic,
2116 /* XXX : not implemented */
2117 spr_register(env, SPR_440_DTV3, "DTV3",
2118 SPR_NOACCESS, SPR_NOACCESS,
2119 &spr_read_generic, &spr_write_generic,
2121 /* XXX : not implemented */
2122 spr_register(env, SPR_440_DVLIM, "DVLIM",
2123 SPR_NOACCESS, SPR_NOACCESS,
2124 &spr_read_generic, &spr_write_generic,
2126 /* XXX : not implemented */
2127 spr_register(env, SPR_440_INV0, "INV0",
2128 SPR_NOACCESS, SPR_NOACCESS,
2129 &spr_read_generic, &spr_write_generic,
2131 /* XXX : not implemented */
2132 spr_register(env, SPR_440_INV1, "INV1",
2133 SPR_NOACCESS, SPR_NOACCESS,
2134 &spr_read_generic, &spr_write_generic,
2136 /* XXX : not implemented */
2137 spr_register(env, SPR_440_INV2, "INV2",
2138 SPR_NOACCESS, SPR_NOACCESS,
2139 &spr_read_generic, &spr_write_generic,
2141 /* XXX : not implemented */
2142 spr_register(env, SPR_440_INV3, "INV3",
2143 SPR_NOACCESS, SPR_NOACCESS,
2144 &spr_read_generic, &spr_write_generic,
2146 /* XXX : not implemented */
2147 spr_register(env, SPR_440_ITV0, "ITV0",
2148 SPR_NOACCESS, SPR_NOACCESS,
2149 &spr_read_generic, &spr_write_generic,
2151 /* XXX : not implemented */
2152 spr_register(env, SPR_440_ITV1, "ITV1",
2153 SPR_NOACCESS, SPR_NOACCESS,
2154 &spr_read_generic, &spr_write_generic,
2156 /* XXX : not implemented */
2157 spr_register(env, SPR_440_ITV2, "ITV2",
2158 SPR_NOACCESS, SPR_NOACCESS,
2159 &spr_read_generic, &spr_write_generic,
2161 /* XXX : not implemented */
2162 spr_register(env, SPR_440_ITV3, "ITV3",
2163 SPR_NOACCESS, SPR_NOACCESS,
2164 &spr_read_generic, &spr_write_generic,
2166 /* XXX : not implemented */
2167 spr_register(env, SPR_440_IVLIM, "IVLIM",
2168 SPR_NOACCESS, SPR_NOACCESS,
2169 &spr_read_generic, &spr_write_generic,
2172 /* XXX : not implemented */
2173 spr_register(env, SPR_BOOKE_DCDBTRH, "DCDBTRH",
2174 SPR_NOACCESS, SPR_NOACCESS,
2175 &spr_read_generic, SPR_NOACCESS,
2177 /* XXX : not implemented */
2178 spr_register(env, SPR_BOOKE_DCDBTRL, "DCDBTRL",
2179 SPR_NOACCESS, SPR_NOACCESS,
2180 &spr_read_generic, SPR_NOACCESS,
2182 /* XXX : not implemented */
2183 spr_register(env, SPR_BOOKE_ICDBDR, "ICDBDR",
2184 SPR_NOACCESS, SPR_NOACCESS,
2185 &spr_read_generic, SPR_NOACCESS,
2187 /* XXX : not implemented */
2188 spr_register(env, SPR_BOOKE_ICDBTRH, "ICDBTRH",
2189 SPR_NOACCESS, SPR_NOACCESS,
2190 &spr_read_generic, SPR_NOACCESS,
2192 /* XXX : not implemented */
2193 spr_register(env, SPR_BOOKE_ICDBTRL, "ICDBTRL",
2194 SPR_NOACCESS, SPR_NOACCESS,
2195 &spr_read_generic, SPR_NOACCESS,
2197 /* XXX : not implemented */
2198 spr_register(env, SPR_440_DBDR, "DBDR",
2199 SPR_NOACCESS, SPR_NOACCESS,
2200 &spr_read_generic, &spr_write_generic,
2202 /* Processor control */
2203 spr_register(env, SPR_4xx_CCR0, "CCR0",
2204 SPR_NOACCESS, SPR_NOACCESS,
2205 &spr_read_generic, &spr_write_generic,
2207 spr_register(env, SPR_440_RSTCFG, "RSTCFG",
2208 SPR_NOACCESS, SPR_NOACCESS,
2209 &spr_read_generic, SPR_NOACCESS,
2211 /* Storage control */
2212 spr_register(env, SPR_440_MMUCR, "MMUCR",
2213 SPR_NOACCESS, SPR_NOACCESS,
2214 &spr_read_generic, &spr_write_generic,
2218 /* SPR shared between PowerPC 40x implementations */
2219 static void gen_spr_40x(CPUPPCState *env)
2222 /* not emulated, as QEMU do not emulate caches */
2223 spr_register(env, SPR_40x_DCCR, "DCCR",
2224 SPR_NOACCESS, SPR_NOACCESS,
2225 &spr_read_generic, &spr_write_generic,
2227 /* not emulated, as QEMU do not emulate caches */
2228 spr_register(env, SPR_40x_ICCR, "ICCR",
2229 SPR_NOACCESS, SPR_NOACCESS,
2230 &spr_read_generic, &spr_write_generic,
2232 /* not emulated, as QEMU do not emulate caches */
2233 spr_register(env, SPR_BOOKE_ICDBDR, "ICDBDR",
2234 SPR_NOACCESS, SPR_NOACCESS,
2235 &spr_read_generic, SPR_NOACCESS,
2238 spr_register(env, SPR_40x_DEAR, "DEAR",
2239 SPR_NOACCESS, SPR_NOACCESS,
2240 &spr_read_generic, &spr_write_generic,
2242 spr_register(env, SPR_40x_ESR, "ESR",
2243 SPR_NOACCESS, SPR_NOACCESS,
2244 &spr_read_generic, &spr_write_generic,
2246 spr_register(env, SPR_40x_EVPR, "EVPR",
2247 SPR_NOACCESS, SPR_NOACCESS,
2248 &spr_read_generic, &spr_write_excp_prefix,
2250 spr_register(env, SPR_40x_SRR2, "SRR2",
2251 &spr_read_generic, &spr_write_generic,
2252 &spr_read_generic, &spr_write_generic,
2254 spr_register(env, SPR_40x_SRR3, "SRR3",
2255 &spr_read_generic, &spr_write_generic,
2256 &spr_read_generic, &spr_write_generic,
2259 spr_register(env, SPR_40x_PIT, "PIT",
2260 SPR_NOACCESS, SPR_NOACCESS,
2261 &spr_read_40x_pit, &spr_write_40x_pit,
2263 spr_register(env, SPR_40x_TCR, "TCR",
2264 SPR_NOACCESS, SPR_NOACCESS,
2265 &spr_read_generic, &spr_write_booke_tcr,
2267 spr_register(env, SPR_40x_TSR, "TSR",
2268 SPR_NOACCESS, SPR_NOACCESS,
2269 &spr_read_generic, &spr_write_booke_tsr,
2273 /* SPR specific to PowerPC 405 implementation */
2274 static void gen_spr_405(CPUPPCState *env)
2277 spr_register(env, SPR_40x_PID, "PID",
2278 SPR_NOACCESS, SPR_NOACCESS,
2279 &spr_read_generic, &spr_write_generic,
2281 spr_register(env, SPR_4xx_CCR0, "CCR0",
2282 SPR_NOACCESS, SPR_NOACCESS,
2283 &spr_read_generic, &spr_write_generic,
2285 /* Debug interface */
2286 /* XXX : not implemented */
2287 spr_register(env, SPR_40x_DBCR0, "DBCR0",
2288 SPR_NOACCESS, SPR_NOACCESS,
2289 &spr_read_generic, &spr_write_40x_dbcr0,
2291 /* XXX : not implemented */
2292 spr_register(env, SPR_405_DBCR1, "DBCR1",
2293 SPR_NOACCESS, SPR_NOACCESS,
2294 &spr_read_generic, &spr_write_generic,
2296 /* XXX : not implemented */
2297 spr_register(env, SPR_40x_DBSR, "DBSR",
2298 SPR_NOACCESS, SPR_NOACCESS,
2299 &spr_read_generic, &spr_write_clear,
2300 /* Last reset was system reset */
2302 /* XXX : not implemented */
2303 spr_register(env, SPR_40x_DAC1, "DAC1",
2304 SPR_NOACCESS, SPR_NOACCESS,
2305 &spr_read_generic, &spr_write_generic,
2307 spr_register(env, SPR_40x_DAC2, "DAC2",
2308 SPR_NOACCESS, SPR_NOACCESS,
2309 &spr_read_generic, &spr_write_generic,
2311 /* XXX : not implemented */
2312 spr_register(env, SPR_405_DVC1, "DVC1",
2313 SPR_NOACCESS, SPR_NOACCESS,
2314 &spr_read_generic, &spr_write_generic,
2316 /* XXX : not implemented */
2317 spr_register(env, SPR_405_DVC2, "DVC2",
2318 SPR_NOACCESS, SPR_NOACCESS,
2319 &spr_read_generic, &spr_write_generic,
2321 /* XXX : not implemented */
2322 spr_register(env, SPR_40x_IAC1, "IAC1",
2323 SPR_NOACCESS, SPR_NOACCESS,
2324 &spr_read_generic, &spr_write_generic,
2326 spr_register(env, SPR_40x_IAC2, "IAC2",
2327 SPR_NOACCESS, SPR_NOACCESS,
2328 &spr_read_generic, &spr_write_generic,
2330 /* XXX : not implemented */
2331 spr_register(env, SPR_405_IAC3, "IAC3",
2332 SPR_NOACCESS, SPR_NOACCESS,
2333 &spr_read_generic, &spr_write_generic,
2335 /* XXX : not implemented */
2336 spr_register(env, SPR_405_IAC4, "IAC4",
2337 SPR_NOACCESS, SPR_NOACCESS,
2338 &spr_read_generic, &spr_write_generic,
2340 /* Storage control */
2341 /* XXX: TODO: not implemented */
2342 spr_register(env, SPR_405_SLER, "SLER",
2343 SPR_NOACCESS, SPR_NOACCESS,
2344 &spr_read_generic, &spr_write_40x_sler,
2346 spr_register(env, SPR_40x_ZPR, "ZPR",
2347 SPR_NOACCESS, SPR_NOACCESS,
2348 &spr_read_generic, &spr_write_generic,
2350 /* XXX : not implemented */
2351 spr_register(env, SPR_405_SU0R, "SU0R",
2352 SPR_NOACCESS, SPR_NOACCESS,
2353 &spr_read_generic, &spr_write_generic,
2356 spr_register(env, SPR_USPRG0, "USPRG0",
2357 &spr_read_ureg, SPR_NOACCESS,
2358 &spr_read_ureg, SPR_NOACCESS,
2360 spr_register(env, SPR_SPRG4, "SPRG4",
2361 SPR_NOACCESS, SPR_NOACCESS,
2362 &spr_read_generic, &spr_write_generic,
2364 spr_register(env, SPR_SPRG5, "SPRG5",
2365 SPR_NOACCESS, SPR_NOACCESS,
2366 spr_read_generic, &spr_write_generic,
2368 spr_register(env, SPR_SPRG6, "SPRG6",
2369 SPR_NOACCESS, SPR_NOACCESS,
2370 spr_read_generic, &spr_write_generic,
2372 spr_register(env, SPR_SPRG7, "SPRG7",
2373 SPR_NOACCESS, SPR_NOACCESS,
2374 spr_read_generic, &spr_write_generic,
2376 gen_spr_usprgh(env);
2379 /* SPR shared between PowerPC 401 & 403 implementations */
2380 static void gen_spr_401_403(CPUPPCState *env)
2383 spr_register(env, SPR_403_VTBL, "TBL",
2384 &spr_read_tbl, SPR_NOACCESS,
2385 &spr_read_tbl, SPR_NOACCESS,
2387 spr_register(env, SPR_403_TBL, "TBL",
2388 SPR_NOACCESS, SPR_NOACCESS,
2389 SPR_NOACCESS, &spr_write_tbl,
2391 spr_register(env, SPR_403_VTBU, "TBU",
2392 &spr_read_tbu, SPR_NOACCESS,
2393 &spr_read_tbu, SPR_NOACCESS,
2395 spr_register(env, SPR_403_TBU, "TBU",
2396 SPR_NOACCESS, SPR_NOACCESS,
2397 SPR_NOACCESS, &spr_write_tbu,
2400 /* not emulated, as QEMU do not emulate caches */
2401 spr_register(env, SPR_403_CDBCR, "CDBCR",
2402 SPR_NOACCESS, SPR_NOACCESS,
2403 &spr_read_generic, &spr_write_generic,
2407 /* SPR specific to PowerPC 401 implementation */
2408 static void gen_spr_401(CPUPPCState *env)
2410 /* Debug interface */
2411 /* XXX : not implemented */
2412 spr_register(env, SPR_40x_DBCR0, "DBCR",
2413 SPR_NOACCESS, SPR_NOACCESS,
2414 &spr_read_generic, &spr_write_40x_dbcr0,
2416 /* XXX : not implemented */
2417 spr_register(env, SPR_40x_DBSR, "DBSR",
2418 SPR_NOACCESS, SPR_NOACCESS,
2419 &spr_read_generic, &spr_write_clear,
2420 /* Last reset was system reset */
2422 /* XXX : not implemented */
2423 spr_register(env, SPR_40x_DAC1, "DAC",
2424 SPR_NOACCESS, SPR_NOACCESS,
2425 &spr_read_generic, &spr_write_generic,
2427 /* XXX : not implemented */
2428 spr_register(env, SPR_40x_IAC1, "IAC",
2429 SPR_NOACCESS, SPR_NOACCESS,
2430 &spr_read_generic, &spr_write_generic,
2432 /* Storage control */
2433 /* XXX: TODO: not implemented */
2434 spr_register(env, SPR_405_SLER, "SLER",
2435 SPR_NOACCESS, SPR_NOACCESS,
2436 &spr_read_generic, &spr_write_40x_sler,
2438 /* not emulated, as QEMU never does speculative access */
2439 spr_register(env, SPR_40x_SGR, "SGR",
2440 SPR_NOACCESS, SPR_NOACCESS,
2441 &spr_read_generic, &spr_write_generic,
2443 /* not emulated, as QEMU do not emulate caches */
2444 spr_register(env, SPR_40x_DCWR, "DCWR",
2445 SPR_NOACCESS, SPR_NOACCESS,
2446 &spr_read_generic, &spr_write_generic,
2450 static void gen_spr_401x2(CPUPPCState *env)
2453 spr_register(env, SPR_40x_PID, "PID",
2454 SPR_NOACCESS, SPR_NOACCESS,
2455 &spr_read_generic, &spr_write_generic,
2457 spr_register(env, SPR_40x_ZPR, "ZPR",
2458 SPR_NOACCESS, SPR_NOACCESS,
2459 &spr_read_generic, &spr_write_generic,
2463 /* SPR specific to PowerPC 403 implementation */
2464 static void gen_spr_403(CPUPPCState *env)
2466 /* Debug interface */
2467 /* XXX : not implemented */
2468 spr_register(env, SPR_40x_DBCR0, "DBCR0",
2469 SPR_NOACCESS, SPR_NOACCESS,
2470 &spr_read_generic, &spr_write_40x_dbcr0,
2472 /* XXX : not implemented */
2473 spr_register(env, SPR_40x_DBSR, "DBSR",
2474 SPR_NOACCESS, SPR_NOACCESS,
2475 &spr_read_generic, &spr_write_clear,
2476 /* Last reset was system reset */
2478 /* XXX : not implemented */
2479 spr_register(env, SPR_40x_DAC1, "DAC1",
2480 SPR_NOACCESS, SPR_NOACCESS,
2481 &spr_read_generic, &spr_write_generic,
2483 /* XXX : not implemented */
2484 spr_register(env, SPR_40x_DAC2, "DAC2",
2485 SPR_NOACCESS, SPR_NOACCESS,
2486 &spr_read_generic, &spr_write_generic,
2488 /* XXX : not implemented */
2489 spr_register(env, SPR_40x_IAC1, "IAC1",
2490 SPR_NOACCESS, SPR_NOACCESS,
2491 &spr_read_generic, &spr_write_generic,
2493 /* XXX : not implemented */
2494 spr_register(env, SPR_40x_IAC2, "IAC2",
2495 SPR_NOACCESS, SPR_NOACCESS,
2496 &spr_read_generic, &spr_write_generic,
2500 static void gen_spr_403_real(CPUPPCState *env)
2502 spr_register(env, SPR_403_PBL1, "PBL1",
2503 SPR_NOACCESS, SPR_NOACCESS,
2504 &spr_read_403_pbr, &spr_write_403_pbr,
2506 spr_register(env, SPR_403_PBU1, "PBU1",
2507 SPR_NOACCESS, SPR_NOACCESS,
2508 &spr_read_403_pbr, &spr_write_403_pbr,
2510 spr_register(env, SPR_403_PBL2, "PBL2",
2511 SPR_NOACCESS, SPR_NOACCESS,
2512 &spr_read_403_pbr, &spr_write_403_pbr,
2514 spr_register(env, SPR_403_PBU2, "PBU2",
2515 SPR_NOACCESS, SPR_NOACCESS,
2516 &spr_read_403_pbr, &spr_write_403_pbr,
2520 static void gen_spr_403_mmu(CPUPPCState *env)
2523 spr_register(env, SPR_40x_PID, "PID",
2524 SPR_NOACCESS, SPR_NOACCESS,
2525 &spr_read_generic, &spr_write_generic,
2527 spr_register(env, SPR_40x_ZPR, "ZPR",
2528 SPR_NOACCESS, SPR_NOACCESS,
2529 &spr_read_generic, &spr_write_generic,
2533 /* SPR specific to PowerPC compression coprocessor extension */
2534 static void gen_spr_compress(CPUPPCState *env)
2536 /* XXX : not implemented */
2537 spr_register(env, SPR_401_SKR, "SKR",
2538 SPR_NOACCESS, SPR_NOACCESS,
2539 &spr_read_generic, &spr_write_generic,
2543 static void gen_spr_5xx_8xx(CPUPPCState *env)
2545 /* Exception processing */
2546 spr_register_kvm(env, SPR_DSISR, "DSISR",
2547 SPR_NOACCESS, SPR_NOACCESS,
2548 &spr_read_generic, &spr_write_generic,
2549 KVM_REG_PPC_DSISR, 0x00000000);
2550 spr_register_kvm(env, SPR_DAR, "DAR",
2551 SPR_NOACCESS, SPR_NOACCESS,
2552 &spr_read_generic, &spr_write_generic,
2553 KVM_REG_PPC_DAR, 0x00000000);
2555 spr_register(env, SPR_DECR, "DECR",
2556 SPR_NOACCESS, SPR_NOACCESS,
2557 &spr_read_decr, &spr_write_decr,
2559 /* XXX : not implemented */
2560 spr_register(env, SPR_MPC_EIE, "EIE",
2561 SPR_NOACCESS, SPR_NOACCESS,
2562 &spr_read_generic, &spr_write_generic,
2564 /* XXX : not implemented */
2565 spr_register(env, SPR_MPC_EID, "EID",
2566 SPR_NOACCESS, SPR_NOACCESS,
2567 &spr_read_generic, &spr_write_generic,
2569 /* XXX : not implemented */
2570 spr_register(env, SPR_MPC_NRI, "NRI",
2571 SPR_NOACCESS, SPR_NOACCESS,
2572 &spr_read_generic, &spr_write_generic,
2574 /* XXX : not implemented */
2575 spr_register(env, SPR_MPC_CMPA, "CMPA",
2576 SPR_NOACCESS, SPR_NOACCESS,
2577 &spr_read_generic, &spr_write_generic,
2579 /* XXX : not implemented */
2580 spr_register(env, SPR_MPC_CMPB, "CMPB",
2581 SPR_NOACCESS, SPR_NOACCESS,
2582 &spr_read_generic, &spr_write_generic,
2584 /* XXX : not implemented */
2585 spr_register(env, SPR_MPC_CMPC, "CMPC",
2586 SPR_NOACCESS, SPR_NOACCESS,
2587 &spr_read_generic, &spr_write_generic,
2589 /* XXX : not implemented */
2590 spr_register(env, SPR_MPC_CMPD, "CMPD",
2591 SPR_NOACCESS, SPR_NOACCESS,
2592 &spr_read_generic, &spr_write_generic,
2594 /* XXX : not implemented */
2595 spr_register(env, SPR_MPC_ECR, "ECR",
2596 SPR_NOACCESS, SPR_NOACCESS,
2597 &spr_read_generic, &spr_write_generic,
2599 /* XXX : not implemented */
2600 spr_register(env, SPR_MPC_DER, "DER",
2601 SPR_NOACCESS, SPR_NOACCESS,
2602 &spr_read_generic, &spr_write_generic,
2604 /* XXX : not implemented */
2605 spr_register(env, SPR_MPC_COUNTA, "COUNTA",
2606 SPR_NOACCESS, SPR_NOACCESS,
2607 &spr_read_generic, &spr_write_generic,
2609 /* XXX : not implemented */
2610 spr_register(env, SPR_MPC_COUNTB, "COUNTB",
2611 SPR_NOACCESS, SPR_NOACCESS,
2612 &spr_read_generic, &spr_write_generic,
2614 /* XXX : not implemented */
2615 spr_register(env, SPR_MPC_CMPE, "CMPE",
2616 SPR_NOACCESS, SPR_NOACCESS,
2617 &spr_read_generic, &spr_write_generic,
2619 /* XXX : not implemented */
2620 spr_register(env, SPR_MPC_CMPF, "CMPF",
2621 SPR_NOACCESS, SPR_NOACCESS,
2622 &spr_read_generic, &spr_write_generic,
2624 /* XXX : not implemented */
2625 spr_register(env, SPR_MPC_CMPG, "CMPG",
2626 SPR_NOACCESS, SPR_NOACCESS,
2627 &spr_read_generic, &spr_write_generic,
2629 /* XXX : not implemented */
2630 spr_register(env, SPR_MPC_CMPH, "CMPH",
2631 SPR_NOACCESS, SPR_NOACCESS,
2632 &spr_read_generic, &spr_write_generic,
2634 /* XXX : not implemented */
2635 spr_register(env, SPR_MPC_LCTRL1, "LCTRL1",
2636 SPR_NOACCESS, SPR_NOACCESS,
2637 &spr_read_generic, &spr_write_generic,
2639 /* XXX : not implemented */
2640 spr_register(env, SPR_MPC_LCTRL2, "LCTRL2",
2641 SPR_NOACCESS, SPR_NOACCESS,
2642 &spr_read_generic, &spr_write_generic,
2644 /* XXX : not implemented */
2645 spr_register(env, SPR_MPC_BAR, "BAR",
2646 SPR_NOACCESS, SPR_NOACCESS,
2647 &spr_read_generic, &spr_write_generic,
2649 /* XXX : not implemented */
2650 spr_register(env, SPR_MPC_DPDR, "DPDR",
2651 SPR_NOACCESS, SPR_NOACCESS,
2652 &spr_read_generic, &spr_write_generic,
2654 /* XXX : not implemented */
2655 spr_register(env, SPR_MPC_IMMR, "IMMR",
2656 SPR_NOACCESS, SPR_NOACCESS,
2657 &spr_read_generic, &spr_write_generic,
2661 static void gen_spr_5xx(CPUPPCState *env)
2663 /* XXX : not implemented */
2664 spr_register(env, SPR_RCPU_MI_GRA, "MI_GRA",
2665 SPR_NOACCESS, SPR_NOACCESS,
2666 &spr_read_generic, &spr_write_generic,
2668 /* XXX : not implemented */
2669 spr_register(env, SPR_RCPU_L2U_GRA, "L2U_GRA",
2670 SPR_NOACCESS, SPR_NOACCESS,
2671 &spr_read_generic, &spr_write_generic,
2673 /* XXX : not implemented */
2674 spr_register(env, SPR_RPCU_BBCMCR, "L2U_BBCMCR",
2675 SPR_NOACCESS, SPR_NOACCESS,
2676 &spr_read_generic, &spr_write_generic,
2678 /* XXX : not implemented */
2679 spr_register(env, SPR_RCPU_L2U_MCR, "L2U_MCR",
2680 SPR_NOACCESS, SPR_NOACCESS,
2681 &spr_read_generic, &spr_write_generic,
2683 /* XXX : not implemented */
2684 spr_register(env, SPR_RCPU_MI_RBA0, "MI_RBA0",
2685 SPR_NOACCESS, SPR_NOACCESS,
2686 &spr_read_generic, &spr_write_generic,
2688 /* XXX : not implemented */
2689 spr_register(env, SPR_RCPU_MI_RBA1, "MI_RBA1",
2690 SPR_NOACCESS, SPR_NOACCESS,
2691 &spr_read_generic, &spr_write_generic,
2693 /* XXX : not implemented */
2694 spr_register(env, SPR_RCPU_MI_RBA2, "MI_RBA2",
2695 SPR_NOACCESS, SPR_NOACCESS,
2696 &spr_read_generic, &spr_write_generic,
2698 /* XXX : not implemented */
2699 spr_register(env, SPR_RCPU_MI_RBA3, "MI_RBA3",
2700 SPR_NOACCESS, SPR_NOACCESS,
2701 &spr_read_generic, &spr_write_generic,
2703 /* XXX : not implemented */
2704 spr_register(env, SPR_RCPU_L2U_RBA0, "L2U_RBA0",
2705 SPR_NOACCESS, SPR_NOACCESS,
2706 &spr_read_generic, &spr_write_generic,
2708 /* XXX : not implemented */
2709 spr_register(env, SPR_RCPU_L2U_RBA1, "L2U_RBA1",
2710 SPR_NOACCESS, SPR_NOACCESS,
2711 &spr_read_generic, &spr_write_generic,
2713 /* XXX : not implemented */
2714 spr_register(env, SPR_RCPU_L2U_RBA2, "L2U_RBA2",
2715 SPR_NOACCESS, SPR_NOACCESS,
2716 &spr_read_generic, &spr_write_generic,
2718 /* XXX : not implemented */
2719 spr_register(env, SPR_RCPU_L2U_RBA3, "L2U_RBA3",
2720 SPR_NOACCESS, SPR_NOACCESS,
2721 &spr_read_generic, &spr_write_generic,
2723 /* XXX : not implemented */
2724 spr_register(env, SPR_RCPU_MI_RA0, "MI_RA0",
2725 SPR_NOACCESS, SPR_NOACCESS,
2726 &spr_read_generic, &spr_write_generic,
2728 /* XXX : not implemented */
2729 spr_register(env, SPR_RCPU_MI_RA1, "MI_RA1",
2730 SPR_NOACCESS, SPR_NOACCESS,
2731 &spr_read_generic, &spr_write_generic,
2733 /* XXX : not implemented */
2734 spr_register(env, SPR_RCPU_MI_RA2, "MI_RA2",
2735 SPR_NOACCESS, SPR_NOACCESS,
2736 &spr_read_generic, &spr_write_generic,
2738 /* XXX : not implemented */
2739 spr_register(env, SPR_RCPU_MI_RA3, "MI_RA3",
2740 SPR_NOACCESS, SPR_NOACCESS,
2741 &spr_read_generic, &spr_write_generic,
2743 /* XXX : not implemented */
2744 spr_register(env, SPR_RCPU_L2U_RA0, "L2U_RA0",
2745 SPR_NOACCESS, SPR_NOACCESS,
2746 &spr_read_generic, &spr_write_generic,
2748 /* XXX : not implemented */
2749 spr_register(env, SPR_RCPU_L2U_RA1, "L2U_RA1",
2750 SPR_NOACCESS, SPR_NOACCESS,
2751 &spr_read_generic, &spr_write_generic,
2753 /* XXX : not implemented */
2754 spr_register(env, SPR_RCPU_L2U_RA2, "L2U_RA2",
2755 SPR_NOACCESS, SPR_NOACCESS,
2756 &spr_read_generic, &spr_write_generic,
2758 /* XXX : not implemented */
2759 spr_register(env, SPR_RCPU_L2U_RA3, "L2U_RA3",
2760 SPR_NOACCESS, SPR_NOACCESS,
2761 &spr_read_generic, &spr_write_generic,
2763 /* XXX : not implemented */
2764 spr_register(env, SPR_RCPU_FPECR, "FPECR",
2765 SPR_NOACCESS, SPR_NOACCESS,
2766 &spr_read_generic, &spr_write_generic,
2770 static void gen_spr_8xx(CPUPPCState *env)
2772 /* XXX : not implemented */
2773 spr_register(env, SPR_MPC_IC_CST, "IC_CST",
2774 SPR_NOACCESS, SPR_NOACCESS,
2775 &spr_read_generic, &spr_write_generic,
2777 /* XXX : not implemented */
2778 spr_register(env, SPR_MPC_IC_ADR, "IC_ADR",
2779 SPR_NOACCESS, SPR_NOACCESS,
2780 &spr_read_generic, &spr_write_generic,
2782 /* XXX : not implemented */
2783 spr_register(env, SPR_MPC_IC_DAT, "IC_DAT",
2784 SPR_NOACCESS, SPR_NOACCESS,
2785 &spr_read_generic, &spr_write_generic,
2787 /* XXX : not implemented */
2788 spr_register(env, SPR_MPC_DC_CST, "DC_CST",
2789 SPR_NOACCESS, SPR_NOACCESS,
2790 &spr_read_generic, &spr_write_generic,
2792 /* XXX : not implemented */
2793 spr_register(env, SPR_MPC_DC_ADR, "DC_ADR",
2794 SPR_NOACCESS, SPR_NOACCESS,
2795 &spr_read_generic, &spr_write_generic,
2797 /* XXX : not implemented */
2798 spr_register(env, SPR_MPC_DC_DAT, "DC_DAT",
2799 SPR_NOACCESS, SPR_NOACCESS,
2800 &spr_read_generic, &spr_write_generic,
2802 /* XXX : not implemented */
2803 spr_register(env, SPR_MPC_MI_CTR, "MI_CTR",
2804 SPR_NOACCESS, SPR_NOACCESS,
2805 &spr_read_generic, &spr_write_generic,
2807 /* XXX : not implemented */
2808 spr_register(env, SPR_MPC_MI_AP, "MI_AP",
2809 SPR_NOACCESS, SPR_NOACCESS,
2810 &spr_read_generic, &spr_write_generic,
2812 /* XXX : not implemented */
2813 spr_register(env, SPR_MPC_MI_EPN, "MI_EPN",
2814 SPR_NOACCESS, SPR_NOACCESS,
2815 &spr_read_generic, &spr_write_generic,
2817 /* XXX : not implemented */
2818 spr_register(env, SPR_MPC_MI_TWC, "MI_TWC",
2819 SPR_NOACCESS, SPR_NOACCESS,
2820 &spr_read_generic, &spr_write_generic,
2822 /* XXX : not implemented */
2823 spr_register(env, SPR_MPC_MI_RPN, "MI_RPN",
2824 SPR_NOACCESS, SPR_NOACCESS,
2825 &spr_read_generic, &spr_write_generic,
2827 /* XXX : not implemented */
2828 spr_register(env, SPR_MPC_MI_DBCAM, "MI_DBCAM",
2829 SPR_NOACCESS, SPR_NOACCESS,
2830 &spr_read_generic, &spr_write_generic,
2832 /* XXX : not implemented */
2833 spr_register(env, SPR_MPC_MI_DBRAM0, "MI_DBRAM0",
2834 SPR_NOACCESS, SPR_NOACCESS,
2835 &spr_read_generic, &spr_write_generic,
2837 /* XXX : not implemented */
2838 spr_register(env, SPR_MPC_MI_DBRAM1, "MI_DBRAM1",
2839 SPR_NOACCESS, SPR_NOACCESS,
2840 &spr_read_generic, &spr_write_generic,
2842 /* XXX : not implemented */
2843 spr_register(env, SPR_MPC_MD_CTR, "MD_CTR",
2844 SPR_NOACCESS, SPR_NOACCESS,
2845 &spr_read_generic, &spr_write_generic,
2847 /* XXX : not implemented */
2848 spr_register(env, SPR_MPC_MD_CASID, "MD_CASID",
2849 SPR_NOACCESS, SPR_NOACCESS,
2850 &spr_read_generic, &spr_write_generic,
2852 /* XXX : not implemented */
2853 spr_register(env, SPR_MPC_MD_AP, "MD_AP",
2854 SPR_NOACCESS, SPR_NOACCESS,
2855 &spr_read_generic, &spr_write_generic,
2857 /* XXX : not implemented */
2858 spr_register(env, SPR_MPC_MD_EPN, "MD_EPN",
2859 SPR_NOACCESS, SPR_NOACCESS,
2860 &spr_read_generic, &spr_write_generic,
2862 /* XXX : not implemented */
2863 spr_register(env, SPR_MPC_MD_TWB, "MD_TWB",
2864 SPR_NOACCESS, SPR_NOACCESS,
2865 &spr_read_generic, &spr_write_generic,
2867 /* XXX : not implemented */
2868 spr_register(env, SPR_MPC_MD_TWC, "MD_TWC",
2869 SPR_NOACCESS, SPR_NOACCESS,
2870 &spr_read_generic, &spr_write_generic,
2872 /* XXX : not implemented */
2873 spr_register(env, SPR_MPC_MD_RPN, "MD_RPN",
2874 SPR_NOACCESS, SPR_NOACCESS,
2875 &spr_read_generic, &spr_write_generic,
2877 /* XXX : not implemented */
2878 spr_register(env, SPR_MPC_MD_TW, "MD_TW",
2879 SPR_NOACCESS, SPR_NOACCESS,
2880 &spr_read_generic, &spr_write_generic,
2882 /* XXX : not implemented */
2883 spr_register(env, SPR_MPC_MD_DBCAM, "MD_DBCAM",
2884 SPR_NOACCESS, SPR_NOACCESS,
2885 &spr_read_generic, &spr_write_generic,
2887 /* XXX : not implemented */
2888 spr_register(env, SPR_MPC_MD_DBRAM0, "MD_DBRAM0",
2889 SPR_NOACCESS, SPR_NOACCESS,
2890 &spr_read_generic, &spr_write_generic,
2892 /* XXX : not implemented */
2893 spr_register(env, SPR_MPC_MD_DBRAM1, "MD_DBRAM1",
2894 SPR_NOACCESS, SPR_NOACCESS,
2895 &spr_read_generic, &spr_write_generic,
2900 * AMR => SPR 29 (Power 2.04)
2901 * CTRL => SPR 136 (Power 2.04)
2902 * CTRL => SPR 152 (Power 2.04)
2903 * SCOMC => SPR 276 (64 bits ?)
2904 * SCOMD => SPR 277 (64 bits ?)
2905 * TBU40 => SPR 286 (Power 2.04 hypv)
2906 * HSPRG0 => SPR 304 (Power 2.04 hypv)
2907 * HSPRG1 => SPR 305 (Power 2.04 hypv)
2908 * HDSISR => SPR 306 (Power 2.04 hypv)
2909 * HDAR => SPR 307 (Power 2.04 hypv)
2910 * PURR => SPR 309 (Power 2.04 hypv)
2911 * HDEC => SPR 310 (Power 2.04 hypv)
2912 * HIOR => SPR 311 (hypv)
2913 * RMOR => SPR 312 (970)
2914 * HRMOR => SPR 313 (Power 2.04 hypv)
2915 * HSRR0 => SPR 314 (Power 2.04 hypv)
2916 * HSRR1 => SPR 315 (Power 2.04 hypv)
2917 * LPIDR => SPR 317 (970)
2918 * EPR => SPR 702 (Power 2.04 emb)
2919 * perf => 768-783 (Power 2.04)
2920 * perf => 784-799 (Power 2.04)
2921 * PPR => SPR 896 (Power 2.04)
2922 * DABRX => 1015 (Power 2.04 hypv)
2923 * FPECR => SPR 1022 (?)
2924 * ... and more (thermal management, performance counters, ...)
2927 /*****************************************************************************/
2928 /* Exception vectors models */
2929 static void init_excp_4xx_real(CPUPPCState *env)
2931 #if !defined(CONFIG_USER_ONLY)
2932 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000100;
2933 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
2934 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
2935 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
2936 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
2937 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
2938 env->excp_vectors[POWERPC_EXCP_PIT] = 0x00001000;
2939 env->excp_vectors[POWERPC_EXCP_FIT] = 0x00001010;
2940 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001020;
2941 env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000;
2942 env->ivor_mask = 0x0000FFF0UL;
2943 env->ivpr_mask = 0xFFFF0000UL;
2944 /* Hardware reset vector */
2945 env->hreset_vector = 0xFFFFFFFCUL;
2949 static void init_excp_4xx_softmmu(CPUPPCState *env)
2951 #if !defined(CONFIG_USER_ONLY)
2952 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000100;
2953 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
2954 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
2955 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
2956 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
2957 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
2958 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
2959 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
2960 env->excp_vectors[POWERPC_EXCP_PIT] = 0x00001000;
2961 env->excp_vectors[POWERPC_EXCP_FIT] = 0x00001010;
2962 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001020;
2963 env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001100;
2964 env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001200;
2965 env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000;
2966 env->ivor_mask = 0x0000FFF0UL;
2967 env->ivpr_mask = 0xFFFF0000UL;
2968 /* Hardware reset vector */
2969 env->hreset_vector = 0xFFFFFFFCUL;
2973 static void init_excp_MPC5xx(CPUPPCState *env)
2975 #if !defined(CONFIG_USER_ONLY)
2976 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
2977 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
2978 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
2979 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
2980 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
2981 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000900;
2982 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
2983 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
2984 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
2985 env->excp_vectors[POWERPC_EXCP_FPA] = 0x00000E00;
2986 env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001000;
2987 env->excp_vectors[POWERPC_EXCP_DABR] = 0x00001C00;
2988 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001C00;
2989 env->excp_vectors[POWERPC_EXCP_MEXTBR] = 0x00001E00;
2990 env->excp_vectors[POWERPC_EXCP_NMEXTBR] = 0x00001F00;
2991 env->ivor_mask = 0x0000FFF0UL;
2992 env->ivpr_mask = 0xFFFF0000UL;
2993 /* Hardware reset vector */
2994 env->hreset_vector = 0x00000100UL;
2998 static void init_excp_MPC8xx(CPUPPCState *env)
3000 #if !defined(CONFIG_USER_ONLY)
3001 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3002 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3003 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3004 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3005 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3006 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3007 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3008 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000900;
3009 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3010 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3011 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3012 env->excp_vectors[POWERPC_EXCP_FPA] = 0x00000E00;
3013 env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001000;
3014 env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001100;
3015 env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001200;
3016 env->excp_vectors[POWERPC_EXCP_ITLBE] = 0x00001300;
3017 env->excp_vectors[POWERPC_EXCP_DTLBE] = 0x00001400;
3018 env->excp_vectors[POWERPC_EXCP_DABR] = 0x00001C00;
3019 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001C00;
3020 env->excp_vectors[POWERPC_EXCP_MEXTBR] = 0x00001E00;
3021 env->excp_vectors[POWERPC_EXCP_NMEXTBR] = 0x00001F00;
3022 env->ivor_mask = 0x0000FFF0UL;
3023 env->ivpr_mask = 0xFFFF0000UL;
3024 /* Hardware reset vector */
3025 env->hreset_vector = 0x00000100UL;
3029 static void init_excp_G2(CPUPPCState *env)
3031 #if !defined(CONFIG_USER_ONLY)
3032 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3033 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3034 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3035 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3036 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3037 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3038 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3039 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3040 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3041 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000A00;
3042 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3043 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3044 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
3045 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
3046 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
3047 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3048 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3049 /* Hardware reset vector */
3050 env->hreset_vector = 0x00000100UL;
3054 static void init_excp_e200(CPUPPCState *env, target_ulong ivpr_mask)
3056 #if !defined(CONFIG_USER_ONLY)
3057 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000FFC;
3058 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000000;
3059 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000000;
3060 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000000;
3061 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000000;
3062 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000000;
3063 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000000;
3064 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000000;
3065 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000000;
3066 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000000;
3067 env->excp_vectors[POWERPC_EXCP_APU] = 0x00000000;
3068 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000000;
3069 env->excp_vectors[POWERPC_EXCP_FIT] = 0x00000000;
3070 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00000000;
3071 env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00000000;
3072 env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00000000;
3073 env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00000000;
3074 env->excp_vectors[POWERPC_EXCP_SPEU] = 0x00000000;
3075 env->excp_vectors[POWERPC_EXCP_EFPDI] = 0x00000000;
3076 env->excp_vectors[POWERPC_EXCP_EFPRI] = 0x00000000;
3077 env->ivor_mask = 0x0000FFF7UL;
3078 env->ivpr_mask = ivpr_mask;
3079 /* Hardware reset vector */
3080 env->hreset_vector = 0xFFFFFFFCUL;
3084 static void init_excp_BookE(CPUPPCState *env)
3086 #if !defined(CONFIG_USER_ONLY)
3087 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000000;
3088 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000000;
3089 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000000;
3090 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000000;
3091 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000000;
3092 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000000;
3093 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000000;
3094 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000000;
3095 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000000;
3096 env->excp_vectors[POWERPC_EXCP_APU] = 0x00000000;
3097 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000000;
3098 env->excp_vectors[POWERPC_EXCP_FIT] = 0x00000000;
3099 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00000000;
3100 env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00000000;
3101 env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00000000;
3102 env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00000000;
3103 env->ivor_mask = 0x0000FFF0UL;
3104 env->ivpr_mask = 0xFFFF0000UL;
3105 /* Hardware reset vector */
3106 env->hreset_vector = 0xFFFFFFFCUL;
3110 static void init_excp_601(CPUPPCState *env)
3112 #if !defined(CONFIG_USER_ONLY)
3113 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3114 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3115 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3116 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3117 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3118 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3119 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3120 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3121 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3122 env->excp_vectors[POWERPC_EXCP_IO] = 0x00000A00;
3123 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3124 env->excp_vectors[POWERPC_EXCP_RUNM] = 0x00002000;
3125 /* Hardware reset vector */
3126 env->hreset_vector = 0x00000100UL;
3130 static void init_excp_602(CPUPPCState *env)
3132 #if !defined(CONFIG_USER_ONLY)
3133 /* XXX: exception prefix has a special behavior on 602 */
3134 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3135 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3136 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3137 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3138 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3139 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3140 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3141 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3142 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3143 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3144 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3145 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
3146 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
3147 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
3148 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3149 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3150 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001500;
3151 env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001600;
3152 /* Hardware reset vector */
3153 env->hreset_vector = 0x00000100UL;
3157 static void init_excp_603(CPUPPCState *env)
3159 #if !defined(CONFIG_USER_ONLY)
3160 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3161 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3162 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3163 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3164 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3165 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3166 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3167 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3168 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3169 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3170 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3171 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
3172 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
3173 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
3174 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3175 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3176 /* Hardware reset vector */
3177 env->hreset_vector = 0x00000100UL;
3181 static void init_excp_604(CPUPPCState *env)
3183 #if !defined(CONFIG_USER_ONLY)
3184 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3185 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3186 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3187 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3188 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3189 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3190 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3191 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3192 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3193 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3194 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3195 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3196 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3197 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3198 /* Hardware reset vector */
3199 env->hreset_vector = 0x00000100UL;
3203 static void init_excp_7x0(CPUPPCState *env)
3205 #if !defined(CONFIG_USER_ONLY)
3206 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3207 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3208 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3209 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3210 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3211 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3212 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3213 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3214 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3215 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3216 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3217 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3218 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3219 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3220 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
3221 /* Hardware reset vector */
3222 env->hreset_vector = 0x00000100UL;
3226 static void init_excp_750cl(CPUPPCState *env)
3228 #if !defined(CONFIG_USER_ONLY)
3229 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3230 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3231 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3232 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3233 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3234 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3235 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3236 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3237 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3238 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3239 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3240 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3241 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3242 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3243 /* Hardware reset vector */
3244 env->hreset_vector = 0x00000100UL;
3248 static void init_excp_750cx(CPUPPCState *env)
3250 #if !defined(CONFIG_USER_ONLY)
3251 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3252 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3253 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3254 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3255 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3256 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3257 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3258 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3259 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3260 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3261 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3262 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3263 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3264 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
3265 /* Hardware reset vector */
3266 env->hreset_vector = 0x00000100UL;
3270 /* XXX: Check if this is correct */
3271 static void init_excp_7x5(CPUPPCState *env)
3273 #if !defined(CONFIG_USER_ONLY)
3274 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3275 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3276 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3277 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3278 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3279 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3280 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3281 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3282 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3283 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3284 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3285 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3286 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
3287 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
3288 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
3289 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3290 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3291 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
3292 /* Hardware reset vector */
3293 env->hreset_vector = 0x00000100UL;
3297 static void init_excp_7400(CPUPPCState *env)
3299 #if !defined(CONFIG_USER_ONLY)
3300 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3301 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3302 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3303 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3304 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3305 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3306 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3307 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3308 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3309 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3310 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3311 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3312 env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
3313 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3314 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3315 env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600;
3316 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
3317 /* Hardware reset vector */
3318 env->hreset_vector = 0x00000100UL;
3322 static void init_excp_7450(CPUPPCState *env)
3324 #if !defined(CONFIG_USER_ONLY)
3325 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3326 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3327 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3328 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3329 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3330 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3331 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3332 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3333 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3334 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3335 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3336 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3337 env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
3338 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
3339 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
3340 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
3341 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3342 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3343 env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600;
3344 /* Hardware reset vector */
3345 env->hreset_vector = 0x00000100UL;
3349 #if defined(TARGET_PPC64)
3350 static void init_excp_970(CPUPPCState *env)
3352 #if !defined(CONFIG_USER_ONLY)
3353 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3354 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3355 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3356 env->excp_vectors[POWERPC_EXCP_DSEG] = 0x00000380;
3357 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3358 env->excp_vectors[POWERPC_EXCP_ISEG] = 0x00000480;
3359 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3360 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3361 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3362 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3363 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3364 env->excp_vectors[POWERPC_EXCP_HDECR] = 0x00000980;
3365 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3366 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3367 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3368 env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
3369 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3370 env->excp_vectors[POWERPC_EXCP_MAINT] = 0x00001600;
3371 env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001700;
3372 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001800;
3373 /* Hardware reset vector */
3374 env->hreset_vector = 0x0000000000000100ULL;
3378 static void init_excp_POWER7(CPUPPCState *env)
3380 #if !defined(CONFIG_USER_ONLY)
3381 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3382 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3383 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3384 env->excp_vectors[POWERPC_EXCP_DSEG] = 0x00000380;
3385 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3386 env->excp_vectors[POWERPC_EXCP_ISEG] = 0x00000480;
3387 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3388 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3389 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3390 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3391 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3392 env->excp_vectors[POWERPC_EXCP_HDECR] = 0x00000980;
3393 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3394 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3395 env->excp_vectors[POWERPC_EXCP_HDSI] = 0x00000E00;
3396 env->excp_vectors[POWERPC_EXCP_HISI] = 0x00000E20;
3397 env->excp_vectors[POWERPC_EXCP_HV_EMU] = 0x00000E40;
3398 env->excp_vectors[POWERPC_EXCP_HV_MAINT] = 0x00000E60;
3399 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3400 env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
3401 env->excp_vectors[POWERPC_EXCP_VSXU] = 0x00000F40;
3402 /* Hardware reset vector */
3403 env->hreset_vector = 0x0000000000000100ULL;
3407 static void init_excp_POWER8(CPUPPCState *env)
3409 init_excp_POWER7(env);
3411 #if !defined(CONFIG_USER_ONLY)
3412 env->excp_vectors[POWERPC_EXCP_SDOOR] = 0x00000A00;
3413 env->excp_vectors[POWERPC_EXCP_FU] = 0x00000F60;
3414 env->excp_vectors[POWERPC_EXCP_HV_FU] = 0x00000F80;
3415 env->excp_vectors[POWERPC_EXCP_SDOOR_HV] = 0x00000E80;
3419 static void init_excp_POWER9(CPUPPCState *env)
3421 init_excp_POWER8(env);
3423 #if !defined(CONFIG_USER_ONLY)
3424 env->excp_vectors[POWERPC_EXCP_HVIRT] = 0x00000EA0;
3425 env->excp_vectors[POWERPC_EXCP_SYSCALL_VECTORED] = 0x00000000;
3429 static void init_excp_POWER10(CPUPPCState *env)
3431 init_excp_POWER9(env);
3436 /*****************************************************************************/
3437 /* Power management enable checks */
3438 static int check_pow_none(CPUPPCState *env)
3443 static int check_pow_nocheck(CPUPPCState *env)
3448 static int check_pow_hid0(CPUPPCState *env)
3450 if (env->spr[SPR_HID0] & 0x00E00000) {
3457 static int check_pow_hid0_74xx(CPUPPCState *env)
3459 if (env->spr[SPR_HID0] & 0x00600000) {
3466 static bool ppc_cpu_interrupts_big_endian_always(PowerPCCPU *cpu)
3472 static bool ppc_cpu_interrupts_big_endian_lpcr(PowerPCCPU *cpu)
3474 return !(cpu->env.spr[SPR_LPCR] & LPCR_ILE);
3478 /*****************************************************************************/
3479 /* PowerPC implementations definitions */
3481 #define POWERPC_FAMILY(_name) \
3483 glue(glue(ppc_, _name), _cpu_family_class_init)(ObjectClass *, void *); \
3485 static const TypeInfo \
3486 glue(glue(ppc_, _name), _cpu_family_type_info) = { \
3487 .name = stringify(_name) "-family-" TYPE_POWERPC_CPU, \
3488 .parent = TYPE_POWERPC_CPU, \
3490 .class_init = glue(glue(ppc_, _name), _cpu_family_class_init), \
3493 static void glue(glue(ppc_, _name), _cpu_family_register_types)(void) \
3495 type_register_static( \
3496 &glue(glue(ppc_, _name), _cpu_family_type_info)); \
3499 type_init(glue(glue(ppc_, _name), _cpu_family_register_types)) \
3501 static void glue(glue(ppc_, _name), _cpu_family_class_init)
3503 static void init_proc_401(CPUPPCState *env)
3506 gen_spr_401_403(env);
3508 init_excp_4xx_real(env);
3509 env->dcache_line_size = 32;
3510 env->icache_line_size = 32;
3511 /* Allocate hardware IRQ controller */
3512 ppc40x_irq_init(env_archcpu(env));
3514 SET_FIT_PERIOD(12, 16, 20, 24);
3515 SET_WDT_PERIOD(16, 20, 24, 28);
3518 POWERPC_FAMILY(401)(ObjectClass *oc, void *data)
3520 DeviceClass *dc = DEVICE_CLASS(oc);
3521 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3523 dc->desc = "PowerPC 401";
3524 pcc->init_proc = init_proc_401;
3525 pcc->check_pow = check_pow_nocheck;
3526 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3527 PPC_WRTEE | PPC_DCR |
3528 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3530 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3531 PPC_4xx_COMMON | PPC_40x_EXCP;
3532 pcc->msr_mask = (1ull << MSR_KEY) |
3541 pcc->mmu_model = POWERPC_MMU_REAL;
3542 pcc->excp_model = POWERPC_EXCP_40x;
3543 pcc->bus_model = PPC_FLAGS_INPUT_401;
3544 pcc->bfd_mach = bfd_mach_ppc_403;
3545 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3546 POWERPC_FLAG_BUS_CLK;
3549 static void init_proc_401x2(CPUPPCState *env)
3552 gen_spr_401_403(env);
3554 gen_spr_compress(env);
3555 /* Memory management */
3556 #if !defined(CONFIG_USER_ONLY)
3560 env->tlb_type = TLB_EMB;
3562 init_excp_4xx_softmmu(env);
3563 env->dcache_line_size = 32;
3564 env->icache_line_size = 32;
3565 /* Allocate hardware IRQ controller */
3566 ppc40x_irq_init(env_archcpu(env));
3568 SET_FIT_PERIOD(12, 16, 20, 24);
3569 SET_WDT_PERIOD(16, 20, 24, 28);
3572 POWERPC_FAMILY(401x2)(ObjectClass *oc, void *data)
3574 DeviceClass *dc = DEVICE_CLASS(oc);
3575 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3577 dc->desc = "PowerPC 401x2";
3578 pcc->init_proc = init_proc_401x2;
3579 pcc->check_pow = check_pow_nocheck;
3580 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
3581 PPC_DCR | PPC_WRTEE |
3582 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3583 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3584 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3585 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3586 PPC_4xx_COMMON | PPC_40x_EXCP;
3587 pcc->msr_mask = (1ull << 20) |
3599 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3600 pcc->excp_model = POWERPC_EXCP_40x;
3601 pcc->bus_model = PPC_FLAGS_INPUT_401;
3602 pcc->bfd_mach = bfd_mach_ppc_403;
3603 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3604 POWERPC_FLAG_BUS_CLK;
3607 static void init_proc_401x3(CPUPPCState *env)
3610 gen_spr_401_403(env);
3613 gen_spr_compress(env);
3614 init_excp_4xx_softmmu(env);
3615 env->dcache_line_size = 32;
3616 env->icache_line_size = 32;
3617 /* Allocate hardware IRQ controller */
3618 ppc40x_irq_init(env_archcpu(env));
3620 SET_FIT_PERIOD(12, 16, 20, 24);
3621 SET_WDT_PERIOD(16, 20, 24, 28);
3624 POWERPC_FAMILY(401x3)(ObjectClass *oc, void *data)
3626 DeviceClass *dc = DEVICE_CLASS(oc);
3627 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3629 dc->desc = "PowerPC 401x3";
3630 pcc->init_proc = init_proc_401x3;
3631 pcc->check_pow = check_pow_nocheck;
3632 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
3633 PPC_DCR | PPC_WRTEE |
3634 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3635 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3636 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3637 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3638 PPC_4xx_COMMON | PPC_40x_EXCP;
3639 pcc->msr_mask = (1ull << 20) |
3652 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3653 pcc->excp_model = POWERPC_EXCP_40x;
3654 pcc->bus_model = PPC_FLAGS_INPUT_401;
3655 pcc->bfd_mach = bfd_mach_ppc_403;
3656 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3657 POWERPC_FLAG_BUS_CLK;
3660 static void init_proc_IOP480(CPUPPCState *env)
3663 gen_spr_401_403(env);
3665 gen_spr_compress(env);
3666 /* Memory management */
3667 #if !defined(CONFIG_USER_ONLY)
3671 env->tlb_type = TLB_EMB;
3673 init_excp_4xx_softmmu(env);
3674 env->dcache_line_size = 32;
3675 env->icache_line_size = 32;
3676 /* Allocate hardware IRQ controller */
3677 ppc40x_irq_init(env_archcpu(env));
3679 SET_FIT_PERIOD(8, 12, 16, 20);
3680 SET_WDT_PERIOD(16, 20, 24, 28);
3683 POWERPC_FAMILY(IOP480)(ObjectClass *oc, void *data)
3685 DeviceClass *dc = DEVICE_CLASS(oc);
3686 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3688 dc->desc = "IOP480";
3689 pcc->init_proc = init_proc_IOP480;
3690 pcc->check_pow = check_pow_nocheck;
3691 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3692 PPC_DCR | PPC_WRTEE |
3693 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3694 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3695 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3696 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3697 PPC_4xx_COMMON | PPC_40x_EXCP;
3698 pcc->msr_mask = (1ull << 20) |
3710 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3711 pcc->excp_model = POWERPC_EXCP_40x;
3712 pcc->bus_model = PPC_FLAGS_INPUT_401;
3713 pcc->bfd_mach = bfd_mach_ppc_403;
3714 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3715 POWERPC_FLAG_BUS_CLK;
3718 static void init_proc_403(CPUPPCState *env)
3721 gen_spr_401_403(env);
3723 gen_spr_403_real(env);
3724 init_excp_4xx_real(env);
3725 env->dcache_line_size = 32;
3726 env->icache_line_size = 32;
3727 /* Allocate hardware IRQ controller */
3728 ppc40x_irq_init(env_archcpu(env));
3730 SET_FIT_PERIOD(8, 12, 16, 20);
3731 SET_WDT_PERIOD(16, 20, 24, 28);
3734 POWERPC_FAMILY(403)(ObjectClass *oc, void *data)
3736 DeviceClass *dc = DEVICE_CLASS(oc);
3737 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3739 dc->desc = "PowerPC 403";
3740 pcc->init_proc = init_proc_403;
3741 pcc->check_pow = check_pow_nocheck;
3742 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3743 PPC_DCR | PPC_WRTEE |
3744 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3746 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3747 PPC_4xx_COMMON | PPC_40x_EXCP;
3748 pcc->msr_mask = (1ull << MSR_POW) |
3757 pcc->mmu_model = POWERPC_MMU_REAL;
3758 pcc->excp_model = POWERPC_EXCP_40x;
3759 pcc->bus_model = PPC_FLAGS_INPUT_401;
3760 pcc->bfd_mach = bfd_mach_ppc_403;
3761 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_PX |
3762 POWERPC_FLAG_BUS_CLK;
3765 static void init_proc_403GCX(CPUPPCState *env)
3768 gen_spr_401_403(env);
3770 gen_spr_403_real(env);
3771 gen_spr_403_mmu(env);
3772 /* Bus access control */
3773 /* not emulated, as QEMU never does speculative access */
3774 spr_register(env, SPR_40x_SGR, "SGR",
3775 SPR_NOACCESS, SPR_NOACCESS,
3776 &spr_read_generic, &spr_write_generic,
3778 /* not emulated, as QEMU do not emulate caches */
3779 spr_register(env, SPR_40x_DCWR, "DCWR",
3780 SPR_NOACCESS, SPR_NOACCESS,
3781 &spr_read_generic, &spr_write_generic,
3783 /* Memory management */
3784 #if !defined(CONFIG_USER_ONLY)
3788 env->tlb_type = TLB_EMB;
3790 init_excp_4xx_softmmu(env);
3791 env->dcache_line_size = 32;
3792 env->icache_line_size = 32;
3793 /* Allocate hardware IRQ controller */
3794 ppc40x_irq_init(env_archcpu(env));
3796 SET_FIT_PERIOD(8, 12, 16, 20);
3797 SET_WDT_PERIOD(16, 20, 24, 28);
3800 POWERPC_FAMILY(403GCX)(ObjectClass *oc, void *data)
3802 DeviceClass *dc = DEVICE_CLASS(oc);
3803 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3805 dc->desc = "PowerPC 403 GCX";
3806 pcc->init_proc = init_proc_403GCX;
3807 pcc->check_pow = check_pow_nocheck;
3808 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3809 PPC_DCR | PPC_WRTEE |
3810 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3812 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3813 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3814 PPC_4xx_COMMON | PPC_40x_EXCP;
3815 pcc->msr_mask = (1ull << MSR_POW) |
3824 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3825 pcc->excp_model = POWERPC_EXCP_40x;
3826 pcc->bus_model = PPC_FLAGS_INPUT_401;
3827 pcc->bfd_mach = bfd_mach_ppc_403;
3828 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_PX |
3829 POWERPC_FLAG_BUS_CLK;
3832 static void init_proc_405(CPUPPCState *env)
3838 /* Bus access control */
3839 /* not emulated, as QEMU never does speculative access */
3840 spr_register(env, SPR_40x_SGR, "SGR",
3841 SPR_NOACCESS, SPR_NOACCESS,
3842 &spr_read_generic, &spr_write_generic,
3844 /* not emulated, as QEMU do not emulate caches */
3845 spr_register(env, SPR_40x_DCWR, "DCWR",
3846 SPR_NOACCESS, SPR_NOACCESS,
3847 &spr_read_generic, &spr_write_generic,
3849 /* Memory management */
3850 #if !defined(CONFIG_USER_ONLY)
3854 env->tlb_type = TLB_EMB;
3856 init_excp_4xx_softmmu(env);
3857 env->dcache_line_size = 32;
3858 env->icache_line_size = 32;
3859 /* Allocate hardware IRQ controller */
3860 ppc40x_irq_init(env_archcpu(env));
3862 SET_FIT_PERIOD(8, 12, 16, 20);
3863 SET_WDT_PERIOD(16, 20, 24, 28);
3866 POWERPC_FAMILY(405)(ObjectClass *oc, void *data)
3868 DeviceClass *dc = DEVICE_CLASS(oc);
3869 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3871 dc->desc = "PowerPC 405";
3872 pcc->init_proc = init_proc_405;
3873 pcc->check_pow = check_pow_nocheck;
3874 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
3875 PPC_DCR | PPC_WRTEE |
3876 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3877 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3878 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3879 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3880 PPC_4xx_COMMON | PPC_405_MAC | PPC_40x_EXCP;
3881 pcc->msr_mask = (1ull << MSR_POW) |
3890 pcc->mmu_model = POWERPC_MMU_SOFT_4xx;
3891 pcc->excp_model = POWERPC_EXCP_40x;
3892 pcc->bus_model = PPC_FLAGS_INPUT_405;
3893 pcc->bfd_mach = bfd_mach_ppc_403;
3894 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
3895 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
3898 static void init_proc_440EP(CPUPPCState *env)
3902 gen_spr_BookE(env, 0x000000000000FFFFULL);
3904 gen_spr_usprgh(env);
3905 /* Processor identification */
3906 spr_register(env, SPR_BOOKE_PIR, "PIR",
3907 SPR_NOACCESS, SPR_NOACCESS,
3908 &spr_read_generic, &spr_write_pir,
3910 /* XXX : not implemented */
3911 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
3912 SPR_NOACCESS, SPR_NOACCESS,
3913 &spr_read_generic, &spr_write_generic,
3915 /* XXX : not implemented */
3916 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
3917 SPR_NOACCESS, SPR_NOACCESS,
3918 &spr_read_generic, &spr_write_generic,
3920 /* XXX : not implemented */
3921 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
3922 SPR_NOACCESS, SPR_NOACCESS,
3923 &spr_read_generic, &spr_write_generic,
3925 /* XXX : not implemented */
3926 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
3927 SPR_NOACCESS, SPR_NOACCESS,
3928 &spr_read_generic, &spr_write_generic,
3930 /* XXX : not implemented */
3931 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
3932 SPR_NOACCESS, SPR_NOACCESS,
3933 &spr_read_generic, &spr_write_generic,
3935 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
3936 SPR_NOACCESS, SPR_NOACCESS,
3937 &spr_read_generic, &spr_write_generic,
3939 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
3940 SPR_NOACCESS, SPR_NOACCESS,
3941 &spr_read_generic, &spr_write_generic,
3943 /* XXX : not implemented */
3944 spr_register(env, SPR_440_CCR1, "CCR1",
3945 SPR_NOACCESS, SPR_NOACCESS,
3946 &spr_read_generic, &spr_write_generic,
3948 /* Memory management */
3949 #if !defined(CONFIG_USER_ONLY)
3953 env->tlb_type = TLB_EMB;
3955 init_excp_BookE(env);
3956 env->dcache_line_size = 32;
3957 env->icache_line_size = 32;
3958 ppc40x_irq_init(env_archcpu(env));
3960 SET_FIT_PERIOD(12, 16, 20, 24);
3961 SET_WDT_PERIOD(20, 24, 28, 32);
3964 POWERPC_FAMILY(440EP)(ObjectClass *oc, void *data)
3966 DeviceClass *dc = DEVICE_CLASS(oc);
3967 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3969 dc->desc = "PowerPC 440 EP";
3970 pcc->init_proc = init_proc_440EP;
3971 pcc->check_pow = check_pow_nocheck;
3972 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3973 PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL |
3974 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
3976 PPC_DCR | PPC_WRTEE | PPC_RFMCI |
3977 PPC_CACHE | PPC_CACHE_ICBI |
3978 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3979 PPC_MEM_TLBSYNC | PPC_MFTB |
3980 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
3982 pcc->msr_mask = (1ull << MSR_POW) |
3994 pcc->mmu_model = POWERPC_MMU_BOOKE;
3995 pcc->excp_model = POWERPC_EXCP_BOOKE;
3996 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
3997 pcc->bfd_mach = bfd_mach_ppc_403;
3998 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
3999 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
4002 POWERPC_FAMILY(460EX)(ObjectClass *oc, void *data)
4004 DeviceClass *dc = DEVICE_CLASS(oc);
4005 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4007 dc->desc = "PowerPC 460 EX";
4008 pcc->init_proc = init_proc_440EP;
4009 pcc->check_pow = check_pow_nocheck;
4010 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4011 PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL |
4012 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
4014 PPC_DCR | PPC_DCRX | PPC_WRTEE | PPC_RFMCI |
4015 PPC_CACHE | PPC_CACHE_ICBI |
4016 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4017 PPC_MEM_TLBSYNC | PPC_MFTB |
4018 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4020 pcc->msr_mask = (1ull << MSR_POW) |
4032 pcc->mmu_model = POWERPC_MMU_BOOKE;
4033 pcc->excp_model = POWERPC_EXCP_BOOKE;
4034 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4035 pcc->bfd_mach = bfd_mach_ppc_403;
4036 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4037 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
4040 static void init_proc_440GP(CPUPPCState *env)
4044 gen_spr_BookE(env, 0x000000000000FFFFULL);
4046 gen_spr_usprgh(env);
4047 /* Processor identification */
4048 spr_register(env, SPR_BOOKE_PIR, "PIR",
4049 SPR_NOACCESS, SPR_NOACCESS,
4050 &spr_read_generic, &spr_write_pir,
4052 /* XXX : not implemented */
4053 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4054 SPR_NOACCESS, SPR_NOACCESS,
4055 &spr_read_generic, &spr_write_generic,
4057 /* XXX : not implemented */
4058 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4059 SPR_NOACCESS, SPR_NOACCESS,
4060 &spr_read_generic, &spr_write_generic,
4062 /* XXX : not implemented */
4063 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
4064 SPR_NOACCESS, SPR_NOACCESS,
4065 &spr_read_generic, &spr_write_generic,
4067 /* XXX : not implemented */
4068 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
4069 SPR_NOACCESS, SPR_NOACCESS,
4070 &spr_read_generic, &spr_write_generic,
4072 /* Memory management */
4073 #if !defined(CONFIG_USER_ONLY)
4077 env->tlb_type = TLB_EMB;
4079 init_excp_BookE(env);
4080 env->dcache_line_size = 32;
4081 env->icache_line_size = 32;
4082 /* XXX: TODO: allocate internal IRQ controller */
4084 SET_FIT_PERIOD(12, 16, 20, 24);
4085 SET_WDT_PERIOD(20, 24, 28, 32);
4088 POWERPC_FAMILY(440GP)(ObjectClass *oc, void *data)
4090 DeviceClass *dc = DEVICE_CLASS(oc);
4091 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4093 dc->desc = "PowerPC 440 GP";
4094 pcc->init_proc = init_proc_440GP;
4095 pcc->check_pow = check_pow_nocheck;
4096 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4097 PPC_DCR | PPC_DCRX | PPC_WRTEE | PPC_MFAPIDI |
4098 PPC_CACHE | PPC_CACHE_ICBI |
4099 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4100 PPC_MEM_TLBSYNC | PPC_TLBIVA | PPC_MFTB |
4101 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4103 pcc->msr_mask = (1ull << MSR_POW) |
4115 pcc->mmu_model = POWERPC_MMU_BOOKE;
4116 pcc->excp_model = POWERPC_EXCP_BOOKE;
4117 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4118 pcc->bfd_mach = bfd_mach_ppc_403;
4119 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4120 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
4123 static void init_proc_440x4(CPUPPCState *env)
4127 gen_spr_BookE(env, 0x000000000000FFFFULL);
4129 gen_spr_usprgh(env);
4130 /* Processor identification */
4131 spr_register(env, SPR_BOOKE_PIR, "PIR",
4132 SPR_NOACCESS, SPR_NOACCESS,
4133 &spr_read_generic, &spr_write_pir,
4135 /* XXX : not implemented */
4136 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4137 SPR_NOACCESS, SPR_NOACCESS,
4138 &spr_read_generic, &spr_write_generic,
4140 /* XXX : not implemented */
4141 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4142 SPR_NOACCESS, SPR_NOACCESS,
4143 &spr_read_generic, &spr_write_generic,
4145 /* XXX : not implemented */
4146 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
4147 SPR_NOACCESS, SPR_NOACCESS,
4148 &spr_read_generic, &spr_write_generic,
4150 /* XXX : not implemented */
4151 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
4152 SPR_NOACCESS, SPR_NOACCESS,
4153 &spr_read_generic, &spr_write_generic,
4155 /* Memory management */
4156 #if !defined(CONFIG_USER_ONLY)
4160 env->tlb_type = TLB_EMB;
4162 init_excp_BookE(env);
4163 env->dcache_line_size = 32;
4164 env->icache_line_size = 32;
4165 /* XXX: TODO: allocate internal IRQ controller */
4167 SET_FIT_PERIOD(12, 16, 20, 24);
4168 SET_WDT_PERIOD(20, 24, 28, 32);
4171 POWERPC_FAMILY(440x4)(ObjectClass *oc, void *data)
4173 DeviceClass *dc = DEVICE_CLASS(oc);
4174 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4176 dc->desc = "PowerPC 440x4";
4177 pcc->init_proc = init_proc_440x4;
4178 pcc->check_pow = check_pow_nocheck;
4179 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4180 PPC_DCR | PPC_WRTEE |
4181 PPC_CACHE | PPC_CACHE_ICBI |
4182 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4183 PPC_MEM_TLBSYNC | PPC_MFTB |
4184 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4186 pcc->msr_mask = (1ull << MSR_POW) |
4198 pcc->mmu_model = POWERPC_MMU_BOOKE;
4199 pcc->excp_model = POWERPC_EXCP_BOOKE;
4200 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4201 pcc->bfd_mach = bfd_mach_ppc_403;
4202 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4203 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
4206 static void init_proc_440x5(CPUPPCState *env)
4210 gen_spr_BookE(env, 0x000000000000FFFFULL);
4212 gen_spr_usprgh(env);
4213 /* Processor identification */
4214 spr_register(env, SPR_BOOKE_PIR, "PIR",
4215 SPR_NOACCESS, SPR_NOACCESS,
4216 &spr_read_generic, &spr_write_pir,
4218 /* XXX : not implemented */
4219 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4220 SPR_NOACCESS, SPR_NOACCESS,
4221 &spr_read_generic, &spr_write_generic,
4223 /* XXX : not implemented */
4224 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4225 SPR_NOACCESS, SPR_NOACCESS,
4226 &spr_read_generic, &spr_write_generic,
4228 /* XXX : not implemented */
4229 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
4230 SPR_NOACCESS, SPR_NOACCESS,
4231 &spr_read_generic, &spr_write_generic,
4233 /* XXX : not implemented */
4234 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
4235 SPR_NOACCESS, SPR_NOACCESS,
4236 &spr_read_generic, &spr_write_generic,
4238 /* XXX : not implemented */
4239 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
4240 SPR_NOACCESS, SPR_NOACCESS,
4241 &spr_read_generic, &spr_write_generic,
4243 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
4244 SPR_NOACCESS, SPR_NOACCESS,
4245 &spr_read_generic, &spr_write_generic,
4247 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
4248 SPR_NOACCESS, SPR_NOACCESS,
4249 &spr_read_generic, &spr_write_generic,
4251 /* XXX : not implemented */
4252 spr_register(env, SPR_440_CCR1, "CCR1",
4253 SPR_NOACCESS, SPR_NOACCESS,
4254 &spr_read_generic, &spr_write_generic,
4256 /* Memory management */
4257 #if !defined(CONFIG_USER_ONLY)
4261 env->tlb_type = TLB_EMB;
4263 init_excp_BookE(env);
4264 env->dcache_line_size = 32;
4265 env->icache_line_size = 32;
4266 ppc40x_irq_init(env_archcpu(env));
4268 SET_FIT_PERIOD(12, 16, 20, 24);
4269 SET_WDT_PERIOD(20, 24, 28, 32);
4272 POWERPC_FAMILY(440x5)(ObjectClass *oc, void *data)
4274 DeviceClass *dc = DEVICE_CLASS(oc);
4275 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4277 dc->desc = "PowerPC 440x5";
4278 pcc->init_proc = init_proc_440x5;
4279 pcc->check_pow = check_pow_nocheck;
4280 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4281 PPC_DCR | PPC_WRTEE | PPC_RFMCI |
4282 PPC_CACHE | PPC_CACHE_ICBI |
4283 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4284 PPC_MEM_TLBSYNC | PPC_MFTB |
4285 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4287 pcc->msr_mask = (1ull << MSR_POW) |
4299 pcc->mmu_model = POWERPC_MMU_BOOKE;
4300 pcc->excp_model = POWERPC_EXCP_BOOKE;
4301 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4302 pcc->bfd_mach = bfd_mach_ppc_403;
4303 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4304 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
4307 POWERPC_FAMILY(440x5wDFPU)(ObjectClass *oc, void *data)
4309 DeviceClass *dc = DEVICE_CLASS(oc);
4310 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4312 dc->desc = "PowerPC 440x5 with double precision FPU";
4313 pcc->init_proc = init_proc_440x5;
4314 pcc->check_pow = check_pow_nocheck;
4315 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4316 PPC_FLOAT | PPC_FLOAT_FSQRT |
4318 PPC_DCR | PPC_WRTEE | PPC_RFMCI |
4319 PPC_CACHE | PPC_CACHE_ICBI |
4320 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4321 PPC_MEM_TLBSYNC | PPC_MFTB |
4322 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4324 pcc->insns_flags2 = PPC2_FP_CVT_S64;
4325 pcc->msr_mask = (1ull << MSR_POW) |
4337 pcc->mmu_model = POWERPC_MMU_BOOKE;
4338 pcc->excp_model = POWERPC_EXCP_BOOKE;
4339 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4340 pcc->bfd_mach = bfd_mach_ppc_403;
4341 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4342 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
4345 static void init_proc_MPC5xx(CPUPPCState *env)
4349 gen_spr_5xx_8xx(env);
4351 init_excp_MPC5xx(env);
4352 env->dcache_line_size = 32;
4353 env->icache_line_size = 32;
4354 /* XXX: TODO: allocate internal IRQ controller */
4357 POWERPC_FAMILY(MPC5xx)(ObjectClass *oc, void *data)
4359 DeviceClass *dc = DEVICE_CLASS(oc);
4360 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4362 dc->desc = "Freescale 5xx cores (aka RCPU)";
4363 pcc->init_proc = init_proc_MPC5xx;
4364 pcc->check_pow = check_pow_none;
4365 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4366 PPC_MEM_EIEIO | PPC_MEM_SYNC |
4367 PPC_CACHE_ICBI | PPC_FLOAT | PPC_FLOAT_STFIWX |
4369 pcc->msr_mask = (1ull << MSR_ILE) |
4381 pcc->mmu_model = POWERPC_MMU_REAL;
4382 pcc->excp_model = POWERPC_EXCP_603;
4383 pcc->bus_model = PPC_FLAGS_INPUT_RCPU;
4384 pcc->bfd_mach = bfd_mach_ppc_505;
4385 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
4386 POWERPC_FLAG_BUS_CLK;
4389 static void init_proc_MPC8xx(CPUPPCState *env)
4393 gen_spr_5xx_8xx(env);
4395 init_excp_MPC8xx(env);
4396 env->dcache_line_size = 32;
4397 env->icache_line_size = 32;
4398 /* XXX: TODO: allocate internal IRQ controller */
4401 POWERPC_FAMILY(MPC8xx)(ObjectClass *oc, void *data)
4403 DeviceClass *dc = DEVICE_CLASS(oc);
4404 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4406 dc->desc = "Freescale 8xx cores (aka PowerQUICC)";
4407 pcc->init_proc = init_proc_MPC8xx;
4408 pcc->check_pow = check_pow_none;
4409 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4410 PPC_MEM_EIEIO | PPC_MEM_SYNC |
4411 PPC_CACHE_ICBI | PPC_MFTB;
4412 pcc->msr_mask = (1ull << MSR_ILE) |
4424 pcc->mmu_model = POWERPC_MMU_MPC8xx;
4425 pcc->excp_model = POWERPC_EXCP_603;
4426 pcc->bus_model = PPC_FLAGS_INPUT_RCPU;
4427 pcc->bfd_mach = bfd_mach_ppc_860;
4428 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
4429 POWERPC_FLAG_BUS_CLK;
4432 /* Freescale 82xx cores (aka PowerQUICC-II) */
4434 static void init_proc_G2(CPUPPCState *env)
4436 gen_spr_ne_601(env);
4438 gen_spr_G2_755(env);
4442 /* External access control */
4443 /* XXX : not implemented */
4444 spr_register(env, SPR_EAR, "EAR",
4445 SPR_NOACCESS, SPR_NOACCESS,
4446 &spr_read_generic, &spr_write_generic,
4448 /* Hardware implementation register */
4449 /* XXX : not implemented */
4450 spr_register(env, SPR_HID0, "HID0",
4451 SPR_NOACCESS, SPR_NOACCESS,
4452 &spr_read_generic, &spr_write_generic,
4454 /* XXX : not implemented */
4455 spr_register(env, SPR_HID1, "HID1",
4456 SPR_NOACCESS, SPR_NOACCESS,
4457 &spr_read_generic, &spr_write_generic,
4459 /* XXX : not implemented */
4460 spr_register(env, SPR_HID2, "HID2",
4461 SPR_NOACCESS, SPR_NOACCESS,
4462 &spr_read_generic, &spr_write_generic,
4464 /* Memory management */
4467 gen_6xx_7xx_soft_tlb(env, 64, 2);
4469 env->dcache_line_size = 32;
4470 env->icache_line_size = 32;
4471 /* Allocate hardware IRQ controller */
4472 ppc6xx_irq_init(env_archcpu(env));
4475 POWERPC_FAMILY(G2)(ObjectClass *oc, void *data)
4477 DeviceClass *dc = DEVICE_CLASS(oc);
4478 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4480 dc->desc = "PowerPC G2";
4481 pcc->init_proc = init_proc_G2;
4482 pcc->check_pow = check_pow_hid0;
4483 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4484 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4486 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4487 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4488 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4489 PPC_SEGMENT | PPC_EXTERN;
4490 pcc->msr_mask = (1ull << MSR_POW) |
4491 (1ull << MSR_TGPR) |
4505 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4506 pcc->excp_model = POWERPC_EXCP_G2;
4507 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4508 pcc->bfd_mach = bfd_mach_ppc_ec603e;
4509 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4510 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
4513 static void init_proc_G2LE(CPUPPCState *env)
4515 gen_spr_ne_601(env);
4517 gen_spr_G2_755(env);
4521 /* External access control */
4522 /* XXX : not implemented */
4523 spr_register(env, SPR_EAR, "EAR",
4524 SPR_NOACCESS, SPR_NOACCESS,
4525 &spr_read_generic, &spr_write_generic,
4527 /* Hardware implementation register */
4528 /* XXX : not implemented */
4529 spr_register(env, SPR_HID0, "HID0",
4530 SPR_NOACCESS, SPR_NOACCESS,
4531 &spr_read_generic, &spr_write_generic,
4533 /* XXX : not implemented */
4534 spr_register(env, SPR_HID1, "HID1",
4535 SPR_NOACCESS, SPR_NOACCESS,
4536 &spr_read_generic, &spr_write_generic,
4538 /* XXX : not implemented */
4539 spr_register(env, SPR_HID2, "HID2",
4540 SPR_NOACCESS, SPR_NOACCESS,
4541 &spr_read_generic, &spr_write_generic,
4544 /* Memory management */
4547 gen_6xx_7xx_soft_tlb(env, 64, 2);
4549 env->dcache_line_size = 32;
4550 env->icache_line_size = 32;
4551 /* Allocate hardware IRQ controller */
4552 ppc6xx_irq_init(env_archcpu(env));
4555 POWERPC_FAMILY(G2LE)(ObjectClass *oc, void *data)
4557 DeviceClass *dc = DEVICE_CLASS(oc);
4558 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4560 dc->desc = "PowerPC G2LE";
4561 pcc->init_proc = init_proc_G2LE;
4562 pcc->check_pow = check_pow_hid0;
4563 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4564 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4566 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4567 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4568 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4569 PPC_SEGMENT | PPC_EXTERN;
4570 pcc->msr_mask = (1ull << MSR_POW) |
4571 (1ull << MSR_TGPR) |
4587 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4588 pcc->excp_model = POWERPC_EXCP_G2;
4589 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4590 pcc->bfd_mach = bfd_mach_ppc_ec603e;
4591 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4592 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
4595 static void init_proc_e200(CPUPPCState *env)
4599 gen_spr_BookE(env, 0x000000070000FFFFULL);
4600 /* XXX : not implemented */
4601 spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
4602 &spr_read_spefscr, &spr_write_spefscr,
4603 &spr_read_spefscr, &spr_write_spefscr,
4605 /* Memory management */
4606 gen_spr_BookE206(env, 0x0000005D, NULL, 0);
4607 /* XXX : not implemented */
4608 spr_register(env, SPR_HID0, "HID0",
4609 SPR_NOACCESS, SPR_NOACCESS,
4610 &spr_read_generic, &spr_write_generic,
4612 /* XXX : not implemented */
4613 spr_register(env, SPR_HID1, "HID1",
4614 SPR_NOACCESS, SPR_NOACCESS,
4615 &spr_read_generic, &spr_write_generic,
4617 /* XXX : not implemented */
4618 spr_register(env, SPR_Exxx_ALTCTXCR, "ALTCTXCR",
4619 SPR_NOACCESS, SPR_NOACCESS,
4620 &spr_read_generic, &spr_write_generic,
4622 /* XXX : not implemented */
4623 spr_register(env, SPR_Exxx_BUCSR, "BUCSR",
4624 SPR_NOACCESS, SPR_NOACCESS,
4625 &spr_read_generic, &spr_write_generic,
4627 /* XXX : not implemented */
4628 spr_register(env, SPR_Exxx_CTXCR, "CTXCR",
4629 SPR_NOACCESS, SPR_NOACCESS,
4630 &spr_read_generic, &spr_write_generic,
4632 /* XXX : not implemented */
4633 spr_register(env, SPR_Exxx_DBCNT, "DBCNT",
4634 SPR_NOACCESS, SPR_NOACCESS,
4635 &spr_read_generic, &spr_write_generic,
4637 /* XXX : not implemented */
4638 spr_register(env, SPR_Exxx_DBCR3, "DBCR3",
4639 SPR_NOACCESS, SPR_NOACCESS,
4640 &spr_read_generic, &spr_write_generic,
4642 /* XXX : not implemented */
4643 spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0",
4644 &spr_read_generic, SPR_NOACCESS,
4645 &spr_read_generic, SPR_NOACCESS,
4647 /* XXX : not implemented */
4648 spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0",
4649 SPR_NOACCESS, SPR_NOACCESS,
4650 &spr_read_generic, &spr_write_generic,
4652 /* XXX : not implemented */
4653 spr_register(env, SPR_Exxx_L1FINV0, "L1FINV0",
4654 SPR_NOACCESS, SPR_NOACCESS,
4655 &spr_read_generic, &spr_write_generic,
4657 /* XXX : not implemented */
4658 spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG",
4659 SPR_NOACCESS, SPR_NOACCESS,
4660 &spr_read_generic, &spr_write_generic,
4662 /* XXX : not implemented */
4663 spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG",
4664 SPR_NOACCESS, SPR_NOACCESS,
4665 &spr_read_generic, &spr_write_generic,
4667 /* XXX : not implemented */
4668 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4669 SPR_NOACCESS, SPR_NOACCESS,
4670 &spr_read_generic, &spr_write_generic,
4672 /* XXX : not implemented */
4673 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4674 SPR_NOACCESS, SPR_NOACCESS,
4675 &spr_read_generic, &spr_write_generic,
4677 /* XXX : not implemented */
4678 spr_register(env, SPR_MMUCSR0, "MMUCSR0",
4679 SPR_NOACCESS, SPR_NOACCESS,
4680 &spr_read_generic, &spr_write_generic,
4681 0x00000000); /* TOFIX */
4682 spr_register(env, SPR_BOOKE_DSRR0, "DSRR0",
4683 SPR_NOACCESS, SPR_NOACCESS,
4684 &spr_read_generic, &spr_write_generic,
4686 spr_register(env, SPR_BOOKE_DSRR1, "DSRR1",
4687 SPR_NOACCESS, SPR_NOACCESS,
4688 &spr_read_generic, &spr_write_generic,
4690 #if !defined(CONFIG_USER_ONLY)
4694 env->tlb_type = TLB_EMB;
4696 init_excp_e200(env, 0xFFFF0000UL);
4697 env->dcache_line_size = 32;
4698 env->icache_line_size = 32;
4699 /* XXX: TODO: allocate internal IRQ controller */
4702 POWERPC_FAMILY(e200)(ObjectClass *oc, void *data)
4704 DeviceClass *dc = DEVICE_CLASS(oc);
4705 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4707 dc->desc = "e200 core";
4708 pcc->init_proc = init_proc_e200;
4709 pcc->check_pow = check_pow_hid0;
4711 * XXX: unimplemented instructions:
4718 * all SPE multiply-accumulate instructions
4720 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
4721 PPC_SPE | PPC_SPE_SINGLE |
4722 PPC_WRTEE | PPC_RFDI |
4723 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
4724 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4725 PPC_MEM_TLBSYNC | PPC_TLBIVAX |
4727 pcc->msr_mask = (1ull << MSR_UCLE) |
4741 pcc->mmu_model = POWERPC_MMU_BOOKE206;
4742 pcc->excp_model = POWERPC_EXCP_BOOKE;
4743 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4744 pcc->bfd_mach = bfd_mach_ppc_860;
4745 pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
4746 POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
4747 POWERPC_FLAG_BUS_CLK;
4750 static void init_proc_e300(CPUPPCState *env)
4752 gen_spr_ne_601(env);
4757 /* hardware implementation registers */
4758 /* XXX : not implemented */
4759 spr_register(env, SPR_HID0, "HID0",
4760 SPR_NOACCESS, SPR_NOACCESS,
4761 &spr_read_generic, &spr_write_generic,
4763 /* XXX : not implemented */
4764 spr_register(env, SPR_HID1, "HID1",
4765 SPR_NOACCESS, SPR_NOACCESS,
4766 &spr_read_generic, &spr_write_generic,
4768 /* XXX : not implemented */
4769 spr_register(env, SPR_HID2, "HID2",
4770 SPR_NOACCESS, SPR_NOACCESS,
4771 &spr_read_generic, &spr_write_generic,
4774 /* XXX : not implemented */
4775 spr_register(env, SPR_DABR, "DABR",
4776 SPR_NOACCESS, SPR_NOACCESS,
4777 &spr_read_generic, &spr_write_generic,
4779 /* XXX : not implemented */
4780 spr_register(env, SPR_DABR2, "DABR2",
4781 SPR_NOACCESS, SPR_NOACCESS,
4782 &spr_read_generic, &spr_write_generic,
4784 /* XXX : not implemented */
4785 spr_register(env, SPR_IABR2, "IABR2",
4786 SPR_NOACCESS, SPR_NOACCESS,
4787 &spr_read_generic, &spr_write_generic,
4789 /* XXX : not implemented */
4790 spr_register(env, SPR_IBCR, "IBCR",
4791 SPR_NOACCESS, SPR_NOACCESS,
4792 &spr_read_generic, &spr_write_generic,
4794 /* XXX : not implemented */
4795 spr_register(env, SPR_DBCR, "DBCR",
4796 SPR_NOACCESS, SPR_NOACCESS,
4797 &spr_read_generic, &spr_write_generic,
4799 /* Memory management */
4802 gen_6xx_7xx_soft_tlb(env, 64, 2);
4804 env->dcache_line_size = 32;
4805 env->icache_line_size = 32;
4806 /* Allocate hardware IRQ controller */
4807 ppc6xx_irq_init(env_archcpu(env));
4810 POWERPC_FAMILY(e300)(ObjectClass *oc, void *data)
4812 DeviceClass *dc = DEVICE_CLASS(oc);
4813 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4815 dc->desc = "e300 core";
4816 pcc->init_proc = init_proc_e300;
4817 pcc->check_pow = check_pow_hid0;
4818 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4819 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4821 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4822 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4823 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4824 PPC_SEGMENT | PPC_EXTERN;
4825 pcc->msr_mask = (1ull << MSR_POW) |
4826 (1ull << MSR_TGPR) |
4842 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4843 pcc->excp_model = POWERPC_EXCP_603;
4844 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4845 pcc->bfd_mach = bfd_mach_ppc_603;
4846 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4847 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
4850 #if !defined(CONFIG_USER_ONLY)
4851 static void spr_write_mas73(DisasContext *ctx, int sprn, int gprn)
4853 TCGv val = tcg_temp_new();
4854 tcg_gen_ext32u_tl(val, cpu_gpr[gprn]);
4855 gen_store_spr(SPR_BOOKE_MAS3, val);
4856 tcg_gen_shri_tl(val, cpu_gpr[gprn], 32);
4857 gen_store_spr(SPR_BOOKE_MAS7, val);
4861 static void spr_read_mas73(DisasContext *ctx, int gprn, int sprn)
4863 TCGv mas7 = tcg_temp_new();
4864 TCGv mas3 = tcg_temp_new();
4865 gen_load_spr(mas7, SPR_BOOKE_MAS7);
4866 tcg_gen_shli_tl(mas7, mas7, 32);
4867 gen_load_spr(mas3, SPR_BOOKE_MAS3);
4868 tcg_gen_or_tl(cpu_gpr[gprn], mas3, mas7);
4869 tcg_temp_free(mas3);
4870 tcg_temp_free(mas7);
4875 enum fsl_e500_version {
4883 static void init_proc_e500(CPUPPCState *env, int version)
4885 uint32_t tlbncfg[2];
4887 uint64_t ivpr_mask = 0xFFFF0000ULL;
4888 uint32_t l1cfg0 = 0x3800 /* 8 ways */
4889 | 0x0020; /* 32 kb */
4890 uint32_t l1cfg1 = 0x3800 /* 8 ways */
4891 | 0x0020; /* 32 kb */
4892 uint32_t mmucfg = 0;
4893 #if !defined(CONFIG_USER_ONLY)
4900 * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't
4901 * complain when accessing them.
4902 * gen_spr_BookE(env, 0x0000000F0000FD7FULL);
4908 ivor_mask = 0x0000000F0000FFFFULL;
4912 ivor_mask = 0x000003FE0000FFFFULL;
4915 ivor_mask = 0x000003FF0000FFFFULL;
4918 gen_spr_BookE(env, ivor_mask);
4919 gen_spr_usprg3(env);
4920 /* Processor identification */
4921 spr_register(env, SPR_BOOKE_PIR, "PIR",
4922 SPR_NOACCESS, SPR_NOACCESS,
4923 &spr_read_generic, &spr_write_pir,
4925 /* XXX : not implemented */
4926 spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
4927 &spr_read_spefscr, &spr_write_spefscr,
4928 &spr_read_spefscr, &spr_write_spefscr,
4930 #if !defined(CONFIG_USER_ONLY)
4931 /* Memory management */
4937 tlbncfg[0] = gen_tlbncfg(2, 1, 1, 0, 256);
4938 tlbncfg[1] = gen_tlbncfg(16, 1, 9, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16);
4941 tlbncfg[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4942 tlbncfg[1] = gen_tlbncfg(16, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16);
4946 tlbncfg[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4947 tlbncfg[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 64);
4952 tlbncfg[0] = 0x08052400;
4953 tlbncfg[1] = 0x40028040;
4956 cpu_abort(env_cpu(env), "Unknown CPU: " TARGET_FMT_lx "\n",
4964 env->dcache_line_size = 32;
4965 env->icache_line_size = 32;
4969 env->dcache_line_size = 64;
4970 env->icache_line_size = 64;
4971 l1cfg0 |= 0x1000000; /* 64 byte cache block size */
4972 l1cfg1 |= 0x1000000; /* 64 byte cache block size */
4975 env->dcache_line_size = 32;
4976 env->icache_line_size = 32;
4977 l1cfg0 |= 0x0F83820;
4978 l1cfg1 |= 0x0B83820;
4981 cpu_abort(env_cpu(env), "Unknown CPU: " TARGET_FMT_lx "\n",
4984 gen_spr_BookE206(env, 0x000000DF, tlbncfg, mmucfg);
4985 /* XXX : not implemented */
4986 spr_register(env, SPR_HID0, "HID0",
4987 SPR_NOACCESS, SPR_NOACCESS,
4988 &spr_read_generic, &spr_write_generic,
4990 /* XXX : not implemented */
4991 spr_register(env, SPR_HID1, "HID1",
4992 SPR_NOACCESS, SPR_NOACCESS,
4993 &spr_read_generic, &spr_write_generic,
4995 /* XXX : not implemented */
4996 spr_register(env, SPR_Exxx_BBEAR, "BBEAR",
4997 SPR_NOACCESS, SPR_NOACCESS,
4998 &spr_read_generic, &spr_write_generic,
5000 /* XXX : not implemented */
5001 spr_register(env, SPR_Exxx_BBTAR, "BBTAR",
5002 SPR_NOACCESS, SPR_NOACCESS,
5003 &spr_read_generic, &spr_write_generic,
5005 /* XXX : not implemented */
5006 spr_register(env, SPR_Exxx_MCAR, "MCAR",
5007 SPR_NOACCESS, SPR_NOACCESS,
5008 &spr_read_generic, &spr_write_generic,
5010 /* XXX : not implemented */
5011 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
5012 SPR_NOACCESS, SPR_NOACCESS,
5013 &spr_read_generic, &spr_write_generic,
5015 /* XXX : not implemented */
5016 spr_register(env, SPR_Exxx_NPIDR, "NPIDR",
5017 SPR_NOACCESS, SPR_NOACCESS,
5018 &spr_read_generic, &spr_write_generic,
5020 /* XXX : not implemented */
5021 spr_register(env, SPR_Exxx_BUCSR, "BUCSR",
5022 SPR_NOACCESS, SPR_NOACCESS,
5023 &spr_read_generic, &spr_write_generic,
5025 /* XXX : not implemented */
5026 spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0",
5027 &spr_read_generic, SPR_NOACCESS,
5028 &spr_read_generic, SPR_NOACCESS,
5030 spr_register(env, SPR_Exxx_L1CFG1, "L1CFG1",
5031 &spr_read_generic, SPR_NOACCESS,
5032 &spr_read_generic, SPR_NOACCESS,
5034 spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0",
5035 SPR_NOACCESS, SPR_NOACCESS,
5036 &spr_read_generic, &spr_write_e500_l1csr0,
5038 spr_register(env, SPR_Exxx_L1CSR1, "L1CSR1",
5039 SPR_NOACCESS, SPR_NOACCESS,
5040 &spr_read_generic, &spr_write_e500_l1csr1,
5042 if (version != fsl_e500v1 && version != fsl_e500v2) {
5043 spr_register(env, SPR_Exxx_L2CSR0, "L2CSR0",
5044 SPR_NOACCESS, SPR_NOACCESS,
5045 &spr_read_generic, &spr_write_e500_l2csr0,
5048 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
5049 SPR_NOACCESS, SPR_NOACCESS,
5050 &spr_read_generic, &spr_write_generic,
5052 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
5053 SPR_NOACCESS, SPR_NOACCESS,
5054 &spr_read_generic, &spr_write_generic,
5056 spr_register(env, SPR_MMUCSR0, "MMUCSR0",
5057 SPR_NOACCESS, SPR_NOACCESS,
5058 &spr_read_generic, &spr_write_booke206_mmucsr0,
5060 spr_register(env, SPR_BOOKE_EPR, "EPR",
5061 SPR_NOACCESS, SPR_NOACCESS,
5062 &spr_read_generic, SPR_NOACCESS,
5064 /* XXX better abstract into Emb.xxx features */
5065 if ((version == fsl_e5500) || (version == fsl_e6500)) {
5066 spr_register(env, SPR_BOOKE_EPCR, "EPCR",
5067 SPR_NOACCESS, SPR_NOACCESS,
5068 &spr_read_generic, &spr_write_generic,
5070 spr_register(env, SPR_BOOKE_MAS7_MAS3, "MAS7_MAS3",
5071 SPR_NOACCESS, SPR_NOACCESS,
5072 &spr_read_mas73, &spr_write_mas73,
5074 ivpr_mask = (target_ulong)~0xFFFFULL;
5077 if (version == fsl_e6500) {
5078 /* Thread identification */
5079 spr_register(env, SPR_TIR, "TIR",
5080 SPR_NOACCESS, SPR_NOACCESS,
5081 &spr_read_generic, SPR_NOACCESS,
5083 spr_register(env, SPR_BOOKE_TLB0PS, "TLB0PS",
5084 SPR_NOACCESS, SPR_NOACCESS,
5085 &spr_read_generic, SPR_NOACCESS,
5087 spr_register(env, SPR_BOOKE_TLB1PS, "TLB1PS",
5088 SPR_NOACCESS, SPR_NOACCESS,
5089 &spr_read_generic, SPR_NOACCESS,
5093 #if !defined(CONFIG_USER_ONLY)
5095 env->tlb_type = TLB_MAS;
5096 for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
5097 env->nb_tlb += booke206_tlb_size(env, i);
5101 init_excp_e200(env, ivpr_mask);
5102 /* Allocate hardware IRQ controller */
5103 ppce500_irq_init(env_archcpu(env));
5106 static void init_proc_e500v1(CPUPPCState *env)
5108 init_proc_e500(env, fsl_e500v1);
5111 POWERPC_FAMILY(e500v1)(ObjectClass *oc, void *data)
5113 DeviceClass *dc = DEVICE_CLASS(oc);
5114 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5116 dc->desc = "e500v1 core";
5117 pcc->init_proc = init_proc_e500v1;
5118 pcc->check_pow = check_pow_hid0;
5119 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
5120 PPC_SPE | PPC_SPE_SINGLE |
5121 PPC_WRTEE | PPC_RFDI |
5122 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5123 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5124 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
5125 pcc->insns_flags2 = PPC2_BOOKE206;
5126 pcc->msr_mask = (1ull << MSR_UCLE) |
5140 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5141 pcc->excp_model = POWERPC_EXCP_BOOKE;
5142 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5143 pcc->bfd_mach = bfd_mach_ppc_860;
5144 pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
5145 POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
5146 POWERPC_FLAG_BUS_CLK;
5149 static void init_proc_e500v2(CPUPPCState *env)
5151 init_proc_e500(env, fsl_e500v2);
5154 POWERPC_FAMILY(e500v2)(ObjectClass *oc, void *data)
5156 DeviceClass *dc = DEVICE_CLASS(oc);
5157 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5159 dc->desc = "e500v2 core";
5160 pcc->init_proc = init_proc_e500v2;
5161 pcc->check_pow = check_pow_hid0;
5162 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
5163 PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE |
5164 PPC_WRTEE | PPC_RFDI |
5165 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5166 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5167 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
5168 pcc->insns_flags2 = PPC2_BOOKE206;
5169 pcc->msr_mask = (1ull << MSR_UCLE) |
5183 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5184 pcc->excp_model = POWERPC_EXCP_BOOKE;
5185 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5186 pcc->bfd_mach = bfd_mach_ppc_860;
5187 pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
5188 POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
5189 POWERPC_FLAG_BUS_CLK;
5192 static void init_proc_e500mc(CPUPPCState *env)
5194 init_proc_e500(env, fsl_e500mc);
5197 POWERPC_FAMILY(e500mc)(ObjectClass *oc, void *data)
5199 DeviceClass *dc = DEVICE_CLASS(oc);
5200 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5202 dc->desc = "e500mc core";
5203 pcc->init_proc = init_proc_e500mc;
5204 pcc->check_pow = check_pow_none;
5205 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
5206 PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
5207 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5208 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5209 PPC_FLOAT | PPC_FLOAT_FRES |
5210 PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
5211 PPC_FLOAT_STFIWX | PPC_WAIT |
5212 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
5213 pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL;
5214 pcc->msr_mask = (1ull << MSR_GS) |
5215 (1ull << MSR_UCLE) |
5228 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5229 pcc->excp_model = POWERPC_EXCP_BOOKE;
5230 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5231 /* FIXME: figure out the correct flag for e500mc */
5232 pcc->bfd_mach = bfd_mach_ppc_e500;
5233 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
5234 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
5238 static void init_proc_e5500(CPUPPCState *env)
5240 init_proc_e500(env, fsl_e5500);
5243 POWERPC_FAMILY(e5500)(ObjectClass *oc, void *data)
5245 DeviceClass *dc = DEVICE_CLASS(oc);
5246 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5248 dc->desc = "e5500 core";
5249 pcc->init_proc = init_proc_e5500;
5250 pcc->check_pow = check_pow_none;
5251 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
5252 PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
5253 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5254 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5255 PPC_FLOAT | PPC_FLOAT_FRES |
5256 PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
5257 PPC_FLOAT_STFIWX | PPC_WAIT |
5258 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC |
5259 PPC_64B | PPC_POPCNTB | PPC_POPCNTWD;
5260 pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_PERM_ISA206 |
5262 pcc->msr_mask = (1ull << MSR_CM) |
5264 (1ull << MSR_UCLE) |
5277 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5278 pcc->excp_model = POWERPC_EXCP_BOOKE;
5279 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5280 /* FIXME: figure out the correct flag for e5500 */
5281 pcc->bfd_mach = bfd_mach_ppc_e500;
5282 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
5283 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
5286 static void init_proc_e6500(CPUPPCState *env)
5288 init_proc_e500(env, fsl_e6500);
5291 POWERPC_FAMILY(e6500)(ObjectClass *oc, void *data)
5293 DeviceClass *dc = DEVICE_CLASS(oc);
5294 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5296 dc->desc = "e6500 core";
5297 pcc->init_proc = init_proc_e6500;
5298 pcc->check_pow = check_pow_none;
5299 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
5300 PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
5301 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5302 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5303 PPC_FLOAT | PPC_FLOAT_FRES |
5304 PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
5305 PPC_FLOAT_STFIWX | PPC_WAIT |
5306 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC |
5307 PPC_64B | PPC_POPCNTB | PPC_POPCNTWD | PPC_ALTIVEC;
5308 pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_PERM_ISA206 |
5309 PPC2_FP_CVT_S64 | PPC2_ATOMIC_ISA206;
5310 pcc->msr_mask = (1ull << MSR_CM) |
5312 (1ull << MSR_UCLE) |
5326 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5327 pcc->excp_model = POWERPC_EXCP_BOOKE;
5328 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5329 pcc->bfd_mach = bfd_mach_ppc_e500;
5330 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
5331 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_VRE;
5336 /* Non-embedded PowerPC */
5338 #define POWERPC_MSRR_601 (0x0000000000001040ULL)
5340 static void init_proc_601(CPUPPCState *env)
5342 gen_spr_ne_601(env);
5345 /* Hardware implementation registers */
5346 /* XXX : not implemented */
5347 spr_register(env, SPR_HID0, "HID0",
5348 SPR_NOACCESS, SPR_NOACCESS,
5349 &spr_read_generic, &spr_write_hid0_601,
5351 /* XXX : not implemented */
5352 spr_register(env, SPR_HID1, "HID1",
5353 SPR_NOACCESS, SPR_NOACCESS,
5354 &spr_read_generic, &spr_write_generic,
5356 /* XXX : not implemented */
5357 spr_register(env, SPR_601_HID2, "HID2",
5358 SPR_NOACCESS, SPR_NOACCESS,
5359 &spr_read_generic, &spr_write_generic,
5361 /* XXX : not implemented */
5362 spr_register(env, SPR_601_HID5, "HID5",
5363 SPR_NOACCESS, SPR_NOACCESS,
5364 &spr_read_generic, &spr_write_generic,
5366 /* Memory management */
5369 * XXX: beware that dcache line size is 64
5370 * but dcbz uses 32 bytes "sectors"
5371 * XXX: this breaks clcs instruction !
5373 env->dcache_line_size = 32;
5374 env->icache_line_size = 64;
5375 /* Allocate hardware IRQ controller */
5376 ppc6xx_irq_init(env_archcpu(env));
5379 POWERPC_FAMILY(601)(ObjectClass *oc, void *data)
5381 DeviceClass *dc = DEVICE_CLASS(oc);
5382 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5384 dc->desc = "PowerPC 601";
5385 pcc->init_proc = init_proc_601;
5386 pcc->check_pow = check_pow_none;
5387 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
5389 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5390 PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
5391 PPC_SEGMENT | PPC_EXTERN;
5392 pcc->msr_mask = (1ull << MSR_EE) |
5402 pcc->mmu_model = POWERPC_MMU_601;
5403 #if defined(CONFIG_SOFTMMU)
5404 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5406 pcc->excp_model = POWERPC_EXCP_601;
5407 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5408 pcc->bfd_mach = bfd_mach_ppc_601;
5409 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK;
5412 #define POWERPC_MSRR_601v (0x0000000000001040ULL)
5414 static void init_proc_601v(CPUPPCState *env)
5417 /* XXX : not implemented */
5418 spr_register(env, SPR_601_HID15, "HID15",
5419 SPR_NOACCESS, SPR_NOACCESS,
5420 &spr_read_generic, &spr_write_generic,
5424 POWERPC_FAMILY(601v)(ObjectClass *oc, void *data)
5426 DeviceClass *dc = DEVICE_CLASS(oc);
5427 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5429 dc->desc = "PowerPC 601v";
5430 pcc->init_proc = init_proc_601v;
5431 pcc->check_pow = check_pow_none;
5432 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
5434 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5435 PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
5436 PPC_SEGMENT | PPC_EXTERN;
5437 pcc->msr_mask = (1ull << MSR_EE) |
5447 pcc->mmu_model = POWERPC_MMU_601;
5448 #if defined(CONFIG_SOFTMMU)
5449 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5451 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5452 pcc->bfd_mach = bfd_mach_ppc_601;
5453 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK;
5456 static void init_proc_602(CPUPPCState *env)
5458 gen_spr_ne_601(env);
5463 /* hardware implementation registers */
5464 /* XXX : not implemented */
5465 spr_register(env, SPR_HID0, "HID0",
5466 SPR_NOACCESS, SPR_NOACCESS,
5467 &spr_read_generic, &spr_write_generic,
5469 /* XXX : not implemented */
5470 spr_register(env, SPR_HID1, "HID1",
5471 SPR_NOACCESS, SPR_NOACCESS,
5472 &spr_read_generic, &spr_write_generic,
5474 /* Memory management */
5476 gen_6xx_7xx_soft_tlb(env, 64, 2);
5478 env->dcache_line_size = 32;
5479 env->icache_line_size = 32;
5480 /* Allocate hardware IRQ controller */
5481 ppc6xx_irq_init(env_archcpu(env));
5484 POWERPC_FAMILY(602)(ObjectClass *oc, void *data)
5486 DeviceClass *dc = DEVICE_CLASS(oc);
5487 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5489 dc->desc = "PowerPC 602";
5490 pcc->init_proc = init_proc_602;
5491 pcc->check_pow = check_pow_hid0;
5492 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5493 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5494 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5495 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5496 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5497 PPC_MEM_TLBIE | PPC_6xx_TLB | PPC_MEM_TLBSYNC |
5498 PPC_SEGMENT | PPC_602_SPEC;
5499 pcc->msr_mask = (1ull << MSR_VSX) |
5502 (1ull << MSR_TGPR) |
5517 /* XXX: 602 MMU is quite specific. Should add a special case */
5518 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
5519 pcc->excp_model = POWERPC_EXCP_602;
5520 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5521 pcc->bfd_mach = bfd_mach_ppc_602;
5522 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
5523 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
5526 static void init_proc_603(CPUPPCState *env)
5528 gen_spr_ne_601(env);
5533 /* hardware implementation registers */
5534 /* XXX : not implemented */
5535 spr_register(env, SPR_HID0, "HID0",
5536 SPR_NOACCESS, SPR_NOACCESS,
5537 &spr_read_generic, &spr_write_generic,
5539 /* XXX : not implemented */
5540 spr_register(env, SPR_HID1, "HID1",
5541 SPR_NOACCESS, SPR_NOACCESS,
5542 &spr_read_generic, &spr_write_generic,
5544 /* Memory management */
5546 gen_6xx_7xx_soft_tlb(env, 64, 2);
5548 env->dcache_line_size = 32;
5549 env->icache_line_size = 32;
5550 /* Allocate hardware IRQ controller */
5551 ppc6xx_irq_init(env_archcpu(env));
5554 POWERPC_FAMILY(603)(ObjectClass *oc, void *data)
5556 DeviceClass *dc = DEVICE_CLASS(oc);
5557 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5559 dc->desc = "PowerPC 603";
5560 pcc->init_proc = init_proc_603;
5561 pcc->check_pow = check_pow_hid0;
5562 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5563 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5564 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5565 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5566 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5567 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
5568 PPC_SEGMENT | PPC_EXTERN;
5569 pcc->msr_mask = (1ull << MSR_POW) |
5570 (1ull << MSR_TGPR) |
5585 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
5586 pcc->excp_model = POWERPC_EXCP_603;
5587 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5588 pcc->bfd_mach = bfd_mach_ppc_603;
5589 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
5590 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
5593 static void init_proc_603E(CPUPPCState *env)
5595 gen_spr_ne_601(env);
5600 /* hardware implementation registers */
5601 /* XXX : not implemented */
5602 spr_register(env, SPR_HID0, "HID0",
5603 SPR_NOACCESS, SPR_NOACCESS,
5604 &spr_read_generic, &spr_write_generic,
5606 /* XXX : not implemented */
5607 spr_register(env, SPR_HID1, "HID1",
5608 SPR_NOACCESS, SPR_NOACCESS,
5609 &spr_read_generic, &spr_write_generic,
5611 /* Memory management */
5613 gen_6xx_7xx_soft_tlb(env, 64, 2);
5615 env->dcache_line_size = 32;
5616 env->icache_line_size = 32;
5617 /* Allocate hardware IRQ controller */
5618 ppc6xx_irq_init(env_archcpu(env));
5621 POWERPC_FAMILY(603E)(ObjectClass *oc, void *data)
5623 DeviceClass *dc = DEVICE_CLASS(oc);
5624 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5626 dc->desc = "PowerPC 603e";
5627 pcc->init_proc = init_proc_603E;
5628 pcc->check_pow = check_pow_hid0;
5629 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5630 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5631 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5632 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5633 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5634 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
5635 PPC_SEGMENT | PPC_EXTERN;
5636 pcc->msr_mask = (1ull << MSR_POW) |
5637 (1ull << MSR_TGPR) |
5652 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
5653 pcc->excp_model = POWERPC_EXCP_603E;
5654 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5655 pcc->bfd_mach = bfd_mach_ppc_ec603e;
5656 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
5657 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
5660 static void init_proc_604(CPUPPCState *env)
5662 gen_spr_ne_601(env);
5667 /* Hardware implementation registers */
5668 /* XXX : not implemented */
5669 spr_register(env, SPR_HID0, "HID0",
5670 SPR_NOACCESS, SPR_NOACCESS,
5671 &spr_read_generic, &spr_write_generic,
5673 /* Memory management */
5676 env->dcache_line_size = 32;
5677 env->icache_line_size = 32;
5678 /* Allocate hardware IRQ controller */
5679 ppc6xx_irq_init(env_archcpu(env));
5682 POWERPC_FAMILY(604)(ObjectClass *oc, void *data)
5684 DeviceClass *dc = DEVICE_CLASS(oc);
5685 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5687 dc->desc = "PowerPC 604";
5688 pcc->init_proc = init_proc_604;
5689 pcc->check_pow = check_pow_nocheck;
5690 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5691 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5692 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5693 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5694 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5695 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5696 PPC_SEGMENT | PPC_EXTERN;
5697 pcc->msr_mask = (1ull << MSR_POW) |
5713 pcc->mmu_model = POWERPC_MMU_32B;
5714 #if defined(CONFIG_SOFTMMU)
5715 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5717 pcc->excp_model = POWERPC_EXCP_604;
5718 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5719 pcc->bfd_mach = bfd_mach_ppc_604;
5720 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5721 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
5724 static void init_proc_604E(CPUPPCState *env)
5726 gen_spr_ne_601(env);
5729 /* XXX : not implemented */
5730 spr_register(env, SPR_7XX_MMCR1, "MMCR1",
5731 SPR_NOACCESS, SPR_NOACCESS,
5732 &spr_read_generic, &spr_write_generic,
5734 /* XXX : not implemented */
5735 spr_register(env, SPR_7XX_PMC3, "PMC3",
5736 SPR_NOACCESS, SPR_NOACCESS,
5737 &spr_read_generic, &spr_write_generic,
5739 /* XXX : not implemented */
5740 spr_register(env, SPR_7XX_PMC4, "PMC4",
5741 SPR_NOACCESS, SPR_NOACCESS,
5742 &spr_read_generic, &spr_write_generic,
5746 /* Hardware implementation registers */
5747 /* XXX : not implemented */
5748 spr_register(env, SPR_HID0, "HID0",
5749 SPR_NOACCESS, SPR_NOACCESS,
5750 &spr_read_generic, &spr_write_generic,
5752 /* XXX : not implemented */
5753 spr_register(env, SPR_HID1, "HID1",
5754 SPR_NOACCESS, SPR_NOACCESS,
5755 &spr_read_generic, &spr_write_generic,
5757 /* Memory management */
5760 env->dcache_line_size = 32;
5761 env->icache_line_size = 32;
5762 /* Allocate hardware IRQ controller */
5763 ppc6xx_irq_init(env_archcpu(env));
5766 POWERPC_FAMILY(604E)(ObjectClass *oc, void *data)
5768 DeviceClass *dc = DEVICE_CLASS(oc);
5769 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5771 dc->desc = "PowerPC 604E";
5772 pcc->init_proc = init_proc_604E;
5773 pcc->check_pow = check_pow_nocheck;
5774 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5775 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5776 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5777 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5778 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5779 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5780 PPC_SEGMENT | PPC_EXTERN;
5781 pcc->msr_mask = (1ull << MSR_POW) |
5797 pcc->mmu_model = POWERPC_MMU_32B;
5798 #if defined(CONFIG_SOFTMMU)
5799 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5801 pcc->excp_model = POWERPC_EXCP_604;
5802 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5803 pcc->bfd_mach = bfd_mach_ppc_604;
5804 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5805 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
5808 static void init_proc_740(CPUPPCState *env)
5810 gen_spr_ne_601(env);
5815 /* Thermal management */
5817 /* Hardware implementation registers */
5818 /* XXX : not implemented */
5819 spr_register(env, SPR_HID0, "HID0",
5820 SPR_NOACCESS, SPR_NOACCESS,
5821 &spr_read_generic, &spr_write_generic,
5823 /* XXX : not implemented */
5824 spr_register(env, SPR_HID1, "HID1",
5825 SPR_NOACCESS, SPR_NOACCESS,
5826 &spr_read_generic, &spr_write_generic,
5828 /* Memory management */
5831 env->dcache_line_size = 32;
5832 env->icache_line_size = 32;
5833 /* Allocate hardware IRQ controller */
5834 ppc6xx_irq_init(env_archcpu(env));
5837 POWERPC_FAMILY(740)(ObjectClass *oc, void *data)
5839 DeviceClass *dc = DEVICE_CLASS(oc);
5840 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5842 dc->desc = "PowerPC 740";
5843 pcc->init_proc = init_proc_740;
5844 pcc->check_pow = check_pow_hid0;
5845 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5846 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5847 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5848 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5849 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5850 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5851 PPC_SEGMENT | PPC_EXTERN;
5852 pcc->msr_mask = (1ull << MSR_POW) |
5868 pcc->mmu_model = POWERPC_MMU_32B;
5869 #if defined(CONFIG_SOFTMMU)
5870 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5872 pcc->excp_model = POWERPC_EXCP_7x0;
5873 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5874 pcc->bfd_mach = bfd_mach_ppc_750;
5875 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5876 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
5879 static void init_proc_750(CPUPPCState *env)
5881 gen_spr_ne_601(env);
5884 /* XXX : not implemented */
5885 spr_register(env, SPR_L2CR, "L2CR",
5886 SPR_NOACCESS, SPR_NOACCESS,
5887 &spr_read_generic, spr_access_nop,
5891 /* Thermal management */
5893 /* Hardware implementation registers */
5894 /* XXX : not implemented */
5895 spr_register(env, SPR_HID0, "HID0",
5896 SPR_NOACCESS, SPR_NOACCESS,
5897 &spr_read_generic, &spr_write_generic,
5899 /* XXX : not implemented */
5900 spr_register(env, SPR_HID1, "HID1",
5901 SPR_NOACCESS, SPR_NOACCESS,
5902 &spr_read_generic, &spr_write_generic,
5904 /* Memory management */
5907 * XXX: high BATs are also present but are known to be bugged on
5911 env->dcache_line_size = 32;
5912 env->icache_line_size = 32;
5913 /* Allocate hardware IRQ controller */
5914 ppc6xx_irq_init(env_archcpu(env));
5917 POWERPC_FAMILY(750)(ObjectClass *oc, void *data)
5919 DeviceClass *dc = DEVICE_CLASS(oc);
5920 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5922 dc->desc = "PowerPC 750";
5923 pcc->init_proc = init_proc_750;
5924 pcc->check_pow = check_pow_hid0;
5925 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5926 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5927 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5928 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5929 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5930 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5931 PPC_SEGMENT | PPC_EXTERN;
5932 pcc->msr_mask = (1ull << MSR_POW) |
5948 pcc->mmu_model = POWERPC_MMU_32B;
5949 #if defined(CONFIG_SOFTMMU)
5950 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5952 pcc->excp_model = POWERPC_EXCP_7x0;
5953 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5954 pcc->bfd_mach = bfd_mach_ppc_750;
5955 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5956 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
5959 static void init_proc_750cl(CPUPPCState *env)
5961 gen_spr_ne_601(env);
5964 /* XXX : not implemented */
5965 spr_register(env, SPR_L2CR, "L2CR",
5966 SPR_NOACCESS, SPR_NOACCESS,
5967 &spr_read_generic, spr_access_nop,
5971 /* Thermal management */
5972 /* Those registers are fake on 750CL */
5973 spr_register(env, SPR_THRM1, "THRM1",
5974 SPR_NOACCESS, SPR_NOACCESS,
5975 &spr_read_generic, &spr_write_generic,
5977 spr_register(env, SPR_THRM2, "THRM2",
5978 SPR_NOACCESS, SPR_NOACCESS,
5979 &spr_read_generic, &spr_write_generic,
5981 spr_register(env, SPR_THRM3, "THRM3",
5982 SPR_NOACCESS, SPR_NOACCESS,
5983 &spr_read_generic, &spr_write_generic,
5985 /* XXX: not implemented */
5986 spr_register(env, SPR_750_TDCL, "TDCL",
5987 SPR_NOACCESS, SPR_NOACCESS,
5988 &spr_read_generic, &spr_write_generic,
5990 spr_register(env, SPR_750_TDCH, "TDCH",
5991 SPR_NOACCESS, SPR_NOACCESS,
5992 &spr_read_generic, &spr_write_generic,
5995 /* XXX : not implemented */
5996 spr_register(env, SPR_750_WPAR, "WPAR",
5997 SPR_NOACCESS, SPR_NOACCESS,
5998 &spr_read_generic, &spr_write_generic,
6000 spr_register(env, SPR_750_DMAL, "DMAL",
6001 SPR_NOACCESS, SPR_NOACCESS,
6002 &spr_read_generic, &spr_write_generic,
6004 spr_register(env, SPR_750_DMAU, "DMAU",
6005 SPR_NOACCESS, SPR_NOACCESS,
6006 &spr_read_generic, &spr_write_generic,
6008 /* Hardware implementation registers */
6009 /* XXX : not implemented */
6010 spr_register(env, SPR_HID0, "HID0",
6011 SPR_NOACCESS, SPR_NOACCESS,
6012 &spr_read_generic, &spr_write_generic,
6014 /* XXX : not implemented */
6015 spr_register(env, SPR_HID1, "HID1",
6016 SPR_NOACCESS, SPR_NOACCESS,
6017 &spr_read_generic, &spr_write_generic,
6019 /* XXX : not implemented */
6020 spr_register(env, SPR_750CL_HID2, "HID2",
6021 SPR_NOACCESS, SPR_NOACCESS,
6022 &spr_read_generic, &spr_write_generic,
6024 /* XXX : not implemented */
6025 spr_register(env, SPR_750CL_HID4, "HID4",
6026 SPR_NOACCESS, SPR_NOACCESS,
6027 &spr_read_generic, &spr_write_generic,
6029 /* Quantization registers */
6030 /* XXX : not implemented */
6031 spr_register(env, SPR_750_GQR0, "GQR0",
6032 SPR_NOACCESS, SPR_NOACCESS,
6033 &spr_read_generic, &spr_write_generic,
6035 /* XXX : not implemented */
6036 spr_register(env, SPR_750_GQR1, "GQR1",
6037 SPR_NOACCESS, SPR_NOACCESS,
6038 &spr_read_generic, &spr_write_generic,
6040 /* XXX : not implemented */
6041 spr_register(env, SPR_750_GQR2, "GQR2",
6042 SPR_NOACCESS, SPR_NOACCESS,
6043 &spr_read_generic, &spr_write_generic,
6045 /* XXX : not implemented */
6046 spr_register(env, SPR_750_GQR3, "GQR3",
6047 SPR_NOACCESS, SPR_NOACCESS,
6048 &spr_read_generic, &spr_write_generic,
6050 /* XXX : not implemented */
6051 spr_register(env, SPR_750_GQR4, "GQR4",
6052 SPR_NOACCESS, SPR_NOACCESS,
6053 &spr_read_generic, &spr_write_generic,
6055 /* XXX : not implemented */
6056 spr_register(env, SPR_750_GQR5, "GQR5",
6057 SPR_NOACCESS, SPR_NOACCESS,
6058 &spr_read_generic, &spr_write_generic,
6060 /* XXX : not implemented */
6061 spr_register(env, SPR_750_GQR6, "GQR6",
6062 SPR_NOACCESS, SPR_NOACCESS,
6063 &spr_read_generic, &spr_write_generic,
6065 /* XXX : not implemented */
6066 spr_register(env, SPR_750_GQR7, "GQR7",
6067 SPR_NOACCESS, SPR_NOACCESS,
6068 &spr_read_generic, &spr_write_generic,
6070 /* Memory management */
6072 /* PowerPC 750cl has 8 DBATs and 8 IBATs */
6074 init_excp_750cl(env);
6075 env->dcache_line_size = 32;
6076 env->icache_line_size = 32;
6077 /* Allocate hardware IRQ controller */
6078 ppc6xx_irq_init(env_archcpu(env));
6081 POWERPC_FAMILY(750cl)(ObjectClass *oc, void *data)
6083 DeviceClass *dc = DEVICE_CLASS(oc);
6084 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6086 dc->desc = "PowerPC 750 CL";
6087 pcc->init_proc = init_proc_750cl;
6088 pcc->check_pow = check_pow_hid0;
6090 * XXX: not implemented:
6091 * cache lock instructions:
6093 * floating point paired instructions
6128 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6129 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6130 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6131 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6132 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6133 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6134 PPC_SEGMENT | PPC_EXTERN;
6135 pcc->msr_mask = (1ull << MSR_POW) |
6151 pcc->mmu_model = POWERPC_MMU_32B;
6152 #if defined(CONFIG_SOFTMMU)
6153 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6155 pcc->excp_model = POWERPC_EXCP_7x0;
6156 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6157 pcc->bfd_mach = bfd_mach_ppc_750;
6158 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6159 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
6162 static void init_proc_750cx(CPUPPCState *env)
6164 gen_spr_ne_601(env);
6167 /* XXX : not implemented */
6168 spr_register(env, SPR_L2CR, "L2CR",
6169 SPR_NOACCESS, SPR_NOACCESS,
6170 &spr_read_generic, spr_access_nop,
6174 /* Thermal management */
6176 /* This register is not implemented but is present for compatibility */
6177 spr_register(env, SPR_SDA, "SDA",
6178 SPR_NOACCESS, SPR_NOACCESS,
6179 &spr_read_generic, &spr_write_generic,
6181 /* Hardware implementation registers */
6182 /* XXX : not implemented */
6183 spr_register(env, SPR_HID0, "HID0",
6184 SPR_NOACCESS, SPR_NOACCESS,
6185 &spr_read_generic, &spr_write_generic,
6187 /* XXX : not implemented */
6188 spr_register(env, SPR_HID1, "HID1",
6189 SPR_NOACCESS, SPR_NOACCESS,
6190 &spr_read_generic, &spr_write_generic,
6192 /* Memory management */
6194 /* PowerPC 750cx has 8 DBATs and 8 IBATs */
6196 init_excp_750cx(env);
6197 env->dcache_line_size = 32;
6198 env->icache_line_size = 32;
6199 /* Allocate hardware IRQ controller */
6200 ppc6xx_irq_init(env_archcpu(env));
6203 POWERPC_FAMILY(750cx)(ObjectClass *oc, void *data)
6205 DeviceClass *dc = DEVICE_CLASS(oc);
6206 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6208 dc->desc = "PowerPC 750CX";
6209 pcc->init_proc = init_proc_750cx;
6210 pcc->check_pow = check_pow_hid0;
6211 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6212 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6213 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6214 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6215 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6216 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6217 PPC_SEGMENT | PPC_EXTERN;
6218 pcc->msr_mask = (1ull << MSR_POW) |
6234 pcc->mmu_model = POWERPC_MMU_32B;
6235 #if defined(CONFIG_SOFTMMU)
6236 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6238 pcc->excp_model = POWERPC_EXCP_7x0;
6239 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6240 pcc->bfd_mach = bfd_mach_ppc_750;
6241 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6242 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
6245 static void init_proc_750fx(CPUPPCState *env)
6247 gen_spr_ne_601(env);
6250 /* XXX : not implemented */
6251 spr_register(env, SPR_L2CR, "L2CR",
6252 SPR_NOACCESS, SPR_NOACCESS,
6253 &spr_read_generic, spr_access_nop,
6257 /* Thermal management */
6259 /* XXX : not implemented */
6260 spr_register(env, SPR_750_THRM4, "THRM4",
6261 SPR_NOACCESS, SPR_NOACCESS,
6262 &spr_read_generic, &spr_write_generic,
6264 /* Hardware implementation registers */
6265 /* XXX : not implemented */
6266 spr_register(env, SPR_HID0, "HID0",
6267 SPR_NOACCESS, SPR_NOACCESS,
6268 &spr_read_generic, &spr_write_generic,
6270 /* XXX : not implemented */
6271 spr_register(env, SPR_HID1, "HID1",
6272 SPR_NOACCESS, SPR_NOACCESS,
6273 &spr_read_generic, &spr_write_generic,
6275 /* XXX : not implemented */
6276 spr_register(env, SPR_750FX_HID2, "HID2",
6277 SPR_NOACCESS, SPR_NOACCESS,
6278 &spr_read_generic, &spr_write_generic,
6280 /* Memory management */
6282 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6285 env->dcache_line_size = 32;
6286 env->icache_line_size = 32;
6287 /* Allocate hardware IRQ controller */
6288 ppc6xx_irq_init(env_archcpu(env));
6291 POWERPC_FAMILY(750fx)(ObjectClass *oc, void *data)
6293 DeviceClass *dc = DEVICE_CLASS(oc);
6294 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6296 dc->desc = "PowerPC 750FX";
6297 pcc->init_proc = init_proc_750fx;
6298 pcc->check_pow = check_pow_hid0;
6299 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6300 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6301 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6302 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6303 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6304 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6305 PPC_SEGMENT | PPC_EXTERN;
6306 pcc->msr_mask = (1ull << MSR_POW) |
6322 pcc->mmu_model = POWERPC_MMU_32B;
6323 #if defined(CONFIG_SOFTMMU)
6324 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6326 pcc->excp_model = POWERPC_EXCP_7x0;
6327 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6328 pcc->bfd_mach = bfd_mach_ppc_750;
6329 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6330 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
6333 static void init_proc_750gx(CPUPPCState *env)
6335 gen_spr_ne_601(env);
6338 /* XXX : not implemented (XXX: different from 750fx) */
6339 spr_register(env, SPR_L2CR, "L2CR",
6340 SPR_NOACCESS, SPR_NOACCESS,
6341 &spr_read_generic, spr_access_nop,
6345 /* Thermal management */
6347 /* XXX : not implemented */
6348 spr_register(env, SPR_750_THRM4, "THRM4",
6349 SPR_NOACCESS, SPR_NOACCESS,
6350 &spr_read_generic, &spr_write_generic,
6352 /* Hardware implementation registers */
6353 /* XXX : not implemented (XXX: different from 750fx) */
6354 spr_register(env, SPR_HID0, "HID0",
6355 SPR_NOACCESS, SPR_NOACCESS,
6356 &spr_read_generic, &spr_write_generic,
6358 /* XXX : not implemented */
6359 spr_register(env, SPR_HID1, "HID1",
6360 SPR_NOACCESS, SPR_NOACCESS,
6361 &spr_read_generic, &spr_write_generic,
6363 /* XXX : not implemented (XXX: different from 750fx) */
6364 spr_register(env, SPR_750FX_HID2, "HID2",
6365 SPR_NOACCESS, SPR_NOACCESS,
6366 &spr_read_generic, &spr_write_generic,
6368 /* Memory management */
6370 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6373 env->dcache_line_size = 32;
6374 env->icache_line_size = 32;
6375 /* Allocate hardware IRQ controller */
6376 ppc6xx_irq_init(env_archcpu(env));
6379 POWERPC_FAMILY(750gx)(ObjectClass *oc, void *data)
6381 DeviceClass *dc = DEVICE_CLASS(oc);
6382 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6384 dc->desc = "PowerPC 750GX";
6385 pcc->init_proc = init_proc_750gx;
6386 pcc->check_pow = check_pow_hid0;
6387 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6388 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6389 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6390 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6391 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6392 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6393 PPC_SEGMENT | PPC_EXTERN;
6394 pcc->msr_mask = (1ull << MSR_POW) |
6410 pcc->mmu_model = POWERPC_MMU_32B;
6411 #if defined(CONFIG_SOFTMMU)
6412 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6414 pcc->excp_model = POWERPC_EXCP_7x0;
6415 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6416 pcc->bfd_mach = bfd_mach_ppc_750;
6417 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6418 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
6421 static void init_proc_745(CPUPPCState *env)
6423 gen_spr_ne_601(env);
6426 gen_spr_G2_755(env);
6429 /* Thermal management */
6431 /* Hardware implementation registers */
6432 /* XXX : not implemented */
6433 spr_register(env, SPR_HID0, "HID0",
6434 SPR_NOACCESS, SPR_NOACCESS,
6435 &spr_read_generic, &spr_write_generic,
6437 /* XXX : not implemented */
6438 spr_register(env, SPR_HID1, "HID1",
6439 SPR_NOACCESS, SPR_NOACCESS,
6440 &spr_read_generic, &spr_write_generic,
6442 /* XXX : not implemented */
6443 spr_register(env, SPR_HID2, "HID2",
6444 SPR_NOACCESS, SPR_NOACCESS,
6445 &spr_read_generic, &spr_write_generic,
6447 /* Memory management */
6450 gen_6xx_7xx_soft_tlb(env, 64, 2);
6452 env->dcache_line_size = 32;
6453 env->icache_line_size = 32;
6454 /* Allocate hardware IRQ controller */
6455 ppc6xx_irq_init(env_archcpu(env));
6458 POWERPC_FAMILY(745)(ObjectClass *oc, void *data)
6460 DeviceClass *dc = DEVICE_CLASS(oc);
6461 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6463 dc->desc = "PowerPC 745";
6464 pcc->init_proc = init_proc_745;
6465 pcc->check_pow = check_pow_hid0;
6466 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6467 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6468 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6469 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6470 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6471 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
6472 PPC_SEGMENT | PPC_EXTERN;
6473 pcc->msr_mask = (1ull << MSR_POW) |
6489 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
6490 pcc->excp_model = POWERPC_EXCP_7x5;
6491 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6492 pcc->bfd_mach = bfd_mach_ppc_750;
6493 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6494 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
6497 static void init_proc_755(CPUPPCState *env)
6499 gen_spr_ne_601(env);
6502 gen_spr_G2_755(env);
6505 /* L2 cache control */
6506 /* XXX : not implemented */
6507 spr_register(env, SPR_L2CR, "L2CR",
6508 SPR_NOACCESS, SPR_NOACCESS,
6509 &spr_read_generic, spr_access_nop,
6511 /* XXX : not implemented */
6512 spr_register(env, SPR_L2PMCR, "L2PMCR",
6513 SPR_NOACCESS, SPR_NOACCESS,
6514 &spr_read_generic, &spr_write_generic,
6516 /* Thermal management */
6518 /* Hardware implementation registers */
6519 /* XXX : not implemented */
6520 spr_register(env, SPR_HID0, "HID0",
6521 SPR_NOACCESS, SPR_NOACCESS,
6522 &spr_read_generic, &spr_write_generic,
6524 /* XXX : not implemented */
6525 spr_register(env, SPR_HID1, "HID1",
6526 SPR_NOACCESS, SPR_NOACCESS,
6527 &spr_read_generic, &spr_write_generic,
6529 /* XXX : not implemented */
6530 spr_register(env, SPR_HID2, "HID2",
6531 SPR_NOACCESS, SPR_NOACCESS,
6532 &spr_read_generic, &spr_write_generic,
6534 /* Memory management */
6537 gen_6xx_7xx_soft_tlb(env, 64, 2);
6539 env->dcache_line_size = 32;
6540 env->icache_line_size = 32;
6541 /* Allocate hardware IRQ controller */
6542 ppc6xx_irq_init(env_archcpu(env));
6545 POWERPC_FAMILY(755)(ObjectClass *oc, void *data)
6547 DeviceClass *dc = DEVICE_CLASS(oc);
6548 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6550 dc->desc = "PowerPC 755";
6551 pcc->init_proc = init_proc_755;
6552 pcc->check_pow = check_pow_hid0;
6553 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6554 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6555 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6556 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6557 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6558 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
6559 PPC_SEGMENT | PPC_EXTERN;
6560 pcc->msr_mask = (1ull << MSR_POW) |
6576 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
6577 pcc->excp_model = POWERPC_EXCP_7x5;
6578 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6579 pcc->bfd_mach = bfd_mach_ppc_750;
6580 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6581 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
6584 static void init_proc_7400(CPUPPCState *env)
6586 gen_spr_ne_601(env);
6591 /* 74xx specific SPR */
6593 /* XXX : not implemented */
6594 spr_register(env, SPR_UBAMR, "UBAMR",
6595 &spr_read_ureg, SPR_NOACCESS,
6596 &spr_read_ureg, SPR_NOACCESS,
6598 /* XXX: this seems not implemented on all revisions. */
6599 /* XXX : not implemented */
6600 spr_register(env, SPR_MSSCR1, "MSSCR1",
6601 SPR_NOACCESS, SPR_NOACCESS,
6602 &spr_read_generic, &spr_write_generic,
6604 /* Thermal management */
6606 /* Memory management */
6608 init_excp_7400(env);
6609 env->dcache_line_size = 32;
6610 env->icache_line_size = 32;
6611 /* Allocate hardware IRQ controller */
6612 ppc6xx_irq_init(env_archcpu(env));
6615 POWERPC_FAMILY(7400)(ObjectClass *oc, void *data)
6617 DeviceClass *dc = DEVICE_CLASS(oc);
6618 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6620 dc->desc = "PowerPC 7400 (aka G4)";
6621 pcc->init_proc = init_proc_7400;
6622 pcc->check_pow = check_pow_hid0;
6623 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6624 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6625 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6627 PPC_CACHE | PPC_CACHE_ICBI |
6628 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6629 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6630 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6632 PPC_SEGMENT | PPC_EXTERN |
6634 pcc->msr_mask = (1ull << MSR_VR) |
6651 pcc->mmu_model = POWERPC_MMU_32B;
6652 #if defined(CONFIG_SOFTMMU)
6653 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6655 pcc->excp_model = POWERPC_EXCP_74xx;
6656 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6657 pcc->bfd_mach = bfd_mach_ppc_7400;
6658 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6659 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6660 POWERPC_FLAG_BUS_CLK;
6663 static void init_proc_7410(CPUPPCState *env)
6665 gen_spr_ne_601(env);
6670 /* 74xx specific SPR */
6672 /* XXX : not implemented */
6673 spr_register(env, SPR_UBAMR, "UBAMR",
6674 &spr_read_ureg, SPR_NOACCESS,
6675 &spr_read_ureg, SPR_NOACCESS,
6677 /* Thermal management */
6680 /* XXX : not implemented */
6681 spr_register(env, SPR_L2PMCR, "L2PMCR",
6682 SPR_NOACCESS, SPR_NOACCESS,
6683 &spr_read_generic, &spr_write_generic,
6686 /* XXX : not implemented */
6687 spr_register(env, SPR_LDSTDB, "LDSTDB",
6688 SPR_NOACCESS, SPR_NOACCESS,
6689 &spr_read_generic, &spr_write_generic,
6691 /* Memory management */
6693 init_excp_7400(env);
6694 env->dcache_line_size = 32;
6695 env->icache_line_size = 32;
6696 /* Allocate hardware IRQ controller */
6697 ppc6xx_irq_init(env_archcpu(env));
6700 POWERPC_FAMILY(7410)(ObjectClass *oc, void *data)
6702 DeviceClass *dc = DEVICE_CLASS(oc);
6703 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6705 dc->desc = "PowerPC 7410 (aka G4)";
6706 pcc->init_proc = init_proc_7410;
6707 pcc->check_pow = check_pow_hid0;
6708 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6709 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6710 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6712 PPC_CACHE | PPC_CACHE_ICBI |
6713 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6714 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6715 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6717 PPC_SEGMENT | PPC_EXTERN |
6719 pcc->msr_mask = (1ull << MSR_VR) |
6736 pcc->mmu_model = POWERPC_MMU_32B;
6737 #if defined(CONFIG_SOFTMMU)
6738 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6740 pcc->excp_model = POWERPC_EXCP_74xx;
6741 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6742 pcc->bfd_mach = bfd_mach_ppc_7400;
6743 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6744 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6745 POWERPC_FLAG_BUS_CLK;
6748 static void init_proc_7440(CPUPPCState *env)
6750 gen_spr_ne_601(env);
6755 /* 74xx specific SPR */
6757 /* XXX : not implemented */
6758 spr_register(env, SPR_UBAMR, "UBAMR",
6759 &spr_read_ureg, SPR_NOACCESS,
6760 &spr_read_ureg, SPR_NOACCESS,
6763 /* XXX : not implemented */
6764 spr_register(env, SPR_LDSTCR, "LDSTCR",
6765 SPR_NOACCESS, SPR_NOACCESS,
6766 &spr_read_generic, &spr_write_generic,
6769 /* XXX : not implemented */
6770 spr_register(env, SPR_ICTRL, "ICTRL",
6771 SPR_NOACCESS, SPR_NOACCESS,
6772 &spr_read_generic, &spr_write_generic,
6775 /* XXX : not implemented */
6776 spr_register(env, SPR_MSSSR0, "MSSSR0",
6777 SPR_NOACCESS, SPR_NOACCESS,
6778 &spr_read_generic, &spr_write_generic,
6781 /* XXX : not implemented */
6782 spr_register(env, SPR_7XX_PMC5, "PMC5",
6783 SPR_NOACCESS, SPR_NOACCESS,
6784 &spr_read_generic, &spr_write_generic,
6786 /* XXX : not implemented */
6787 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
6788 &spr_read_ureg, SPR_NOACCESS,
6789 &spr_read_ureg, SPR_NOACCESS,
6791 /* XXX : not implemented */
6792 spr_register(env, SPR_7XX_PMC6, "PMC6",
6793 SPR_NOACCESS, SPR_NOACCESS,
6794 &spr_read_generic, &spr_write_generic,
6796 /* XXX : not implemented */
6797 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
6798 &spr_read_ureg, SPR_NOACCESS,
6799 &spr_read_ureg, SPR_NOACCESS,
6801 /* Memory management */
6803 gen_74xx_soft_tlb(env, 128, 2);
6804 init_excp_7450(env);
6805 env->dcache_line_size = 32;
6806 env->icache_line_size = 32;
6807 /* Allocate hardware IRQ controller */
6808 ppc6xx_irq_init(env_archcpu(env));
6811 POWERPC_FAMILY(7440)(ObjectClass *oc, void *data)
6813 DeviceClass *dc = DEVICE_CLASS(oc);
6814 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6816 dc->desc = "PowerPC 7440 (aka G4)";
6817 pcc->init_proc = init_proc_7440;
6818 pcc->check_pow = check_pow_hid0_74xx;
6819 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6820 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6821 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6823 PPC_CACHE | PPC_CACHE_ICBI |
6824 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6825 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6826 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6827 PPC_MEM_TLBIA | PPC_74xx_TLB |
6828 PPC_SEGMENT | PPC_EXTERN |
6830 pcc->msr_mask = (1ull << MSR_VR) |
6847 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
6848 pcc->excp_model = POWERPC_EXCP_74xx;
6849 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6850 pcc->bfd_mach = bfd_mach_ppc_7400;
6851 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6852 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6853 POWERPC_FLAG_BUS_CLK;
6856 static void init_proc_7450(CPUPPCState *env)
6858 gen_spr_ne_601(env);
6863 /* 74xx specific SPR */
6865 /* Level 3 cache control */
6868 /* XXX : not implemented */
6869 spr_register(env, SPR_L3ITCR1, "L3ITCR1",
6870 SPR_NOACCESS, SPR_NOACCESS,
6871 &spr_read_generic, &spr_write_generic,
6874 /* XXX : not implemented */
6875 spr_register(env, SPR_L3ITCR2, "L3ITCR2",
6876 SPR_NOACCESS, SPR_NOACCESS,
6877 &spr_read_generic, &spr_write_generic,
6880 /* XXX : not implemented */
6881 spr_register(env, SPR_L3ITCR3, "L3ITCR3",
6882 SPR_NOACCESS, SPR_NOACCESS,
6883 &spr_read_generic, &spr_write_generic,
6886 /* XXX : not implemented */
6887 spr_register(env, SPR_L3OHCR, "L3OHCR",
6888 SPR_NOACCESS, SPR_NOACCESS,
6889 &spr_read_generic, &spr_write_generic,
6891 /* XXX : not implemented */
6892 spr_register(env, SPR_UBAMR, "UBAMR",
6893 &spr_read_ureg, SPR_NOACCESS,
6894 &spr_read_ureg, SPR_NOACCESS,
6897 /* XXX : not implemented */
6898 spr_register(env, SPR_LDSTCR, "LDSTCR",
6899 SPR_NOACCESS, SPR_NOACCESS,
6900 &spr_read_generic, &spr_write_generic,
6903 /* XXX : not implemented */
6904 spr_register(env, SPR_ICTRL, "ICTRL",
6905 SPR_NOACCESS, SPR_NOACCESS,
6906 &spr_read_generic, &spr_write_generic,
6909 /* XXX : not implemented */
6910 spr_register(env, SPR_MSSSR0, "MSSSR0",
6911 SPR_NOACCESS, SPR_NOACCESS,
6912 &spr_read_generic, &spr_write_generic,
6915 /* XXX : not implemented */
6916 spr_register(env, SPR_7XX_PMC5, "PMC5",
6917 SPR_NOACCESS, SPR_NOACCESS,
6918 &spr_read_generic, &spr_write_generic,
6920 /* XXX : not implemented */
6921 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
6922 &spr_read_ureg, SPR_NOACCESS,
6923 &spr_read_ureg, SPR_NOACCESS,
6925 /* XXX : not implemented */
6926 spr_register(env, SPR_7XX_PMC6, "PMC6",
6927 SPR_NOACCESS, SPR_NOACCESS,
6928 &spr_read_generic, &spr_write_generic,
6930 /* XXX : not implemented */
6931 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
6932 &spr_read_ureg, SPR_NOACCESS,
6933 &spr_read_ureg, SPR_NOACCESS,
6935 /* Memory management */
6937 gen_74xx_soft_tlb(env, 128, 2);
6938 init_excp_7450(env);
6939 env->dcache_line_size = 32;
6940 env->icache_line_size = 32;
6941 /* Allocate hardware IRQ controller */
6942 ppc6xx_irq_init(env_archcpu(env));
6945 POWERPC_FAMILY(7450)(ObjectClass *oc, void *data)
6947 DeviceClass *dc = DEVICE_CLASS(oc);
6948 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6950 dc->desc = "PowerPC 7450 (aka G4)";
6951 pcc->init_proc = init_proc_7450;
6952 pcc->check_pow = check_pow_hid0_74xx;
6953 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6954 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6955 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6957 PPC_CACHE | PPC_CACHE_ICBI |
6958 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6959 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6960 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6961 PPC_MEM_TLBIA | PPC_74xx_TLB |
6962 PPC_SEGMENT | PPC_EXTERN |
6964 pcc->msr_mask = (1ull << MSR_VR) |
6981 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
6982 pcc->excp_model = POWERPC_EXCP_74xx;
6983 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6984 pcc->bfd_mach = bfd_mach_ppc_7400;
6985 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6986 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6987 POWERPC_FLAG_BUS_CLK;
6990 static void init_proc_7445(CPUPPCState *env)
6992 gen_spr_ne_601(env);
6997 /* 74xx specific SPR */
7000 /* XXX : not implemented */
7001 spr_register(env, SPR_LDSTCR, "LDSTCR",
7002 SPR_NOACCESS, SPR_NOACCESS,
7003 &spr_read_generic, &spr_write_generic,
7006 /* XXX : not implemented */
7007 spr_register(env, SPR_ICTRL, "ICTRL",
7008 SPR_NOACCESS, SPR_NOACCESS,
7009 &spr_read_generic, &spr_write_generic,
7012 /* XXX : not implemented */
7013 spr_register(env, SPR_MSSSR0, "MSSSR0",
7014 SPR_NOACCESS, SPR_NOACCESS,
7015 &spr_read_generic, &spr_write_generic,
7018 /* XXX : not implemented */
7019 spr_register(env, SPR_7XX_PMC5, "PMC5",
7020 SPR_NOACCESS, SPR_NOACCESS,
7021 &spr_read_generic, &spr_write_generic,
7023 /* XXX : not implemented */
7024 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
7025 &spr_read_ureg, SPR_NOACCESS,
7026 &spr_read_ureg, SPR_NOACCESS,
7028 /* XXX : not implemented */
7029 spr_register(env, SPR_7XX_PMC6, "PMC6",
7030 SPR_NOACCESS, SPR_NOACCESS,
7031 &spr_read_generic, &spr_write_generic,
7033 /* XXX : not implemented */
7034 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
7035 &spr_read_ureg, SPR_NOACCESS,
7036 &spr_read_ureg, SPR_NOACCESS,
7039 spr_register(env, SPR_SPRG4, "SPRG4",
7040 SPR_NOACCESS, SPR_NOACCESS,
7041 &spr_read_generic, &spr_write_generic,
7043 spr_register(env, SPR_USPRG4, "USPRG4",
7044 &spr_read_ureg, SPR_NOACCESS,
7045 &spr_read_ureg, SPR_NOACCESS,
7047 spr_register(env, SPR_SPRG5, "SPRG5",
7048 SPR_NOACCESS, SPR_NOACCESS,
7049 &spr_read_generic, &spr_write_generic,
7051 spr_register(env, SPR_USPRG5, "USPRG5",
7052 &spr_read_ureg, SPR_NOACCESS,
7053 &spr_read_ureg, SPR_NOACCESS,
7055 spr_register(env, SPR_SPRG6, "SPRG6",
7056 SPR_NOACCESS, SPR_NOACCESS,
7057 &spr_read_generic, &spr_write_generic,
7059 spr_register(env, SPR_USPRG6, "USPRG6",
7060 &spr_read_ureg, SPR_NOACCESS,
7061 &spr_read_ureg, SPR_NOACCESS,
7063 spr_register(env, SPR_SPRG7, "SPRG7",
7064 SPR_NOACCESS, SPR_NOACCESS,
7065 &spr_read_generic, &spr_write_generic,
7067 spr_register(env, SPR_USPRG7, "USPRG7",
7068 &spr_read_ureg, SPR_NOACCESS,
7069 &spr_read_ureg, SPR_NOACCESS,
7071 /* Memory management */
7074 gen_74xx_soft_tlb(env, 128, 2);
7075 init_excp_7450(env);
7076 env->dcache_line_size = 32;
7077 env->icache_line_size = 32;
7078 /* Allocate hardware IRQ controller */
7079 ppc6xx_irq_init(env_archcpu(env));
7082 POWERPC_FAMILY(7445)(ObjectClass *oc, void *data)
7084 DeviceClass *dc = DEVICE_CLASS(oc);
7085 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7087 dc->desc = "PowerPC 7445 (aka G4)";
7088 pcc->init_proc = init_proc_7445;
7089 pcc->check_pow = check_pow_hid0_74xx;
7090 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7091 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7092 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7094 PPC_CACHE | PPC_CACHE_ICBI |
7095 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7096 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7097 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7098 PPC_MEM_TLBIA | PPC_74xx_TLB |
7099 PPC_SEGMENT | PPC_EXTERN |
7101 pcc->msr_mask = (1ull << MSR_VR) |
7118 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
7119 pcc->excp_model = POWERPC_EXCP_74xx;
7120 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7121 pcc->bfd_mach = bfd_mach_ppc_7400;
7122 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7123 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7124 POWERPC_FLAG_BUS_CLK;
7127 static void init_proc_7455(CPUPPCState *env)
7129 gen_spr_ne_601(env);
7134 /* 74xx specific SPR */
7136 /* Level 3 cache control */
7139 /* XXX : not implemented */
7140 spr_register(env, SPR_LDSTCR, "LDSTCR",
7141 SPR_NOACCESS, SPR_NOACCESS,
7142 &spr_read_generic, &spr_write_generic,
7145 /* XXX : not implemented */
7146 spr_register(env, SPR_ICTRL, "ICTRL",
7147 SPR_NOACCESS, SPR_NOACCESS,
7148 &spr_read_generic, &spr_write_generic,
7151 /* XXX : not implemented */
7152 spr_register(env, SPR_MSSSR0, "MSSSR0",
7153 SPR_NOACCESS, SPR_NOACCESS,
7154 &spr_read_generic, &spr_write_generic,
7157 /* XXX : not implemented */
7158 spr_register(env, SPR_7XX_PMC5, "PMC5",
7159 SPR_NOACCESS, SPR_NOACCESS,
7160 &spr_read_generic, &spr_write_generic,
7162 /* XXX : not implemented */
7163 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
7164 &spr_read_ureg, SPR_NOACCESS,
7165 &spr_read_ureg, SPR_NOACCESS,
7167 /* XXX : not implemented */
7168 spr_register(env, SPR_7XX_PMC6, "PMC6",
7169 SPR_NOACCESS, SPR_NOACCESS,
7170 &spr_read_generic, &spr_write_generic,
7172 /* XXX : not implemented */
7173 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
7174 &spr_read_ureg, SPR_NOACCESS,
7175 &spr_read_ureg, SPR_NOACCESS,
7178 spr_register(env, SPR_SPRG4, "SPRG4",
7179 SPR_NOACCESS, SPR_NOACCESS,
7180 &spr_read_generic, &spr_write_generic,
7182 spr_register(env, SPR_USPRG4, "USPRG4",
7183 &spr_read_ureg, SPR_NOACCESS,
7184 &spr_read_ureg, SPR_NOACCESS,
7186 spr_register(env, SPR_SPRG5, "SPRG5",
7187 SPR_NOACCESS, SPR_NOACCESS,
7188 &spr_read_generic, &spr_write_generic,
7190 spr_register(env, SPR_USPRG5, "USPRG5",
7191 &spr_read_ureg, SPR_NOACCESS,
7192 &spr_read_ureg, SPR_NOACCESS,
7194 spr_register(env, SPR_SPRG6, "SPRG6",
7195 SPR_NOACCESS, SPR_NOACCESS,
7196 &spr_read_generic, &spr_write_generic,
7198 spr_register(env, SPR_USPRG6, "USPRG6",
7199 &spr_read_ureg, SPR_NOACCESS,
7200 &spr_read_ureg, SPR_NOACCESS,
7202 spr_register(env, SPR_SPRG7, "SPRG7",
7203 SPR_NOACCESS, SPR_NOACCESS,
7204 &spr_read_generic, &spr_write_generic,
7206 spr_register(env, SPR_USPRG7, "USPRG7",
7207 &spr_read_ureg, SPR_NOACCESS,
7208 &spr_read_ureg, SPR_NOACCESS,
7210 /* Memory management */
7213 gen_74xx_soft_tlb(env, 128, 2);
7214 init_excp_7450(env);
7215 env->dcache_line_size = 32;
7216 env->icache_line_size = 32;
7217 /* Allocate hardware IRQ controller */
7218 ppc6xx_irq_init(env_archcpu(env));
7221 POWERPC_FAMILY(7455)(ObjectClass *oc, void *data)
7223 DeviceClass *dc = DEVICE_CLASS(oc);
7224 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7226 dc->desc = "PowerPC 7455 (aka G4)";
7227 pcc->init_proc = init_proc_7455;
7228 pcc->check_pow = check_pow_hid0_74xx;
7229 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7230 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7231 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7233 PPC_CACHE | PPC_CACHE_ICBI |
7234 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7235 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7236 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7237 PPC_MEM_TLBIA | PPC_74xx_TLB |
7238 PPC_SEGMENT | PPC_EXTERN |
7240 pcc->msr_mask = (1ull << MSR_VR) |
7257 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
7258 pcc->excp_model = POWERPC_EXCP_74xx;
7259 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7260 pcc->bfd_mach = bfd_mach_ppc_7400;
7261 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7262 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7263 POWERPC_FLAG_BUS_CLK;
7266 static void init_proc_7457(CPUPPCState *env)
7268 gen_spr_ne_601(env);
7273 /* 74xx specific SPR */
7275 /* Level 3 cache control */
7278 /* XXX : not implemented */
7279 spr_register(env, SPR_L3ITCR1, "L3ITCR1",
7280 SPR_NOACCESS, SPR_NOACCESS,
7281 &spr_read_generic, &spr_write_generic,
7284 /* XXX : not implemented */
7285 spr_register(env, SPR_L3ITCR2, "L3ITCR2",
7286 SPR_NOACCESS, SPR_NOACCESS,
7287 &spr_read_generic, &spr_write_generic,
7290 /* XXX : not implemented */
7291 spr_register(env, SPR_L3ITCR3, "L3ITCR3",
7292 SPR_NOACCESS, SPR_NOACCESS,
7293 &spr_read_generic, &spr_write_generic,
7296 /* XXX : not implemented */
7297 spr_register(env, SPR_L3OHCR, "L3OHCR",
7298 SPR_NOACCESS, SPR_NOACCESS,
7299 &spr_read_generic, &spr_write_generic,
7302 /* XXX : not implemented */
7303 spr_register(env, SPR_LDSTCR, "LDSTCR",
7304 SPR_NOACCESS, SPR_NOACCESS,
7305 &spr_read_generic, &spr_write_generic,
7308 /* XXX : not implemented */
7309 spr_register(env, SPR_ICTRL, "ICTRL",
7310 SPR_NOACCESS, SPR_NOACCESS,
7311 &spr_read_generic, &spr_write_generic,
7314 /* XXX : not implemented */
7315 spr_register(env, SPR_MSSSR0, "MSSSR0",
7316 SPR_NOACCESS, SPR_NOACCESS,
7317 &spr_read_generic, &spr_write_generic,
7320 /* XXX : not implemented */
7321 spr_register(env, SPR_7XX_PMC5, "PMC5",
7322 SPR_NOACCESS, SPR_NOACCESS,
7323 &spr_read_generic, &spr_write_generic,
7325 /* XXX : not implemented */
7326 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
7327 &spr_read_ureg, SPR_NOACCESS,
7328 &spr_read_ureg, SPR_NOACCESS,
7330 /* XXX : not implemented */
7331 spr_register(env, SPR_7XX_PMC6, "PMC6",
7332 SPR_NOACCESS, SPR_NOACCESS,
7333 &spr_read_generic, &spr_write_generic,
7335 /* XXX : not implemented */
7336 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
7337 &spr_read_ureg, SPR_NOACCESS,
7338 &spr_read_ureg, SPR_NOACCESS,
7341 spr_register(env, SPR_SPRG4, "SPRG4",
7342 SPR_NOACCESS, SPR_NOACCESS,
7343 &spr_read_generic, &spr_write_generic,
7345 spr_register(env, SPR_USPRG4, "USPRG4",
7346 &spr_read_ureg, SPR_NOACCESS,
7347 &spr_read_ureg, SPR_NOACCESS,
7349 spr_register(env, SPR_SPRG5, "SPRG5",
7350 SPR_NOACCESS, SPR_NOACCESS,
7351 &spr_read_generic, &spr_write_generic,
7353 spr_register(env, SPR_USPRG5, "USPRG5",
7354 &spr_read_ureg, SPR_NOACCESS,
7355 &spr_read_ureg, SPR_NOACCESS,
7357 spr_register(env, SPR_SPRG6, "SPRG6",
7358 SPR_NOACCESS, SPR_NOACCESS,
7359 &spr_read_generic, &spr_write_generic,
7361 spr_register(env, SPR_USPRG6, "USPRG6",
7362 &spr_read_ureg, SPR_NOACCESS,
7363 &spr_read_ureg, SPR_NOACCESS,
7365 spr_register(env, SPR_SPRG7, "SPRG7",
7366 SPR_NOACCESS, SPR_NOACCESS,
7367 &spr_read_generic, &spr_write_generic,
7369 spr_register(env, SPR_USPRG7, "USPRG7",
7370 &spr_read_ureg, SPR_NOACCESS,
7371 &spr_read_ureg, SPR_NOACCESS,
7373 /* Memory management */
7376 gen_74xx_soft_tlb(env, 128, 2);
7377 init_excp_7450(env);
7378 env->dcache_line_size = 32;
7379 env->icache_line_size = 32;
7380 /* Allocate hardware IRQ controller */
7381 ppc6xx_irq_init(env_archcpu(env));
7384 POWERPC_FAMILY(7457)(ObjectClass *oc, void *data)
7386 DeviceClass *dc = DEVICE_CLASS(oc);
7387 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7389 dc->desc = "PowerPC 7457 (aka G4)";
7390 pcc->init_proc = init_proc_7457;
7391 pcc->check_pow = check_pow_hid0_74xx;
7392 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7393 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7394 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7396 PPC_CACHE | PPC_CACHE_ICBI |
7397 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7398 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7399 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7400 PPC_MEM_TLBIA | PPC_74xx_TLB |
7401 PPC_SEGMENT | PPC_EXTERN |
7403 pcc->msr_mask = (1ull << MSR_VR) |
7420 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
7421 pcc->excp_model = POWERPC_EXCP_74xx;
7422 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7423 pcc->bfd_mach = bfd_mach_ppc_7400;
7424 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7425 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7426 POWERPC_FLAG_BUS_CLK;
7429 static void init_proc_e600(CPUPPCState *env)
7431 gen_spr_ne_601(env);
7436 /* 74xx specific SPR */
7438 /* XXX : not implemented */
7439 spr_register(env, SPR_UBAMR, "UBAMR",
7440 &spr_read_ureg, SPR_NOACCESS,
7441 &spr_read_ureg, SPR_NOACCESS,
7443 /* XXX : not implemented */
7444 spr_register(env, SPR_LDSTCR, "LDSTCR",
7445 SPR_NOACCESS, SPR_NOACCESS,
7446 &spr_read_generic, &spr_write_generic,
7448 /* XXX : not implemented */
7449 spr_register(env, SPR_ICTRL, "ICTRL",
7450 SPR_NOACCESS, SPR_NOACCESS,
7451 &spr_read_generic, &spr_write_generic,
7453 /* XXX : not implemented */
7454 spr_register(env, SPR_MSSSR0, "MSSSR0",
7455 SPR_NOACCESS, SPR_NOACCESS,
7456 &spr_read_generic, &spr_write_generic,
7458 /* XXX : not implemented */
7459 spr_register(env, SPR_7XX_PMC5, "PMC5",
7460 SPR_NOACCESS, SPR_NOACCESS,
7461 &spr_read_generic, &spr_write_generic,
7463 /* XXX : not implemented */
7464 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
7465 &spr_read_ureg, SPR_NOACCESS,
7466 &spr_read_ureg, SPR_NOACCESS,
7468 /* XXX : not implemented */
7469 spr_register(env, SPR_7XX_PMC6, "PMC6",
7470 SPR_NOACCESS, SPR_NOACCESS,
7471 &spr_read_generic, &spr_write_generic,
7473 /* XXX : not implemented */
7474 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
7475 &spr_read_ureg, SPR_NOACCESS,
7476 &spr_read_ureg, SPR_NOACCESS,
7479 spr_register(env, SPR_SPRG4, "SPRG4",
7480 SPR_NOACCESS, SPR_NOACCESS,
7481 &spr_read_generic, &spr_write_generic,
7483 spr_register(env, SPR_USPRG4, "USPRG4",
7484 &spr_read_ureg, SPR_NOACCESS,
7485 &spr_read_ureg, SPR_NOACCESS,
7487 spr_register(env, SPR_SPRG5, "SPRG5",
7488 SPR_NOACCESS, SPR_NOACCESS,
7489 &spr_read_generic, &spr_write_generic,
7491 spr_register(env, SPR_USPRG5, "USPRG5",
7492 &spr_read_ureg, SPR_NOACCESS,
7493 &spr_read_ureg, SPR_NOACCESS,
7495 spr_register(env, SPR_SPRG6, "SPRG6",
7496 SPR_NOACCESS, SPR_NOACCESS,
7497 &spr_read_generic, &spr_write_generic,
7499 spr_register(env, SPR_USPRG6, "USPRG6",
7500 &spr_read_ureg, SPR_NOACCESS,
7501 &spr_read_ureg, SPR_NOACCESS,
7503 spr_register(env, SPR_SPRG7, "SPRG7",
7504 SPR_NOACCESS, SPR_NOACCESS,
7505 &spr_read_generic, &spr_write_generic,
7507 spr_register(env, SPR_USPRG7, "USPRG7",
7508 &spr_read_ureg, SPR_NOACCESS,
7509 &spr_read_ureg, SPR_NOACCESS,
7511 /* Memory management */
7514 gen_74xx_soft_tlb(env, 128, 2);
7515 init_excp_7450(env);
7516 env->dcache_line_size = 32;
7517 env->icache_line_size = 32;
7518 /* Allocate hardware IRQ controller */
7519 ppc6xx_irq_init(env_archcpu(env));
7522 POWERPC_FAMILY(e600)(ObjectClass *oc, void *data)
7524 DeviceClass *dc = DEVICE_CLASS(oc);
7525 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7527 dc->desc = "PowerPC e600";
7528 pcc->init_proc = init_proc_e600;
7529 pcc->check_pow = check_pow_hid0_74xx;
7530 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7531 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7532 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7534 PPC_CACHE | PPC_CACHE_ICBI |
7535 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7536 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7537 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7538 PPC_MEM_TLBIA | PPC_74xx_TLB |
7539 PPC_SEGMENT | PPC_EXTERN |
7541 pcc->insns_flags2 = PPC_NONE;
7542 pcc->msr_mask = (1ull << MSR_VR) |
7559 pcc->mmu_model = POWERPC_MMU_32B;
7560 #if defined(CONFIG_SOFTMMU)
7561 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
7563 pcc->excp_model = POWERPC_EXCP_74xx;
7564 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7565 pcc->bfd_mach = bfd_mach_ppc_7400;
7566 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7567 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7568 POWERPC_FLAG_BUS_CLK;
7571 #if defined(TARGET_PPC64)
7572 #if defined(CONFIG_USER_ONLY)
7573 #define POWERPC970_HID5_INIT 0x00000080
7575 #define POWERPC970_HID5_INIT 0x00000000
7578 static void gen_fscr_facility_check(DisasContext *ctx, int facility_sprn,
7579 int bit, int sprn, int cause)
7581 TCGv_i32 t1 = tcg_const_i32(bit);
7582 TCGv_i32 t2 = tcg_const_i32(sprn);
7583 TCGv_i32 t3 = tcg_const_i32(cause);
7585 gen_helper_fscr_facility_check(cpu_env, t1, t2, t3);
7587 tcg_temp_free_i32(t3);
7588 tcg_temp_free_i32(t2);
7589 tcg_temp_free_i32(t1);
7592 static void gen_msr_facility_check(DisasContext *ctx, int facility_sprn,
7593 int bit, int sprn, int cause)
7595 TCGv_i32 t1 = tcg_const_i32(bit);
7596 TCGv_i32 t2 = tcg_const_i32(sprn);
7597 TCGv_i32 t3 = tcg_const_i32(cause);
7599 gen_helper_msr_facility_check(cpu_env, t1, t2, t3);
7601 tcg_temp_free_i32(t3);
7602 tcg_temp_free_i32(t2);
7603 tcg_temp_free_i32(t1);
7606 static void spr_read_prev_upper32(DisasContext *ctx, int gprn, int sprn)
7608 TCGv spr_up = tcg_temp_new();
7609 TCGv spr = tcg_temp_new();
7611 gen_load_spr(spr, sprn - 1);
7612 tcg_gen_shri_tl(spr_up, spr, 32);
7613 tcg_gen_ext32u_tl(cpu_gpr[gprn], spr_up);
7616 tcg_temp_free(spr_up);
7619 static void spr_write_prev_upper32(DisasContext *ctx, int sprn, int gprn)
7621 TCGv spr = tcg_temp_new();
7623 gen_load_spr(spr, sprn - 1);
7624 tcg_gen_deposit_tl(spr, spr, cpu_gpr[gprn], 32, 32);
7625 gen_store_spr(sprn - 1, spr);
7630 static int check_pow_970(CPUPPCState *env)
7632 if (env->spr[SPR_HID0] & (HID0_DEEPNAP | HID0_DOZE | HID0_NAP)) {
7639 static void gen_spr_970_hid(CPUPPCState *env)
7641 /* Hardware implementation registers */
7642 /* XXX : not implemented */
7643 spr_register(env, SPR_HID0, "HID0",
7644 SPR_NOACCESS, SPR_NOACCESS,
7645 &spr_read_generic, &spr_write_clear,
7647 spr_register(env, SPR_HID1, "HID1",
7648 SPR_NOACCESS, SPR_NOACCESS,
7649 &spr_read_generic, &spr_write_generic,
7651 spr_register(env, SPR_970_HID5, "HID5",
7652 SPR_NOACCESS, SPR_NOACCESS,
7653 &spr_read_generic, &spr_write_generic,
7654 POWERPC970_HID5_INIT);
7657 static void gen_spr_970_hior(CPUPPCState *env)
7659 spr_register(env, SPR_HIOR, "SPR_HIOR",
7660 SPR_NOACCESS, SPR_NOACCESS,
7661 &spr_read_hior, &spr_write_hior,
7665 static void gen_spr_book3s_ctrl(CPUPPCState *env)
7667 spr_register(env, SPR_CTRL, "SPR_CTRL",
7668 SPR_NOACCESS, SPR_NOACCESS,
7669 SPR_NOACCESS, &spr_write_generic,
7671 spr_register(env, SPR_UCTRL, "SPR_UCTRL",
7672 &spr_read_ureg, SPR_NOACCESS,
7673 &spr_read_ureg, SPR_NOACCESS,
7677 static void gen_spr_book3s_altivec(CPUPPCState *env)
7679 if (!(env->insns_flags & PPC_ALTIVEC)) {
7683 spr_register_kvm(env, SPR_VRSAVE, "VRSAVE",
7684 &spr_read_generic, &spr_write_generic,
7685 &spr_read_generic, &spr_write_generic,
7686 KVM_REG_PPC_VRSAVE, 0x00000000);
7689 * Can't find information on what this should be on reset. This
7690 * value is the one used by 74xx processors.
7692 vscr_init(env, 0x00010000);
7695 static void gen_spr_book3s_dbg(CPUPPCState *env)
7698 * TODO: different specs define different scopes for these,
7699 * will have to address this:
7700 * 970: super/write and super/read
7701 * powerisa 2.03..2.04: hypv/write and super/read.
7702 * powerisa 2.05 and newer: hypv/write and hypv/read.
7704 spr_register_kvm(env, SPR_DABR, "DABR",
7705 SPR_NOACCESS, SPR_NOACCESS,
7706 &spr_read_generic, &spr_write_generic,
7707 KVM_REG_PPC_DABR, 0x00000000);
7708 spr_register_kvm(env, SPR_DABRX, "DABRX",
7709 SPR_NOACCESS, SPR_NOACCESS,
7710 &spr_read_generic, &spr_write_generic,
7711 KVM_REG_PPC_DABRX, 0x00000000);
7714 static void gen_spr_book3s_207_dbg(CPUPPCState *env)
7716 spr_register_kvm_hv(env, SPR_DAWR, "DAWR",
7717 SPR_NOACCESS, SPR_NOACCESS,
7718 SPR_NOACCESS, SPR_NOACCESS,
7719 &spr_read_generic, &spr_write_generic,
7720 KVM_REG_PPC_DAWR, 0x00000000);
7721 spr_register_kvm_hv(env, SPR_DAWRX, "DAWRX",
7722 SPR_NOACCESS, SPR_NOACCESS,
7723 SPR_NOACCESS, SPR_NOACCESS,
7724 &spr_read_generic, &spr_write_generic,
7725 KVM_REG_PPC_DAWRX, 0x00000000);
7726 spr_register_kvm_hv(env, SPR_CIABR, "CIABR",
7727 SPR_NOACCESS, SPR_NOACCESS,
7728 SPR_NOACCESS, SPR_NOACCESS,
7729 &spr_read_generic, &spr_write_generic,
7730 KVM_REG_PPC_CIABR, 0x00000000);
7733 static void gen_spr_970_dbg(CPUPPCState *env)
7736 spr_register(env, SPR_IABR, "IABR",
7737 SPR_NOACCESS, SPR_NOACCESS,
7738 &spr_read_generic, &spr_write_generic,
7742 static void gen_spr_book3s_pmu_sup(CPUPPCState *env)
7744 spr_register_kvm(env, SPR_POWER_MMCR0, "MMCR0",
7745 SPR_NOACCESS, SPR_NOACCESS,
7746 &spr_read_generic, &spr_write_generic,
7747 KVM_REG_PPC_MMCR0, 0x00000000);
7748 spr_register_kvm(env, SPR_POWER_MMCR1, "MMCR1",
7749 SPR_NOACCESS, SPR_NOACCESS,
7750 &spr_read_generic, &spr_write_generic,
7751 KVM_REG_PPC_MMCR1, 0x00000000);
7752 spr_register_kvm(env, SPR_POWER_MMCRA, "MMCRA",
7753 SPR_NOACCESS, SPR_NOACCESS,
7754 &spr_read_generic, &spr_write_generic,
7755 KVM_REG_PPC_MMCRA, 0x00000000);
7756 spr_register_kvm(env, SPR_POWER_PMC1, "PMC1",
7757 SPR_NOACCESS, SPR_NOACCESS,
7758 &spr_read_generic, &spr_write_generic,
7759 KVM_REG_PPC_PMC1, 0x00000000);
7760 spr_register_kvm(env, SPR_POWER_PMC2, "PMC2",
7761 SPR_NOACCESS, SPR_NOACCESS,
7762 &spr_read_generic, &spr_write_generic,
7763 KVM_REG_PPC_PMC2, 0x00000000);
7764 spr_register_kvm(env, SPR_POWER_PMC3, "PMC3",
7765 SPR_NOACCESS, SPR_NOACCESS,
7766 &spr_read_generic, &spr_write_generic,
7767 KVM_REG_PPC_PMC3, 0x00000000);
7768 spr_register_kvm(env, SPR_POWER_PMC4, "PMC4",
7769 SPR_NOACCESS, SPR_NOACCESS,
7770 &spr_read_generic, &spr_write_generic,
7771 KVM_REG_PPC_PMC4, 0x00000000);
7772 spr_register_kvm(env, SPR_POWER_PMC5, "PMC5",
7773 SPR_NOACCESS, SPR_NOACCESS,
7774 &spr_read_generic, &spr_write_generic,
7775 KVM_REG_PPC_PMC5, 0x00000000);
7776 spr_register_kvm(env, SPR_POWER_PMC6, "PMC6",
7777 SPR_NOACCESS, SPR_NOACCESS,
7778 &spr_read_generic, &spr_write_generic,
7779 KVM_REG_PPC_PMC6, 0x00000000);
7780 spr_register_kvm(env, SPR_POWER_SIAR, "SIAR",
7781 SPR_NOACCESS, SPR_NOACCESS,
7782 &spr_read_generic, &spr_write_generic,
7783 KVM_REG_PPC_SIAR, 0x00000000);
7784 spr_register_kvm(env, SPR_POWER_SDAR, "SDAR",
7785 SPR_NOACCESS, SPR_NOACCESS,
7786 &spr_read_generic, &spr_write_generic,
7787 KVM_REG_PPC_SDAR, 0x00000000);
7790 static void gen_spr_book3s_pmu_user(CPUPPCState *env)
7792 spr_register(env, SPR_POWER_UMMCR0, "UMMCR0",
7793 &spr_read_ureg, SPR_NOACCESS,
7794 &spr_read_ureg, &spr_write_ureg,
7796 spr_register(env, SPR_POWER_UMMCR1, "UMMCR1",
7797 &spr_read_ureg, SPR_NOACCESS,
7798 &spr_read_ureg, &spr_write_ureg,
7800 spr_register(env, SPR_POWER_UMMCRA, "UMMCRA",
7801 &spr_read_ureg, SPR_NOACCESS,
7802 &spr_read_ureg, &spr_write_ureg,
7804 spr_register(env, SPR_POWER_UPMC1, "UPMC1",
7805 &spr_read_ureg, SPR_NOACCESS,
7806 &spr_read_ureg, &spr_write_ureg,
7808 spr_register(env, SPR_POWER_UPMC2, "UPMC2",
7809 &spr_read_ureg, SPR_NOACCESS,
7810 &spr_read_ureg, &spr_write_ureg,
7812 spr_register(env, SPR_POWER_UPMC3, "UPMC3",
7813 &spr_read_ureg, SPR_NOACCESS,
7814 &spr_read_ureg, &spr_write_ureg,
7816 spr_register(env, SPR_POWER_UPMC4, "UPMC4",
7817 &spr_read_ureg, SPR_NOACCESS,
7818 &spr_read_ureg, &spr_write_ureg,
7820 spr_register(env, SPR_POWER_UPMC5, "UPMC5",
7821 &spr_read_ureg, SPR_NOACCESS,
7822 &spr_read_ureg, &spr_write_ureg,
7824 spr_register(env, SPR_POWER_UPMC6, "UPMC6",
7825 &spr_read_ureg, SPR_NOACCESS,
7826 &spr_read_ureg, &spr_write_ureg,
7828 spr_register(env, SPR_POWER_USIAR, "USIAR",
7829 &spr_read_ureg, SPR_NOACCESS,
7830 &spr_read_ureg, &spr_write_ureg,
7832 spr_register(env, SPR_POWER_USDAR, "USDAR",
7833 &spr_read_ureg, SPR_NOACCESS,
7834 &spr_read_ureg, &spr_write_ureg,
7838 static void gen_spr_970_pmu_sup(CPUPPCState *env)
7840 spr_register_kvm(env, SPR_970_PMC7, "PMC7",
7841 SPR_NOACCESS, SPR_NOACCESS,
7842 &spr_read_generic, &spr_write_generic,
7843 KVM_REG_PPC_PMC7, 0x00000000);
7844 spr_register_kvm(env, SPR_970_PMC8, "PMC8",
7845 SPR_NOACCESS, SPR_NOACCESS,
7846 &spr_read_generic, &spr_write_generic,
7847 KVM_REG_PPC_PMC8, 0x00000000);
7850 static void gen_spr_970_pmu_user(CPUPPCState *env)
7852 spr_register(env, SPR_970_UPMC7, "UPMC7",
7853 &spr_read_ureg, SPR_NOACCESS,
7854 &spr_read_ureg, &spr_write_ureg,
7856 spr_register(env, SPR_970_UPMC8, "UPMC8",
7857 &spr_read_ureg, SPR_NOACCESS,
7858 &spr_read_ureg, &spr_write_ureg,
7862 static void gen_spr_power8_pmu_sup(CPUPPCState *env)
7864 spr_register_kvm(env, SPR_POWER_MMCR2, "MMCR2",
7865 SPR_NOACCESS, SPR_NOACCESS,
7866 &spr_read_generic, &spr_write_generic,
7867 KVM_REG_PPC_MMCR2, 0x00000000);
7868 spr_register_kvm(env, SPR_POWER_MMCRS, "MMCRS",
7869 SPR_NOACCESS, SPR_NOACCESS,
7870 &spr_read_generic, &spr_write_generic,
7871 KVM_REG_PPC_MMCRS, 0x00000000);
7872 spr_register_kvm(env, SPR_POWER_SIER, "SIER",
7873 SPR_NOACCESS, SPR_NOACCESS,
7874 &spr_read_generic, &spr_write_generic,
7875 KVM_REG_PPC_SIER, 0x00000000);
7876 spr_register_kvm(env, SPR_POWER_SPMC1, "SPMC1",
7877 SPR_NOACCESS, SPR_NOACCESS,
7878 &spr_read_generic, &spr_write_generic,
7879 KVM_REG_PPC_SPMC1, 0x00000000);
7880 spr_register_kvm(env, SPR_POWER_SPMC2, "SPMC2",
7881 SPR_NOACCESS, SPR_NOACCESS,
7882 &spr_read_generic, &spr_write_generic,
7883 KVM_REG_PPC_SPMC2, 0x00000000);
7884 spr_register_kvm(env, SPR_TACR, "TACR",
7885 SPR_NOACCESS, SPR_NOACCESS,
7886 &spr_read_generic, &spr_write_generic,
7887 KVM_REG_PPC_TACR, 0x00000000);
7888 spr_register_kvm(env, SPR_TCSCR, "TCSCR",
7889 SPR_NOACCESS, SPR_NOACCESS,
7890 &spr_read_generic, &spr_write_generic,
7891 KVM_REG_PPC_TCSCR, 0x00000000);
7892 spr_register_kvm(env, SPR_CSIGR, "CSIGR",
7893 SPR_NOACCESS, SPR_NOACCESS,
7894 &spr_read_generic, &spr_write_generic,
7895 KVM_REG_PPC_CSIGR, 0x00000000);
7898 static void gen_spr_power8_pmu_user(CPUPPCState *env)
7900 spr_register(env, SPR_POWER_UMMCR2, "UMMCR2",
7901 &spr_read_ureg, SPR_NOACCESS,
7902 &spr_read_ureg, &spr_write_ureg,
7904 spr_register(env, SPR_POWER_USIER, "USIER",
7905 &spr_read_generic, SPR_NOACCESS,
7906 &spr_read_generic, &spr_write_generic,
7910 static void gen_spr_power5p_ear(CPUPPCState *env)
7912 /* External access control */
7913 spr_register(env, SPR_EAR, "EAR",
7914 SPR_NOACCESS, SPR_NOACCESS,
7915 &spr_read_generic, &spr_write_generic,
7919 static void gen_spr_power5p_tb(CPUPPCState *env)
7921 /* TBU40 (High 40 bits of the Timebase register */
7922 spr_register_hv(env, SPR_TBU40, "TBU40",
7923 SPR_NOACCESS, SPR_NOACCESS,
7924 SPR_NOACCESS, SPR_NOACCESS,
7925 SPR_NOACCESS, &spr_write_tbu40,
7929 #if !defined(CONFIG_USER_ONLY)
7930 static void spr_write_hmer(DisasContext *ctx, int sprn, int gprn)
7932 TCGv hmer = tcg_temp_new();
7934 gen_load_spr(hmer, sprn);
7935 tcg_gen_and_tl(hmer, cpu_gpr[gprn], hmer);
7936 gen_store_spr(sprn, hmer);
7937 spr_store_dump_spr(sprn);
7938 tcg_temp_free(hmer);
7941 static void spr_write_lpcr(DisasContext *ctx, int sprn, int gprn)
7943 gen_helper_store_lpcr(cpu_env, cpu_gpr[gprn]);
7945 #endif /* !defined(CONFIG_USER_ONLY) */
7947 static void gen_spr_970_lpar(CPUPPCState *env)
7949 #if !defined(CONFIG_USER_ONLY)
7951 * PPC970: HID4 covers things later controlled by the LPCR and
7952 * RMOR in later CPUs, but with a different encoding. We only
7953 * support the 970 in "Apple mode" which has all hypervisor
7954 * facilities disabled by strapping, so we can basically just
7957 spr_register(env, SPR_970_HID4, "HID4",
7958 SPR_NOACCESS, SPR_NOACCESS,
7959 &spr_read_generic, &spr_write_generic,
7964 static void gen_spr_power5p_lpar(CPUPPCState *env)
7966 #if !defined(CONFIG_USER_ONLY)
7967 /* Logical partitionning */
7968 spr_register_kvm_hv(env, SPR_LPCR, "LPCR",
7969 SPR_NOACCESS, SPR_NOACCESS,
7970 SPR_NOACCESS, SPR_NOACCESS,
7971 &spr_read_generic, &spr_write_lpcr,
7972 KVM_REG_PPC_LPCR, LPCR_LPES0 | LPCR_LPES1);
7973 spr_register_hv(env, SPR_HDEC, "HDEC",
7974 SPR_NOACCESS, SPR_NOACCESS,
7975 SPR_NOACCESS, SPR_NOACCESS,
7976 &spr_read_hdecr, &spr_write_hdecr, 0);
7980 static void gen_spr_book3s_ids(CPUPPCState *env)
7982 /* FIXME: Will need to deal with thread vs core only SPRs */
7984 /* Processor identification */
7985 spr_register_hv(env, SPR_PIR, "PIR",
7986 SPR_NOACCESS, SPR_NOACCESS,
7987 &spr_read_generic, SPR_NOACCESS,
7988 &spr_read_generic, NULL,
7990 spr_register_hv(env, SPR_HID0, "HID0",
7991 SPR_NOACCESS, SPR_NOACCESS,
7992 SPR_NOACCESS, SPR_NOACCESS,
7993 &spr_read_generic, &spr_write_generic,
7995 spr_register_hv(env, SPR_TSCR, "TSCR",
7996 SPR_NOACCESS, SPR_NOACCESS,
7997 SPR_NOACCESS, SPR_NOACCESS,
7998 &spr_read_generic, &spr_write_generic,
8000 spr_register_hv(env, SPR_HMER, "HMER",
8001 SPR_NOACCESS, SPR_NOACCESS,
8002 SPR_NOACCESS, SPR_NOACCESS,
8003 &spr_read_generic, &spr_write_hmer,
8005 spr_register_hv(env, SPR_HMEER, "HMEER",
8006 SPR_NOACCESS, SPR_NOACCESS,
8007 SPR_NOACCESS, SPR_NOACCESS,
8008 &spr_read_generic, &spr_write_generic,
8010 spr_register_hv(env, SPR_TFMR, "TFMR",
8011 SPR_NOACCESS, SPR_NOACCESS,
8012 SPR_NOACCESS, SPR_NOACCESS,
8013 &spr_read_generic, &spr_write_generic,
8015 spr_register_hv(env, SPR_LPIDR, "LPIDR",
8016 SPR_NOACCESS, SPR_NOACCESS,
8017 SPR_NOACCESS, SPR_NOACCESS,
8018 &spr_read_generic, &spr_write_lpidr,
8020 spr_register_hv(env, SPR_HFSCR, "HFSCR",
8021 SPR_NOACCESS, SPR_NOACCESS,
8022 SPR_NOACCESS, SPR_NOACCESS,
8023 &spr_read_generic, &spr_write_generic,
8025 spr_register_hv(env, SPR_MMCRC, "MMCRC",
8026 SPR_NOACCESS, SPR_NOACCESS,
8027 SPR_NOACCESS, SPR_NOACCESS,
8028 &spr_read_generic, &spr_write_generic,
8030 spr_register_hv(env, SPR_MMCRH, "MMCRH",
8031 SPR_NOACCESS, SPR_NOACCESS,
8032 SPR_NOACCESS, SPR_NOACCESS,
8033 &spr_read_generic, &spr_write_generic,
8035 spr_register_hv(env, SPR_HSPRG0, "HSPRG0",
8036 SPR_NOACCESS, SPR_NOACCESS,
8037 SPR_NOACCESS, SPR_NOACCESS,
8038 &spr_read_generic, &spr_write_generic,
8040 spr_register_hv(env, SPR_HSPRG1, "HSPRG1",
8041 SPR_NOACCESS, SPR_NOACCESS,
8042 SPR_NOACCESS, SPR_NOACCESS,
8043 &spr_read_generic, &spr_write_generic,
8045 spr_register_hv(env, SPR_HSRR0, "HSRR0",
8046 SPR_NOACCESS, SPR_NOACCESS,
8047 SPR_NOACCESS, SPR_NOACCESS,
8048 &spr_read_generic, &spr_write_generic,
8050 spr_register_hv(env, SPR_HSRR1, "HSRR1",
8051 SPR_NOACCESS, SPR_NOACCESS,
8052 SPR_NOACCESS, SPR_NOACCESS,
8053 &spr_read_generic, &spr_write_generic,
8055 spr_register_hv(env, SPR_HDAR, "HDAR",
8056 SPR_NOACCESS, SPR_NOACCESS,
8057 SPR_NOACCESS, SPR_NOACCESS,
8058 &spr_read_generic, &spr_write_generic,
8060 spr_register_hv(env, SPR_HDSISR, "HDSISR",
8061 SPR_NOACCESS, SPR_NOACCESS,
8062 SPR_NOACCESS, SPR_NOACCESS,
8063 &spr_read_generic, &spr_write_generic,
8065 spr_register_hv(env, SPR_HRMOR, "HRMOR",
8066 SPR_NOACCESS, SPR_NOACCESS,
8067 SPR_NOACCESS, SPR_NOACCESS,
8068 &spr_read_generic, &spr_write_generic,
8072 static void gen_spr_rmor(CPUPPCState *env)
8074 spr_register_hv(env, SPR_RMOR, "RMOR",
8075 SPR_NOACCESS, SPR_NOACCESS,
8076 SPR_NOACCESS, SPR_NOACCESS,
8077 &spr_read_generic, &spr_write_generic,
8081 static void gen_spr_power8_ids(CPUPPCState *env)
8083 /* Thread identification */
8084 spr_register(env, SPR_TIR, "TIR",
8085 SPR_NOACCESS, SPR_NOACCESS,
8086 &spr_read_generic, SPR_NOACCESS,
8090 static void gen_spr_book3s_purr(CPUPPCState *env)
8092 #if !defined(CONFIG_USER_ONLY)
8093 /* PURR & SPURR: Hack - treat these as aliases for the TB for now */
8094 spr_register_kvm_hv(env, SPR_PURR, "PURR",
8095 &spr_read_purr, SPR_NOACCESS,
8096 &spr_read_purr, SPR_NOACCESS,
8097 &spr_read_purr, &spr_write_purr,
8098 KVM_REG_PPC_PURR, 0x00000000);
8099 spr_register_kvm_hv(env, SPR_SPURR, "SPURR",
8100 &spr_read_purr, SPR_NOACCESS,
8101 &spr_read_purr, SPR_NOACCESS,
8102 &spr_read_purr, &spr_write_purr,
8103 KVM_REG_PPC_SPURR, 0x00000000);
8107 static void gen_spr_power6_dbg(CPUPPCState *env)
8109 #if !defined(CONFIG_USER_ONLY)
8110 spr_register(env, SPR_CFAR, "SPR_CFAR",
8111 SPR_NOACCESS, SPR_NOACCESS,
8112 &spr_read_cfar, &spr_write_cfar,
8117 static void gen_spr_power5p_common(CPUPPCState *env)
8119 spr_register_kvm(env, SPR_PPR, "PPR",
8120 &spr_read_generic, &spr_write_generic,
8121 &spr_read_generic, &spr_write_generic,
8122 KVM_REG_PPC_PPR, 0x00000000);
8125 static void gen_spr_power6_common(CPUPPCState *env)
8127 #if !defined(CONFIG_USER_ONLY)
8128 spr_register_kvm(env, SPR_DSCR, "SPR_DSCR",
8129 SPR_NOACCESS, SPR_NOACCESS,
8130 &spr_read_generic, &spr_write_generic,
8131 KVM_REG_PPC_DSCR, 0x00000000);
8134 * Register PCR to report POWERPC_EXCP_PRIV_REG instead of
8135 * POWERPC_EXCP_INVAL_SPR in userspace. Permit hypervisor access.
8137 spr_register_hv(env, SPR_PCR, "PCR",
8138 SPR_NOACCESS, SPR_NOACCESS,
8139 SPR_NOACCESS, SPR_NOACCESS,
8140 &spr_read_generic, &spr_write_pcr,
8144 static void spr_read_tar(DisasContext *ctx, int gprn, int sprn)
8146 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_TAR, sprn, FSCR_IC_TAR);
8147 spr_read_generic(ctx, gprn, sprn);
8150 static void spr_write_tar(DisasContext *ctx, int sprn, int gprn)
8152 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_TAR, sprn, FSCR_IC_TAR);
8153 spr_write_generic(ctx, sprn, gprn);
8156 static void gen_spr_power8_tce_address_control(CPUPPCState *env)
8158 spr_register_kvm(env, SPR_TAR, "TAR",
8159 &spr_read_tar, &spr_write_tar,
8160 &spr_read_generic, &spr_write_generic,
8161 KVM_REG_PPC_TAR, 0x00000000);
8164 static void spr_read_tm(DisasContext *ctx, int gprn, int sprn)
8166 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8167 spr_read_generic(ctx, gprn, sprn);
8170 static void spr_write_tm(DisasContext *ctx, int sprn, int gprn)
8172 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8173 spr_write_generic(ctx, sprn, gprn);
8176 static void spr_read_tm_upper32(DisasContext *ctx, int gprn, int sprn)
8178 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8179 spr_read_prev_upper32(ctx, gprn, sprn);
8182 static void spr_write_tm_upper32(DisasContext *ctx, int sprn, int gprn)
8184 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8185 spr_write_prev_upper32(ctx, sprn, gprn);
8188 static void gen_spr_power8_tm(CPUPPCState *env)
8190 spr_register_kvm(env, SPR_TFHAR, "TFHAR",
8191 &spr_read_tm, &spr_write_tm,
8192 &spr_read_tm, &spr_write_tm,
8193 KVM_REG_PPC_TFHAR, 0x00000000);
8194 spr_register_kvm(env, SPR_TFIAR, "TFIAR",
8195 &spr_read_tm, &spr_write_tm,
8196 &spr_read_tm, &spr_write_tm,
8197 KVM_REG_PPC_TFIAR, 0x00000000);
8198 spr_register_kvm(env, SPR_TEXASR, "TEXASR",
8199 &spr_read_tm, &spr_write_tm,
8200 &spr_read_tm, &spr_write_tm,
8201 KVM_REG_PPC_TEXASR, 0x00000000);
8202 spr_register(env, SPR_TEXASRU, "TEXASRU",
8203 &spr_read_tm_upper32, &spr_write_tm_upper32,
8204 &spr_read_tm_upper32, &spr_write_tm_upper32,
8208 static void spr_read_ebb(DisasContext *ctx, int gprn, int sprn)
8210 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8211 spr_read_generic(ctx, gprn, sprn);
8214 static void spr_write_ebb(DisasContext *ctx, int sprn, int gprn)
8216 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8217 spr_write_generic(ctx, sprn, gprn);
8220 static void spr_read_ebb_upper32(DisasContext *ctx, int gprn, int sprn)
8222 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8223 spr_read_prev_upper32(ctx, gprn, sprn);
8226 static void spr_write_ebb_upper32(DisasContext *ctx, int sprn, int gprn)
8228 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8229 spr_write_prev_upper32(ctx, sprn, gprn);
8232 static void gen_spr_power8_ebb(CPUPPCState *env)
8234 spr_register(env, SPR_BESCRS, "BESCRS",
8235 &spr_read_ebb, &spr_write_ebb,
8236 &spr_read_generic, &spr_write_generic,
8238 spr_register(env, SPR_BESCRSU, "BESCRSU",
8239 &spr_read_ebb_upper32, &spr_write_ebb_upper32,
8240 &spr_read_prev_upper32, &spr_write_prev_upper32,
8242 spr_register(env, SPR_BESCRR, "BESCRR",
8243 &spr_read_ebb, &spr_write_ebb,
8244 &spr_read_generic, &spr_write_generic,
8246 spr_register(env, SPR_BESCRRU, "BESCRRU",
8247 &spr_read_ebb_upper32, &spr_write_ebb_upper32,
8248 &spr_read_prev_upper32, &spr_write_prev_upper32,
8250 spr_register_kvm(env, SPR_EBBHR, "EBBHR",
8251 &spr_read_ebb, &spr_write_ebb,
8252 &spr_read_generic, &spr_write_generic,
8253 KVM_REG_PPC_EBBHR, 0x00000000);
8254 spr_register_kvm(env, SPR_EBBRR, "EBBRR",
8255 &spr_read_ebb, &spr_write_ebb,
8256 &spr_read_generic, &spr_write_generic,
8257 KVM_REG_PPC_EBBRR, 0x00000000);
8258 spr_register_kvm(env, SPR_BESCR, "BESCR",
8259 &spr_read_ebb, &spr_write_ebb,
8260 &spr_read_generic, &spr_write_generic,
8261 KVM_REG_PPC_BESCR, 0x00000000);
8264 /* Virtual Time Base */
8265 static void gen_spr_vtb(CPUPPCState *env)
8267 spr_register_kvm_hv(env, SPR_VTB, "VTB",
8268 SPR_NOACCESS, SPR_NOACCESS,
8269 &spr_read_vtb, SPR_NOACCESS,
8270 &spr_read_vtb, &spr_write_vtb,
8271 KVM_REG_PPC_VTB, 0x00000000);
8274 static void gen_spr_power8_fscr(CPUPPCState *env)
8276 #if defined(CONFIG_USER_ONLY)
8277 target_ulong initval = 1ULL << FSCR_TAR;
8279 target_ulong initval = 0;
8281 spr_register_kvm(env, SPR_FSCR, "FSCR",
8282 SPR_NOACCESS, SPR_NOACCESS,
8283 &spr_read_generic, &spr_write_generic,
8284 KVM_REG_PPC_FSCR, initval);
8287 static void gen_spr_power8_pspb(CPUPPCState *env)
8289 spr_register_kvm(env, SPR_PSPB, "PSPB",
8290 SPR_NOACCESS, SPR_NOACCESS,
8291 &spr_read_generic, &spr_write_generic32,
8292 KVM_REG_PPC_PSPB, 0);
8295 static void gen_spr_power8_dpdes(CPUPPCState *env)
8297 #if !defined(CONFIG_USER_ONLY)
8298 /* Directed Privileged Door-bell Exception State, used for IPI */
8299 spr_register_kvm_hv(env, SPR_DPDES, "DPDES",
8300 SPR_NOACCESS, SPR_NOACCESS,
8301 &spr_read_dpdes, SPR_NOACCESS,
8302 &spr_read_dpdes, &spr_write_dpdes,
8303 KVM_REG_PPC_DPDES, 0x00000000);
8307 static void gen_spr_power8_ic(CPUPPCState *env)
8309 #if !defined(CONFIG_USER_ONLY)
8310 spr_register_hv(env, SPR_IC, "IC",
8311 SPR_NOACCESS, SPR_NOACCESS,
8312 &spr_read_generic, SPR_NOACCESS,
8313 &spr_read_generic, &spr_write_generic,
8318 static void gen_spr_power8_book4(CPUPPCState *env)
8320 /* Add a number of P8 book4 registers */
8321 #if !defined(CONFIG_USER_ONLY)
8322 spr_register_kvm(env, SPR_ACOP, "ACOP",
8323 SPR_NOACCESS, SPR_NOACCESS,
8324 &spr_read_generic, &spr_write_generic,
8325 KVM_REG_PPC_ACOP, 0);
8326 spr_register_kvm(env, SPR_BOOKS_PID, "PID",
8327 SPR_NOACCESS, SPR_NOACCESS,
8328 &spr_read_generic, &spr_write_pidr,
8329 KVM_REG_PPC_PID, 0);
8330 spr_register_kvm(env, SPR_WORT, "WORT",
8331 SPR_NOACCESS, SPR_NOACCESS,
8332 &spr_read_generic, &spr_write_generic,
8333 KVM_REG_PPC_WORT, 0);
8337 static void gen_spr_power7_book4(CPUPPCState *env)
8339 /* Add a number of P7 book4 registers */
8340 #if !defined(CONFIG_USER_ONLY)
8341 spr_register_kvm(env, SPR_ACOP, "ACOP",
8342 SPR_NOACCESS, SPR_NOACCESS,
8343 &spr_read_generic, &spr_write_generic,
8344 KVM_REG_PPC_ACOP, 0);
8345 spr_register_kvm(env, SPR_BOOKS_PID, "PID",
8346 SPR_NOACCESS, SPR_NOACCESS,
8347 &spr_read_generic, &spr_write_generic,
8348 KVM_REG_PPC_PID, 0);
8352 static void gen_spr_power8_rpr(CPUPPCState *env)
8354 #if !defined(CONFIG_USER_ONLY)
8355 spr_register_hv(env, SPR_RPR, "RPR",
8356 SPR_NOACCESS, SPR_NOACCESS,
8357 SPR_NOACCESS, SPR_NOACCESS,
8358 &spr_read_generic, &spr_write_generic,
8359 0x00000103070F1F3F);
8363 static void gen_spr_power9_mmu(CPUPPCState *env)
8365 #if !defined(CONFIG_USER_ONLY)
8366 /* Partition Table Control */
8367 spr_register_kvm_hv(env, SPR_PTCR, "PTCR",
8368 SPR_NOACCESS, SPR_NOACCESS,
8369 SPR_NOACCESS, SPR_NOACCESS,
8370 &spr_read_generic, &spr_write_ptcr,
8371 KVM_REG_PPC_PTCR, 0x00000000);
8372 /* Address Segment Descriptor Register */
8373 spr_register_hv(env, SPR_ASDR, "ASDR",
8374 SPR_NOACCESS, SPR_NOACCESS,
8375 SPR_NOACCESS, SPR_NOACCESS,
8376 &spr_read_generic, &spr_write_generic,
8377 0x0000000000000000);
8381 static void init_proc_book3s_common(CPUPPCState *env)
8383 gen_spr_ne_601(env);
8385 gen_spr_usprg3(env);
8386 gen_spr_book3s_altivec(env);
8387 gen_spr_book3s_pmu_sup(env);
8388 gen_spr_book3s_pmu_user(env);
8389 gen_spr_book3s_ctrl(env);
8392 static void init_proc_970(CPUPPCState *env)
8394 /* Common Registers */
8395 init_proc_book3s_common(env);
8397 gen_spr_book3s_dbg(env);
8399 /* 970 Specific Registers */
8400 gen_spr_970_hid(env);
8401 gen_spr_970_hior(env);
8403 gen_spr_970_pmu_sup(env);
8404 gen_spr_970_pmu_user(env);
8405 gen_spr_970_lpar(env);
8406 gen_spr_970_dbg(env);
8409 env->dcache_line_size = 128;
8410 env->icache_line_size = 128;
8412 /* Allocate hardware IRQ controller */
8414 ppc970_irq_init(env_archcpu(env));
8417 POWERPC_FAMILY(970)(ObjectClass *oc, void *data)
8419 DeviceClass *dc = DEVICE_CLASS(oc);
8420 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8422 dc->desc = "PowerPC 970";
8423 pcc->init_proc = init_proc_970;
8424 pcc->check_pow = check_pow_970;
8425 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
8426 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8427 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
8429 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8430 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8431 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
8432 PPC_64B | PPC_ALTIVEC |
8433 PPC_SEGMENT_64B | PPC_SLBI;
8434 pcc->insns_flags2 = PPC2_FP_CVT_S64;
8435 pcc->msr_mask = (1ull << MSR_SF) |
8450 pcc->mmu_model = POWERPC_MMU_64B;
8451 #if defined(CONFIG_SOFTMMU)
8452 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
8453 pcc->hash64_opts = &ppc_hash64_opts_basic;
8455 pcc->excp_model = POWERPC_EXCP_970;
8456 pcc->bus_model = PPC_FLAGS_INPUT_970;
8457 pcc->bfd_mach = bfd_mach_ppc64;
8458 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8459 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8460 POWERPC_FLAG_BUS_CLK;
8461 pcc->l1_dcache_size = 0x8000;
8462 pcc->l1_icache_size = 0x10000;
8465 static void init_proc_power5plus(CPUPPCState *env)
8467 /* Common Registers */
8468 init_proc_book3s_common(env);
8470 gen_spr_book3s_dbg(env);
8472 /* POWER5+ Specific Registers */
8473 gen_spr_970_hid(env);
8474 gen_spr_970_hior(env);
8476 gen_spr_970_pmu_sup(env);
8477 gen_spr_970_pmu_user(env);
8478 gen_spr_power5p_common(env);
8479 gen_spr_power5p_lpar(env);
8480 gen_spr_power5p_ear(env);
8481 gen_spr_power5p_tb(env);
8484 env->dcache_line_size = 128;
8485 env->icache_line_size = 128;
8487 /* Allocate hardware IRQ controller */
8489 ppc970_irq_init(env_archcpu(env));
8492 POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data)
8494 DeviceClass *dc = DEVICE_CLASS(oc);
8495 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8497 dc->fw_name = "PowerPC,POWER5";
8498 dc->desc = "POWER5+";
8499 pcc->init_proc = init_proc_power5plus;
8500 pcc->check_pow = check_pow_970;
8501 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
8502 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8503 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
8505 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8506 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8507 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
8509 PPC_SEGMENT_64B | PPC_SLBI;
8510 pcc->insns_flags2 = PPC2_FP_CVT_S64;
8511 pcc->msr_mask = (1ull << MSR_SF) |
8526 pcc->lpcr_mask = LPCR_RMLS | LPCR_ILE | LPCR_LPES0 | LPCR_LPES1 |
8527 LPCR_RMI | LPCR_HDICE;
8528 pcc->mmu_model = POWERPC_MMU_2_03;
8529 #if defined(CONFIG_SOFTMMU)
8530 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
8531 pcc->hash64_opts = &ppc_hash64_opts_basic;
8532 pcc->lrg_decr_bits = 32;
8534 pcc->excp_model = POWERPC_EXCP_970;
8535 pcc->bus_model = PPC_FLAGS_INPUT_970;
8536 pcc->bfd_mach = bfd_mach_ppc64;
8537 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8538 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8539 POWERPC_FLAG_BUS_CLK;
8540 pcc->l1_dcache_size = 0x8000;
8541 pcc->l1_icache_size = 0x10000;
8544 static void init_proc_POWER7(CPUPPCState *env)
8546 /* Common Registers */
8547 init_proc_book3s_common(env);
8549 gen_spr_book3s_dbg(env);
8551 /* POWER7 Specific Registers */
8552 gen_spr_book3s_ids(env);
8555 gen_spr_book3s_purr(env);
8556 gen_spr_power5p_common(env);
8557 gen_spr_power5p_lpar(env);
8558 gen_spr_power5p_ear(env);
8559 gen_spr_power5p_tb(env);
8560 gen_spr_power6_common(env);
8561 gen_spr_power6_dbg(env);
8562 gen_spr_power7_book4(env);
8565 env->dcache_line_size = 128;
8566 env->icache_line_size = 128;
8568 /* Allocate hardware IRQ controller */
8569 init_excp_POWER7(env);
8570 ppcPOWER7_irq_init(env_archcpu(env));
8573 static bool ppc_pvr_match_power7(PowerPCCPUClass *pcc, uint32_t pvr)
8575 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7P_BASE) {
8578 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7_BASE) {
8584 static bool cpu_has_work_POWER7(CPUState *cs)
8586 PowerPCCPU *cpu = POWERPC_CPU(cs);
8587 CPUPPCState *env = &cpu->env;
8590 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
8593 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
8594 (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) {
8597 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
8598 (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) {
8601 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
8602 (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
8605 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
8606 (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
8609 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
8614 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
8618 POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
8620 DeviceClass *dc = DEVICE_CLASS(oc);
8621 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8622 CPUClass *cc = CPU_CLASS(oc);
8624 dc->fw_name = "PowerPC,POWER7";
8625 dc->desc = "POWER7";
8626 pcc->pvr_match = ppc_pvr_match_power7;
8627 pcc->pcr_mask = PCR_VEC_DIS | PCR_VSX_DIS | PCR_COMPAT_2_05;
8628 pcc->pcr_supported = PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
8629 pcc->init_proc = init_proc_POWER7;
8630 pcc->check_pow = check_pow_nocheck;
8631 cc->has_work = cpu_has_work_POWER7;
8632 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
8633 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8634 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
8635 PPC_FLOAT_FRSQRTES |
8638 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8639 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8640 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
8641 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
8642 PPC_SEGMENT_64B | PPC_SLBI |
8643 PPC_POPCNTB | PPC_POPCNTWD |
8645 pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
8646 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
8647 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
8648 PPC2_FP_TST_ISA206 | PPC2_FP_CVT_S64 |
8650 pcc->msr_mask = (1ull << MSR_SF) |
8666 pcc->lpcr_mask = LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_DPFD |
8667 LPCR_VRMASD | LPCR_RMLS | LPCR_ILE |
8668 LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2 |
8669 LPCR_MER | LPCR_TC |
8670 LPCR_LPES0 | LPCR_LPES1 | LPCR_HDICE;
8671 pcc->lpcr_pm = LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2;
8672 pcc->mmu_model = POWERPC_MMU_2_06;
8673 #if defined(CONFIG_SOFTMMU)
8674 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
8675 pcc->hash64_opts = &ppc_hash64_opts_POWER7;
8676 pcc->lrg_decr_bits = 32;
8678 pcc->excp_model = POWERPC_EXCP_POWER7;
8679 pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
8680 pcc->bfd_mach = bfd_mach_ppc64;
8681 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8682 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8683 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
8685 pcc->l1_dcache_size = 0x8000;
8686 pcc->l1_icache_size = 0x8000;
8687 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
8690 static void init_proc_POWER8(CPUPPCState *env)
8692 /* Common Registers */
8693 init_proc_book3s_common(env);
8695 gen_spr_book3s_207_dbg(env);
8697 /* POWER8 Specific Registers */
8698 gen_spr_book3s_ids(env);
8702 gen_spr_book3s_purr(env);
8703 gen_spr_power5p_common(env);
8704 gen_spr_power5p_lpar(env);
8705 gen_spr_power5p_ear(env);
8706 gen_spr_power5p_tb(env);
8707 gen_spr_power6_common(env);
8708 gen_spr_power6_dbg(env);
8709 gen_spr_power8_tce_address_control(env);
8710 gen_spr_power8_ids(env);
8711 gen_spr_power8_ebb(env);
8712 gen_spr_power8_fscr(env);
8713 gen_spr_power8_pmu_sup(env);
8714 gen_spr_power8_pmu_user(env);
8715 gen_spr_power8_tm(env);
8716 gen_spr_power8_pspb(env);
8717 gen_spr_power8_dpdes(env);
8719 gen_spr_power8_ic(env);
8720 gen_spr_power8_book4(env);
8721 gen_spr_power8_rpr(env);
8724 env->dcache_line_size = 128;
8725 env->icache_line_size = 128;
8727 /* Allocate hardware IRQ controller */
8728 init_excp_POWER8(env);
8729 ppcPOWER7_irq_init(env_archcpu(env));
8732 static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, uint32_t pvr)
8734 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8NVL_BASE) {
8737 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8E_BASE) {
8740 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8_BASE) {
8746 static bool cpu_has_work_POWER8(CPUState *cs)
8748 PowerPCCPU *cpu = POWERPC_CPU(cs);
8749 CPUPPCState *env = &cpu->env;
8752 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
8755 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
8756 (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) {
8759 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
8760 (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) {
8763 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
8764 (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
8767 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
8768 (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
8771 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
8772 (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) {
8775 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
8776 (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) {
8779 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
8784 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
8788 POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
8790 DeviceClass *dc = DEVICE_CLASS(oc);
8791 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8792 CPUClass *cc = CPU_CLASS(oc);
8794 dc->fw_name = "PowerPC,POWER8";
8795 dc->desc = "POWER8";
8796 pcc->pvr_match = ppc_pvr_match_power8;
8797 pcc->pcr_mask = PCR_TM_DIS | PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
8798 pcc->pcr_supported = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
8799 pcc->init_proc = init_proc_POWER8;
8800 pcc->check_pow = check_pow_nocheck;
8801 cc->has_work = cpu_has_work_POWER8;
8802 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
8803 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8804 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
8805 PPC_FLOAT_FRSQRTES |
8808 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8809 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8810 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
8811 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
8812 PPC_SEGMENT_64B | PPC_SLBI |
8813 PPC_POPCNTB | PPC_POPCNTWD |
8815 pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
8816 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
8817 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
8818 PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
8819 PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
8820 PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
8821 PPC2_TM | PPC2_PM_ISA206;
8822 pcc->msr_mask = (1ull << MSR_SF) |
8842 pcc->lpcr_mask = LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV |
8843 LPCR_DPFD | LPCR_VRMASD | LPCR_RMLS | LPCR_ILE |
8844 LPCR_AIL | LPCR_ONL | LPCR_P8_PECE0 | LPCR_P8_PECE1 |
8845 LPCR_P8_PECE2 | LPCR_P8_PECE3 | LPCR_P8_PECE4 |
8846 LPCR_MER | LPCR_TC | LPCR_LPES0 | LPCR_HDICE;
8847 pcc->lpcr_pm = LPCR_P8_PECE0 | LPCR_P8_PECE1 | LPCR_P8_PECE2 |
8848 LPCR_P8_PECE3 | LPCR_P8_PECE4;
8849 pcc->mmu_model = POWERPC_MMU_2_07;
8850 #if defined(CONFIG_SOFTMMU)
8851 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
8852 pcc->hash64_opts = &ppc_hash64_opts_POWER7;
8853 pcc->lrg_decr_bits = 32;
8854 pcc->n_host_threads = 8;
8856 pcc->excp_model = POWERPC_EXCP_POWER8;
8857 pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
8858 pcc->bfd_mach = bfd_mach_ppc64;
8859 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8860 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8861 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
8862 POWERPC_FLAG_VSX | POWERPC_FLAG_TM;
8863 pcc->l1_dcache_size = 0x8000;
8864 pcc->l1_icache_size = 0x8000;
8865 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
8868 #ifdef CONFIG_SOFTMMU
8870 * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
8871 * Encoded as array of int_32s in the form:
8872 * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
8874 * y -> radix mode supported page size (encoded as a shift)
8876 static struct ppc_radix_page_info POWER9_radix_page_info = {
8879 0x0000000c, /* 4K - enc: 0x0 */
8880 0xa0000010, /* 64K - enc: 0x5 */
8881 0x20000015, /* 2M - enc: 0x1 */
8882 0x4000001e /* 1G - enc: 0x2 */
8885 #endif /* CONFIG_SOFTMMU */
8887 static void init_proc_POWER9(CPUPPCState *env)
8889 /* Common Registers */
8890 init_proc_book3s_common(env);
8891 gen_spr_book3s_207_dbg(env);
8893 /* POWER8 Specific Registers */
8894 gen_spr_book3s_ids(env);
8897 gen_spr_book3s_purr(env);
8898 gen_spr_power5p_common(env);
8899 gen_spr_power5p_lpar(env);
8900 gen_spr_power5p_ear(env);
8901 gen_spr_power5p_tb(env);
8902 gen_spr_power6_common(env);
8903 gen_spr_power6_dbg(env);
8904 gen_spr_power8_tce_address_control(env);
8905 gen_spr_power8_ids(env);
8906 gen_spr_power8_ebb(env);
8907 gen_spr_power8_fscr(env);
8908 gen_spr_power8_pmu_sup(env);
8909 gen_spr_power8_pmu_user(env);
8910 gen_spr_power8_tm(env);
8911 gen_spr_power8_pspb(env);
8912 gen_spr_power8_dpdes(env);
8914 gen_spr_power8_ic(env);
8915 gen_spr_power8_book4(env);
8916 gen_spr_power8_rpr(env);
8917 gen_spr_power9_mmu(env);
8919 /* POWER9 Specific registers */
8920 spr_register_kvm(env, SPR_TIDR, "TIDR", NULL, NULL,
8921 spr_read_generic, spr_write_generic,
8922 KVM_REG_PPC_TIDR, 0);
8924 /* FIXME: Filter fields properly based on privilege level */
8925 spr_register_kvm_hv(env, SPR_PSSCR, "PSSCR", NULL, NULL, NULL, NULL,
8926 spr_read_generic, spr_write_generic,
8927 KVM_REG_PPC_PSSCR, 0);
8930 env->dcache_line_size = 128;
8931 env->icache_line_size = 128;
8933 /* Allocate hardware IRQ controller */
8934 init_excp_POWER9(env);
8935 ppcPOWER9_irq_init(env_archcpu(env));
8938 static bool ppc_pvr_match_power9(PowerPCCPUClass *pcc, uint32_t pvr)
8940 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER9_BASE) {
8946 static bool cpu_has_work_POWER9(CPUState *cs)
8948 PowerPCCPU *cpu = POWERPC_CPU(cs);
8949 CPUPPCState *env = &cpu->env;
8952 uint64_t psscr = env->spr[SPR_PSSCR];
8954 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
8958 /* If EC is clear, just return true on any pending interrupt */
8959 if (!(psscr & PSSCR_EC)) {
8962 /* External Exception */
8963 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
8964 (env->spr[SPR_LPCR] & LPCR_EEE)) {
8965 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
8966 if (heic == 0 || !msr_hv || msr_pr) {
8970 /* Decrementer Exception */
8971 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
8972 (env->spr[SPR_LPCR] & LPCR_DEE)) {
8975 /* Machine Check or Hypervisor Maintenance Exception */
8976 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK |
8977 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) {
8980 /* Privileged Doorbell Exception */
8981 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
8982 (env->spr[SPR_LPCR] & LPCR_PDEE)) {
8985 /* Hypervisor Doorbell Exception */
8986 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
8987 (env->spr[SPR_LPCR] & LPCR_HDEE)) {
8990 /* Hypervisor virtualization exception */
8991 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) &&
8992 (env->spr[SPR_LPCR] & LPCR_HVEE)) {
8995 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
9000 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
9004 POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
9006 DeviceClass *dc = DEVICE_CLASS(oc);
9007 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
9008 CPUClass *cc = CPU_CLASS(oc);
9010 dc->fw_name = "PowerPC,POWER9";
9011 dc->desc = "POWER9";
9012 pcc->pvr_match = ppc_pvr_match_power9;
9013 pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07;
9014 pcc->pcr_supported = PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 |
9016 pcc->init_proc = init_proc_POWER9;
9017 pcc->check_pow = check_pow_nocheck;
9018 cc->has_work = cpu_has_work_POWER9;
9019 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
9020 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
9021 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
9022 PPC_FLOAT_FRSQRTES |
9025 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
9026 PPC_MEM_SYNC | PPC_MEM_EIEIO |
9028 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
9029 PPC_SEGMENT_64B | PPC_SLBI |
9030 PPC_POPCNTB | PPC_POPCNTWD |
9032 pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
9033 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
9034 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
9035 PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
9036 PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
9037 PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
9038 PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL;
9039 pcc->msr_mask = (1ull << MSR_SF) |
9057 pcc->lpcr_mask = LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD |
9058 (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL |
9059 LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR | LPCR_LD |
9060 (LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE | LPCR_EEE |
9061 LPCR_DEE | LPCR_OEE))
9062 | LPCR_MER | LPCR_GTSE | LPCR_TC |
9063 LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE | LPCR_HDICE;
9064 pcc->lpcr_pm = LPCR_PDEE | LPCR_HDEE | LPCR_EEE | LPCR_DEE | LPCR_OEE;
9065 pcc->mmu_model = POWERPC_MMU_3_00;
9066 #if defined(CONFIG_SOFTMMU)
9067 pcc->handle_mmu_fault = ppc64_v3_handle_mmu_fault;
9068 /* segment page size remain the same */
9069 pcc->hash64_opts = &ppc_hash64_opts_POWER7;
9070 pcc->radix_page_info = &POWER9_radix_page_info;
9071 pcc->lrg_decr_bits = 56;
9072 pcc->n_host_threads = 4;
9074 pcc->excp_model = POWERPC_EXCP_POWER9;
9075 pcc->bus_model = PPC_FLAGS_INPUT_POWER9;
9076 pcc->bfd_mach = bfd_mach_ppc64;
9077 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
9078 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
9079 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
9080 POWERPC_FLAG_VSX | POWERPC_FLAG_TM | POWERPC_FLAG_SCV;
9081 pcc->l1_dcache_size = 0x8000;
9082 pcc->l1_icache_size = 0x8000;
9083 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
9086 #ifdef CONFIG_SOFTMMU
9088 * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
9089 * Encoded as array of int_32s in the form:
9090 * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
9092 * y -> radix mode supported page size (encoded as a shift)
9094 static struct ppc_radix_page_info POWER10_radix_page_info = {
9097 0x0000000c, /* 4K - enc: 0x0 */
9098 0xa0000010, /* 64K - enc: 0x5 */
9099 0x20000015, /* 2M - enc: 0x1 */
9100 0x4000001e /* 1G - enc: 0x2 */
9103 #endif /* CONFIG_SOFTMMU */
9105 static void init_proc_POWER10(CPUPPCState *env)
9107 /* Common Registers */
9108 init_proc_book3s_common(env);
9109 gen_spr_book3s_207_dbg(env);
9111 /* POWER8 Specific Registers */
9112 gen_spr_book3s_ids(env);
9115 gen_spr_book3s_purr(env);
9116 gen_spr_power5p_common(env);
9117 gen_spr_power5p_lpar(env);
9118 gen_spr_power5p_ear(env);
9119 gen_spr_power6_common(env);
9120 gen_spr_power6_dbg(env);
9121 gen_spr_power8_tce_address_control(env);
9122 gen_spr_power8_ids(env);
9123 gen_spr_power8_ebb(env);
9124 gen_spr_power8_fscr(env);
9125 gen_spr_power8_pmu_sup(env);
9126 gen_spr_power8_pmu_user(env);
9127 gen_spr_power8_tm(env);
9128 gen_spr_power8_pspb(env);
9130 gen_spr_power8_ic(env);
9131 gen_spr_power8_book4(env);
9132 gen_spr_power8_rpr(env);
9133 gen_spr_power9_mmu(env);
9135 /* FIXME: Filter fields properly based on privilege level */
9136 spr_register_kvm_hv(env, SPR_PSSCR, "PSSCR", NULL, NULL, NULL, NULL,
9137 spr_read_generic, spr_write_generic,
9138 KVM_REG_PPC_PSSCR, 0);
9141 env->dcache_line_size = 128;
9142 env->icache_line_size = 128;
9144 /* Allocate hardware IRQ controller */
9145 init_excp_POWER10(env);
9146 ppcPOWER9_irq_init(env_archcpu(env));
9149 static bool ppc_pvr_match_power10(PowerPCCPUClass *pcc, uint32_t pvr)
9151 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER10_BASE) {
9157 static bool cpu_has_work_POWER10(CPUState *cs)
9159 PowerPCCPU *cpu = POWERPC_CPU(cs);
9160 CPUPPCState *env = &cpu->env;
9163 uint64_t psscr = env->spr[SPR_PSSCR];
9165 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
9169 /* If EC is clear, just return true on any pending interrupt */
9170 if (!(psscr & PSSCR_EC)) {
9173 /* External Exception */
9174 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
9175 (env->spr[SPR_LPCR] & LPCR_EEE)) {
9176 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
9177 if (heic == 0 || !msr_hv || msr_pr) {
9181 /* Decrementer Exception */
9182 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
9183 (env->spr[SPR_LPCR] & LPCR_DEE)) {
9186 /* Machine Check or Hypervisor Maintenance Exception */
9187 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK |
9188 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) {
9191 /* Privileged Doorbell Exception */
9192 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
9193 (env->spr[SPR_LPCR] & LPCR_PDEE)) {
9196 /* Hypervisor Doorbell Exception */
9197 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
9198 (env->spr[SPR_LPCR] & LPCR_HDEE)) {
9201 /* Hypervisor virtualization exception */
9202 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) &&
9203 (env->spr[SPR_LPCR] & LPCR_HVEE)) {
9206 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
9211 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
9215 POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data)
9217 DeviceClass *dc = DEVICE_CLASS(oc);
9218 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
9219 CPUClass *cc = CPU_CLASS(oc);
9221 dc->fw_name = "PowerPC,POWER10";
9222 dc->desc = "POWER10";
9223 pcc->pvr_match = ppc_pvr_match_power10;
9224 pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07 |
9226 pcc->pcr_supported = PCR_COMPAT_3_10 | PCR_COMPAT_3_00 | PCR_COMPAT_2_07 |
9227 PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
9228 pcc->init_proc = init_proc_POWER10;
9229 pcc->check_pow = check_pow_nocheck;
9230 cc->has_work = cpu_has_work_POWER10;
9231 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
9232 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
9233 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
9234 PPC_FLOAT_FRSQRTES |
9237 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
9238 PPC_MEM_SYNC | PPC_MEM_EIEIO |
9240 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
9241 PPC_SEGMENT_64B | PPC_SLBI |
9242 PPC_POPCNTB | PPC_POPCNTWD |
9244 pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
9245 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
9246 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
9247 PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
9248 PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
9249 PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
9250 PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL | PPC2_ISA310;
9251 pcc->msr_mask = (1ull << MSR_SF) |
9269 pcc->lpcr_mask = LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD |
9270 (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL |
9271 LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR | LPCR_LD |
9272 (LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE | LPCR_EEE |
9273 LPCR_DEE | LPCR_OEE))
9274 | LPCR_MER | LPCR_GTSE | LPCR_TC |
9275 LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE | LPCR_HDICE;
9276 pcc->lpcr_pm = LPCR_PDEE | LPCR_HDEE | LPCR_EEE | LPCR_DEE | LPCR_OEE;
9277 pcc->mmu_model = POWERPC_MMU_3_00;
9278 #if defined(CONFIG_SOFTMMU)
9279 pcc->handle_mmu_fault = ppc64_v3_handle_mmu_fault;
9280 /* segment page size remain the same */
9281 pcc->hash64_opts = &ppc_hash64_opts_POWER7;
9282 pcc->radix_page_info = &POWER10_radix_page_info;
9283 pcc->lrg_decr_bits = 56;
9285 pcc->excp_model = POWERPC_EXCP_POWER9;
9286 pcc->bus_model = PPC_FLAGS_INPUT_POWER9;
9287 pcc->bfd_mach = bfd_mach_ppc64;
9288 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
9289 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
9290 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
9291 POWERPC_FLAG_VSX | POWERPC_FLAG_TM;
9292 pcc->l1_dcache_size = 0x8000;
9293 pcc->l1_icache_size = 0x8000;
9294 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
9297 #if !defined(CONFIG_USER_ONLY)
9298 void cpu_ppc_set_vhyp(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp)
9300 CPUPPCState *env = &cpu->env;
9305 * With a virtual hypervisor mode we never allow the CPU to go
9306 * hypervisor mode itself
9308 env->msr_mask &= ~MSR_HVB;
9311 #endif /* !defined(CONFIG_USER_ONLY) */
9313 #endif /* defined(TARGET_PPC64) */
9315 /*****************************************************************************/
9316 /* Generic CPU instantiation routine */
9317 static void init_ppc_proc(PowerPCCPU *cpu)
9319 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
9320 CPUPPCState *env = &cpu->env;
9321 #if !defined(CONFIG_USER_ONLY)
9324 env->irq_inputs = NULL;
9325 /* Set all exception vectors to an invalid address */
9326 for (i = 0; i < POWERPC_EXCP_NB; i++) {
9327 env->excp_vectors[i] = (target_ulong)(-1ULL);
9329 env->ivor_mask = 0x00000000;
9330 env->ivpr_mask = 0x00000000;
9331 /* Default MMU definitions */
9335 env->tlb_type = TLB_NONE;
9337 /* Register SPR common to all PowerPC implementations */
9338 gen_spr_generic(env);
9339 spr_register(env, SPR_PVR, "PVR",
9340 /* Linux permits userspace to read PVR */
9341 #if defined(CONFIG_LINUX_USER)
9347 &spr_read_generic, SPR_NOACCESS,
9349 /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
9350 if (pcc->svr != POWERPC_SVR_NONE) {
9351 if (pcc->svr & POWERPC_SVR_E500) {
9352 spr_register(env, SPR_E500_SVR, "SVR",
9353 SPR_NOACCESS, SPR_NOACCESS,
9354 &spr_read_generic, SPR_NOACCESS,
9355 pcc->svr & ~POWERPC_SVR_E500);
9357 spr_register(env, SPR_SVR, "SVR",
9358 SPR_NOACCESS, SPR_NOACCESS,
9359 &spr_read_generic, SPR_NOACCESS,
9363 /* PowerPC implementation specific initialisations (SPRs, timers, ...) */
9364 (*pcc->init_proc)(env);
9366 #if !defined(CONFIG_USER_ONLY)
9367 ppc_gdb_gen_spr_xml(cpu);
9370 /* MSR bits & flags consistency checks */
9371 if (env->msr_mask & (1 << 25)) {
9372 switch (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
9373 case POWERPC_FLAG_SPE:
9374 case POWERPC_FLAG_VRE:
9377 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9378 "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n");
9381 } else if (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
9382 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9383 "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n");
9386 if (env->msr_mask & (1 << 17)) {
9387 switch (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
9388 case POWERPC_FLAG_TGPR:
9389 case POWERPC_FLAG_CE:
9392 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9393 "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n");
9396 } else if (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
9397 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9398 "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n");
9401 if (env->msr_mask & (1 << 10)) {
9402 switch (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
9403 POWERPC_FLAG_UBLE)) {
9404 case POWERPC_FLAG_SE:
9405 case POWERPC_FLAG_DWE:
9406 case POWERPC_FLAG_UBLE:
9409 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9410 "Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE or "
9411 "POWERPC_FLAG_UBLE\n");
9414 } else if (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
9415 POWERPC_FLAG_UBLE)) {
9416 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9417 "Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE nor "
9418 "POWERPC_FLAG_UBLE\n");
9421 if (env->msr_mask & (1 << 9)) {
9422 switch (env->flags & (POWERPC_FLAG_BE | POWERPC_FLAG_DE)) {
9423 case POWERPC_FLAG_BE:
9424 case POWERPC_FLAG_DE:
9427 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9428 "Should define POWERPC_FLAG_BE or POWERPC_FLAG_DE\n");
9431 } else if (env->flags & (POWERPC_FLAG_BE | POWERPC_FLAG_DE)) {
9432 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9433 "Should not define POWERPC_FLAG_BE nor POWERPC_FLAG_DE\n");
9436 if (env->msr_mask & (1 << 2)) {
9437 switch (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
9438 case POWERPC_FLAG_PX:
9439 case POWERPC_FLAG_PMM:
9442 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9443 "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n");
9446 } else if (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
9447 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9448 "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
9451 if ((env->flags & (POWERPC_FLAG_RTC_CLK | POWERPC_FLAG_BUS_CLK)) == 0) {
9452 fprintf(stderr, "PowerPC flags inconsistency\n"
9453 "Should define the time-base and decrementer clock source\n");
9456 /* Allocate TLBs buffer when needed */
9457 #if !defined(CONFIG_USER_ONLY)
9458 if (env->nb_tlb != 0) {
9459 int nb_tlb = env->nb_tlb;
9460 if (env->id_tlbs != 0) {
9463 switch (env->tlb_type) {
9465 env->tlb.tlb6 = g_new0(ppc6xx_tlb_t, nb_tlb);
9468 env->tlb.tlbe = g_new0(ppcemb_tlb_t, nb_tlb);
9471 env->tlb.tlbm = g_new0(ppcmas_tlb_t, nb_tlb);
9474 /* Pre-compute some useful values */
9475 env->tlb_per_way = env->nb_tlb / env->nb_ways;
9477 if (env->irq_inputs == NULL) {
9478 warn_report("no internal IRQ controller registered."
9479 " Attempt QEMU to crash very soon !");
9482 if (env->check_pow == NULL) {
9483 warn_report("no power management check handler registered."
9484 " Attempt QEMU to crash very soon !");
9488 #if defined(PPC_DUMP_CPU)
9489 static void dump_ppc_sprs(CPUPPCState *env)
9492 #if !defined(CONFIG_USER_ONLY)
9498 printf("Special purpose registers:\n");
9499 for (i = 0; i < 32; i++) {
9500 for (j = 0; j < 32; j++) {
9502 spr = &env->spr_cb[n];
9503 uw = spr->uea_write != NULL && spr->uea_write != SPR_NOACCESS;
9504 ur = spr->uea_read != NULL && spr->uea_read != SPR_NOACCESS;
9505 #if !defined(CONFIG_USER_ONLY)
9506 sw = spr->oea_write != NULL && spr->oea_write != SPR_NOACCESS;
9507 sr = spr->oea_read != NULL && spr->oea_read != SPR_NOACCESS;
9508 if (sw || sr || uw || ur) {
9509 printf("SPR: %4d (%03x) %-8s s%c%c u%c%c\n",
9510 (i << 5) | j, (i << 5) | j, spr->name,
9511 sw ? 'w' : '-', sr ? 'r' : '-',
9512 uw ? 'w' : '-', ur ? 'r' : '-');
9516 printf("SPR: %4d (%03x) %-8s u%c%c\n",
9517 (i << 5) | j, (i << 5) | j, spr->name,
9518 uw ? 'w' : '-', ur ? 'r' : '-');
9528 /*****************************************************************************/
9532 PPC_DIRECT = 0, /* Opcode routine */
9533 PPC_INDIRECT = 1, /* Indirect opcode table */
9536 #define PPC_OPCODE_MASK 0x3
9538 static inline int is_indirect_opcode(void *handler)
9540 return ((uintptr_t)handler & PPC_OPCODE_MASK) == PPC_INDIRECT;
9543 static inline opc_handler_t **ind_table(void *handler)
9545 return (opc_handler_t **)((uintptr_t)handler & ~PPC_OPCODE_MASK);
9548 /* Instruction table creation */
9549 /* Opcodes tables creation */
9550 static void fill_new_table(opc_handler_t **table, int len)
9554 for (i = 0; i < len; i++) {
9555 table[i] = &invalid_handler;
9559 static int create_new_table(opc_handler_t **table, unsigned char idx)
9561 opc_handler_t **tmp;
9563 tmp = g_new(opc_handler_t *, PPC_CPU_INDIRECT_OPCODES_LEN);
9564 fill_new_table(tmp, PPC_CPU_INDIRECT_OPCODES_LEN);
9565 table[idx] = (opc_handler_t *)((uintptr_t)tmp | PPC_INDIRECT);
9570 static int insert_in_table(opc_handler_t **table, unsigned char idx,
9571 opc_handler_t *handler)
9573 if (table[idx] != &invalid_handler) {
9576 table[idx] = handler;
9581 static int register_direct_insn(opc_handler_t **ppc_opcodes,
9582 unsigned char idx, opc_handler_t *handler)
9584 if (insert_in_table(ppc_opcodes, idx, handler) < 0) {
9585 printf("*** ERROR: opcode %02x already assigned in main "
9586 "opcode table\n", idx);
9587 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9588 printf(" Registered handler '%s' - new handler '%s'\n",
9589 ppc_opcodes[idx]->oname, handler->oname);
9597 static int register_ind_in_table(opc_handler_t **table,
9598 unsigned char idx1, unsigned char idx2,
9599 opc_handler_t *handler)
9601 if (table[idx1] == &invalid_handler) {
9602 if (create_new_table(table, idx1) < 0) {
9603 printf("*** ERROR: unable to create indirect table "
9604 "idx=%02x\n", idx1);
9608 if (!is_indirect_opcode(table[idx1])) {
9609 printf("*** ERROR: idx %02x already assigned to a direct "
9611 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9612 printf(" Registered handler '%s' - new handler '%s'\n",
9613 ind_table(table[idx1])[idx2]->oname, handler->oname);
9618 if (handler != NULL &&
9619 insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) {
9620 printf("*** ERROR: opcode %02x already assigned in "
9621 "opcode table %02x\n", idx2, idx1);
9622 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9623 printf(" Registered handler '%s' - new handler '%s'\n",
9624 ind_table(table[idx1])[idx2]->oname, handler->oname);
9632 static int register_ind_insn(opc_handler_t **ppc_opcodes,
9633 unsigned char idx1, unsigned char idx2,
9634 opc_handler_t *handler)
9636 return register_ind_in_table(ppc_opcodes, idx1, idx2, handler);
9639 static int register_dblind_insn(opc_handler_t **ppc_opcodes,
9640 unsigned char idx1, unsigned char idx2,
9641 unsigned char idx3, opc_handler_t *handler)
9643 if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
9644 printf("*** ERROR: unable to join indirect table idx "
9645 "[%02x-%02x]\n", idx1, idx2);
9648 if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3,
9650 printf("*** ERROR: unable to insert opcode "
9651 "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
9658 static int register_trplind_insn(opc_handler_t **ppc_opcodes,
9659 unsigned char idx1, unsigned char idx2,
9660 unsigned char idx3, unsigned char idx4,
9661 opc_handler_t *handler)
9663 opc_handler_t **table;
9665 if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
9666 printf("*** ERROR: unable to join indirect table idx "
9667 "[%02x-%02x]\n", idx1, idx2);
9670 table = ind_table(ppc_opcodes[idx1]);
9671 if (register_ind_in_table(table, idx2, idx3, NULL) < 0) {
9672 printf("*** ERROR: unable to join 2nd-level indirect table idx "
9673 "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
9676 table = ind_table(table[idx2]);
9677 if (register_ind_in_table(table, idx3, idx4, handler) < 0) {
9678 printf("*** ERROR: unable to insert opcode "
9679 "[%02x-%02x-%02x-%02x]\n", idx1, idx2, idx3, idx4);
9684 static int register_insn(opc_handler_t **ppc_opcodes, opcode_t *insn)
9686 if (insn->opc2 != 0xFF) {
9687 if (insn->opc3 != 0xFF) {
9688 if (insn->opc4 != 0xFF) {
9689 if (register_trplind_insn(ppc_opcodes, insn->opc1, insn->opc2,
9690 insn->opc3, insn->opc4,
9691 &insn->handler) < 0) {
9695 if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2,
9696 insn->opc3, &insn->handler) < 0) {
9701 if (register_ind_insn(ppc_opcodes, insn->opc1,
9702 insn->opc2, &insn->handler) < 0) {
9707 if (register_direct_insn(ppc_opcodes, insn->opc1, &insn->handler) < 0) {
9715 static int test_opcode_table(opc_handler_t **table, int len)
9719 for (i = 0, count = 0; i < len; i++) {
9720 /* Consistency fixup */
9721 if (table[i] == NULL) {
9722 table[i] = &invalid_handler;
9724 if (table[i] != &invalid_handler) {
9725 if (is_indirect_opcode(table[i])) {
9726 tmp = test_opcode_table(ind_table(table[i]),
9727 PPC_CPU_INDIRECT_OPCODES_LEN);
9730 table[i] = &invalid_handler;
9743 static void fix_opcode_tables(opc_handler_t **ppc_opcodes)
9745 if (test_opcode_table(ppc_opcodes, PPC_CPU_OPCODES_LEN) == 0) {
9746 printf("*** WARNING: no opcode defined !\n");
9750 /*****************************************************************************/
9751 static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp)
9753 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
9756 fill_new_table(cpu->opcodes, PPC_CPU_OPCODES_LEN);
9757 for (opc = opcodes; opc < &opcodes[ARRAY_SIZE(opcodes)]; opc++) {
9758 if (((opc->handler.type & pcc->insns_flags) != 0) ||
9759 ((opc->handler.type2 & pcc->insns_flags2) != 0)) {
9760 if (register_insn(cpu->opcodes, opc) < 0) {
9761 error_setg(errp, "ERROR initializing PowerPC instruction "
9762 "0x%02x 0x%02x 0x%02x", opc->opc1, opc->opc2,
9768 fix_opcode_tables(cpu->opcodes);
9773 #if defined(PPC_DUMP_CPU)
9774 static void dump_ppc_insns(CPUPPCState *env)
9776 opc_handler_t **table, *handler;
9778 uint8_t opc1, opc2, opc3, opc4;
9780 printf("Instructions set:\n");
9781 /* opc1 is 6 bits long */
9782 for (opc1 = 0x00; opc1 < PPC_CPU_OPCODES_LEN; opc1++) {
9783 table = env->opcodes;
9784 handler = table[opc1];
9785 if (is_indirect_opcode(handler)) {
9786 /* opc2 is 5 bits long */
9787 for (opc2 = 0; opc2 < PPC_CPU_INDIRECT_OPCODES_LEN; opc2++) {
9788 table = env->opcodes;
9789 handler = env->opcodes[opc1];
9790 table = ind_table(handler);
9791 handler = table[opc2];
9792 if (is_indirect_opcode(handler)) {
9793 table = ind_table(handler);
9794 /* opc3 is 5 bits long */
9795 for (opc3 = 0; opc3 < PPC_CPU_INDIRECT_OPCODES_LEN;
9797 handler = table[opc3];
9798 if (is_indirect_opcode(handler)) {
9799 table = ind_table(handler);
9800 /* opc4 is 5 bits long */
9801 for (opc4 = 0; opc4 < PPC_CPU_INDIRECT_OPCODES_LEN;
9803 handler = table[opc4];
9804 if (handler->handler != &gen_invalid) {
9805 printf("INSN: %02x %02x %02x %02x -- "
9806 "(%02d %04d %02d) : %s\n",
9807 opc1, opc2, opc3, opc4,
9808 opc1, (opc3 << 5) | opc2, opc4,
9813 if (handler->handler != &gen_invalid) {
9814 /* Special hack to properly dump SPE insns */
9815 p = strchr(handler->oname, '_');
9817 printf("INSN: %02x %02x %02x (%02d %04d) : "
9819 opc1, opc2, opc3, opc1,
9824 if ((p - handler->oname) != strlen(q)
9825 || (memcmp(handler->oname, q, strlen(q))
9827 /* First instruction */
9828 printf("INSN: %02x %02x %02x"
9829 "(%02d %04d) : %.*s\n",
9830 opc1, opc2 << 1, opc3, opc1,
9831 (opc3 << 6) | (opc2 << 1),
9832 (int)(p - handler->oname),
9835 if (strcmp(p + 1, q) != 0) {
9836 /* Second instruction */
9837 printf("INSN: %02x %02x %02x "
9838 "(%02d %04d) : %s\n", opc1,
9839 (opc2 << 1) | 1, opc3, opc1,
9840 (opc3 << 6) | (opc2 << 1) | 1,
9848 if (handler->handler != &gen_invalid) {
9849 printf("INSN: %02x %02x -- (%02d %04d) : %s\n",
9850 opc1, opc2, opc1, opc2, handler->oname);
9855 if (handler->handler != &gen_invalid) {
9856 printf("INSN: %02x -- -- (%02d ----) : %s\n",
9857 opc1, opc1, handler->oname);
9864 static bool avr_need_swap(CPUPPCState *env)
9866 #ifdef HOST_WORDS_BIGENDIAN
9873 #if !defined(CONFIG_USER_ONLY)
9874 static int gdb_find_spr_idx(CPUPPCState *env, int n)
9878 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
9879 ppc_spr_t *spr = &env->spr_cb[i];
9881 if (spr->name && spr->gdb_id == n) {
9888 static int gdb_get_spr_reg(CPUPPCState *env, GByteArray *buf, int n)
9893 reg = gdb_find_spr_idx(env, n);
9898 len = TARGET_LONG_SIZE;
9899 gdb_get_regl(buf, env->spr[reg]);
9900 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, len), len);
9904 static int gdb_set_spr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
9909 reg = gdb_find_spr_idx(env, n);
9914 len = TARGET_LONG_SIZE;
9915 ppc_maybe_bswap_register(env, mem_buf, len);
9916 env->spr[reg] = ldn_p(mem_buf, len);
9922 static int gdb_get_float_reg(CPUPPCState *env, GByteArray *buf, int n)
9926 gdb_get_reg64(buf, *cpu_fpr_ptr(env, n));
9927 mem_buf = gdb_get_reg_ptr(buf, 8);
9928 ppc_maybe_bswap_register(env, mem_buf, 8);
9932 gdb_get_reg32(buf, env->fpscr);
9933 mem_buf = gdb_get_reg_ptr(buf, 4);
9934 ppc_maybe_bswap_register(env, mem_buf, 4);
9940 static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
9943 ppc_maybe_bswap_register(env, mem_buf, 8);
9944 *cpu_fpr_ptr(env, n) = ldq_p(mem_buf);
9948 ppc_maybe_bswap_register(env, mem_buf, 4);
9949 helper_store_fpscr(env, ldl_p(mem_buf), 0xffffffff);
9955 static int gdb_get_avr_reg(CPUPPCState *env, GByteArray *buf, int n)
9960 ppc_avr_t *avr = cpu_avr_ptr(env, n);
9961 if (!avr_need_swap(env)) {
9962 gdb_get_reg128(buf, avr->u64[0] , avr->u64[1]);
9964 gdb_get_reg128(buf, avr->u64[1] , avr->u64[0]);
9966 mem_buf = gdb_get_reg_ptr(buf, 16);
9967 ppc_maybe_bswap_register(env, mem_buf, 8);
9968 ppc_maybe_bswap_register(env, mem_buf + 8, 8);
9972 gdb_get_reg32(buf, helper_mfvscr(env));
9973 mem_buf = gdb_get_reg_ptr(buf, 4);
9974 ppc_maybe_bswap_register(env, mem_buf, 4);
9978 gdb_get_reg32(buf, (uint32_t)env->spr[SPR_VRSAVE]);
9979 mem_buf = gdb_get_reg_ptr(buf, 4);
9980 ppc_maybe_bswap_register(env, mem_buf, 4);
9986 static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
9989 ppc_avr_t *avr = cpu_avr_ptr(env, n);
9990 ppc_maybe_bswap_register(env, mem_buf, 8);
9991 ppc_maybe_bswap_register(env, mem_buf + 8, 8);
9992 if (!avr_need_swap(env)) {
9993 avr->u64[0] = ldq_p(mem_buf);
9994 avr->u64[1] = ldq_p(mem_buf + 8);
9996 avr->u64[1] = ldq_p(mem_buf);
9997 avr->u64[0] = ldq_p(mem_buf + 8);
10002 ppc_maybe_bswap_register(env, mem_buf, 4);
10003 helper_mtvscr(env, ldl_p(mem_buf));
10007 ppc_maybe_bswap_register(env, mem_buf, 4);
10008 env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf);
10014 static int gdb_get_spe_reg(CPUPPCState *env, GByteArray *buf, int n)
10017 #if defined(TARGET_PPC64)
10018 gdb_get_reg32(buf, env->gpr[n] >> 32);
10019 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
10021 gdb_get_reg32(buf, env->gprh[n]);
10026 gdb_get_reg64(buf, env->spe_acc);
10027 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
10031 gdb_get_reg32(buf, env->spe_fscr);
10032 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
10038 static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
10041 #if defined(TARGET_PPC64)
10042 target_ulong lo = (uint32_t)env->gpr[n];
10045 ppc_maybe_bswap_register(env, mem_buf, 4);
10047 hi = (target_ulong)ldl_p(mem_buf) << 32;
10048 env->gpr[n] = lo | hi;
10050 env->gprh[n] = ldl_p(mem_buf);
10055 ppc_maybe_bswap_register(env, mem_buf, 8);
10056 env->spe_acc = ldq_p(mem_buf);
10060 ppc_maybe_bswap_register(env, mem_buf, 4);
10061 env->spe_fscr = ldl_p(mem_buf);
10067 static int gdb_get_vsx_reg(CPUPPCState *env, GByteArray *buf, int n)
10070 gdb_get_reg64(buf, *cpu_vsrl_ptr(env, n));
10071 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
10077 static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
10080 ppc_maybe_bswap_register(env, mem_buf, 8);
10081 *cpu_vsrl_ptr(env, n) = ldq_p(mem_buf);
10087 static int ppc_fixup_cpu(PowerPCCPU *cpu)
10089 CPUPPCState *env = &cpu->env;
10092 * TCG doesn't (yet) emulate some groups of instructions that are
10093 * implemented on some otherwise supported CPUs (e.g. VSX and
10094 * decimal floating point instructions on POWER7). We remove
10095 * unsupported instruction groups from the cpu state's instruction
10096 * masks and hope the guest can cope. For at least the pseries
10097 * machine, the unavailability of these instructions can be
10098 * advertised to the guest via the device tree.
10100 if ((env->insns_flags & ~PPC_TCG_INSNS)
10101 || (env->insns_flags2 & ~PPC_TCG_INSNS2)) {
10102 warn_report("Disabling some instructions which are not "
10103 "emulated by TCG (0x%" PRIx64 ", 0x%" PRIx64 ")",
10104 env->insns_flags & ~PPC_TCG_INSNS,
10105 env->insns_flags2 & ~PPC_TCG_INSNS2);
10107 env->insns_flags &= PPC_TCG_INSNS;
10108 env->insns_flags2 &= PPC_TCG_INSNS2;
10112 static void ppc_cpu_realize(DeviceState *dev, Error **errp)
10114 CPUState *cs = CPU(dev);
10115 PowerPCCPU *cpu = POWERPC_CPU(dev);
10116 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
10117 Error *local_err = NULL;
10119 cpu_exec_realizefn(cs, &local_err);
10120 if (local_err != NULL) {
10121 error_propagate(errp, local_err);
10124 if (cpu->vcpu_id == UNASSIGNED_CPU_INDEX) {
10125 cpu->vcpu_id = cs->cpu_index;
10128 if (tcg_enabled()) {
10129 if (ppc_fixup_cpu(cpu) != 0) {
10130 error_setg(errp, "Unable to emulate selected CPU with TCG");
10135 create_ppc_opcodes(cpu, &local_err);
10136 if (local_err != NULL) {
10137 error_propagate(errp, local_err);
10140 init_ppc_proc(cpu);
10142 if (pcc->insns_flags & PPC_FLOAT) {
10143 gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
10144 33, "power-fpu.xml", 0);
10146 if (pcc->insns_flags & PPC_ALTIVEC) {
10147 gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
10148 34, "power-altivec.xml", 0);
10150 if (pcc->insns_flags & PPC_SPE) {
10151 gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
10152 34, "power-spe.xml", 0);
10154 if (pcc->insns_flags2 & PPC2_VSX) {
10155 gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg,
10156 32, "power-vsx.xml", 0);
10158 #ifndef CONFIG_USER_ONLY
10159 gdb_register_coprocessor(cs, gdb_get_spr_reg, gdb_set_spr_reg,
10160 pcc->gdb_num_sprs, "power-spr.xml", 0);
10162 qemu_init_vcpu(cs);
10164 pcc->parent_realize(dev, errp);
10166 #if defined(PPC_DUMP_CPU)
10168 CPUPPCState *env = &cpu->env;
10169 const char *mmu_model, *excp_model, *bus_model;
10170 switch (env->mmu_model) {
10171 case POWERPC_MMU_32B:
10172 mmu_model = "PowerPC 32";
10174 case POWERPC_MMU_SOFT_6xx:
10175 mmu_model = "PowerPC 6xx/7xx with software driven TLBs";
10177 case POWERPC_MMU_SOFT_74xx:
10178 mmu_model = "PowerPC 74xx with software driven TLBs";
10180 case POWERPC_MMU_SOFT_4xx:
10181 mmu_model = "PowerPC 4xx with software driven TLBs";
10183 case POWERPC_MMU_SOFT_4xx_Z:
10184 mmu_model = "PowerPC 4xx with software driven TLBs "
10185 "and zones protections";
10187 case POWERPC_MMU_REAL:
10188 mmu_model = "PowerPC real mode only";
10190 case POWERPC_MMU_MPC8xx:
10191 mmu_model = "PowerPC MPC8xx";
10193 case POWERPC_MMU_BOOKE:
10194 mmu_model = "PowerPC BookE";
10196 case POWERPC_MMU_BOOKE206:
10197 mmu_model = "PowerPC BookE 2.06";
10199 case POWERPC_MMU_601:
10200 mmu_model = "PowerPC 601";
10202 #if defined(TARGET_PPC64)
10203 case POWERPC_MMU_64B:
10204 mmu_model = "PowerPC 64";
10208 mmu_model = "Unknown or invalid";
10211 switch (env->excp_model) {
10212 case POWERPC_EXCP_STD:
10213 excp_model = "PowerPC";
10215 case POWERPC_EXCP_40x:
10216 excp_model = "PowerPC 40x";
10218 case POWERPC_EXCP_601:
10219 excp_model = "PowerPC 601";
10221 case POWERPC_EXCP_602:
10222 excp_model = "PowerPC 602";
10224 case POWERPC_EXCP_603:
10225 excp_model = "PowerPC 603";
10227 case POWERPC_EXCP_603E:
10228 excp_model = "PowerPC 603e";
10230 case POWERPC_EXCP_604:
10231 excp_model = "PowerPC 604";
10233 case POWERPC_EXCP_7x0:
10234 excp_model = "PowerPC 740/750";
10236 case POWERPC_EXCP_7x5:
10237 excp_model = "PowerPC 745/755";
10239 case POWERPC_EXCP_74xx:
10240 excp_model = "PowerPC 74xx";
10242 case POWERPC_EXCP_BOOKE:
10243 excp_model = "PowerPC BookE";
10245 #if defined(TARGET_PPC64)
10246 case POWERPC_EXCP_970:
10247 excp_model = "PowerPC 970";
10251 excp_model = "Unknown or invalid";
10254 switch (env->bus_model) {
10255 case PPC_FLAGS_INPUT_6xx:
10256 bus_model = "PowerPC 6xx";
10258 case PPC_FLAGS_INPUT_BookE:
10259 bus_model = "PowerPC BookE";
10261 case PPC_FLAGS_INPUT_405:
10262 bus_model = "PowerPC 405";
10264 case PPC_FLAGS_INPUT_401:
10265 bus_model = "PowerPC 401/403";
10267 case PPC_FLAGS_INPUT_RCPU:
10268 bus_model = "RCPU / MPC8xx";
10270 #if defined(TARGET_PPC64)
10271 case PPC_FLAGS_INPUT_970:
10272 bus_model = "PowerPC 970";
10276 bus_model = "Unknown or invalid";
10279 printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64 "\n"
10280 " MMU model : %s\n",
10281 object_class_get_name(OBJECT_CLASS(pcc)),
10282 pcc->pvr, pcc->msr_mask, mmu_model);
10283 #if !defined(CONFIG_USER_ONLY)
10284 if (env->tlb.tlb6) {
10285 printf(" %d %s TLB in %d ways\n",
10286 env->nb_tlb, env->id_tlbs ? "splitted" : "merged",
10290 printf(" Exceptions model : %s\n"
10291 " Bus model : %s\n",
10292 excp_model, bus_model);
10293 printf(" MSR features :\n");
10294 if (env->flags & POWERPC_FLAG_SPE) {
10295 printf(" signal processing engine enable"
10297 } else if (env->flags & POWERPC_FLAG_VRE) {
10298 printf(" vector processor enable\n");
10300 if (env->flags & POWERPC_FLAG_TGPR) {
10301 printf(" temporary GPRs\n");
10302 } else if (env->flags & POWERPC_FLAG_CE) {
10303 printf(" critical input enable\n");
10305 if (env->flags & POWERPC_FLAG_SE) {
10306 printf(" single-step trace mode\n");
10307 } else if (env->flags & POWERPC_FLAG_DWE) {
10308 printf(" debug wait enable\n");
10309 } else if (env->flags & POWERPC_FLAG_UBLE) {
10310 printf(" user BTB lock enable\n");
10312 if (env->flags & POWERPC_FLAG_BE) {
10313 printf(" branch-step trace mode\n");
10314 } else if (env->flags & POWERPC_FLAG_DE) {
10315 printf(" debug interrupt enable\n");
10317 if (env->flags & POWERPC_FLAG_PX) {
10318 printf(" inclusive protection\n");
10319 } else if (env->flags & POWERPC_FLAG_PMM) {
10320 printf(" performance monitor mark\n");
10322 if (env->flags == POWERPC_FLAG_NONE) {
10325 printf(" Time-base/decrementer clock source: %s\n",
10326 env->flags & POWERPC_FLAG_RTC_CLK ? "RTC clock" : "bus clock");
10327 dump_ppc_insns(env);
10328 dump_ppc_sprs(env);
10335 cpu_exec_unrealizefn(cs);
10338 static void ppc_cpu_unrealize(DeviceState *dev)
10340 PowerPCCPU *cpu = POWERPC_CPU(dev);
10341 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
10342 opc_handler_t **table, **table_2;
10345 pcc->parent_unrealize(dev);
10347 cpu_remove_sync(CPU(cpu));
10349 for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) {
10350 if (cpu->opcodes[i] == &invalid_handler) {
10353 if (is_indirect_opcode(cpu->opcodes[i])) {
10354 table = ind_table(cpu->opcodes[i]);
10355 for (j = 0; j < PPC_CPU_INDIRECT_OPCODES_LEN; j++) {
10356 if (table[j] == &invalid_handler) {
10359 if (is_indirect_opcode(table[j])) {
10360 table_2 = ind_table(table[j]);
10361 for (k = 0; k < PPC_CPU_INDIRECT_OPCODES_LEN; k++) {
10362 if (table_2[k] != &invalid_handler &&
10363 is_indirect_opcode(table_2[k])) {
10364 g_free((opc_handler_t *)((uintptr_t)table_2[k] &
10368 g_free((opc_handler_t *)((uintptr_t)table[j] &
10372 g_free((opc_handler_t *)((uintptr_t)cpu->opcodes[i] &
10378 static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b)
10380 ObjectClass *oc = (ObjectClass *)a;
10381 uint32_t pvr = *(uint32_t *)b;
10382 PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
10384 /* -cpu host does a PVR lookup during construction */
10385 if (unlikely(strcmp(object_class_get_name(oc),
10386 TYPE_HOST_POWERPC_CPU) == 0)) {
10390 return pcc->pvr == pvr ? 0 : -1;
10393 PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr)
10395 GSList *list, *item;
10396 PowerPCCPUClass *pcc = NULL;
10398 list = object_class_get_list(TYPE_POWERPC_CPU, false);
10399 item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr);
10400 if (item != NULL) {
10401 pcc = POWERPC_CPU_CLASS(item->data);
10403 g_slist_free(list);
10408 static gint ppc_cpu_compare_class_pvr_mask(gconstpointer a, gconstpointer b)
10410 ObjectClass *oc = (ObjectClass *)a;
10411 uint32_t pvr = *(uint32_t *)b;
10412 PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
10414 /* -cpu host does a PVR lookup during construction */
10415 if (unlikely(strcmp(object_class_get_name(oc),
10416 TYPE_HOST_POWERPC_CPU) == 0)) {
10420 if (pcc->pvr_match(pcc, pvr)) {
10427 PowerPCCPUClass *ppc_cpu_class_by_pvr_mask(uint32_t pvr)
10429 GSList *list, *item;
10430 PowerPCCPUClass *pcc = NULL;
10432 list = object_class_get_list(TYPE_POWERPC_CPU, true);
10433 item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr_mask);
10434 if (item != NULL) {
10435 pcc = POWERPC_CPU_CLASS(item->data);
10437 g_slist_free(list);
10442 static const char *ppc_cpu_lookup_alias(const char *alias)
10446 for (ai = 0; ppc_cpu_aliases[ai].alias != NULL; ai++) {
10447 if (strcmp(ppc_cpu_aliases[ai].alias, alias) == 0) {
10448 return ppc_cpu_aliases[ai].model;
10455 static ObjectClass *ppc_cpu_class_by_name(const char *name)
10457 char *cpu_model, *typename;
10463 * Lookup by PVR if cpu_model is valid 8 digit hex number (excl:
10464 * 0x prefix if present)
10466 if (!qemu_strtoul(name, &p, 16, &pvr)) {
10467 int len = p - name;
10468 len = (len == 10) && (name[1] == 'x') ? len - 2 : len;
10469 if ((len == 8) && (*p == '\0')) {
10470 return OBJECT_CLASS(ppc_cpu_class_by_pvr(pvr));
10474 cpu_model = g_ascii_strdown(name, -1);
10475 p = ppc_cpu_lookup_alias(cpu_model);
10478 cpu_model = g_strdup(p);
10481 typename = g_strdup_printf("%s" POWERPC_CPU_TYPE_SUFFIX, cpu_model);
10482 oc = object_class_by_name(typename);
10489 PowerPCCPUClass *ppc_cpu_get_family_class(PowerPCCPUClass *pcc)
10491 ObjectClass *oc = OBJECT_CLASS(pcc);
10493 while (oc && !object_class_is_abstract(oc)) {
10494 oc = object_class_get_parent(oc);
10498 return POWERPC_CPU_CLASS(oc);
10501 /* Sort by PVR, ordering special case "host" last. */
10502 static gint ppc_cpu_list_compare(gconstpointer a, gconstpointer b)
10504 ObjectClass *oc_a = (ObjectClass *)a;
10505 ObjectClass *oc_b = (ObjectClass *)b;
10506 PowerPCCPUClass *pcc_a = POWERPC_CPU_CLASS(oc_a);
10507 PowerPCCPUClass *pcc_b = POWERPC_CPU_CLASS(oc_b);
10508 const char *name_a = object_class_get_name(oc_a);
10509 const char *name_b = object_class_get_name(oc_b);
10511 if (strcmp(name_a, TYPE_HOST_POWERPC_CPU) == 0) {
10513 } else if (strcmp(name_b, TYPE_HOST_POWERPC_CPU) == 0) {
10516 /* Avoid an integer overflow during subtraction */
10517 if (pcc_a->pvr < pcc_b->pvr) {
10519 } else if (pcc_a->pvr > pcc_b->pvr) {
10527 static void ppc_cpu_list_entry(gpointer data, gpointer user_data)
10529 ObjectClass *oc = data;
10530 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
10531 DeviceClass *family = DEVICE_CLASS(ppc_cpu_get_family_class(pcc));
10532 const char *typename = object_class_get_name(oc);
10536 if (unlikely(strcmp(typename, TYPE_HOST_POWERPC_CPU) == 0)) {
10540 name = g_strndup(typename,
10541 strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX));
10542 qemu_printf("PowerPC %-16s PVR %08x\n", name, pcc->pvr);
10543 for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
10544 PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
10545 ObjectClass *alias_oc = ppc_cpu_class_by_name(alias->model);
10547 if (alias_oc != oc) {
10551 * If running with KVM, we might update the family alias later, so
10552 * avoid printing the wrong alias here and use "preferred" instead
10554 if (strcmp(alias->alias, family->desc) == 0) {
10555 qemu_printf("PowerPC %-16s (alias for preferred %s CPU)\n",
10556 alias->alias, family->desc);
10558 qemu_printf("PowerPC %-16s (alias for %s)\n",
10559 alias->alias, name);
10565 void ppc_cpu_list(void)
10569 list = object_class_get_list(TYPE_POWERPC_CPU, false);
10570 list = g_slist_sort(list, ppc_cpu_list_compare);
10571 g_slist_foreach(list, ppc_cpu_list_entry, NULL);
10572 g_slist_free(list);
10576 qemu_printf("PowerPC %-16s\n", "host");
10580 static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
10582 ObjectClass *oc = data;
10583 CpuDefinitionInfoList **first = user_data;
10584 const char *typename;
10585 CpuDefinitionInfo *info;
10587 typename = object_class_get_name(oc);
10588 info = g_malloc0(sizeof(*info));
10589 info->name = g_strndup(typename,
10590 strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX));
10592 QAPI_LIST_PREPEND(*first, info);
10595 CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
10597 CpuDefinitionInfoList *cpu_list = NULL;
10601 list = object_class_get_list(TYPE_POWERPC_CPU, false);
10602 g_slist_foreach(list, ppc_cpu_defs_entry, &cpu_list);
10603 g_slist_free(list);
10605 for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
10606 PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
10608 CpuDefinitionInfo *info;
10610 oc = ppc_cpu_class_by_name(alias->model);
10615 info = g_malloc0(sizeof(*info));
10616 info->name = g_strdup(alias->alias);
10617 info->q_typename = g_strdup(object_class_get_name(oc));
10619 QAPI_LIST_PREPEND(cpu_list, info);
10625 static void ppc_cpu_set_pc(CPUState *cs, vaddr value)
10627 PowerPCCPU *cpu = POWERPC_CPU(cs);
10629 cpu->env.nip = value;
10632 static bool ppc_cpu_has_work(CPUState *cs)
10634 PowerPCCPU *cpu = POWERPC_CPU(cs);
10635 CPUPPCState *env = &cpu->env;
10637 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
10640 static void ppc_cpu_reset(DeviceState *dev)
10642 CPUState *s = CPU(dev);
10643 PowerPCCPU *cpu = POWERPC_CPU(s);
10644 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
10645 CPUPPCState *env = &cpu->env;
10649 pcc->parent_reset(dev);
10651 msr = (target_ulong)0;
10652 msr |= (target_ulong)MSR_HVB;
10653 msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
10654 msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
10655 msr |= (target_ulong)1 << MSR_EP;
10656 #if defined(DO_SINGLE_STEP) && 0
10657 /* Single step trace mode */
10658 msr |= (target_ulong)1 << MSR_SE;
10659 msr |= (target_ulong)1 << MSR_BE;
10661 #if defined(CONFIG_USER_ONLY)
10662 msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
10663 msr |= (target_ulong)1 << MSR_FE0; /* Allow floating point exceptions */
10664 msr |= (target_ulong)1 << MSR_FE1;
10665 msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
10666 msr |= (target_ulong)1 << MSR_VSX; /* Allow VSX usage */
10667 msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
10668 msr |= (target_ulong)1 << MSR_PR;
10669 #if defined(TARGET_PPC64)
10670 msr |= (target_ulong)1 << MSR_TM; /* Transactional memory */
10672 #if !defined(TARGET_WORDS_BIGENDIAN)
10673 msr |= (target_ulong)1 << MSR_LE; /* Little-endian user mode */
10674 if (!((env->msr_mask >> MSR_LE) & 1)) {
10675 fprintf(stderr, "Selected CPU does not support little-endian.\n");
10681 #if defined(TARGET_PPC64)
10682 if (mmu_is_64bit(env->mmu_model)) {
10683 msr |= (1ULL << MSR_SF);
10687 hreg_store_msr(env, msr, 1);
10689 #if !defined(CONFIG_USER_ONLY)
10690 env->nip = env->hreset_vector | env->excp_prefix;
10691 if (env->mmu_model != POWERPC_MMU_REAL) {
10692 ppc_tlb_invalidate_all(env);
10696 hreg_compute_hflags(env);
10697 env->reserve_addr = (target_ulong)-1ULL;
10698 /* Be sure no exception or interrupt is pending */
10699 env->pending_interrupts = 0;
10700 s->exception_index = POWERPC_EXCP_NONE;
10701 env->error_code = 0;
10702 ppc_irq_reset(cpu);
10704 /* tininess for underflow is detected before rounding */
10705 set_float_detect_tininess(float_tininess_before_rounding,
10708 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
10709 ppc_spr_t *spr = &env->spr_cb[i];
10714 env->spr[i] = spr->default_value;
10718 #ifndef CONFIG_USER_ONLY
10720 static bool ppc_cpu_is_big_endian(CPUState *cs)
10722 PowerPCCPU *cpu = POWERPC_CPU(cs);
10723 CPUPPCState *env = &cpu->env;
10725 cpu_synchronize_state(cs);
10731 static void ppc_cpu_exec_enter(CPUState *cs)
10733 PowerPCCPU *cpu = POWERPC_CPU(cs);
10736 PPCVirtualHypervisorClass *vhc =
10737 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
10738 vhc->cpu_exec_enter(cpu->vhyp, cpu);
10742 static void ppc_cpu_exec_exit(CPUState *cs)
10744 PowerPCCPU *cpu = POWERPC_CPU(cs);
10747 PPCVirtualHypervisorClass *vhc =
10748 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
10749 vhc->cpu_exec_exit(cpu->vhyp, cpu);
10752 #endif /* CONFIG_TCG */
10754 #endif /* !CONFIG_USER_ONLY */
10756 static void ppc_cpu_instance_init(Object *obj)
10758 PowerPCCPU *cpu = POWERPC_CPU(obj);
10759 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
10760 CPUPPCState *env = &cpu->env;
10762 cpu_set_cpustate_pointers(cpu);
10763 cpu->vcpu_id = UNASSIGNED_CPU_INDEX;
10765 env->msr_mask = pcc->msr_mask;
10766 env->mmu_model = pcc->mmu_model;
10767 env->excp_model = pcc->excp_model;
10768 env->bus_model = pcc->bus_model;
10769 env->insns_flags = pcc->insns_flags;
10770 env->insns_flags2 = pcc->insns_flags2;
10771 env->flags = pcc->flags;
10772 env->bfd_mach = pcc->bfd_mach;
10773 env->check_pow = pcc->check_pow;
10776 * Mark HV mode as supported if the CPU has an MSR_HV bit in the
10777 * msr_mask. The mask can later be cleared by PAPR mode but the hv
10778 * mode support will remain, thus enforcing that we cannot use
10779 * priv. instructions in guest in PAPR mode. For 970 we currently
10780 * simply don't set HV in msr_mask thus simulating an "Apple mode"
10781 * 970. If we ever want to support 970 HV mode, we'll have to add
10782 * a processor attribute of some sort.
10784 #if !defined(CONFIG_USER_ONLY)
10785 env->has_hv_mode = !!(env->msr_mask & MSR_HVB);
10788 ppc_hash64_init(cpu);
10791 static void ppc_cpu_instance_finalize(Object *obj)
10793 PowerPCCPU *cpu = POWERPC_CPU(obj);
10795 ppc_hash64_finalize(cpu);
10798 static bool ppc_pvr_match_default(PowerPCCPUClass *pcc, uint32_t pvr)
10800 return pcc->pvr == pvr;
10803 static gchar *ppc_gdb_arch_name(CPUState *cs)
10805 #if defined(TARGET_PPC64)
10806 return g_strdup("powerpc:common64");
10808 return g_strdup("powerpc:common");
10812 static void ppc_disas_set_info(CPUState *cs, disassemble_info *info)
10814 PowerPCCPU *cpu = POWERPC_CPU(cs);
10815 CPUPPCState *env = &cpu->env;
10817 if ((env->hflags >> MSR_LE) & 1) {
10818 info->endian = BFD_ENDIAN_LITTLE;
10820 info->mach = env->bfd_mach;
10821 if (!env->bfd_mach) {
10822 #ifdef TARGET_PPC64
10823 info->mach = bfd_mach_ppc64;
10825 info->mach = bfd_mach_ppc;
10828 info->disassembler_options = (char *)"any";
10829 info->print_insn = print_insn_ppc;
10831 info->cap_arch = CS_ARCH_PPC;
10832 #ifdef TARGET_PPC64
10833 info->cap_mode = CS_MODE_64;
10837 static Property ppc_cpu_properties[] = {
10838 DEFINE_PROP_BOOL("pre-2.8-migration", PowerPCCPU, pre_2_8_migration, false),
10839 DEFINE_PROP_BOOL("pre-2.10-migration", PowerPCCPU, pre_2_10_migration,
10841 DEFINE_PROP_BOOL("pre-3.0-migration", PowerPCCPU, pre_3_0_migration,
10843 DEFINE_PROP_END_OF_LIST(),
10847 #include "hw/core/tcg-cpu-ops.h"
10849 static struct TCGCPUOps ppc_tcg_ops = {
10850 .initialize = ppc_translate_init,
10851 .cpu_exec_interrupt = ppc_cpu_exec_interrupt,
10852 .tlb_fill = ppc_cpu_tlb_fill,
10854 #ifndef CONFIG_USER_ONLY
10855 .do_interrupt = ppc_cpu_do_interrupt,
10856 .cpu_exec_enter = ppc_cpu_exec_enter,
10857 .cpu_exec_exit = ppc_cpu_exec_exit,
10858 .do_unaligned_access = ppc_cpu_do_unaligned_access,
10859 #endif /* !CONFIG_USER_ONLY */
10861 #endif /* CONFIG_TCG */
10863 static void ppc_cpu_class_init(ObjectClass *oc, void *data)
10865 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
10866 CPUClass *cc = CPU_CLASS(oc);
10867 DeviceClass *dc = DEVICE_CLASS(oc);
10869 device_class_set_parent_realize(dc, ppc_cpu_realize,
10870 &pcc->parent_realize);
10871 device_class_set_parent_unrealize(dc, ppc_cpu_unrealize,
10872 &pcc->parent_unrealize);
10873 pcc->pvr_match = ppc_pvr_match_default;
10874 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_always;
10875 device_class_set_props(dc, ppc_cpu_properties);
10877 device_class_set_parent_reset(dc, ppc_cpu_reset, &pcc->parent_reset);
10879 cc->class_by_name = ppc_cpu_class_by_name;
10880 cc->has_work = ppc_cpu_has_work;
10881 cc->dump_state = ppc_cpu_dump_state;
10882 cc->dump_statistics = ppc_cpu_dump_statistics;
10883 cc->set_pc = ppc_cpu_set_pc;
10884 cc->gdb_read_register = ppc_cpu_gdb_read_register;
10885 cc->gdb_write_register = ppc_cpu_gdb_write_register;
10886 #ifndef CONFIG_USER_ONLY
10887 cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
10888 cc->vmsd = &vmstate_ppc_cpu;
10890 #if defined(CONFIG_SOFTMMU)
10891 cc->write_elf64_note = ppc64_cpu_write_elf64_note;
10892 cc->write_elf32_note = ppc32_cpu_write_elf32_note;
10895 cc->gdb_num_core_regs = 71;
10896 #ifndef CONFIG_USER_ONLY
10897 cc->gdb_get_dynamic_xml = ppc_gdb_get_dynamic_xml;
10899 #ifdef USE_APPLE_GDB
10900 cc->gdb_read_register = ppc_cpu_gdb_read_register_apple;
10901 cc->gdb_write_register = ppc_cpu_gdb_write_register_apple;
10902 cc->gdb_num_core_regs = 71 + 32;
10905 cc->gdb_arch_name = ppc_gdb_arch_name;
10906 #if defined(TARGET_PPC64)
10907 cc->gdb_core_xml_file = "power64-core.xml";
10909 cc->gdb_core_xml_file = "power-core.xml";
10911 #ifndef CONFIG_USER_ONLY
10912 cc->virtio_is_big_endian = ppc_cpu_is_big_endian;
10914 cc->disas_set_info = ppc_disas_set_info;
10916 dc->fw_name = "PowerPC,UNKNOWN";
10919 cc->tcg_ops = &ppc_tcg_ops;
10920 #endif /* CONFIG_TCG */
10923 static const TypeInfo ppc_cpu_type_info = {
10924 .name = TYPE_POWERPC_CPU,
10925 .parent = TYPE_CPU,
10926 .instance_size = sizeof(PowerPCCPU),
10927 .instance_align = __alignof__(PowerPCCPU),
10928 .instance_init = ppc_cpu_instance_init,
10929 .instance_finalize = ppc_cpu_instance_finalize,
10931 .class_size = sizeof(PowerPCCPUClass),
10932 .class_init = ppc_cpu_class_init,
10935 #ifndef CONFIG_USER_ONLY
10936 static const TypeInfo ppc_vhyp_type_info = {
10937 .name = TYPE_PPC_VIRTUAL_HYPERVISOR,
10938 .parent = TYPE_INTERFACE,
10939 .class_size = sizeof(PPCVirtualHypervisorClass),
10943 static void ppc_cpu_register_types(void)
10945 type_register_static(&ppc_cpu_type_info);
10946 #ifndef CONFIG_USER_ONLY
10947 type_register_static(&ppc_vhyp_type_info);
10951 type_init(ppc_cpu_register_types)