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 "qemu/cutils.h"
41 #include "disas/capstone.h"
42 #include "fpu/softfloat.h"
43 #include "qapi/qapi-commands-machine-target.h"
45 /* #define PPC_DUMP_CPU */
46 /* #define PPC_DEBUG_SPR */
47 /* #define PPC_DUMP_SPR_ACCESSES */
48 /* #define USE_APPLE_GDB */
52 * do nothing but store/retrieve spr value
54 static void spr_load_dump_spr(int sprn)
56 #ifdef PPC_DUMP_SPR_ACCESSES
57 TCGv_i32 t0 = tcg_const_i32(sprn);
58 gen_helper_load_dump_spr(cpu_env, t0);
59 tcg_temp_free_i32(t0);
63 static void spr_read_generic(DisasContext *ctx, int gprn, int sprn)
65 gen_load_spr(cpu_gpr[gprn], sprn);
66 spr_load_dump_spr(sprn);
69 static void spr_store_dump_spr(int sprn)
71 #ifdef PPC_DUMP_SPR_ACCESSES
72 TCGv_i32 t0 = tcg_const_i32(sprn);
73 gen_helper_store_dump_spr(cpu_env, t0);
74 tcg_temp_free_i32(t0);
78 static void spr_write_generic(DisasContext *ctx, int sprn, int gprn)
80 gen_store_spr(sprn, cpu_gpr[gprn]);
81 spr_store_dump_spr(sprn);
84 #if !defined(CONFIG_USER_ONLY)
85 static void spr_write_generic32(DisasContext *ctx, int sprn, int gprn)
88 TCGv t0 = tcg_temp_new();
89 tcg_gen_ext32u_tl(t0, cpu_gpr[gprn]);
90 gen_store_spr(sprn, t0);
92 spr_store_dump_spr(sprn);
94 spr_write_generic(ctx, sprn, gprn);
98 static void spr_write_clear(DisasContext *ctx, int sprn, int gprn)
100 TCGv t0 = tcg_temp_new();
101 TCGv t1 = tcg_temp_new();
102 gen_load_spr(t0, sprn);
103 tcg_gen_neg_tl(t1, cpu_gpr[gprn]);
104 tcg_gen_and_tl(t0, t0, t1);
105 gen_store_spr(sprn, t0);
110 static void spr_access_nop(DisasContext *ctx, int sprn, int gprn)
116 /* SPR common to all PowerPC */
118 static void spr_read_xer(DisasContext *ctx, int gprn, int sprn)
120 gen_read_xer(ctx, cpu_gpr[gprn]);
123 static void spr_write_xer(DisasContext *ctx, int sprn, int gprn)
125 gen_write_xer(cpu_gpr[gprn]);
129 static void spr_read_lr(DisasContext *ctx, int gprn, int sprn)
131 tcg_gen_mov_tl(cpu_gpr[gprn], cpu_lr);
134 static void spr_write_lr(DisasContext *ctx, int sprn, int gprn)
136 tcg_gen_mov_tl(cpu_lr, cpu_gpr[gprn]);
140 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
141 static void spr_read_cfar(DisasContext *ctx, int gprn, int sprn)
143 tcg_gen_mov_tl(cpu_gpr[gprn], cpu_cfar);
146 static void spr_write_cfar(DisasContext *ctx, int sprn, int gprn)
148 tcg_gen_mov_tl(cpu_cfar, cpu_gpr[gprn]);
150 #endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
153 static void spr_read_ctr(DisasContext *ctx, int gprn, int sprn)
155 tcg_gen_mov_tl(cpu_gpr[gprn], cpu_ctr);
158 static void spr_write_ctr(DisasContext *ctx, int sprn, int gprn)
160 tcg_gen_mov_tl(cpu_ctr, cpu_gpr[gprn]);
163 /* User read access to SPR */
169 static void spr_read_ureg(DisasContext *ctx, int gprn, int sprn)
171 gen_load_spr(cpu_gpr[gprn], sprn + 0x10);
174 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
175 static void spr_write_ureg(DisasContext *ctx, int sprn, int gprn)
177 gen_store_spr(sprn + 0x10, cpu_gpr[gprn]);
181 /* SPR common to all non-embedded PowerPC */
183 #if !defined(CONFIG_USER_ONLY)
184 static void spr_read_decr(DisasContext *ctx, int gprn, int sprn)
186 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
189 gen_helper_load_decr(cpu_gpr[gprn], cpu_env);
190 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
191 gen_stop_exception(ctx);
195 static void spr_write_decr(DisasContext *ctx, int sprn, int gprn)
197 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
200 gen_helper_store_decr(cpu_env, cpu_gpr[gprn]);
201 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
202 gen_stop_exception(ctx);
207 /* SPR common to all non-embedded PowerPC, except 601 */
209 static void spr_read_tbl(DisasContext *ctx, int gprn, int sprn)
211 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
214 gen_helper_load_tbl(cpu_gpr[gprn], cpu_env);
215 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
217 gen_stop_exception(ctx);
221 static void spr_read_tbu(DisasContext *ctx, int gprn, int sprn)
223 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
226 gen_helper_load_tbu(cpu_gpr[gprn], cpu_env);
227 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
229 gen_stop_exception(ctx);
234 static void spr_read_atbl(DisasContext *ctx, int gprn, int sprn)
236 gen_helper_load_atbl(cpu_gpr[gprn], cpu_env);
240 static void spr_read_atbu(DisasContext *ctx, int gprn, int sprn)
242 gen_helper_load_atbu(cpu_gpr[gprn], cpu_env);
245 #if !defined(CONFIG_USER_ONLY)
246 static void spr_write_tbl(DisasContext *ctx, int sprn, int gprn)
248 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
251 gen_helper_store_tbl(cpu_env, cpu_gpr[gprn]);
252 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
254 gen_stop_exception(ctx);
258 static void spr_write_tbu(DisasContext *ctx, int sprn, int gprn)
260 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
263 gen_helper_store_tbu(cpu_env, cpu_gpr[gprn]);
264 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
266 gen_stop_exception(ctx);
271 static void spr_write_atbl(DisasContext *ctx, int sprn, int gprn)
273 gen_helper_store_atbl(cpu_env, cpu_gpr[gprn]);
277 static void spr_write_atbu(DisasContext *ctx, int sprn, int gprn)
279 gen_helper_store_atbu(cpu_env, cpu_gpr[gprn]);
282 #if defined(TARGET_PPC64)
284 static void spr_read_purr(DisasContext *ctx, int gprn, int sprn)
286 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
289 gen_helper_load_purr(cpu_gpr[gprn], cpu_env);
290 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
291 gen_stop_exception(ctx);
295 static void spr_write_purr(DisasContext *ctx, int sprn, int gprn)
297 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
300 gen_helper_store_purr(cpu_env, cpu_gpr[gprn]);
301 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
302 gen_stop_exception(ctx);
307 static void spr_read_hdecr(DisasContext *ctx, int gprn, int sprn)
309 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
312 gen_helper_load_hdecr(cpu_gpr[gprn], cpu_env);
313 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
315 gen_stop_exception(ctx);
319 static void spr_write_hdecr(DisasContext *ctx, int sprn, int gprn)
321 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
324 gen_helper_store_hdecr(cpu_env, cpu_gpr[gprn]);
325 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
327 gen_stop_exception(ctx);
331 static void spr_read_vtb(DisasContext *ctx, int gprn, int sprn)
333 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
336 gen_helper_load_vtb(cpu_gpr[gprn], cpu_env);
337 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
338 gen_stop_exception(ctx);
342 static void spr_write_vtb(DisasContext *ctx, int sprn, int gprn)
344 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
347 gen_helper_store_vtb(cpu_env, cpu_gpr[gprn]);
348 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
349 gen_stop_exception(ctx);
353 static void spr_write_tbu40(DisasContext *ctx, int sprn, int gprn)
355 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
358 gen_helper_store_tbu40(cpu_env, cpu_gpr[gprn]);
359 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
360 gen_stop_exception(ctx);
367 #if !defined(CONFIG_USER_ONLY)
368 /* IBAT0U...IBAT0U */
369 /* IBAT0L...IBAT7L */
370 static void spr_read_ibat(DisasContext *ctx, int gprn, int sprn)
372 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env,
373 offsetof(CPUPPCState,
374 IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2]));
377 static void spr_read_ibat_h(DisasContext *ctx, int gprn, int sprn)
379 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env,
380 offsetof(CPUPPCState,
381 IBAT[sprn & 1][((sprn - SPR_IBAT4U) / 2) + 4]));
384 static void spr_write_ibatu(DisasContext *ctx, int sprn, int gprn)
386 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2);
387 gen_helper_store_ibatu(cpu_env, t0, cpu_gpr[gprn]);
388 tcg_temp_free_i32(t0);
391 static void spr_write_ibatu_h(DisasContext *ctx, int sprn, int gprn)
393 TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_IBAT4U) / 2) + 4);
394 gen_helper_store_ibatu(cpu_env, t0, cpu_gpr[gprn]);
395 tcg_temp_free_i32(t0);
398 static void spr_write_ibatl(DisasContext *ctx, int sprn, int gprn)
400 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0L) / 2);
401 gen_helper_store_ibatl(cpu_env, t0, cpu_gpr[gprn]);
402 tcg_temp_free_i32(t0);
405 static void spr_write_ibatl_h(DisasContext *ctx, int sprn, int gprn)
407 TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_IBAT4L) / 2) + 4);
408 gen_helper_store_ibatl(cpu_env, t0, cpu_gpr[gprn]);
409 tcg_temp_free_i32(t0);
412 /* DBAT0U...DBAT7U */
413 /* DBAT0L...DBAT7L */
414 static void spr_read_dbat(DisasContext *ctx, int gprn, int sprn)
416 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env,
417 offsetof(CPUPPCState,
418 DBAT[sprn & 1][(sprn - SPR_DBAT0U) / 2]));
421 static void spr_read_dbat_h(DisasContext *ctx, int gprn, int sprn)
423 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env,
424 offsetof(CPUPPCState,
425 DBAT[sprn & 1][((sprn - SPR_DBAT4U) / 2) + 4]));
428 static void spr_write_dbatu(DisasContext *ctx, int sprn, int gprn)
430 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_DBAT0U) / 2);
431 gen_helper_store_dbatu(cpu_env, t0, cpu_gpr[gprn]);
432 tcg_temp_free_i32(t0);
435 static void spr_write_dbatu_h(DisasContext *ctx, int sprn, int gprn)
437 TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_DBAT4U) / 2) + 4);
438 gen_helper_store_dbatu(cpu_env, t0, cpu_gpr[gprn]);
439 tcg_temp_free_i32(t0);
442 static void spr_write_dbatl(DisasContext *ctx, int sprn, int gprn)
444 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_DBAT0L) / 2);
445 gen_helper_store_dbatl(cpu_env, t0, cpu_gpr[gprn]);
446 tcg_temp_free_i32(t0);
449 static void spr_write_dbatl_h(DisasContext *ctx, int sprn, int gprn)
451 TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_DBAT4L) / 2) + 4);
452 gen_helper_store_dbatl(cpu_env, t0, cpu_gpr[gprn]);
453 tcg_temp_free_i32(t0);
457 static void spr_write_sdr1(DisasContext *ctx, int sprn, int gprn)
459 gen_helper_store_sdr1(cpu_env, cpu_gpr[gprn]);
462 #if defined(TARGET_PPC64)
463 /* 64 bits PowerPC specific SPRs */
465 static void spr_write_pidr(DisasContext *ctx, int sprn, int gprn)
467 gen_helper_store_pidr(cpu_env, cpu_gpr[gprn]);
470 static void spr_write_lpidr(DisasContext *ctx, int sprn, int gprn)
472 gen_helper_store_lpidr(cpu_env, cpu_gpr[gprn]);
475 static void spr_read_hior(DisasContext *ctx, int gprn, int sprn)
477 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, excp_prefix));
480 static void spr_write_hior(DisasContext *ctx, int sprn, int gprn)
482 TCGv t0 = tcg_temp_new();
483 tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0x3FFFFF00000ULL);
484 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, excp_prefix));
487 static void spr_write_ptcr(DisasContext *ctx, int sprn, int gprn)
489 gen_helper_store_ptcr(cpu_env, cpu_gpr[gprn]);
492 static void spr_write_pcr(DisasContext *ctx, int sprn, int gprn)
494 gen_helper_store_pcr(cpu_env, cpu_gpr[gprn]);
498 static void spr_read_dpdes(DisasContext *ctx, int gprn, int sprn)
500 gen_helper_load_dpdes(cpu_gpr[gprn], cpu_env);
503 static void spr_write_dpdes(DisasContext *ctx, int sprn, int gprn)
505 gen_helper_store_dpdes(cpu_env, cpu_gpr[gprn]);
510 /* PowerPC 601 specific registers */
512 static void spr_read_601_rtcl(DisasContext *ctx, int gprn, int sprn)
514 gen_helper_load_601_rtcl(cpu_gpr[gprn], cpu_env);
517 static void spr_read_601_rtcu(DisasContext *ctx, int gprn, int sprn)
519 gen_helper_load_601_rtcu(cpu_gpr[gprn], cpu_env);
522 #if !defined(CONFIG_USER_ONLY)
523 static void spr_write_601_rtcu(DisasContext *ctx, int sprn, int gprn)
525 gen_helper_store_601_rtcu(cpu_env, cpu_gpr[gprn]);
528 static void spr_write_601_rtcl(DisasContext *ctx, int sprn, int gprn)
530 gen_helper_store_601_rtcl(cpu_env, cpu_gpr[gprn]);
533 static void spr_write_hid0_601(DisasContext *ctx, int sprn, int gprn)
535 gen_helper_store_hid0_601(cpu_env, cpu_gpr[gprn]);
536 /* Must stop the translation as endianness may have changed */
537 gen_stop_exception(ctx);
542 #if !defined(CONFIG_USER_ONLY)
543 static void spr_read_601_ubat(DisasContext *ctx, int gprn, int sprn)
545 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env,
546 offsetof(CPUPPCState,
547 IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2]));
550 static void spr_write_601_ubatu(DisasContext *ctx, int sprn, int gprn)
552 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2);
553 gen_helper_store_601_batl(cpu_env, t0, cpu_gpr[gprn]);
554 tcg_temp_free_i32(t0);
557 static void spr_write_601_ubatl(DisasContext *ctx, int sprn, int gprn)
559 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2);
560 gen_helper_store_601_batu(cpu_env, t0, cpu_gpr[gprn]);
561 tcg_temp_free_i32(t0);
565 /* PowerPC 40x specific registers */
566 #if !defined(CONFIG_USER_ONLY)
567 static void spr_read_40x_pit(DisasContext *ctx, int gprn, int sprn)
569 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
572 gen_helper_load_40x_pit(cpu_gpr[gprn], cpu_env);
573 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
574 gen_stop_exception(ctx);
578 static void spr_write_40x_pit(DisasContext *ctx, int sprn, int gprn)
580 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
583 gen_helper_store_40x_pit(cpu_env, cpu_gpr[gprn]);
584 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
585 gen_stop_exception(ctx);
589 static void spr_write_40x_dbcr0(DisasContext *ctx, int sprn, int gprn)
591 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
594 gen_store_spr(sprn, cpu_gpr[gprn]);
595 gen_helper_store_40x_dbcr0(cpu_env, cpu_gpr[gprn]);
596 /* We must stop translation as we may have rebooted */
597 gen_stop_exception(ctx);
598 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
599 gen_stop_exception(ctx);
603 static void spr_write_40x_sler(DisasContext *ctx, int sprn, int gprn)
605 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
608 gen_helper_store_40x_sler(cpu_env, cpu_gpr[gprn]);
609 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
610 gen_stop_exception(ctx);
614 static void spr_write_booke_tcr(DisasContext *ctx, int sprn, int gprn)
616 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
619 gen_helper_store_booke_tcr(cpu_env, cpu_gpr[gprn]);
620 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
621 gen_stop_exception(ctx);
625 static void spr_write_booke_tsr(DisasContext *ctx, int sprn, int gprn)
627 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
630 gen_helper_store_booke_tsr(cpu_env, cpu_gpr[gprn]);
631 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
632 gen_stop_exception(ctx);
637 /* PowerPC 403 specific registers */
638 /* PBL1 / PBU1 / PBL2 / PBU2 */
639 #if !defined(CONFIG_USER_ONLY)
640 static void spr_read_403_pbr(DisasContext *ctx, int gprn, int sprn)
642 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env,
643 offsetof(CPUPPCState, pb[sprn - SPR_403_PBL1]));
646 static void spr_write_403_pbr(DisasContext *ctx, int sprn, int gprn)
648 TCGv_i32 t0 = tcg_const_i32(sprn - SPR_403_PBL1);
649 gen_helper_store_403_pbr(cpu_env, t0, cpu_gpr[gprn]);
650 tcg_temp_free_i32(t0);
653 static void spr_write_pir(DisasContext *ctx, int sprn, int gprn)
655 TCGv t0 = tcg_temp_new();
656 tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0xF);
657 gen_store_spr(SPR_PIR, t0);
662 /* SPE specific registers */
663 static void spr_read_spefscr(DisasContext *ctx, int gprn, int sprn)
665 TCGv_i32 t0 = tcg_temp_new_i32();
666 tcg_gen_ld_i32(t0, cpu_env, offsetof(CPUPPCState, spe_fscr));
667 tcg_gen_extu_i32_tl(cpu_gpr[gprn], t0);
668 tcg_temp_free_i32(t0);
671 static void spr_write_spefscr(DisasContext *ctx, int sprn, int gprn)
673 TCGv_i32 t0 = tcg_temp_new_i32();
674 tcg_gen_trunc_tl_i32(t0, cpu_gpr[gprn]);
675 tcg_gen_st_i32(t0, cpu_env, offsetof(CPUPPCState, spe_fscr));
676 tcg_temp_free_i32(t0);
679 #if !defined(CONFIG_USER_ONLY)
680 /* Callback used to write the exception vector base */
681 static void spr_write_excp_prefix(DisasContext *ctx, int sprn, int gprn)
683 TCGv t0 = tcg_temp_new();
684 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUPPCState, ivpr_mask));
685 tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]);
686 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, excp_prefix));
687 gen_store_spr(sprn, t0);
691 static void spr_write_excp_vector(DisasContext *ctx, int sprn, int gprn)
695 if (sprn >= SPR_BOOKE_IVOR0 && sprn <= SPR_BOOKE_IVOR15) {
696 sprn_offs = sprn - SPR_BOOKE_IVOR0;
697 } else if (sprn >= SPR_BOOKE_IVOR32 && sprn <= SPR_BOOKE_IVOR37) {
698 sprn_offs = sprn - SPR_BOOKE_IVOR32 + 32;
699 } else if (sprn >= SPR_BOOKE_IVOR38 && sprn <= SPR_BOOKE_IVOR42) {
700 sprn_offs = sprn - SPR_BOOKE_IVOR38 + 38;
702 printf("Trying to write an unknown exception vector %d %03x\n",
704 gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
708 TCGv t0 = tcg_temp_new();
709 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUPPCState, ivor_mask));
710 tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]);
711 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, excp_vectors[sprn_offs]));
712 gen_store_spr(sprn, t0);
717 static inline void vscr_init(CPUPPCState *env, uint32_t val)
719 /* Altivec always uses round-to-nearest */
720 set_float_rounding_mode(float_round_nearest_even, &env->vec_status);
721 helper_mtvscr(env, val);
724 #ifdef CONFIG_USER_ONLY
725 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
726 oea_read, oea_write, one_reg_id, initial_value) \
727 _spr_register(env, num, name, uea_read, uea_write, initial_value)
728 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
729 oea_read, oea_write, hea_read, hea_write, \
730 one_reg_id, initial_value) \
731 _spr_register(env, num, name, uea_read, uea_write, initial_value)
733 #if !defined(CONFIG_KVM)
734 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
735 oea_read, oea_write, one_reg_id, initial_value) \
736 _spr_register(env, num, name, uea_read, uea_write, \
737 oea_read, oea_write, oea_read, oea_write, initial_value)
738 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
739 oea_read, oea_write, hea_read, hea_write, \
740 one_reg_id, initial_value) \
741 _spr_register(env, num, name, uea_read, uea_write, \
742 oea_read, oea_write, hea_read, hea_write, initial_value)
744 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
745 oea_read, oea_write, one_reg_id, initial_value) \
746 _spr_register(env, num, name, uea_read, uea_write, \
747 oea_read, oea_write, oea_read, oea_write, \
748 one_reg_id, initial_value)
749 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
750 oea_read, oea_write, hea_read, hea_write, \
751 one_reg_id, initial_value) \
752 _spr_register(env, num, name, uea_read, uea_write, \
753 oea_read, oea_write, hea_read, hea_write, \
754 one_reg_id, initial_value)
758 #define spr_register(env, num, name, uea_read, uea_write, \
759 oea_read, oea_write, initial_value) \
760 spr_register_kvm(env, num, name, uea_read, uea_write, \
761 oea_read, oea_write, 0, initial_value)
763 #define spr_register_hv(env, num, name, uea_read, uea_write, \
764 oea_read, oea_write, hea_read, hea_write, \
766 spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
767 oea_read, oea_write, hea_read, hea_write, \
770 static inline void _spr_register(CPUPPCState *env, int num,
772 void (*uea_read)(DisasContext *ctx,
774 void (*uea_write)(DisasContext *ctx,
776 #if !defined(CONFIG_USER_ONLY)
778 void (*oea_read)(DisasContext *ctx,
780 void (*oea_write)(DisasContext *ctx,
782 void (*hea_read)(DisasContext *opaque,
784 void (*hea_write)(DisasContext *opaque,
787 #if defined(CONFIG_KVM)
790 target_ulong initial_value)
794 spr = &env->spr_cb[num];
795 if (spr->name != NULL || env->spr[num] != 0x00000000 ||
796 #if !defined(CONFIG_USER_ONLY)
797 spr->oea_read != NULL || spr->oea_write != NULL ||
799 spr->uea_read != NULL || spr->uea_write != NULL) {
800 printf("Error: Trying to register SPR %d (%03x) twice !\n", num, num);
803 #if defined(PPC_DEBUG_SPR)
804 printf("*** register spr %d (%03x) %s val " TARGET_FMT_lx "\n", num, num,
805 name, initial_value);
808 spr->uea_read = uea_read;
809 spr->uea_write = uea_write;
810 #if !defined(CONFIG_USER_ONLY)
811 spr->oea_read = oea_read;
812 spr->oea_write = oea_write;
813 spr->hea_read = hea_read;
814 spr->hea_write = hea_write;
816 #if defined(CONFIG_KVM)
817 spr->one_reg_id = one_reg_id,
819 env->spr[num] = spr->default_value = initial_value;
822 /* Generic PowerPC SPRs */
823 static void gen_spr_generic(CPUPPCState *env)
825 /* Integer processing */
826 spr_register(env, SPR_XER, "XER",
827 &spr_read_xer, &spr_write_xer,
828 &spr_read_xer, &spr_write_xer,
831 spr_register(env, SPR_LR, "LR",
832 &spr_read_lr, &spr_write_lr,
833 &spr_read_lr, &spr_write_lr,
835 spr_register(env, SPR_CTR, "CTR",
836 &spr_read_ctr, &spr_write_ctr,
837 &spr_read_ctr, &spr_write_ctr,
839 /* Interrupt processing */
840 spr_register(env, SPR_SRR0, "SRR0",
841 SPR_NOACCESS, SPR_NOACCESS,
842 &spr_read_generic, &spr_write_generic,
844 spr_register(env, SPR_SRR1, "SRR1",
845 SPR_NOACCESS, SPR_NOACCESS,
846 &spr_read_generic, &spr_write_generic,
848 /* Processor control */
849 spr_register(env, SPR_SPRG0, "SPRG0",
850 SPR_NOACCESS, SPR_NOACCESS,
851 &spr_read_generic, &spr_write_generic,
853 spr_register(env, SPR_SPRG1, "SPRG1",
854 SPR_NOACCESS, SPR_NOACCESS,
855 &spr_read_generic, &spr_write_generic,
857 spr_register(env, SPR_SPRG2, "SPRG2",
858 SPR_NOACCESS, SPR_NOACCESS,
859 &spr_read_generic, &spr_write_generic,
861 spr_register(env, SPR_SPRG3, "SPRG3",
862 SPR_NOACCESS, SPR_NOACCESS,
863 &spr_read_generic, &spr_write_generic,
867 /* SPR common to all non-embedded PowerPC, including 601 */
868 static void gen_spr_ne_601(CPUPPCState *env)
870 /* Exception processing */
871 spr_register_kvm(env, SPR_DSISR, "DSISR",
872 SPR_NOACCESS, SPR_NOACCESS,
873 &spr_read_generic, &spr_write_generic,
874 KVM_REG_PPC_DSISR, 0x00000000);
875 spr_register_kvm(env, SPR_DAR, "DAR",
876 SPR_NOACCESS, SPR_NOACCESS,
877 &spr_read_generic, &spr_write_generic,
878 KVM_REG_PPC_DAR, 0x00000000);
880 spr_register(env, SPR_DECR, "DECR",
881 SPR_NOACCESS, SPR_NOACCESS,
882 &spr_read_decr, &spr_write_decr,
886 /* Storage Description Register 1 */
887 static void gen_spr_sdr1(CPUPPCState *env)
889 #ifndef CONFIG_USER_ONLY
890 if (env->has_hv_mode) {
892 * SDR1 is a hypervisor resource on CPUs which have a
895 spr_register_hv(env, SPR_SDR1, "SDR1",
896 SPR_NOACCESS, SPR_NOACCESS,
897 SPR_NOACCESS, SPR_NOACCESS,
898 &spr_read_generic, &spr_write_sdr1,
901 spr_register(env, SPR_SDR1, "SDR1",
902 SPR_NOACCESS, SPR_NOACCESS,
903 &spr_read_generic, &spr_write_sdr1,
910 static void gen_low_BATs(CPUPPCState *env)
912 #if !defined(CONFIG_USER_ONLY)
913 spr_register(env, SPR_IBAT0U, "IBAT0U",
914 SPR_NOACCESS, SPR_NOACCESS,
915 &spr_read_ibat, &spr_write_ibatu,
917 spr_register(env, SPR_IBAT0L, "IBAT0L",
918 SPR_NOACCESS, SPR_NOACCESS,
919 &spr_read_ibat, &spr_write_ibatl,
921 spr_register(env, SPR_IBAT1U, "IBAT1U",
922 SPR_NOACCESS, SPR_NOACCESS,
923 &spr_read_ibat, &spr_write_ibatu,
925 spr_register(env, SPR_IBAT1L, "IBAT1L",
926 SPR_NOACCESS, SPR_NOACCESS,
927 &spr_read_ibat, &spr_write_ibatl,
929 spr_register(env, SPR_IBAT2U, "IBAT2U",
930 SPR_NOACCESS, SPR_NOACCESS,
931 &spr_read_ibat, &spr_write_ibatu,
933 spr_register(env, SPR_IBAT2L, "IBAT2L",
934 SPR_NOACCESS, SPR_NOACCESS,
935 &spr_read_ibat, &spr_write_ibatl,
937 spr_register(env, SPR_IBAT3U, "IBAT3U",
938 SPR_NOACCESS, SPR_NOACCESS,
939 &spr_read_ibat, &spr_write_ibatu,
941 spr_register(env, SPR_IBAT3L, "IBAT3L",
942 SPR_NOACCESS, SPR_NOACCESS,
943 &spr_read_ibat, &spr_write_ibatl,
945 spr_register(env, SPR_DBAT0U, "DBAT0U",
946 SPR_NOACCESS, SPR_NOACCESS,
947 &spr_read_dbat, &spr_write_dbatu,
949 spr_register(env, SPR_DBAT0L, "DBAT0L",
950 SPR_NOACCESS, SPR_NOACCESS,
951 &spr_read_dbat, &spr_write_dbatl,
953 spr_register(env, SPR_DBAT1U, "DBAT1U",
954 SPR_NOACCESS, SPR_NOACCESS,
955 &spr_read_dbat, &spr_write_dbatu,
957 spr_register(env, SPR_DBAT1L, "DBAT1L",
958 SPR_NOACCESS, SPR_NOACCESS,
959 &spr_read_dbat, &spr_write_dbatl,
961 spr_register(env, SPR_DBAT2U, "DBAT2U",
962 SPR_NOACCESS, SPR_NOACCESS,
963 &spr_read_dbat, &spr_write_dbatu,
965 spr_register(env, SPR_DBAT2L, "DBAT2L",
966 SPR_NOACCESS, SPR_NOACCESS,
967 &spr_read_dbat, &spr_write_dbatl,
969 spr_register(env, SPR_DBAT3U, "DBAT3U",
970 SPR_NOACCESS, SPR_NOACCESS,
971 &spr_read_dbat, &spr_write_dbatu,
973 spr_register(env, SPR_DBAT3L, "DBAT3L",
974 SPR_NOACCESS, SPR_NOACCESS,
975 &spr_read_dbat, &spr_write_dbatl,
982 static void gen_high_BATs(CPUPPCState *env)
984 #if !defined(CONFIG_USER_ONLY)
985 spr_register(env, SPR_IBAT4U, "IBAT4U",
986 SPR_NOACCESS, SPR_NOACCESS,
987 &spr_read_ibat_h, &spr_write_ibatu_h,
989 spr_register(env, SPR_IBAT4L, "IBAT4L",
990 SPR_NOACCESS, SPR_NOACCESS,
991 &spr_read_ibat_h, &spr_write_ibatl_h,
993 spr_register(env, SPR_IBAT5U, "IBAT5U",
994 SPR_NOACCESS, SPR_NOACCESS,
995 &spr_read_ibat_h, &spr_write_ibatu_h,
997 spr_register(env, SPR_IBAT5L, "IBAT5L",
998 SPR_NOACCESS, SPR_NOACCESS,
999 &spr_read_ibat_h, &spr_write_ibatl_h,
1001 spr_register(env, SPR_IBAT6U, "IBAT6U",
1002 SPR_NOACCESS, SPR_NOACCESS,
1003 &spr_read_ibat_h, &spr_write_ibatu_h,
1005 spr_register(env, SPR_IBAT6L, "IBAT6L",
1006 SPR_NOACCESS, SPR_NOACCESS,
1007 &spr_read_ibat_h, &spr_write_ibatl_h,
1009 spr_register(env, SPR_IBAT7U, "IBAT7U",
1010 SPR_NOACCESS, SPR_NOACCESS,
1011 &spr_read_ibat_h, &spr_write_ibatu_h,
1013 spr_register(env, SPR_IBAT7L, "IBAT7L",
1014 SPR_NOACCESS, SPR_NOACCESS,
1015 &spr_read_ibat_h, &spr_write_ibatl_h,
1017 spr_register(env, SPR_DBAT4U, "DBAT4U",
1018 SPR_NOACCESS, SPR_NOACCESS,
1019 &spr_read_dbat_h, &spr_write_dbatu_h,
1021 spr_register(env, SPR_DBAT4L, "DBAT4L",
1022 SPR_NOACCESS, SPR_NOACCESS,
1023 &spr_read_dbat_h, &spr_write_dbatl_h,
1025 spr_register(env, SPR_DBAT5U, "DBAT5U",
1026 SPR_NOACCESS, SPR_NOACCESS,
1027 &spr_read_dbat_h, &spr_write_dbatu_h,
1029 spr_register(env, SPR_DBAT5L, "DBAT5L",
1030 SPR_NOACCESS, SPR_NOACCESS,
1031 &spr_read_dbat_h, &spr_write_dbatl_h,
1033 spr_register(env, SPR_DBAT6U, "DBAT6U",
1034 SPR_NOACCESS, SPR_NOACCESS,
1035 &spr_read_dbat_h, &spr_write_dbatu_h,
1037 spr_register(env, SPR_DBAT6L, "DBAT6L",
1038 SPR_NOACCESS, SPR_NOACCESS,
1039 &spr_read_dbat_h, &spr_write_dbatl_h,
1041 spr_register(env, SPR_DBAT7U, "DBAT7U",
1042 SPR_NOACCESS, SPR_NOACCESS,
1043 &spr_read_dbat_h, &spr_write_dbatu_h,
1045 spr_register(env, SPR_DBAT7L, "DBAT7L",
1046 SPR_NOACCESS, SPR_NOACCESS,
1047 &spr_read_dbat_h, &spr_write_dbatl_h,
1053 /* Generic PowerPC time base */
1054 static void gen_tbl(CPUPPCState *env)
1056 spr_register(env, SPR_VTBL, "TBL",
1057 &spr_read_tbl, SPR_NOACCESS,
1058 &spr_read_tbl, SPR_NOACCESS,
1060 spr_register(env, SPR_TBL, "TBL",
1061 &spr_read_tbl, SPR_NOACCESS,
1062 &spr_read_tbl, &spr_write_tbl,
1064 spr_register(env, SPR_VTBU, "TBU",
1065 &spr_read_tbu, SPR_NOACCESS,
1066 &spr_read_tbu, SPR_NOACCESS,
1068 spr_register(env, SPR_TBU, "TBU",
1069 &spr_read_tbu, SPR_NOACCESS,
1070 &spr_read_tbu, &spr_write_tbu,
1074 /* Softare table search registers */
1075 static void gen_6xx_7xx_soft_tlb(CPUPPCState *env, int nb_tlbs, int nb_ways)
1077 #if !defined(CONFIG_USER_ONLY)
1078 env->nb_tlb = nb_tlbs;
1079 env->nb_ways = nb_ways;
1081 env->tlb_type = TLB_6XX;
1082 spr_register(env, SPR_DMISS, "DMISS",
1083 SPR_NOACCESS, SPR_NOACCESS,
1084 &spr_read_generic, SPR_NOACCESS,
1086 spr_register(env, SPR_DCMP, "DCMP",
1087 SPR_NOACCESS, SPR_NOACCESS,
1088 &spr_read_generic, SPR_NOACCESS,
1090 spr_register(env, SPR_HASH1, "HASH1",
1091 SPR_NOACCESS, SPR_NOACCESS,
1092 &spr_read_generic, SPR_NOACCESS,
1094 spr_register(env, SPR_HASH2, "HASH2",
1095 SPR_NOACCESS, SPR_NOACCESS,
1096 &spr_read_generic, SPR_NOACCESS,
1098 spr_register(env, SPR_IMISS, "IMISS",
1099 SPR_NOACCESS, SPR_NOACCESS,
1100 &spr_read_generic, SPR_NOACCESS,
1102 spr_register(env, SPR_ICMP, "ICMP",
1103 SPR_NOACCESS, SPR_NOACCESS,
1104 &spr_read_generic, SPR_NOACCESS,
1106 spr_register(env, SPR_RPA, "RPA",
1107 SPR_NOACCESS, SPR_NOACCESS,
1108 &spr_read_generic, &spr_write_generic,
1113 /* SPR common to MPC755 and G2 */
1114 static void gen_spr_G2_755(CPUPPCState *env)
1117 spr_register(env, SPR_SPRG4, "SPRG4",
1118 SPR_NOACCESS, SPR_NOACCESS,
1119 &spr_read_generic, &spr_write_generic,
1121 spr_register(env, SPR_SPRG5, "SPRG5",
1122 SPR_NOACCESS, SPR_NOACCESS,
1123 &spr_read_generic, &spr_write_generic,
1125 spr_register(env, SPR_SPRG6, "SPRG6",
1126 SPR_NOACCESS, SPR_NOACCESS,
1127 &spr_read_generic, &spr_write_generic,
1129 spr_register(env, SPR_SPRG7, "SPRG7",
1130 SPR_NOACCESS, SPR_NOACCESS,
1131 &spr_read_generic, &spr_write_generic,
1135 /* SPR common to all 7xx PowerPC implementations */
1136 static void gen_spr_7xx(CPUPPCState *env)
1139 /* XXX : not implemented */
1140 spr_register_kvm(env, SPR_DABR, "DABR",
1141 SPR_NOACCESS, SPR_NOACCESS,
1142 &spr_read_generic, &spr_write_generic,
1143 KVM_REG_PPC_DABR, 0x00000000);
1144 /* XXX : not implemented */
1145 spr_register(env, SPR_IABR, "IABR",
1146 SPR_NOACCESS, SPR_NOACCESS,
1147 &spr_read_generic, &spr_write_generic,
1149 /* Cache management */
1150 /* XXX : not implemented */
1151 spr_register(env, SPR_ICTC, "ICTC",
1152 SPR_NOACCESS, SPR_NOACCESS,
1153 &spr_read_generic, &spr_write_generic,
1155 /* Performance monitors */
1156 /* XXX : not implemented */
1157 spr_register(env, SPR_7XX_MMCR0, "MMCR0",
1158 SPR_NOACCESS, SPR_NOACCESS,
1159 &spr_read_generic, &spr_write_generic,
1161 /* XXX : not implemented */
1162 spr_register(env, SPR_7XX_MMCR1, "MMCR1",
1163 SPR_NOACCESS, SPR_NOACCESS,
1164 &spr_read_generic, &spr_write_generic,
1166 /* XXX : not implemented */
1167 spr_register(env, SPR_7XX_PMC1, "PMC1",
1168 SPR_NOACCESS, SPR_NOACCESS,
1169 &spr_read_generic, &spr_write_generic,
1171 /* XXX : not implemented */
1172 spr_register(env, SPR_7XX_PMC2, "PMC2",
1173 SPR_NOACCESS, SPR_NOACCESS,
1174 &spr_read_generic, &spr_write_generic,
1176 /* XXX : not implemented */
1177 spr_register(env, SPR_7XX_PMC3, "PMC3",
1178 SPR_NOACCESS, SPR_NOACCESS,
1179 &spr_read_generic, &spr_write_generic,
1181 /* XXX : not implemented */
1182 spr_register(env, SPR_7XX_PMC4, "PMC4",
1183 SPR_NOACCESS, SPR_NOACCESS,
1184 &spr_read_generic, &spr_write_generic,
1186 /* XXX : not implemented */
1187 spr_register(env, SPR_7XX_SIAR, "SIAR",
1188 SPR_NOACCESS, SPR_NOACCESS,
1189 &spr_read_generic, SPR_NOACCESS,
1191 /* XXX : not implemented */
1192 spr_register(env, SPR_7XX_UMMCR0, "UMMCR0",
1193 &spr_read_ureg, SPR_NOACCESS,
1194 &spr_read_ureg, SPR_NOACCESS,
1196 /* XXX : not implemented */
1197 spr_register(env, SPR_7XX_UMMCR1, "UMMCR1",
1198 &spr_read_ureg, SPR_NOACCESS,
1199 &spr_read_ureg, SPR_NOACCESS,
1201 /* XXX : not implemented */
1202 spr_register(env, SPR_7XX_UPMC1, "UPMC1",
1203 &spr_read_ureg, SPR_NOACCESS,
1204 &spr_read_ureg, SPR_NOACCESS,
1206 /* XXX : not implemented */
1207 spr_register(env, SPR_7XX_UPMC2, "UPMC2",
1208 &spr_read_ureg, SPR_NOACCESS,
1209 &spr_read_ureg, SPR_NOACCESS,
1211 /* XXX : not implemented */
1212 spr_register(env, SPR_7XX_UPMC3, "UPMC3",
1213 &spr_read_ureg, SPR_NOACCESS,
1214 &spr_read_ureg, SPR_NOACCESS,
1216 /* XXX : not implemented */
1217 spr_register(env, SPR_7XX_UPMC4, "UPMC4",
1218 &spr_read_ureg, SPR_NOACCESS,
1219 &spr_read_ureg, SPR_NOACCESS,
1221 /* XXX : not implemented */
1222 spr_register(env, SPR_7XX_USIAR, "USIAR",
1223 &spr_read_ureg, SPR_NOACCESS,
1224 &spr_read_ureg, SPR_NOACCESS,
1226 /* External access control */
1227 /* XXX : not implemented */
1228 spr_register(env, SPR_EAR, "EAR",
1229 SPR_NOACCESS, SPR_NOACCESS,
1230 &spr_read_generic, &spr_write_generic,
1235 #ifndef CONFIG_USER_ONLY
1236 static void spr_write_amr(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 PR=0 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 */
1249 gen_load_spr(t1, SPR_UAMOR);
1251 gen_load_spr(t1, SPR_AMOR);
1254 /* Mask new bits into t2 */
1255 tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]);
1257 /* Load AMR and clear new bits in t0 */
1258 gen_load_spr(t0, SPR_AMR);
1259 tcg_gen_andc_tl(t0, t0, t1);
1261 /* Or'in new bits and write it out */
1262 tcg_gen_or_tl(t0, t0, t2);
1263 gen_store_spr(SPR_AMR, t0);
1264 spr_store_dump_spr(SPR_AMR);
1271 static void spr_write_uamor(DisasContext *ctx, int sprn, int gprn)
1273 TCGv t0 = tcg_temp_new();
1274 TCGv t1 = tcg_temp_new();
1275 TCGv t2 = tcg_temp_new();
1278 * Note, the HV=1 case is handled earlier by simply using
1279 * spr_write_generic for HV mode in the SPR table
1282 /* Build insertion mask into t1 based on context */
1283 gen_load_spr(t1, SPR_AMOR);
1285 /* Mask new bits into t2 */
1286 tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]);
1288 /* Load AMR and clear new bits in t0 */
1289 gen_load_spr(t0, SPR_UAMOR);
1290 tcg_gen_andc_tl(t0, t0, t1);
1292 /* Or'in new bits and write it out */
1293 tcg_gen_or_tl(t0, t0, t2);
1294 gen_store_spr(SPR_UAMOR, t0);
1295 spr_store_dump_spr(SPR_UAMOR);
1302 static void spr_write_iamr(DisasContext *ctx, int sprn, int gprn)
1304 TCGv t0 = tcg_temp_new();
1305 TCGv t1 = tcg_temp_new();
1306 TCGv t2 = tcg_temp_new();
1309 * Note, the HV=1 case is handled earlier by simply using
1310 * spr_write_generic for HV mode in the SPR table
1313 /* Build insertion mask into t1 based on context */
1314 gen_load_spr(t1, SPR_AMOR);
1316 /* Mask new bits into t2 */
1317 tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]);
1319 /* Load AMR and clear new bits in t0 */
1320 gen_load_spr(t0, SPR_IAMR);
1321 tcg_gen_andc_tl(t0, t0, t1);
1323 /* Or'in new bits and write it out */
1324 tcg_gen_or_tl(t0, t0, t2);
1325 gen_store_spr(SPR_IAMR, t0);
1326 spr_store_dump_spr(SPR_IAMR);
1332 #endif /* CONFIG_USER_ONLY */
1334 static void gen_spr_amr(CPUPPCState *env)
1336 #ifndef CONFIG_USER_ONLY
1338 * Virtual Page Class Key protection
1340 * The AMR is accessible either via SPR 13 or SPR 29. 13 is
1341 * userspace accessible, 29 is privileged. So we only need to set
1342 * the kvm ONE_REG id on one of them, we use 29
1344 spr_register(env, SPR_UAMR, "UAMR",
1345 &spr_read_generic, &spr_write_amr,
1346 &spr_read_generic, &spr_write_amr,
1348 spr_register_kvm_hv(env, SPR_AMR, "AMR",
1349 SPR_NOACCESS, SPR_NOACCESS,
1350 &spr_read_generic, &spr_write_amr,
1351 &spr_read_generic, &spr_write_generic,
1352 KVM_REG_PPC_AMR, 0);
1353 spr_register_kvm_hv(env, SPR_UAMOR, "UAMOR",
1354 SPR_NOACCESS, SPR_NOACCESS,
1355 &spr_read_generic, &spr_write_uamor,
1356 &spr_read_generic, &spr_write_generic,
1357 KVM_REG_PPC_UAMOR, 0);
1358 spr_register_hv(env, SPR_AMOR, "AMOR",
1359 SPR_NOACCESS, SPR_NOACCESS,
1360 SPR_NOACCESS, SPR_NOACCESS,
1361 &spr_read_generic, &spr_write_generic,
1363 #endif /* !CONFIG_USER_ONLY */
1366 static void gen_spr_iamr(CPUPPCState *env)
1368 #ifndef CONFIG_USER_ONLY
1369 spr_register_kvm_hv(env, SPR_IAMR, "IAMR",
1370 SPR_NOACCESS, SPR_NOACCESS,
1371 &spr_read_generic, &spr_write_iamr,
1372 &spr_read_generic, &spr_write_generic,
1373 KVM_REG_PPC_IAMR, 0);
1374 #endif /* !CONFIG_USER_ONLY */
1376 #endif /* TARGET_PPC64 */
1378 #ifndef CONFIG_USER_ONLY
1379 static void spr_read_thrm(DisasContext *ctx, int gprn, int sprn)
1381 gen_helper_fixup_thrm(cpu_env);
1382 gen_load_spr(cpu_gpr[gprn], sprn);
1383 spr_load_dump_spr(sprn);
1385 #endif /* !CONFIG_USER_ONLY */
1387 static void gen_spr_thrm(CPUPPCState *env)
1389 /* Thermal management */
1390 /* XXX : not implemented */
1391 spr_register(env, SPR_THRM1, "THRM1",
1392 SPR_NOACCESS, SPR_NOACCESS,
1393 &spr_read_thrm, &spr_write_generic,
1395 /* XXX : not implemented */
1396 spr_register(env, SPR_THRM2, "THRM2",
1397 SPR_NOACCESS, SPR_NOACCESS,
1398 &spr_read_thrm, &spr_write_generic,
1400 /* XXX : not implemented */
1401 spr_register(env, SPR_THRM3, "THRM3",
1402 SPR_NOACCESS, SPR_NOACCESS,
1403 &spr_read_thrm, &spr_write_generic,
1407 /* SPR specific to PowerPC 604 implementation */
1408 static void gen_spr_604(CPUPPCState *env)
1410 /* Processor identification */
1411 spr_register(env, SPR_PIR, "PIR",
1412 SPR_NOACCESS, SPR_NOACCESS,
1413 &spr_read_generic, &spr_write_pir,
1416 /* XXX : not implemented */
1417 spr_register(env, SPR_IABR, "IABR",
1418 SPR_NOACCESS, SPR_NOACCESS,
1419 &spr_read_generic, &spr_write_generic,
1421 /* XXX : not implemented */
1422 spr_register_kvm(env, SPR_DABR, "DABR",
1423 SPR_NOACCESS, SPR_NOACCESS,
1424 &spr_read_generic, &spr_write_generic,
1425 KVM_REG_PPC_DABR, 0x00000000);
1426 /* Performance counters */
1427 /* XXX : not implemented */
1428 spr_register(env, SPR_7XX_MMCR0, "MMCR0",
1429 SPR_NOACCESS, SPR_NOACCESS,
1430 &spr_read_generic, &spr_write_generic,
1432 /* XXX : not implemented */
1433 spr_register(env, SPR_7XX_PMC1, "PMC1",
1434 SPR_NOACCESS, SPR_NOACCESS,
1435 &spr_read_generic, &spr_write_generic,
1437 /* XXX : not implemented */
1438 spr_register(env, SPR_7XX_PMC2, "PMC2",
1439 SPR_NOACCESS, SPR_NOACCESS,
1440 &spr_read_generic, &spr_write_generic,
1442 /* XXX : not implemented */
1443 spr_register(env, SPR_7XX_SIAR, "SIAR",
1444 SPR_NOACCESS, SPR_NOACCESS,
1445 &spr_read_generic, SPR_NOACCESS,
1447 /* XXX : not implemented */
1448 spr_register(env, SPR_SDA, "SDA",
1449 SPR_NOACCESS, SPR_NOACCESS,
1450 &spr_read_generic, SPR_NOACCESS,
1452 /* External access control */
1453 /* XXX : not implemented */
1454 spr_register(env, SPR_EAR, "EAR",
1455 SPR_NOACCESS, SPR_NOACCESS,
1456 &spr_read_generic, &spr_write_generic,
1460 /* SPR specific to PowerPC 603 implementation */
1461 static void gen_spr_603(CPUPPCState *env)
1463 /* External access control */
1464 /* XXX : not implemented */
1465 spr_register(env, SPR_EAR, "EAR",
1466 SPR_NOACCESS, SPR_NOACCESS,
1467 &spr_read_generic, &spr_write_generic,
1470 /* XXX : not implemented */
1471 spr_register(env, SPR_IABR, "IABR",
1472 SPR_NOACCESS, SPR_NOACCESS,
1473 &spr_read_generic, &spr_write_generic,
1478 /* SPR specific to PowerPC G2 implementation */
1479 static void gen_spr_G2(CPUPPCState *env)
1481 /* Memory base address */
1483 /* XXX : not implemented */
1484 spr_register(env, SPR_MBAR, "MBAR",
1485 SPR_NOACCESS, SPR_NOACCESS,
1486 &spr_read_generic, &spr_write_generic,
1488 /* Exception processing */
1489 spr_register(env, SPR_BOOKE_CSRR0, "CSRR0",
1490 SPR_NOACCESS, SPR_NOACCESS,
1491 &spr_read_generic, &spr_write_generic,
1493 spr_register(env, SPR_BOOKE_CSRR1, "CSRR1",
1494 SPR_NOACCESS, SPR_NOACCESS,
1495 &spr_read_generic, &spr_write_generic,
1498 /* XXX : not implemented */
1499 spr_register(env, SPR_DABR, "DABR",
1500 SPR_NOACCESS, SPR_NOACCESS,
1501 &spr_read_generic, &spr_write_generic,
1503 /* XXX : not implemented */
1504 spr_register(env, SPR_DABR2, "DABR2",
1505 SPR_NOACCESS, SPR_NOACCESS,
1506 &spr_read_generic, &spr_write_generic,
1508 /* XXX : not implemented */
1509 spr_register(env, SPR_IABR, "IABR",
1510 SPR_NOACCESS, SPR_NOACCESS,
1511 &spr_read_generic, &spr_write_generic,
1513 /* XXX : not implemented */
1514 spr_register(env, SPR_IABR2, "IABR2",
1515 SPR_NOACCESS, SPR_NOACCESS,
1516 &spr_read_generic, &spr_write_generic,
1518 /* XXX : not implemented */
1519 spr_register(env, SPR_IBCR, "IBCR",
1520 SPR_NOACCESS, SPR_NOACCESS,
1521 &spr_read_generic, &spr_write_generic,
1523 /* XXX : not implemented */
1524 spr_register(env, SPR_DBCR, "DBCR",
1525 SPR_NOACCESS, SPR_NOACCESS,
1526 &spr_read_generic, &spr_write_generic,
1530 /* SPR specific to PowerPC 602 implementation */
1531 static void gen_spr_602(CPUPPCState *env)
1534 /* XXX : not implemented */
1535 spr_register(env, SPR_SER, "SER",
1536 SPR_NOACCESS, SPR_NOACCESS,
1537 &spr_read_generic, &spr_write_generic,
1539 /* XXX : not implemented */
1540 spr_register(env, SPR_SEBR, "SEBR",
1541 SPR_NOACCESS, SPR_NOACCESS,
1542 &spr_read_generic, &spr_write_generic,
1544 /* XXX : not implemented */
1545 spr_register(env, SPR_ESASRR, "ESASRR",
1546 SPR_NOACCESS, SPR_NOACCESS,
1547 &spr_read_generic, &spr_write_generic,
1549 /* Floating point status */
1550 /* XXX : not implemented */
1551 spr_register(env, SPR_SP, "SP",
1552 SPR_NOACCESS, SPR_NOACCESS,
1553 &spr_read_generic, &spr_write_generic,
1555 /* XXX : not implemented */
1556 spr_register(env, SPR_LT, "LT",
1557 SPR_NOACCESS, SPR_NOACCESS,
1558 &spr_read_generic, &spr_write_generic,
1560 /* Watchdog timer */
1561 /* XXX : not implemented */
1562 spr_register(env, SPR_TCR, "TCR",
1563 SPR_NOACCESS, SPR_NOACCESS,
1564 &spr_read_generic, &spr_write_generic,
1566 /* Interrupt base */
1567 spr_register(env, SPR_IBR, "IBR",
1568 SPR_NOACCESS, SPR_NOACCESS,
1569 &spr_read_generic, &spr_write_generic,
1571 /* XXX : not implemented */
1572 spr_register(env, SPR_IABR, "IABR",
1573 SPR_NOACCESS, SPR_NOACCESS,
1574 &spr_read_generic, &spr_write_generic,
1578 /* SPR specific to PowerPC 601 implementation */
1579 static void gen_spr_601(CPUPPCState *env)
1581 /* Multiplication/division register */
1583 spr_register(env, SPR_MQ, "MQ",
1584 &spr_read_generic, &spr_write_generic,
1585 &spr_read_generic, &spr_write_generic,
1588 spr_register(env, SPR_601_RTCU, "RTCU",
1589 SPR_NOACCESS, SPR_NOACCESS,
1590 SPR_NOACCESS, &spr_write_601_rtcu,
1592 spr_register(env, SPR_601_VRTCU, "RTCU",
1593 &spr_read_601_rtcu, SPR_NOACCESS,
1594 &spr_read_601_rtcu, SPR_NOACCESS,
1596 spr_register(env, SPR_601_RTCL, "RTCL",
1597 SPR_NOACCESS, SPR_NOACCESS,
1598 SPR_NOACCESS, &spr_write_601_rtcl,
1600 spr_register(env, SPR_601_VRTCL, "RTCL",
1601 &spr_read_601_rtcl, SPR_NOACCESS,
1602 &spr_read_601_rtcl, SPR_NOACCESS,
1606 spr_register(env, SPR_601_UDECR, "UDECR",
1607 &spr_read_decr, SPR_NOACCESS,
1608 &spr_read_decr, SPR_NOACCESS,
1611 /* External access control */
1612 /* XXX : not implemented */
1613 spr_register(env, SPR_EAR, "EAR",
1614 SPR_NOACCESS, SPR_NOACCESS,
1615 &spr_read_generic, &spr_write_generic,
1617 /* Memory management */
1618 #if !defined(CONFIG_USER_ONLY)
1619 spr_register(env, SPR_IBAT0U, "IBAT0U",
1620 SPR_NOACCESS, SPR_NOACCESS,
1621 &spr_read_601_ubat, &spr_write_601_ubatu,
1623 spr_register(env, SPR_IBAT0L, "IBAT0L",
1624 SPR_NOACCESS, SPR_NOACCESS,
1625 &spr_read_601_ubat, &spr_write_601_ubatl,
1627 spr_register(env, SPR_IBAT1U, "IBAT1U",
1628 SPR_NOACCESS, SPR_NOACCESS,
1629 &spr_read_601_ubat, &spr_write_601_ubatu,
1631 spr_register(env, SPR_IBAT1L, "IBAT1L",
1632 SPR_NOACCESS, SPR_NOACCESS,
1633 &spr_read_601_ubat, &spr_write_601_ubatl,
1635 spr_register(env, SPR_IBAT2U, "IBAT2U",
1636 SPR_NOACCESS, SPR_NOACCESS,
1637 &spr_read_601_ubat, &spr_write_601_ubatu,
1639 spr_register(env, SPR_IBAT2L, "IBAT2L",
1640 SPR_NOACCESS, SPR_NOACCESS,
1641 &spr_read_601_ubat, &spr_write_601_ubatl,
1643 spr_register(env, SPR_IBAT3U, "IBAT3U",
1644 SPR_NOACCESS, SPR_NOACCESS,
1645 &spr_read_601_ubat, &spr_write_601_ubatu,
1647 spr_register(env, SPR_IBAT3L, "IBAT3L",
1648 SPR_NOACCESS, SPR_NOACCESS,
1649 &spr_read_601_ubat, &spr_write_601_ubatl,
1655 static void gen_spr_74xx(CPUPPCState *env)
1657 /* Processor identification */
1658 spr_register(env, SPR_PIR, "PIR",
1659 SPR_NOACCESS, SPR_NOACCESS,
1660 &spr_read_generic, &spr_write_pir,
1662 /* XXX : not implemented */
1663 spr_register(env, SPR_74XX_MMCR2, "MMCR2",
1664 SPR_NOACCESS, SPR_NOACCESS,
1665 &spr_read_generic, &spr_write_generic,
1667 /* XXX : not implemented */
1668 spr_register(env, SPR_74XX_UMMCR2, "UMMCR2",
1669 &spr_read_ureg, SPR_NOACCESS,
1670 &spr_read_ureg, SPR_NOACCESS,
1672 /* XXX: not implemented */
1673 spr_register(env, SPR_BAMR, "BAMR",
1674 SPR_NOACCESS, SPR_NOACCESS,
1675 &spr_read_generic, &spr_write_generic,
1677 /* XXX : not implemented */
1678 spr_register(env, SPR_MSSCR0, "MSSCR0",
1679 SPR_NOACCESS, SPR_NOACCESS,
1680 &spr_read_generic, &spr_write_generic,
1682 /* Hardware implementation registers */
1683 /* XXX : not implemented */
1684 spr_register(env, SPR_HID0, "HID0",
1685 SPR_NOACCESS, SPR_NOACCESS,
1686 &spr_read_generic, &spr_write_generic,
1688 /* XXX : not implemented */
1689 spr_register(env, SPR_HID1, "HID1",
1690 SPR_NOACCESS, SPR_NOACCESS,
1691 &spr_read_generic, &spr_write_generic,
1694 spr_register(env, SPR_VRSAVE, "VRSAVE",
1695 &spr_read_generic, &spr_write_generic,
1696 &spr_read_generic, &spr_write_generic,
1698 /* XXX : not implemented */
1699 spr_register(env, SPR_L2CR, "L2CR",
1700 SPR_NOACCESS, SPR_NOACCESS,
1701 &spr_read_generic, spr_access_nop,
1703 /* Not strictly an SPR */
1704 vscr_init(env, 0x00010000);
1707 static void gen_l3_ctrl(CPUPPCState *env)
1710 /* XXX : not implemented */
1711 spr_register(env, SPR_L3CR, "L3CR",
1712 SPR_NOACCESS, SPR_NOACCESS,
1713 &spr_read_generic, &spr_write_generic,
1716 /* XXX : not implemented */
1717 spr_register(env, SPR_L3ITCR0, "L3ITCR0",
1718 SPR_NOACCESS, SPR_NOACCESS,
1719 &spr_read_generic, &spr_write_generic,
1722 /* XXX : not implemented */
1723 spr_register(env, SPR_L3PM, "L3PM",
1724 SPR_NOACCESS, SPR_NOACCESS,
1725 &spr_read_generic, &spr_write_generic,
1729 static void gen_74xx_soft_tlb(CPUPPCState *env, int nb_tlbs, int nb_ways)
1731 #if !defined(CONFIG_USER_ONLY)
1732 env->nb_tlb = nb_tlbs;
1733 env->nb_ways = nb_ways;
1735 env->tlb_type = TLB_6XX;
1736 /* XXX : not implemented */
1737 spr_register(env, SPR_PTEHI, "PTEHI",
1738 SPR_NOACCESS, SPR_NOACCESS,
1739 &spr_read_generic, &spr_write_generic,
1741 /* XXX : not implemented */
1742 spr_register(env, SPR_PTELO, "PTELO",
1743 SPR_NOACCESS, SPR_NOACCESS,
1744 &spr_read_generic, &spr_write_generic,
1746 /* XXX : not implemented */
1747 spr_register(env, SPR_TLBMISS, "TLBMISS",
1748 SPR_NOACCESS, SPR_NOACCESS,
1749 &spr_read_generic, &spr_write_generic,
1754 #if !defined(CONFIG_USER_ONLY)
1755 static void spr_write_e500_l1csr0(DisasContext *ctx, int sprn, int gprn)
1757 TCGv t0 = tcg_temp_new();
1759 tcg_gen_andi_tl(t0, cpu_gpr[gprn], L1CSR0_DCE | L1CSR0_CPE);
1760 gen_store_spr(sprn, t0);
1764 static void spr_write_e500_l1csr1(DisasContext *ctx, int sprn, int gprn)
1766 TCGv t0 = tcg_temp_new();
1768 tcg_gen_andi_tl(t0, cpu_gpr[gprn], L1CSR1_ICE | L1CSR1_CPE);
1769 gen_store_spr(sprn, t0);
1773 static void spr_write_e500_l2csr0(DisasContext *ctx, int sprn, int gprn)
1775 TCGv t0 = tcg_temp_new();
1777 tcg_gen_andi_tl(t0, cpu_gpr[gprn],
1778 ~(E500_L2CSR0_L2FI | E500_L2CSR0_L2FL | E500_L2CSR0_L2LFC));
1779 gen_store_spr(sprn, t0);
1783 static void spr_write_booke206_mmucsr0(DisasContext *ctx, int sprn, int gprn)
1785 gen_helper_booke206_tlbflush(cpu_env, cpu_gpr[gprn]);
1788 static void spr_write_booke_pid(DisasContext *ctx, int sprn, int gprn)
1790 TCGv_i32 t0 = tcg_const_i32(sprn);
1791 gen_helper_booke_setpid(cpu_env, t0, cpu_gpr[gprn]);
1792 tcg_temp_free_i32(t0);
1794 static void spr_write_eplc(DisasContext *ctx, int sprn, int gprn)
1796 gen_helper_booke_set_eplc(cpu_env, cpu_gpr[gprn]);
1798 static void spr_write_epsc(DisasContext *ctx, int sprn, int gprn)
1800 gen_helper_booke_set_epsc(cpu_env, cpu_gpr[gprn]);
1805 static void gen_spr_usprg3(CPUPPCState *env)
1807 spr_register(env, SPR_USPRG3, "USPRG3",
1808 &spr_read_ureg, SPR_NOACCESS,
1809 &spr_read_ureg, SPR_NOACCESS,
1813 static void gen_spr_usprgh(CPUPPCState *env)
1815 spr_register(env, SPR_USPRG4, "USPRG4",
1816 &spr_read_ureg, SPR_NOACCESS,
1817 &spr_read_ureg, SPR_NOACCESS,
1819 spr_register(env, SPR_USPRG5, "USPRG5",
1820 &spr_read_ureg, SPR_NOACCESS,
1821 &spr_read_ureg, SPR_NOACCESS,
1823 spr_register(env, SPR_USPRG6, "USPRG6",
1824 &spr_read_ureg, SPR_NOACCESS,
1825 &spr_read_ureg, SPR_NOACCESS,
1827 spr_register(env, SPR_USPRG7, "USPRG7",
1828 &spr_read_ureg, SPR_NOACCESS,
1829 &spr_read_ureg, SPR_NOACCESS,
1833 /* PowerPC BookE SPR */
1834 static void gen_spr_BookE(CPUPPCState *env, uint64_t ivor_mask)
1836 const char *ivor_names[64] = {
1837 "IVOR0", "IVOR1", "IVOR2", "IVOR3",
1838 "IVOR4", "IVOR5", "IVOR6", "IVOR7",
1839 "IVOR8", "IVOR9", "IVOR10", "IVOR11",
1840 "IVOR12", "IVOR13", "IVOR14", "IVOR15",
1841 "IVOR16", "IVOR17", "IVOR18", "IVOR19",
1842 "IVOR20", "IVOR21", "IVOR22", "IVOR23",
1843 "IVOR24", "IVOR25", "IVOR26", "IVOR27",
1844 "IVOR28", "IVOR29", "IVOR30", "IVOR31",
1845 "IVOR32", "IVOR33", "IVOR34", "IVOR35",
1846 "IVOR36", "IVOR37", "IVOR38", "IVOR39",
1847 "IVOR40", "IVOR41", "IVOR42", "IVOR43",
1848 "IVOR44", "IVOR45", "IVOR46", "IVOR47",
1849 "IVOR48", "IVOR49", "IVOR50", "IVOR51",
1850 "IVOR52", "IVOR53", "IVOR54", "IVOR55",
1851 "IVOR56", "IVOR57", "IVOR58", "IVOR59",
1852 "IVOR60", "IVOR61", "IVOR62", "IVOR63",
1854 #define SPR_BOOKE_IVORxx (-1)
1855 int ivor_sprn[64] = {
1856 SPR_BOOKE_IVOR0, SPR_BOOKE_IVOR1, SPR_BOOKE_IVOR2, SPR_BOOKE_IVOR3,
1857 SPR_BOOKE_IVOR4, SPR_BOOKE_IVOR5, SPR_BOOKE_IVOR6, SPR_BOOKE_IVOR7,
1858 SPR_BOOKE_IVOR8, SPR_BOOKE_IVOR9, SPR_BOOKE_IVOR10, SPR_BOOKE_IVOR11,
1859 SPR_BOOKE_IVOR12, SPR_BOOKE_IVOR13, SPR_BOOKE_IVOR14, SPR_BOOKE_IVOR15,
1860 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1861 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1862 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1863 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1864 SPR_BOOKE_IVOR32, SPR_BOOKE_IVOR33, SPR_BOOKE_IVOR34, SPR_BOOKE_IVOR35,
1865 SPR_BOOKE_IVOR36, SPR_BOOKE_IVOR37, SPR_BOOKE_IVOR38, SPR_BOOKE_IVOR39,
1866 SPR_BOOKE_IVOR40, SPR_BOOKE_IVOR41, SPR_BOOKE_IVOR42, SPR_BOOKE_IVORxx,
1867 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1868 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1869 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1870 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1871 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1875 /* Interrupt processing */
1876 spr_register(env, SPR_BOOKE_CSRR0, "CSRR0",
1877 SPR_NOACCESS, SPR_NOACCESS,
1878 &spr_read_generic, &spr_write_generic,
1880 spr_register(env, SPR_BOOKE_CSRR1, "CSRR1",
1881 SPR_NOACCESS, SPR_NOACCESS,
1882 &spr_read_generic, &spr_write_generic,
1885 /* XXX : not implemented */
1886 spr_register(env, SPR_BOOKE_IAC1, "IAC1",
1887 SPR_NOACCESS, SPR_NOACCESS,
1888 &spr_read_generic, &spr_write_generic,
1890 /* XXX : not implemented */
1891 spr_register(env, SPR_BOOKE_IAC2, "IAC2",
1892 SPR_NOACCESS, SPR_NOACCESS,
1893 &spr_read_generic, &spr_write_generic,
1895 /* XXX : not implemented */
1896 spr_register(env, SPR_BOOKE_DAC1, "DAC1",
1897 SPR_NOACCESS, SPR_NOACCESS,
1898 &spr_read_generic, &spr_write_generic,
1900 /* XXX : not implemented */
1901 spr_register(env, SPR_BOOKE_DAC2, "DAC2",
1902 SPR_NOACCESS, SPR_NOACCESS,
1903 &spr_read_generic, &spr_write_generic,
1905 /* XXX : not implemented */
1906 spr_register(env, SPR_BOOKE_DBCR0, "DBCR0",
1907 SPR_NOACCESS, SPR_NOACCESS,
1908 &spr_read_generic, &spr_write_40x_dbcr0,
1910 /* XXX : not implemented */
1911 spr_register(env, SPR_BOOKE_DBCR1, "DBCR1",
1912 SPR_NOACCESS, SPR_NOACCESS,
1913 &spr_read_generic, &spr_write_generic,
1915 /* XXX : not implemented */
1916 spr_register(env, SPR_BOOKE_DBCR2, "DBCR2",
1917 SPR_NOACCESS, SPR_NOACCESS,
1918 &spr_read_generic, &spr_write_generic,
1920 spr_register(env, SPR_BOOKE_DSRR0, "DSRR0",
1921 SPR_NOACCESS, SPR_NOACCESS,
1922 &spr_read_generic, &spr_write_generic,
1924 spr_register(env, SPR_BOOKE_DSRR1, "DSRR1",
1925 SPR_NOACCESS, SPR_NOACCESS,
1926 &spr_read_generic, &spr_write_generic,
1928 /* XXX : not implemented */
1929 spr_register(env, SPR_BOOKE_DBSR, "DBSR",
1930 SPR_NOACCESS, SPR_NOACCESS,
1931 &spr_read_generic, &spr_write_clear,
1933 spr_register(env, SPR_BOOKE_DEAR, "DEAR",
1934 SPR_NOACCESS, SPR_NOACCESS,
1935 &spr_read_generic, &spr_write_generic,
1937 spr_register(env, SPR_BOOKE_ESR, "ESR",
1938 SPR_NOACCESS, SPR_NOACCESS,
1939 &spr_read_generic, &spr_write_generic,
1941 spr_register(env, SPR_BOOKE_IVPR, "IVPR",
1942 SPR_NOACCESS, SPR_NOACCESS,
1943 &spr_read_generic, &spr_write_excp_prefix,
1945 /* Exception vectors */
1946 for (i = 0; i < 64; i++) {
1947 if (ivor_mask & (1ULL << i)) {
1948 if (ivor_sprn[i] == SPR_BOOKE_IVORxx) {
1949 fprintf(stderr, "ERROR: IVOR %d SPR is not defined\n", i);
1952 spr_register(env, ivor_sprn[i], ivor_names[i],
1953 SPR_NOACCESS, SPR_NOACCESS,
1954 &spr_read_generic, &spr_write_excp_vector,
1958 spr_register(env, SPR_BOOKE_PID, "PID",
1959 SPR_NOACCESS, SPR_NOACCESS,
1960 &spr_read_generic, &spr_write_booke_pid,
1962 spr_register(env, SPR_BOOKE_TCR, "TCR",
1963 SPR_NOACCESS, SPR_NOACCESS,
1964 &spr_read_generic, &spr_write_booke_tcr,
1966 spr_register(env, SPR_BOOKE_TSR, "TSR",
1967 SPR_NOACCESS, SPR_NOACCESS,
1968 &spr_read_generic, &spr_write_booke_tsr,
1971 spr_register(env, SPR_DECR, "DECR",
1972 SPR_NOACCESS, SPR_NOACCESS,
1973 &spr_read_decr, &spr_write_decr,
1975 spr_register(env, SPR_BOOKE_DECAR, "DECAR",
1976 SPR_NOACCESS, SPR_NOACCESS,
1977 SPR_NOACCESS, &spr_write_generic,
1980 spr_register(env, SPR_USPRG0, "USPRG0",
1981 &spr_read_generic, &spr_write_generic,
1982 &spr_read_generic, &spr_write_generic,
1984 spr_register(env, SPR_SPRG4, "SPRG4",
1985 SPR_NOACCESS, SPR_NOACCESS,
1986 &spr_read_generic, &spr_write_generic,
1988 spr_register(env, SPR_SPRG5, "SPRG5",
1989 SPR_NOACCESS, SPR_NOACCESS,
1990 &spr_read_generic, &spr_write_generic,
1992 spr_register(env, SPR_SPRG6, "SPRG6",
1993 SPR_NOACCESS, SPR_NOACCESS,
1994 &spr_read_generic, &spr_write_generic,
1996 spr_register(env, SPR_SPRG7, "SPRG7",
1997 SPR_NOACCESS, SPR_NOACCESS,
1998 &spr_read_generic, &spr_write_generic,
2000 spr_register(env, SPR_BOOKE_SPRG8, "SPRG8",
2001 SPR_NOACCESS, SPR_NOACCESS,
2002 &spr_read_generic, &spr_write_generic,
2004 spr_register(env, SPR_BOOKE_SPRG9, "SPRG9",
2005 SPR_NOACCESS, SPR_NOACCESS,
2006 &spr_read_generic, &spr_write_generic,
2010 static inline uint32_t gen_tlbncfg(uint32_t assoc, uint32_t minsize,
2011 uint32_t maxsize, uint32_t flags,
2014 return (assoc << TLBnCFG_ASSOC_SHIFT) |
2015 (minsize << TLBnCFG_MINSIZE_SHIFT) |
2016 (maxsize << TLBnCFG_MAXSIZE_SHIFT) |
2020 /* BookE 2.06 storage control registers */
2021 static void gen_spr_BookE206(CPUPPCState *env, uint32_t mas_mask,
2022 uint32_t *tlbncfg, uint32_t mmucfg)
2024 #if !defined(CONFIG_USER_ONLY)
2025 const char *mas_names[8] = {
2026 "MAS0", "MAS1", "MAS2", "MAS3", "MAS4", "MAS5", "MAS6", "MAS7",
2029 SPR_BOOKE_MAS0, SPR_BOOKE_MAS1, SPR_BOOKE_MAS2, SPR_BOOKE_MAS3,
2030 SPR_BOOKE_MAS4, SPR_BOOKE_MAS5, SPR_BOOKE_MAS6, SPR_BOOKE_MAS7,
2034 /* TLB assist registers */
2035 /* XXX : not implemented */
2036 for (i = 0; i < 8; i++) {
2037 void (*uea_write)(DisasContext *ctx, int sprn, int gprn) =
2038 &spr_write_generic32;
2039 if (i == 2 && (mas_mask & (1 << i)) && (env->insns_flags & PPC_64B)) {
2040 uea_write = &spr_write_generic;
2042 if (mas_mask & (1 << i)) {
2043 spr_register(env, mas_sprn[i], mas_names[i],
2044 SPR_NOACCESS, SPR_NOACCESS,
2045 &spr_read_generic, uea_write,
2049 if (env->nb_pids > 1) {
2050 /* XXX : not implemented */
2051 spr_register(env, SPR_BOOKE_PID1, "PID1",
2052 SPR_NOACCESS, SPR_NOACCESS,
2053 &spr_read_generic, &spr_write_booke_pid,
2056 if (env->nb_pids > 2) {
2057 /* XXX : not implemented */
2058 spr_register(env, SPR_BOOKE_PID2, "PID2",
2059 SPR_NOACCESS, SPR_NOACCESS,
2060 &spr_read_generic, &spr_write_booke_pid,
2064 spr_register(env, SPR_BOOKE_EPLC, "EPLC",
2065 SPR_NOACCESS, SPR_NOACCESS,
2066 &spr_read_generic, &spr_write_eplc,
2068 spr_register(env, SPR_BOOKE_EPSC, "EPSC",
2069 SPR_NOACCESS, SPR_NOACCESS,
2070 &spr_read_generic, &spr_write_epsc,
2073 /* XXX : not implemented */
2074 spr_register(env, SPR_MMUCFG, "MMUCFG",
2075 SPR_NOACCESS, SPR_NOACCESS,
2076 &spr_read_generic, SPR_NOACCESS,
2078 switch (env->nb_ways) {
2080 spr_register(env, SPR_BOOKE_TLB3CFG, "TLB3CFG",
2081 SPR_NOACCESS, SPR_NOACCESS,
2082 &spr_read_generic, SPR_NOACCESS,
2086 spr_register(env, SPR_BOOKE_TLB2CFG, "TLB2CFG",
2087 SPR_NOACCESS, SPR_NOACCESS,
2088 &spr_read_generic, SPR_NOACCESS,
2092 spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG",
2093 SPR_NOACCESS, SPR_NOACCESS,
2094 &spr_read_generic, SPR_NOACCESS,
2098 spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG",
2099 SPR_NOACCESS, SPR_NOACCESS,
2100 &spr_read_generic, SPR_NOACCESS,
2109 gen_spr_usprgh(env);
2112 /* SPR specific to PowerPC 440 implementation */
2113 static void gen_spr_440(CPUPPCState *env)
2116 /* XXX : not implemented */
2117 spr_register(env, SPR_440_DNV0, "DNV0",
2118 SPR_NOACCESS, SPR_NOACCESS,
2119 &spr_read_generic, &spr_write_generic,
2121 /* XXX : not implemented */
2122 spr_register(env, SPR_440_DNV1, "DNV1",
2123 SPR_NOACCESS, SPR_NOACCESS,
2124 &spr_read_generic, &spr_write_generic,
2126 /* XXX : not implemented */
2127 spr_register(env, SPR_440_DNV2, "DNV2",
2128 SPR_NOACCESS, SPR_NOACCESS,
2129 &spr_read_generic, &spr_write_generic,
2131 /* XXX : not implemented */
2132 spr_register(env, SPR_440_DNV3, "DNV3",
2133 SPR_NOACCESS, SPR_NOACCESS,
2134 &spr_read_generic, &spr_write_generic,
2136 /* XXX : not implemented */
2137 spr_register(env, SPR_440_DTV0, "DTV0",
2138 SPR_NOACCESS, SPR_NOACCESS,
2139 &spr_read_generic, &spr_write_generic,
2141 /* XXX : not implemented */
2142 spr_register(env, SPR_440_DTV1, "DTV1",
2143 SPR_NOACCESS, SPR_NOACCESS,
2144 &spr_read_generic, &spr_write_generic,
2146 /* XXX : not implemented */
2147 spr_register(env, SPR_440_DTV2, "DTV2",
2148 SPR_NOACCESS, SPR_NOACCESS,
2149 &spr_read_generic, &spr_write_generic,
2151 /* XXX : not implemented */
2152 spr_register(env, SPR_440_DTV3, "DTV3",
2153 SPR_NOACCESS, SPR_NOACCESS,
2154 &spr_read_generic, &spr_write_generic,
2156 /* XXX : not implemented */
2157 spr_register(env, SPR_440_DVLIM, "DVLIM",
2158 SPR_NOACCESS, SPR_NOACCESS,
2159 &spr_read_generic, &spr_write_generic,
2161 /* XXX : not implemented */
2162 spr_register(env, SPR_440_INV0, "INV0",
2163 SPR_NOACCESS, SPR_NOACCESS,
2164 &spr_read_generic, &spr_write_generic,
2166 /* XXX : not implemented */
2167 spr_register(env, SPR_440_INV1, "INV1",
2168 SPR_NOACCESS, SPR_NOACCESS,
2169 &spr_read_generic, &spr_write_generic,
2171 /* XXX : not implemented */
2172 spr_register(env, SPR_440_INV2, "INV2",
2173 SPR_NOACCESS, SPR_NOACCESS,
2174 &spr_read_generic, &spr_write_generic,
2176 /* XXX : not implemented */
2177 spr_register(env, SPR_440_INV3, "INV3",
2178 SPR_NOACCESS, SPR_NOACCESS,
2179 &spr_read_generic, &spr_write_generic,
2181 /* XXX : not implemented */
2182 spr_register(env, SPR_440_ITV0, "ITV0",
2183 SPR_NOACCESS, SPR_NOACCESS,
2184 &spr_read_generic, &spr_write_generic,
2186 /* XXX : not implemented */
2187 spr_register(env, SPR_440_ITV1, "ITV1",
2188 SPR_NOACCESS, SPR_NOACCESS,
2189 &spr_read_generic, &spr_write_generic,
2191 /* XXX : not implemented */
2192 spr_register(env, SPR_440_ITV2, "ITV2",
2193 SPR_NOACCESS, SPR_NOACCESS,
2194 &spr_read_generic, &spr_write_generic,
2196 /* XXX : not implemented */
2197 spr_register(env, SPR_440_ITV3, "ITV3",
2198 SPR_NOACCESS, SPR_NOACCESS,
2199 &spr_read_generic, &spr_write_generic,
2201 /* XXX : not implemented */
2202 spr_register(env, SPR_440_IVLIM, "IVLIM",
2203 SPR_NOACCESS, SPR_NOACCESS,
2204 &spr_read_generic, &spr_write_generic,
2207 /* XXX : not implemented */
2208 spr_register(env, SPR_BOOKE_DCDBTRH, "DCDBTRH",
2209 SPR_NOACCESS, SPR_NOACCESS,
2210 &spr_read_generic, SPR_NOACCESS,
2212 /* XXX : not implemented */
2213 spr_register(env, SPR_BOOKE_DCDBTRL, "DCDBTRL",
2214 SPR_NOACCESS, SPR_NOACCESS,
2215 &spr_read_generic, SPR_NOACCESS,
2217 /* XXX : not implemented */
2218 spr_register(env, SPR_BOOKE_ICDBDR, "ICDBDR",
2219 SPR_NOACCESS, SPR_NOACCESS,
2220 &spr_read_generic, SPR_NOACCESS,
2222 /* XXX : not implemented */
2223 spr_register(env, SPR_BOOKE_ICDBTRH, "ICDBTRH",
2224 SPR_NOACCESS, SPR_NOACCESS,
2225 &spr_read_generic, SPR_NOACCESS,
2227 /* XXX : not implemented */
2228 spr_register(env, SPR_BOOKE_ICDBTRL, "ICDBTRL",
2229 SPR_NOACCESS, SPR_NOACCESS,
2230 &spr_read_generic, SPR_NOACCESS,
2232 /* XXX : not implemented */
2233 spr_register(env, SPR_440_DBDR, "DBDR",
2234 SPR_NOACCESS, SPR_NOACCESS,
2235 &spr_read_generic, &spr_write_generic,
2237 /* Processor control */
2238 spr_register(env, SPR_4xx_CCR0, "CCR0",
2239 SPR_NOACCESS, SPR_NOACCESS,
2240 &spr_read_generic, &spr_write_generic,
2242 spr_register(env, SPR_440_RSTCFG, "RSTCFG",
2243 SPR_NOACCESS, SPR_NOACCESS,
2244 &spr_read_generic, SPR_NOACCESS,
2246 /* Storage control */
2247 spr_register(env, SPR_440_MMUCR, "MMUCR",
2248 SPR_NOACCESS, SPR_NOACCESS,
2249 &spr_read_generic, &spr_write_generic,
2253 /* SPR shared between PowerPC 40x implementations */
2254 static void gen_spr_40x(CPUPPCState *env)
2257 /* not emulated, as QEMU do not emulate caches */
2258 spr_register(env, SPR_40x_DCCR, "DCCR",
2259 SPR_NOACCESS, SPR_NOACCESS,
2260 &spr_read_generic, &spr_write_generic,
2262 /* not emulated, as QEMU do not emulate caches */
2263 spr_register(env, SPR_40x_ICCR, "ICCR",
2264 SPR_NOACCESS, SPR_NOACCESS,
2265 &spr_read_generic, &spr_write_generic,
2267 /* not emulated, as QEMU do not emulate caches */
2268 spr_register(env, SPR_BOOKE_ICDBDR, "ICDBDR",
2269 SPR_NOACCESS, SPR_NOACCESS,
2270 &spr_read_generic, SPR_NOACCESS,
2273 spr_register(env, SPR_40x_DEAR, "DEAR",
2274 SPR_NOACCESS, SPR_NOACCESS,
2275 &spr_read_generic, &spr_write_generic,
2277 spr_register(env, SPR_40x_ESR, "ESR",
2278 SPR_NOACCESS, SPR_NOACCESS,
2279 &spr_read_generic, &spr_write_generic,
2281 spr_register(env, SPR_40x_EVPR, "EVPR",
2282 SPR_NOACCESS, SPR_NOACCESS,
2283 &spr_read_generic, &spr_write_excp_prefix,
2285 spr_register(env, SPR_40x_SRR2, "SRR2",
2286 &spr_read_generic, &spr_write_generic,
2287 &spr_read_generic, &spr_write_generic,
2289 spr_register(env, SPR_40x_SRR3, "SRR3",
2290 &spr_read_generic, &spr_write_generic,
2291 &spr_read_generic, &spr_write_generic,
2294 spr_register(env, SPR_40x_PIT, "PIT",
2295 SPR_NOACCESS, SPR_NOACCESS,
2296 &spr_read_40x_pit, &spr_write_40x_pit,
2298 spr_register(env, SPR_40x_TCR, "TCR",
2299 SPR_NOACCESS, SPR_NOACCESS,
2300 &spr_read_generic, &spr_write_booke_tcr,
2302 spr_register(env, SPR_40x_TSR, "TSR",
2303 SPR_NOACCESS, SPR_NOACCESS,
2304 &spr_read_generic, &spr_write_booke_tsr,
2308 /* SPR specific to PowerPC 405 implementation */
2309 static void gen_spr_405(CPUPPCState *env)
2312 spr_register(env, SPR_40x_PID, "PID",
2313 SPR_NOACCESS, SPR_NOACCESS,
2314 &spr_read_generic, &spr_write_generic,
2316 spr_register(env, SPR_4xx_CCR0, "CCR0",
2317 SPR_NOACCESS, SPR_NOACCESS,
2318 &spr_read_generic, &spr_write_generic,
2320 /* Debug interface */
2321 /* XXX : not implemented */
2322 spr_register(env, SPR_40x_DBCR0, "DBCR0",
2323 SPR_NOACCESS, SPR_NOACCESS,
2324 &spr_read_generic, &spr_write_40x_dbcr0,
2326 /* XXX : not implemented */
2327 spr_register(env, SPR_405_DBCR1, "DBCR1",
2328 SPR_NOACCESS, SPR_NOACCESS,
2329 &spr_read_generic, &spr_write_generic,
2331 /* XXX : not implemented */
2332 spr_register(env, SPR_40x_DBSR, "DBSR",
2333 SPR_NOACCESS, SPR_NOACCESS,
2334 &spr_read_generic, &spr_write_clear,
2335 /* Last reset was system reset */
2337 /* XXX : not implemented */
2338 spr_register(env, SPR_40x_DAC1, "DAC1",
2339 SPR_NOACCESS, SPR_NOACCESS,
2340 &spr_read_generic, &spr_write_generic,
2342 spr_register(env, SPR_40x_DAC2, "DAC2",
2343 SPR_NOACCESS, SPR_NOACCESS,
2344 &spr_read_generic, &spr_write_generic,
2346 /* XXX : not implemented */
2347 spr_register(env, SPR_405_DVC1, "DVC1",
2348 SPR_NOACCESS, SPR_NOACCESS,
2349 &spr_read_generic, &spr_write_generic,
2351 /* XXX : not implemented */
2352 spr_register(env, SPR_405_DVC2, "DVC2",
2353 SPR_NOACCESS, SPR_NOACCESS,
2354 &spr_read_generic, &spr_write_generic,
2356 /* XXX : not implemented */
2357 spr_register(env, SPR_40x_IAC1, "IAC1",
2358 SPR_NOACCESS, SPR_NOACCESS,
2359 &spr_read_generic, &spr_write_generic,
2361 spr_register(env, SPR_40x_IAC2, "IAC2",
2362 SPR_NOACCESS, SPR_NOACCESS,
2363 &spr_read_generic, &spr_write_generic,
2365 /* XXX : not implemented */
2366 spr_register(env, SPR_405_IAC3, "IAC3",
2367 SPR_NOACCESS, SPR_NOACCESS,
2368 &spr_read_generic, &spr_write_generic,
2370 /* XXX : not implemented */
2371 spr_register(env, SPR_405_IAC4, "IAC4",
2372 SPR_NOACCESS, SPR_NOACCESS,
2373 &spr_read_generic, &spr_write_generic,
2375 /* Storage control */
2376 /* XXX: TODO: not implemented */
2377 spr_register(env, SPR_405_SLER, "SLER",
2378 SPR_NOACCESS, SPR_NOACCESS,
2379 &spr_read_generic, &spr_write_40x_sler,
2381 spr_register(env, SPR_40x_ZPR, "ZPR",
2382 SPR_NOACCESS, SPR_NOACCESS,
2383 &spr_read_generic, &spr_write_generic,
2385 /* XXX : not implemented */
2386 spr_register(env, SPR_405_SU0R, "SU0R",
2387 SPR_NOACCESS, SPR_NOACCESS,
2388 &spr_read_generic, &spr_write_generic,
2391 spr_register(env, SPR_USPRG0, "USPRG0",
2392 &spr_read_ureg, SPR_NOACCESS,
2393 &spr_read_ureg, SPR_NOACCESS,
2395 spr_register(env, SPR_SPRG4, "SPRG4",
2396 SPR_NOACCESS, SPR_NOACCESS,
2397 &spr_read_generic, &spr_write_generic,
2399 spr_register(env, SPR_SPRG5, "SPRG5",
2400 SPR_NOACCESS, SPR_NOACCESS,
2401 spr_read_generic, &spr_write_generic,
2403 spr_register(env, SPR_SPRG6, "SPRG6",
2404 SPR_NOACCESS, SPR_NOACCESS,
2405 spr_read_generic, &spr_write_generic,
2407 spr_register(env, SPR_SPRG7, "SPRG7",
2408 SPR_NOACCESS, SPR_NOACCESS,
2409 spr_read_generic, &spr_write_generic,
2411 gen_spr_usprgh(env);
2414 /* SPR shared between PowerPC 401 & 403 implementations */
2415 static void gen_spr_401_403(CPUPPCState *env)
2418 spr_register(env, SPR_403_VTBL, "TBL",
2419 &spr_read_tbl, SPR_NOACCESS,
2420 &spr_read_tbl, SPR_NOACCESS,
2422 spr_register(env, SPR_403_TBL, "TBL",
2423 SPR_NOACCESS, SPR_NOACCESS,
2424 SPR_NOACCESS, &spr_write_tbl,
2426 spr_register(env, SPR_403_VTBU, "TBU",
2427 &spr_read_tbu, SPR_NOACCESS,
2428 &spr_read_tbu, SPR_NOACCESS,
2430 spr_register(env, SPR_403_TBU, "TBU",
2431 SPR_NOACCESS, SPR_NOACCESS,
2432 SPR_NOACCESS, &spr_write_tbu,
2435 /* not emulated, as QEMU do not emulate caches */
2436 spr_register(env, SPR_403_CDBCR, "CDBCR",
2437 SPR_NOACCESS, SPR_NOACCESS,
2438 &spr_read_generic, &spr_write_generic,
2442 /* SPR specific to PowerPC 401 implementation */
2443 static void gen_spr_401(CPUPPCState *env)
2445 /* Debug interface */
2446 /* XXX : not implemented */
2447 spr_register(env, SPR_40x_DBCR0, "DBCR",
2448 SPR_NOACCESS, SPR_NOACCESS,
2449 &spr_read_generic, &spr_write_40x_dbcr0,
2451 /* XXX : not implemented */
2452 spr_register(env, SPR_40x_DBSR, "DBSR",
2453 SPR_NOACCESS, SPR_NOACCESS,
2454 &spr_read_generic, &spr_write_clear,
2455 /* Last reset was system reset */
2457 /* XXX : not implemented */
2458 spr_register(env, SPR_40x_DAC1, "DAC",
2459 SPR_NOACCESS, SPR_NOACCESS,
2460 &spr_read_generic, &spr_write_generic,
2462 /* XXX : not implemented */
2463 spr_register(env, SPR_40x_IAC1, "IAC",
2464 SPR_NOACCESS, SPR_NOACCESS,
2465 &spr_read_generic, &spr_write_generic,
2467 /* Storage control */
2468 /* XXX: TODO: not implemented */
2469 spr_register(env, SPR_405_SLER, "SLER",
2470 SPR_NOACCESS, SPR_NOACCESS,
2471 &spr_read_generic, &spr_write_40x_sler,
2473 /* not emulated, as QEMU never does speculative access */
2474 spr_register(env, SPR_40x_SGR, "SGR",
2475 SPR_NOACCESS, SPR_NOACCESS,
2476 &spr_read_generic, &spr_write_generic,
2478 /* not emulated, as QEMU do not emulate caches */
2479 spr_register(env, SPR_40x_DCWR, "DCWR",
2480 SPR_NOACCESS, SPR_NOACCESS,
2481 &spr_read_generic, &spr_write_generic,
2485 static void gen_spr_401x2(CPUPPCState *env)
2488 spr_register(env, SPR_40x_PID, "PID",
2489 SPR_NOACCESS, SPR_NOACCESS,
2490 &spr_read_generic, &spr_write_generic,
2492 spr_register(env, SPR_40x_ZPR, "ZPR",
2493 SPR_NOACCESS, SPR_NOACCESS,
2494 &spr_read_generic, &spr_write_generic,
2498 /* SPR specific to PowerPC 403 implementation */
2499 static void gen_spr_403(CPUPPCState *env)
2501 /* Debug interface */
2502 /* XXX : not implemented */
2503 spr_register(env, SPR_40x_DBCR0, "DBCR0",
2504 SPR_NOACCESS, SPR_NOACCESS,
2505 &spr_read_generic, &spr_write_40x_dbcr0,
2507 /* XXX : not implemented */
2508 spr_register(env, SPR_40x_DBSR, "DBSR",
2509 SPR_NOACCESS, SPR_NOACCESS,
2510 &spr_read_generic, &spr_write_clear,
2511 /* Last reset was system reset */
2513 /* XXX : not implemented */
2514 spr_register(env, SPR_40x_DAC1, "DAC1",
2515 SPR_NOACCESS, SPR_NOACCESS,
2516 &spr_read_generic, &spr_write_generic,
2518 /* XXX : not implemented */
2519 spr_register(env, SPR_40x_DAC2, "DAC2",
2520 SPR_NOACCESS, SPR_NOACCESS,
2521 &spr_read_generic, &spr_write_generic,
2523 /* XXX : not implemented */
2524 spr_register(env, SPR_40x_IAC1, "IAC1",
2525 SPR_NOACCESS, SPR_NOACCESS,
2526 &spr_read_generic, &spr_write_generic,
2528 /* XXX : not implemented */
2529 spr_register(env, SPR_40x_IAC2, "IAC2",
2530 SPR_NOACCESS, SPR_NOACCESS,
2531 &spr_read_generic, &spr_write_generic,
2535 static void gen_spr_403_real(CPUPPCState *env)
2537 spr_register(env, SPR_403_PBL1, "PBL1",
2538 SPR_NOACCESS, SPR_NOACCESS,
2539 &spr_read_403_pbr, &spr_write_403_pbr,
2541 spr_register(env, SPR_403_PBU1, "PBU1",
2542 SPR_NOACCESS, SPR_NOACCESS,
2543 &spr_read_403_pbr, &spr_write_403_pbr,
2545 spr_register(env, SPR_403_PBL2, "PBL2",
2546 SPR_NOACCESS, SPR_NOACCESS,
2547 &spr_read_403_pbr, &spr_write_403_pbr,
2549 spr_register(env, SPR_403_PBU2, "PBU2",
2550 SPR_NOACCESS, SPR_NOACCESS,
2551 &spr_read_403_pbr, &spr_write_403_pbr,
2555 static void gen_spr_403_mmu(CPUPPCState *env)
2558 spr_register(env, SPR_40x_PID, "PID",
2559 SPR_NOACCESS, SPR_NOACCESS,
2560 &spr_read_generic, &spr_write_generic,
2562 spr_register(env, SPR_40x_ZPR, "ZPR",
2563 SPR_NOACCESS, SPR_NOACCESS,
2564 &spr_read_generic, &spr_write_generic,
2568 /* SPR specific to PowerPC compression coprocessor extension */
2569 static void gen_spr_compress(CPUPPCState *env)
2571 /* XXX : not implemented */
2572 spr_register(env, SPR_401_SKR, "SKR",
2573 SPR_NOACCESS, SPR_NOACCESS,
2574 &spr_read_generic, &spr_write_generic,
2578 static void gen_spr_5xx_8xx(CPUPPCState *env)
2580 /* Exception processing */
2581 spr_register_kvm(env, SPR_DSISR, "DSISR",
2582 SPR_NOACCESS, SPR_NOACCESS,
2583 &spr_read_generic, &spr_write_generic,
2584 KVM_REG_PPC_DSISR, 0x00000000);
2585 spr_register_kvm(env, SPR_DAR, "DAR",
2586 SPR_NOACCESS, SPR_NOACCESS,
2587 &spr_read_generic, &spr_write_generic,
2588 KVM_REG_PPC_DAR, 0x00000000);
2590 spr_register(env, SPR_DECR, "DECR",
2591 SPR_NOACCESS, SPR_NOACCESS,
2592 &spr_read_decr, &spr_write_decr,
2594 /* XXX : not implemented */
2595 spr_register(env, SPR_MPC_EIE, "EIE",
2596 SPR_NOACCESS, SPR_NOACCESS,
2597 &spr_read_generic, &spr_write_generic,
2599 /* XXX : not implemented */
2600 spr_register(env, SPR_MPC_EID, "EID",
2601 SPR_NOACCESS, SPR_NOACCESS,
2602 &spr_read_generic, &spr_write_generic,
2604 /* XXX : not implemented */
2605 spr_register(env, SPR_MPC_NRI, "NRI",
2606 SPR_NOACCESS, SPR_NOACCESS,
2607 &spr_read_generic, &spr_write_generic,
2609 /* XXX : not implemented */
2610 spr_register(env, SPR_MPC_CMPA, "CMPA",
2611 SPR_NOACCESS, SPR_NOACCESS,
2612 &spr_read_generic, &spr_write_generic,
2614 /* XXX : not implemented */
2615 spr_register(env, SPR_MPC_CMPB, "CMPB",
2616 SPR_NOACCESS, SPR_NOACCESS,
2617 &spr_read_generic, &spr_write_generic,
2619 /* XXX : not implemented */
2620 spr_register(env, SPR_MPC_CMPC, "CMPC",
2621 SPR_NOACCESS, SPR_NOACCESS,
2622 &spr_read_generic, &spr_write_generic,
2624 /* XXX : not implemented */
2625 spr_register(env, SPR_MPC_CMPD, "CMPD",
2626 SPR_NOACCESS, SPR_NOACCESS,
2627 &spr_read_generic, &spr_write_generic,
2629 /* XXX : not implemented */
2630 spr_register(env, SPR_MPC_ECR, "ECR",
2631 SPR_NOACCESS, SPR_NOACCESS,
2632 &spr_read_generic, &spr_write_generic,
2634 /* XXX : not implemented */
2635 spr_register(env, SPR_MPC_DER, "DER",
2636 SPR_NOACCESS, SPR_NOACCESS,
2637 &spr_read_generic, &spr_write_generic,
2639 /* XXX : not implemented */
2640 spr_register(env, SPR_MPC_COUNTA, "COUNTA",
2641 SPR_NOACCESS, SPR_NOACCESS,
2642 &spr_read_generic, &spr_write_generic,
2644 /* XXX : not implemented */
2645 spr_register(env, SPR_MPC_COUNTB, "COUNTB",
2646 SPR_NOACCESS, SPR_NOACCESS,
2647 &spr_read_generic, &spr_write_generic,
2649 /* XXX : not implemented */
2650 spr_register(env, SPR_MPC_CMPE, "CMPE",
2651 SPR_NOACCESS, SPR_NOACCESS,
2652 &spr_read_generic, &spr_write_generic,
2654 /* XXX : not implemented */
2655 spr_register(env, SPR_MPC_CMPF, "CMPF",
2656 SPR_NOACCESS, SPR_NOACCESS,
2657 &spr_read_generic, &spr_write_generic,
2659 /* XXX : not implemented */
2660 spr_register(env, SPR_MPC_CMPG, "CMPG",
2661 SPR_NOACCESS, SPR_NOACCESS,
2662 &spr_read_generic, &spr_write_generic,
2664 /* XXX : not implemented */
2665 spr_register(env, SPR_MPC_CMPH, "CMPH",
2666 SPR_NOACCESS, SPR_NOACCESS,
2667 &spr_read_generic, &spr_write_generic,
2669 /* XXX : not implemented */
2670 spr_register(env, SPR_MPC_LCTRL1, "LCTRL1",
2671 SPR_NOACCESS, SPR_NOACCESS,
2672 &spr_read_generic, &spr_write_generic,
2674 /* XXX : not implemented */
2675 spr_register(env, SPR_MPC_LCTRL2, "LCTRL2",
2676 SPR_NOACCESS, SPR_NOACCESS,
2677 &spr_read_generic, &spr_write_generic,
2679 /* XXX : not implemented */
2680 spr_register(env, SPR_MPC_BAR, "BAR",
2681 SPR_NOACCESS, SPR_NOACCESS,
2682 &spr_read_generic, &spr_write_generic,
2684 /* XXX : not implemented */
2685 spr_register(env, SPR_MPC_DPDR, "DPDR",
2686 SPR_NOACCESS, SPR_NOACCESS,
2687 &spr_read_generic, &spr_write_generic,
2689 /* XXX : not implemented */
2690 spr_register(env, SPR_MPC_IMMR, "IMMR",
2691 SPR_NOACCESS, SPR_NOACCESS,
2692 &spr_read_generic, &spr_write_generic,
2696 static void gen_spr_5xx(CPUPPCState *env)
2698 /* XXX : not implemented */
2699 spr_register(env, SPR_RCPU_MI_GRA, "MI_GRA",
2700 SPR_NOACCESS, SPR_NOACCESS,
2701 &spr_read_generic, &spr_write_generic,
2703 /* XXX : not implemented */
2704 spr_register(env, SPR_RCPU_L2U_GRA, "L2U_GRA",
2705 SPR_NOACCESS, SPR_NOACCESS,
2706 &spr_read_generic, &spr_write_generic,
2708 /* XXX : not implemented */
2709 spr_register(env, SPR_RPCU_BBCMCR, "L2U_BBCMCR",
2710 SPR_NOACCESS, SPR_NOACCESS,
2711 &spr_read_generic, &spr_write_generic,
2713 /* XXX : not implemented */
2714 spr_register(env, SPR_RCPU_L2U_MCR, "L2U_MCR",
2715 SPR_NOACCESS, SPR_NOACCESS,
2716 &spr_read_generic, &spr_write_generic,
2718 /* XXX : not implemented */
2719 spr_register(env, SPR_RCPU_MI_RBA0, "MI_RBA0",
2720 SPR_NOACCESS, SPR_NOACCESS,
2721 &spr_read_generic, &spr_write_generic,
2723 /* XXX : not implemented */
2724 spr_register(env, SPR_RCPU_MI_RBA1, "MI_RBA1",
2725 SPR_NOACCESS, SPR_NOACCESS,
2726 &spr_read_generic, &spr_write_generic,
2728 /* XXX : not implemented */
2729 spr_register(env, SPR_RCPU_MI_RBA2, "MI_RBA2",
2730 SPR_NOACCESS, SPR_NOACCESS,
2731 &spr_read_generic, &spr_write_generic,
2733 /* XXX : not implemented */
2734 spr_register(env, SPR_RCPU_MI_RBA3, "MI_RBA3",
2735 SPR_NOACCESS, SPR_NOACCESS,
2736 &spr_read_generic, &spr_write_generic,
2738 /* XXX : not implemented */
2739 spr_register(env, SPR_RCPU_L2U_RBA0, "L2U_RBA0",
2740 SPR_NOACCESS, SPR_NOACCESS,
2741 &spr_read_generic, &spr_write_generic,
2743 /* XXX : not implemented */
2744 spr_register(env, SPR_RCPU_L2U_RBA1, "L2U_RBA1",
2745 SPR_NOACCESS, SPR_NOACCESS,
2746 &spr_read_generic, &spr_write_generic,
2748 /* XXX : not implemented */
2749 spr_register(env, SPR_RCPU_L2U_RBA2, "L2U_RBA2",
2750 SPR_NOACCESS, SPR_NOACCESS,
2751 &spr_read_generic, &spr_write_generic,
2753 /* XXX : not implemented */
2754 spr_register(env, SPR_RCPU_L2U_RBA3, "L2U_RBA3",
2755 SPR_NOACCESS, SPR_NOACCESS,
2756 &spr_read_generic, &spr_write_generic,
2758 /* XXX : not implemented */
2759 spr_register(env, SPR_RCPU_MI_RA0, "MI_RA0",
2760 SPR_NOACCESS, SPR_NOACCESS,
2761 &spr_read_generic, &spr_write_generic,
2763 /* XXX : not implemented */
2764 spr_register(env, SPR_RCPU_MI_RA1, "MI_RA1",
2765 SPR_NOACCESS, SPR_NOACCESS,
2766 &spr_read_generic, &spr_write_generic,
2768 /* XXX : not implemented */
2769 spr_register(env, SPR_RCPU_MI_RA2, "MI_RA2",
2770 SPR_NOACCESS, SPR_NOACCESS,
2771 &spr_read_generic, &spr_write_generic,
2773 /* XXX : not implemented */
2774 spr_register(env, SPR_RCPU_MI_RA3, "MI_RA3",
2775 SPR_NOACCESS, SPR_NOACCESS,
2776 &spr_read_generic, &spr_write_generic,
2778 /* XXX : not implemented */
2779 spr_register(env, SPR_RCPU_L2U_RA0, "L2U_RA0",
2780 SPR_NOACCESS, SPR_NOACCESS,
2781 &spr_read_generic, &spr_write_generic,
2783 /* XXX : not implemented */
2784 spr_register(env, SPR_RCPU_L2U_RA1, "L2U_RA1",
2785 SPR_NOACCESS, SPR_NOACCESS,
2786 &spr_read_generic, &spr_write_generic,
2788 /* XXX : not implemented */
2789 spr_register(env, SPR_RCPU_L2U_RA2, "L2U_RA2",
2790 SPR_NOACCESS, SPR_NOACCESS,
2791 &spr_read_generic, &spr_write_generic,
2793 /* XXX : not implemented */
2794 spr_register(env, SPR_RCPU_L2U_RA3, "L2U_RA3",
2795 SPR_NOACCESS, SPR_NOACCESS,
2796 &spr_read_generic, &spr_write_generic,
2798 /* XXX : not implemented */
2799 spr_register(env, SPR_RCPU_FPECR, "FPECR",
2800 SPR_NOACCESS, SPR_NOACCESS,
2801 &spr_read_generic, &spr_write_generic,
2805 static void gen_spr_8xx(CPUPPCState *env)
2807 /* XXX : not implemented */
2808 spr_register(env, SPR_MPC_IC_CST, "IC_CST",
2809 SPR_NOACCESS, SPR_NOACCESS,
2810 &spr_read_generic, &spr_write_generic,
2812 /* XXX : not implemented */
2813 spr_register(env, SPR_MPC_IC_ADR, "IC_ADR",
2814 SPR_NOACCESS, SPR_NOACCESS,
2815 &spr_read_generic, &spr_write_generic,
2817 /* XXX : not implemented */
2818 spr_register(env, SPR_MPC_IC_DAT, "IC_DAT",
2819 SPR_NOACCESS, SPR_NOACCESS,
2820 &spr_read_generic, &spr_write_generic,
2822 /* XXX : not implemented */
2823 spr_register(env, SPR_MPC_DC_CST, "DC_CST",
2824 SPR_NOACCESS, SPR_NOACCESS,
2825 &spr_read_generic, &spr_write_generic,
2827 /* XXX : not implemented */
2828 spr_register(env, SPR_MPC_DC_ADR, "DC_ADR",
2829 SPR_NOACCESS, SPR_NOACCESS,
2830 &spr_read_generic, &spr_write_generic,
2832 /* XXX : not implemented */
2833 spr_register(env, SPR_MPC_DC_DAT, "DC_DAT",
2834 SPR_NOACCESS, SPR_NOACCESS,
2835 &spr_read_generic, &spr_write_generic,
2837 /* XXX : not implemented */
2838 spr_register(env, SPR_MPC_MI_CTR, "MI_CTR",
2839 SPR_NOACCESS, SPR_NOACCESS,
2840 &spr_read_generic, &spr_write_generic,
2842 /* XXX : not implemented */
2843 spr_register(env, SPR_MPC_MI_AP, "MI_AP",
2844 SPR_NOACCESS, SPR_NOACCESS,
2845 &spr_read_generic, &spr_write_generic,
2847 /* XXX : not implemented */
2848 spr_register(env, SPR_MPC_MI_EPN, "MI_EPN",
2849 SPR_NOACCESS, SPR_NOACCESS,
2850 &spr_read_generic, &spr_write_generic,
2852 /* XXX : not implemented */
2853 spr_register(env, SPR_MPC_MI_TWC, "MI_TWC",
2854 SPR_NOACCESS, SPR_NOACCESS,
2855 &spr_read_generic, &spr_write_generic,
2857 /* XXX : not implemented */
2858 spr_register(env, SPR_MPC_MI_RPN, "MI_RPN",
2859 SPR_NOACCESS, SPR_NOACCESS,
2860 &spr_read_generic, &spr_write_generic,
2862 /* XXX : not implemented */
2863 spr_register(env, SPR_MPC_MI_DBCAM, "MI_DBCAM",
2864 SPR_NOACCESS, SPR_NOACCESS,
2865 &spr_read_generic, &spr_write_generic,
2867 /* XXX : not implemented */
2868 spr_register(env, SPR_MPC_MI_DBRAM0, "MI_DBRAM0",
2869 SPR_NOACCESS, SPR_NOACCESS,
2870 &spr_read_generic, &spr_write_generic,
2872 /* XXX : not implemented */
2873 spr_register(env, SPR_MPC_MI_DBRAM1, "MI_DBRAM1",
2874 SPR_NOACCESS, SPR_NOACCESS,
2875 &spr_read_generic, &spr_write_generic,
2877 /* XXX : not implemented */
2878 spr_register(env, SPR_MPC_MD_CTR, "MD_CTR",
2879 SPR_NOACCESS, SPR_NOACCESS,
2880 &spr_read_generic, &spr_write_generic,
2882 /* XXX : not implemented */
2883 spr_register(env, SPR_MPC_MD_CASID, "MD_CASID",
2884 SPR_NOACCESS, SPR_NOACCESS,
2885 &spr_read_generic, &spr_write_generic,
2887 /* XXX : not implemented */
2888 spr_register(env, SPR_MPC_MD_AP, "MD_AP",
2889 SPR_NOACCESS, SPR_NOACCESS,
2890 &spr_read_generic, &spr_write_generic,
2892 /* XXX : not implemented */
2893 spr_register(env, SPR_MPC_MD_EPN, "MD_EPN",
2894 SPR_NOACCESS, SPR_NOACCESS,
2895 &spr_read_generic, &spr_write_generic,
2897 /* XXX : not implemented */
2898 spr_register(env, SPR_MPC_MD_TWB, "MD_TWB",
2899 SPR_NOACCESS, SPR_NOACCESS,
2900 &spr_read_generic, &spr_write_generic,
2902 /* XXX : not implemented */
2903 spr_register(env, SPR_MPC_MD_TWC, "MD_TWC",
2904 SPR_NOACCESS, SPR_NOACCESS,
2905 &spr_read_generic, &spr_write_generic,
2907 /* XXX : not implemented */
2908 spr_register(env, SPR_MPC_MD_RPN, "MD_RPN",
2909 SPR_NOACCESS, SPR_NOACCESS,
2910 &spr_read_generic, &spr_write_generic,
2912 /* XXX : not implemented */
2913 spr_register(env, SPR_MPC_MD_TW, "MD_TW",
2914 SPR_NOACCESS, SPR_NOACCESS,
2915 &spr_read_generic, &spr_write_generic,
2917 /* XXX : not implemented */
2918 spr_register(env, SPR_MPC_MD_DBCAM, "MD_DBCAM",
2919 SPR_NOACCESS, SPR_NOACCESS,
2920 &spr_read_generic, &spr_write_generic,
2922 /* XXX : not implemented */
2923 spr_register(env, SPR_MPC_MD_DBRAM0, "MD_DBRAM0",
2924 SPR_NOACCESS, SPR_NOACCESS,
2925 &spr_read_generic, &spr_write_generic,
2927 /* XXX : not implemented */
2928 spr_register(env, SPR_MPC_MD_DBRAM1, "MD_DBRAM1",
2929 SPR_NOACCESS, SPR_NOACCESS,
2930 &spr_read_generic, &spr_write_generic,
2935 * AMR => SPR 29 (Power 2.04)
2936 * CTRL => SPR 136 (Power 2.04)
2937 * CTRL => SPR 152 (Power 2.04)
2938 * SCOMC => SPR 276 (64 bits ?)
2939 * SCOMD => SPR 277 (64 bits ?)
2940 * TBU40 => SPR 286 (Power 2.04 hypv)
2941 * HSPRG0 => SPR 304 (Power 2.04 hypv)
2942 * HSPRG1 => SPR 305 (Power 2.04 hypv)
2943 * HDSISR => SPR 306 (Power 2.04 hypv)
2944 * HDAR => SPR 307 (Power 2.04 hypv)
2945 * PURR => SPR 309 (Power 2.04 hypv)
2946 * HDEC => SPR 310 (Power 2.04 hypv)
2947 * HIOR => SPR 311 (hypv)
2948 * RMOR => SPR 312 (970)
2949 * HRMOR => SPR 313 (Power 2.04 hypv)
2950 * HSRR0 => SPR 314 (Power 2.04 hypv)
2951 * HSRR1 => SPR 315 (Power 2.04 hypv)
2952 * LPIDR => SPR 317 (970)
2953 * EPR => SPR 702 (Power 2.04 emb)
2954 * perf => 768-783 (Power 2.04)
2955 * perf => 784-799 (Power 2.04)
2956 * PPR => SPR 896 (Power 2.04)
2957 * DABRX => 1015 (Power 2.04 hypv)
2958 * FPECR => SPR 1022 (?)
2959 * ... and more (thermal management, performance counters, ...)
2962 /*****************************************************************************/
2963 /* Exception vectors models */
2964 static void init_excp_4xx_real(CPUPPCState *env)
2966 #if !defined(CONFIG_USER_ONLY)
2967 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000100;
2968 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
2969 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
2970 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
2971 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
2972 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
2973 env->excp_vectors[POWERPC_EXCP_PIT] = 0x00001000;
2974 env->excp_vectors[POWERPC_EXCP_FIT] = 0x00001010;
2975 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001020;
2976 env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000;
2977 env->ivor_mask = 0x0000FFF0UL;
2978 env->ivpr_mask = 0xFFFF0000UL;
2979 /* Hardware reset vector */
2980 env->hreset_vector = 0xFFFFFFFCUL;
2984 static void init_excp_4xx_softmmu(CPUPPCState *env)
2986 #if !defined(CONFIG_USER_ONLY)
2987 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000100;
2988 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
2989 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
2990 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
2991 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
2992 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
2993 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
2994 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
2995 env->excp_vectors[POWERPC_EXCP_PIT] = 0x00001000;
2996 env->excp_vectors[POWERPC_EXCP_FIT] = 0x00001010;
2997 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001020;
2998 env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001100;
2999 env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001200;
3000 env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000;
3001 env->ivor_mask = 0x0000FFF0UL;
3002 env->ivpr_mask = 0xFFFF0000UL;
3003 /* Hardware reset vector */
3004 env->hreset_vector = 0xFFFFFFFCUL;
3008 static void init_excp_MPC5xx(CPUPPCState *env)
3010 #if !defined(CONFIG_USER_ONLY)
3011 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3012 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3013 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3014 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3015 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3016 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000900;
3017 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3018 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3019 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3020 env->excp_vectors[POWERPC_EXCP_FPA] = 0x00000E00;
3021 env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001000;
3022 env->excp_vectors[POWERPC_EXCP_DABR] = 0x00001C00;
3023 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001C00;
3024 env->excp_vectors[POWERPC_EXCP_MEXTBR] = 0x00001E00;
3025 env->excp_vectors[POWERPC_EXCP_NMEXTBR] = 0x00001F00;
3026 env->ivor_mask = 0x0000FFF0UL;
3027 env->ivpr_mask = 0xFFFF0000UL;
3028 /* Hardware reset vector */
3029 env->hreset_vector = 0x00000100UL;
3033 static void init_excp_MPC8xx(CPUPPCState *env)
3035 #if !defined(CONFIG_USER_ONLY)
3036 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3037 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3038 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3039 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3040 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3041 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3042 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3043 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000900;
3044 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3045 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3046 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3047 env->excp_vectors[POWERPC_EXCP_FPA] = 0x00000E00;
3048 env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001000;
3049 env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001100;
3050 env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001200;
3051 env->excp_vectors[POWERPC_EXCP_ITLBE] = 0x00001300;
3052 env->excp_vectors[POWERPC_EXCP_DTLBE] = 0x00001400;
3053 env->excp_vectors[POWERPC_EXCP_DABR] = 0x00001C00;
3054 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001C00;
3055 env->excp_vectors[POWERPC_EXCP_MEXTBR] = 0x00001E00;
3056 env->excp_vectors[POWERPC_EXCP_NMEXTBR] = 0x00001F00;
3057 env->ivor_mask = 0x0000FFF0UL;
3058 env->ivpr_mask = 0xFFFF0000UL;
3059 /* Hardware reset vector */
3060 env->hreset_vector = 0x00000100UL;
3064 static void init_excp_G2(CPUPPCState *env)
3066 #if !defined(CONFIG_USER_ONLY)
3067 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3068 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3069 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3070 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3071 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3072 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3073 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3074 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3075 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3076 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000A00;
3077 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3078 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3079 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
3080 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
3081 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
3082 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3083 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3084 /* Hardware reset vector */
3085 env->hreset_vector = 0x00000100UL;
3089 static void init_excp_e200(CPUPPCState *env, target_ulong ivpr_mask)
3091 #if !defined(CONFIG_USER_ONLY)
3092 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000FFC;
3093 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000000;
3094 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000000;
3095 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000000;
3096 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000000;
3097 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000000;
3098 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000000;
3099 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000000;
3100 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000000;
3101 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000000;
3102 env->excp_vectors[POWERPC_EXCP_APU] = 0x00000000;
3103 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000000;
3104 env->excp_vectors[POWERPC_EXCP_FIT] = 0x00000000;
3105 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00000000;
3106 env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00000000;
3107 env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00000000;
3108 env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00000000;
3109 env->excp_vectors[POWERPC_EXCP_SPEU] = 0x00000000;
3110 env->excp_vectors[POWERPC_EXCP_EFPDI] = 0x00000000;
3111 env->excp_vectors[POWERPC_EXCP_EFPRI] = 0x00000000;
3112 env->ivor_mask = 0x0000FFF7UL;
3113 env->ivpr_mask = ivpr_mask;
3114 /* Hardware reset vector */
3115 env->hreset_vector = 0xFFFFFFFCUL;
3119 static void init_excp_BookE(CPUPPCState *env)
3121 #if !defined(CONFIG_USER_ONLY)
3122 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000000;
3123 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000000;
3124 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000000;
3125 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000000;
3126 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000000;
3127 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000000;
3128 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000000;
3129 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000000;
3130 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000000;
3131 env->excp_vectors[POWERPC_EXCP_APU] = 0x00000000;
3132 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000000;
3133 env->excp_vectors[POWERPC_EXCP_FIT] = 0x00000000;
3134 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00000000;
3135 env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00000000;
3136 env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00000000;
3137 env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00000000;
3138 env->ivor_mask = 0x0000FFF0UL;
3139 env->ivpr_mask = 0xFFFF0000UL;
3140 /* Hardware reset vector */
3141 env->hreset_vector = 0xFFFFFFFCUL;
3145 static void init_excp_601(CPUPPCState *env)
3147 #if !defined(CONFIG_USER_ONLY)
3148 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3149 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3150 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3151 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3152 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3153 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3154 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3155 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3156 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3157 env->excp_vectors[POWERPC_EXCP_IO] = 0x00000A00;
3158 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3159 env->excp_vectors[POWERPC_EXCP_RUNM] = 0x00002000;
3160 /* Hardware reset vector */
3161 env->hreset_vector = 0x00000100UL;
3165 static void init_excp_602(CPUPPCState *env)
3167 #if !defined(CONFIG_USER_ONLY)
3168 /* XXX: exception prefix has a special behavior on 602 */
3169 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3170 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3171 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3172 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3173 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3174 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3175 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3176 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3177 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3178 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3179 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3180 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
3181 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
3182 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
3183 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3184 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3185 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001500;
3186 env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001600;
3187 /* Hardware reset vector */
3188 env->hreset_vector = 0x00000100UL;
3192 static void init_excp_603(CPUPPCState *env)
3194 #if !defined(CONFIG_USER_ONLY)
3195 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3196 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3197 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3198 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3199 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3200 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3201 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3202 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3203 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3204 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3205 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3206 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
3207 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
3208 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
3209 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3210 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3211 /* Hardware reset vector */
3212 env->hreset_vector = 0x00000100UL;
3216 static void init_excp_604(CPUPPCState *env)
3218 #if !defined(CONFIG_USER_ONLY)
3219 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3220 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3221 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3222 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3223 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3224 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3225 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3226 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3227 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3228 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3229 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3230 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3231 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3232 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3233 /* Hardware reset vector */
3234 env->hreset_vector = 0x00000100UL;
3238 static void init_excp_7x0(CPUPPCState *env)
3240 #if !defined(CONFIG_USER_ONLY)
3241 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3242 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3243 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3244 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3245 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3246 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3247 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3248 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3249 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3250 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3251 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3252 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3253 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3254 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3255 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
3256 /* Hardware reset vector */
3257 env->hreset_vector = 0x00000100UL;
3261 static void init_excp_750cl(CPUPPCState *env)
3263 #if !defined(CONFIG_USER_ONLY)
3264 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3265 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3266 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3267 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3268 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3269 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3270 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3271 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3272 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3273 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3274 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3275 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3276 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3277 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3278 /* Hardware reset vector */
3279 env->hreset_vector = 0x00000100UL;
3283 static void init_excp_750cx(CPUPPCState *env)
3285 #if !defined(CONFIG_USER_ONLY)
3286 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3287 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3288 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3289 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3290 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3291 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3292 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3293 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3294 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3295 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3296 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3297 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3298 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3299 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
3300 /* Hardware reset vector */
3301 env->hreset_vector = 0x00000100UL;
3305 /* XXX: Check if this is correct */
3306 static void init_excp_7x5(CPUPPCState *env)
3308 #if !defined(CONFIG_USER_ONLY)
3309 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3310 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3311 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3312 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3313 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3314 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3315 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3316 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3317 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3318 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3319 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3320 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3321 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
3322 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
3323 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
3324 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3325 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3326 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
3327 /* Hardware reset vector */
3328 env->hreset_vector = 0x00000100UL;
3332 static void init_excp_7400(CPUPPCState *env)
3334 #if !defined(CONFIG_USER_ONLY)
3335 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3336 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3337 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3338 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3339 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3340 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3341 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3342 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3343 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3344 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3345 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3346 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3347 env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
3348 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3349 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3350 env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600;
3351 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
3352 /* Hardware reset vector */
3353 env->hreset_vector = 0x00000100UL;
3357 static void init_excp_7450(CPUPPCState *env)
3359 #if !defined(CONFIG_USER_ONLY)
3360 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3361 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3362 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3363 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3364 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3365 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3366 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3367 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3368 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3369 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3370 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3371 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3372 env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
3373 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
3374 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
3375 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
3376 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3377 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3378 env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600;
3379 /* Hardware reset vector */
3380 env->hreset_vector = 0x00000100UL;
3384 #if defined(TARGET_PPC64)
3385 static void init_excp_970(CPUPPCState *env)
3387 #if !defined(CONFIG_USER_ONLY)
3388 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3389 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3390 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3391 env->excp_vectors[POWERPC_EXCP_DSEG] = 0x00000380;
3392 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3393 env->excp_vectors[POWERPC_EXCP_ISEG] = 0x00000480;
3394 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3395 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3396 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3397 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3398 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3399 env->excp_vectors[POWERPC_EXCP_HDECR] = 0x00000980;
3400 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3401 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3402 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3403 env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
3404 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3405 env->excp_vectors[POWERPC_EXCP_MAINT] = 0x00001600;
3406 env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001700;
3407 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001800;
3408 /* Hardware reset vector */
3409 env->hreset_vector = 0x0000000000000100ULL;
3413 static void init_excp_POWER7(CPUPPCState *env)
3415 #if !defined(CONFIG_USER_ONLY)
3416 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3417 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3418 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3419 env->excp_vectors[POWERPC_EXCP_DSEG] = 0x00000380;
3420 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3421 env->excp_vectors[POWERPC_EXCP_ISEG] = 0x00000480;
3422 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3423 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3424 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3425 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3426 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3427 env->excp_vectors[POWERPC_EXCP_HDECR] = 0x00000980;
3428 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3429 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3430 env->excp_vectors[POWERPC_EXCP_HDSI] = 0x00000E00;
3431 env->excp_vectors[POWERPC_EXCP_HISI] = 0x00000E20;
3432 env->excp_vectors[POWERPC_EXCP_HV_EMU] = 0x00000E40;
3433 env->excp_vectors[POWERPC_EXCP_HV_MAINT] = 0x00000E60;
3434 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3435 env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
3436 env->excp_vectors[POWERPC_EXCP_VSXU] = 0x00000F40;
3437 /* Hardware reset vector */
3438 env->hreset_vector = 0x0000000000000100ULL;
3442 static void init_excp_POWER8(CPUPPCState *env)
3444 init_excp_POWER7(env);
3446 #if !defined(CONFIG_USER_ONLY)
3447 env->excp_vectors[POWERPC_EXCP_SDOOR] = 0x00000A00;
3448 env->excp_vectors[POWERPC_EXCP_FU] = 0x00000F60;
3449 env->excp_vectors[POWERPC_EXCP_HV_FU] = 0x00000F80;
3450 env->excp_vectors[POWERPC_EXCP_SDOOR_HV] = 0x00000E80;
3454 static void init_excp_POWER9(CPUPPCState *env)
3456 init_excp_POWER8(env);
3458 #if !defined(CONFIG_USER_ONLY)
3459 env->excp_vectors[POWERPC_EXCP_HVIRT] = 0x00000EA0;
3460 env->excp_vectors[POWERPC_EXCP_SYSCALL_VECTORED] = 0x00000000;
3464 static void init_excp_POWER10(CPUPPCState *env)
3466 init_excp_POWER9(env);
3471 /*****************************************************************************/
3472 /* Power management enable checks */
3473 static int check_pow_none(CPUPPCState *env)
3478 static int check_pow_nocheck(CPUPPCState *env)
3483 static int check_pow_hid0(CPUPPCState *env)
3485 if (env->spr[SPR_HID0] & 0x00E00000) {
3492 static int check_pow_hid0_74xx(CPUPPCState *env)
3494 if (env->spr[SPR_HID0] & 0x00600000) {
3501 static bool ppc_cpu_interrupts_big_endian_always(PowerPCCPU *cpu)
3507 static bool ppc_cpu_interrupts_big_endian_lpcr(PowerPCCPU *cpu)
3509 return !(cpu->env.spr[SPR_LPCR] & LPCR_ILE);
3513 /*****************************************************************************/
3514 /* PowerPC implementations definitions */
3516 #define POWERPC_FAMILY(_name) \
3518 glue(glue(ppc_, _name), _cpu_family_class_init)(ObjectClass *, void *); \
3520 static const TypeInfo \
3521 glue(glue(ppc_, _name), _cpu_family_type_info) = { \
3522 .name = stringify(_name) "-family-" TYPE_POWERPC_CPU, \
3523 .parent = TYPE_POWERPC_CPU, \
3525 .class_init = glue(glue(ppc_, _name), _cpu_family_class_init), \
3528 static void glue(glue(ppc_, _name), _cpu_family_register_types)(void) \
3530 type_register_static( \
3531 &glue(glue(ppc_, _name), _cpu_family_type_info)); \
3534 type_init(glue(glue(ppc_, _name), _cpu_family_register_types)) \
3536 static void glue(glue(ppc_, _name), _cpu_family_class_init)
3538 static void init_proc_401(CPUPPCState *env)
3541 gen_spr_401_403(env);
3543 init_excp_4xx_real(env);
3544 env->dcache_line_size = 32;
3545 env->icache_line_size = 32;
3546 /* Allocate hardware IRQ controller */
3547 ppc40x_irq_init(env_archcpu(env));
3549 SET_FIT_PERIOD(12, 16, 20, 24);
3550 SET_WDT_PERIOD(16, 20, 24, 28);
3553 POWERPC_FAMILY(401)(ObjectClass *oc, void *data)
3555 DeviceClass *dc = DEVICE_CLASS(oc);
3556 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3558 dc->desc = "PowerPC 401";
3559 pcc->init_proc = init_proc_401;
3560 pcc->check_pow = check_pow_nocheck;
3561 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3562 PPC_WRTEE | PPC_DCR |
3563 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3565 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3566 PPC_4xx_COMMON | PPC_40x_EXCP;
3567 pcc->msr_mask = (1ull << MSR_KEY) |
3576 pcc->mmu_model = POWERPC_MMU_REAL;
3577 pcc->excp_model = POWERPC_EXCP_40x;
3578 pcc->bus_model = PPC_FLAGS_INPUT_401;
3579 pcc->bfd_mach = bfd_mach_ppc_403;
3580 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3581 POWERPC_FLAG_BUS_CLK;
3584 static void init_proc_401x2(CPUPPCState *env)
3587 gen_spr_401_403(env);
3589 gen_spr_compress(env);
3590 /* Memory management */
3591 #if !defined(CONFIG_USER_ONLY)
3595 env->tlb_type = TLB_EMB;
3597 init_excp_4xx_softmmu(env);
3598 env->dcache_line_size = 32;
3599 env->icache_line_size = 32;
3600 /* Allocate hardware IRQ controller */
3601 ppc40x_irq_init(env_archcpu(env));
3603 SET_FIT_PERIOD(12, 16, 20, 24);
3604 SET_WDT_PERIOD(16, 20, 24, 28);
3607 POWERPC_FAMILY(401x2)(ObjectClass *oc, void *data)
3609 DeviceClass *dc = DEVICE_CLASS(oc);
3610 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3612 dc->desc = "PowerPC 401x2";
3613 pcc->init_proc = init_proc_401x2;
3614 pcc->check_pow = check_pow_nocheck;
3615 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
3616 PPC_DCR | PPC_WRTEE |
3617 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3618 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3619 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3620 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3621 PPC_4xx_COMMON | PPC_40x_EXCP;
3622 pcc->msr_mask = (1ull << 20) |
3634 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3635 pcc->excp_model = POWERPC_EXCP_40x;
3636 pcc->bus_model = PPC_FLAGS_INPUT_401;
3637 pcc->bfd_mach = bfd_mach_ppc_403;
3638 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3639 POWERPC_FLAG_BUS_CLK;
3642 static void init_proc_401x3(CPUPPCState *env)
3645 gen_spr_401_403(env);
3648 gen_spr_compress(env);
3649 init_excp_4xx_softmmu(env);
3650 env->dcache_line_size = 32;
3651 env->icache_line_size = 32;
3652 /* Allocate hardware IRQ controller */
3653 ppc40x_irq_init(env_archcpu(env));
3655 SET_FIT_PERIOD(12, 16, 20, 24);
3656 SET_WDT_PERIOD(16, 20, 24, 28);
3659 POWERPC_FAMILY(401x3)(ObjectClass *oc, void *data)
3661 DeviceClass *dc = DEVICE_CLASS(oc);
3662 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3664 dc->desc = "PowerPC 401x3";
3665 pcc->init_proc = init_proc_401x3;
3666 pcc->check_pow = check_pow_nocheck;
3667 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
3668 PPC_DCR | PPC_WRTEE |
3669 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3670 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3671 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3672 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3673 PPC_4xx_COMMON | PPC_40x_EXCP;
3674 pcc->msr_mask = (1ull << 20) |
3687 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3688 pcc->excp_model = POWERPC_EXCP_40x;
3689 pcc->bus_model = PPC_FLAGS_INPUT_401;
3690 pcc->bfd_mach = bfd_mach_ppc_403;
3691 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3692 POWERPC_FLAG_BUS_CLK;
3695 static void init_proc_IOP480(CPUPPCState *env)
3698 gen_spr_401_403(env);
3700 gen_spr_compress(env);
3701 /* Memory management */
3702 #if !defined(CONFIG_USER_ONLY)
3706 env->tlb_type = TLB_EMB;
3708 init_excp_4xx_softmmu(env);
3709 env->dcache_line_size = 32;
3710 env->icache_line_size = 32;
3711 /* Allocate hardware IRQ controller */
3712 ppc40x_irq_init(env_archcpu(env));
3714 SET_FIT_PERIOD(8, 12, 16, 20);
3715 SET_WDT_PERIOD(16, 20, 24, 28);
3718 POWERPC_FAMILY(IOP480)(ObjectClass *oc, void *data)
3720 DeviceClass *dc = DEVICE_CLASS(oc);
3721 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3723 dc->desc = "IOP480";
3724 pcc->init_proc = init_proc_IOP480;
3725 pcc->check_pow = check_pow_nocheck;
3726 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3727 PPC_DCR | PPC_WRTEE |
3728 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3729 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3730 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3731 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3732 PPC_4xx_COMMON | PPC_40x_EXCP;
3733 pcc->msr_mask = (1ull << 20) |
3745 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3746 pcc->excp_model = POWERPC_EXCP_40x;
3747 pcc->bus_model = PPC_FLAGS_INPUT_401;
3748 pcc->bfd_mach = bfd_mach_ppc_403;
3749 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3750 POWERPC_FLAG_BUS_CLK;
3753 static void init_proc_403(CPUPPCState *env)
3756 gen_spr_401_403(env);
3758 gen_spr_403_real(env);
3759 init_excp_4xx_real(env);
3760 env->dcache_line_size = 32;
3761 env->icache_line_size = 32;
3762 /* Allocate hardware IRQ controller */
3763 ppc40x_irq_init(env_archcpu(env));
3765 SET_FIT_PERIOD(8, 12, 16, 20);
3766 SET_WDT_PERIOD(16, 20, 24, 28);
3769 POWERPC_FAMILY(403)(ObjectClass *oc, void *data)
3771 DeviceClass *dc = DEVICE_CLASS(oc);
3772 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3774 dc->desc = "PowerPC 403";
3775 pcc->init_proc = init_proc_403;
3776 pcc->check_pow = check_pow_nocheck;
3777 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3778 PPC_DCR | PPC_WRTEE |
3779 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3781 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3782 PPC_4xx_COMMON | PPC_40x_EXCP;
3783 pcc->msr_mask = (1ull << MSR_POW) |
3792 pcc->mmu_model = POWERPC_MMU_REAL;
3793 pcc->excp_model = POWERPC_EXCP_40x;
3794 pcc->bus_model = PPC_FLAGS_INPUT_401;
3795 pcc->bfd_mach = bfd_mach_ppc_403;
3796 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_PX |
3797 POWERPC_FLAG_BUS_CLK;
3800 static void init_proc_403GCX(CPUPPCState *env)
3803 gen_spr_401_403(env);
3805 gen_spr_403_real(env);
3806 gen_spr_403_mmu(env);
3807 /* Bus access control */
3808 /* not emulated, as QEMU never does speculative access */
3809 spr_register(env, SPR_40x_SGR, "SGR",
3810 SPR_NOACCESS, SPR_NOACCESS,
3811 &spr_read_generic, &spr_write_generic,
3813 /* not emulated, as QEMU do not emulate caches */
3814 spr_register(env, SPR_40x_DCWR, "DCWR",
3815 SPR_NOACCESS, SPR_NOACCESS,
3816 &spr_read_generic, &spr_write_generic,
3818 /* Memory management */
3819 #if !defined(CONFIG_USER_ONLY)
3823 env->tlb_type = TLB_EMB;
3825 init_excp_4xx_softmmu(env);
3826 env->dcache_line_size = 32;
3827 env->icache_line_size = 32;
3828 /* Allocate hardware IRQ controller */
3829 ppc40x_irq_init(env_archcpu(env));
3831 SET_FIT_PERIOD(8, 12, 16, 20);
3832 SET_WDT_PERIOD(16, 20, 24, 28);
3835 POWERPC_FAMILY(403GCX)(ObjectClass *oc, void *data)
3837 DeviceClass *dc = DEVICE_CLASS(oc);
3838 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3840 dc->desc = "PowerPC 403 GCX";
3841 pcc->init_proc = init_proc_403GCX;
3842 pcc->check_pow = check_pow_nocheck;
3843 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3844 PPC_DCR | PPC_WRTEE |
3845 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3847 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3848 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3849 PPC_4xx_COMMON | PPC_40x_EXCP;
3850 pcc->msr_mask = (1ull << MSR_POW) |
3859 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3860 pcc->excp_model = POWERPC_EXCP_40x;
3861 pcc->bus_model = PPC_FLAGS_INPUT_401;
3862 pcc->bfd_mach = bfd_mach_ppc_403;
3863 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_PX |
3864 POWERPC_FLAG_BUS_CLK;
3867 static void init_proc_405(CPUPPCState *env)
3873 /* Bus access control */
3874 /* not emulated, as QEMU never does speculative access */
3875 spr_register(env, SPR_40x_SGR, "SGR",
3876 SPR_NOACCESS, SPR_NOACCESS,
3877 &spr_read_generic, &spr_write_generic,
3879 /* not emulated, as QEMU do not emulate caches */
3880 spr_register(env, SPR_40x_DCWR, "DCWR",
3881 SPR_NOACCESS, SPR_NOACCESS,
3882 &spr_read_generic, &spr_write_generic,
3884 /* Memory management */
3885 #if !defined(CONFIG_USER_ONLY)
3889 env->tlb_type = TLB_EMB;
3891 init_excp_4xx_softmmu(env);
3892 env->dcache_line_size = 32;
3893 env->icache_line_size = 32;
3894 /* Allocate hardware IRQ controller */
3895 ppc40x_irq_init(env_archcpu(env));
3897 SET_FIT_PERIOD(8, 12, 16, 20);
3898 SET_WDT_PERIOD(16, 20, 24, 28);
3901 POWERPC_FAMILY(405)(ObjectClass *oc, void *data)
3903 DeviceClass *dc = DEVICE_CLASS(oc);
3904 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3906 dc->desc = "PowerPC 405";
3907 pcc->init_proc = init_proc_405;
3908 pcc->check_pow = check_pow_nocheck;
3909 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
3910 PPC_DCR | PPC_WRTEE |
3911 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3912 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3913 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3914 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3915 PPC_4xx_COMMON | PPC_405_MAC | PPC_40x_EXCP;
3916 pcc->msr_mask = (1ull << MSR_POW) |
3925 pcc->mmu_model = POWERPC_MMU_SOFT_4xx;
3926 pcc->excp_model = POWERPC_EXCP_40x;
3927 pcc->bus_model = PPC_FLAGS_INPUT_405;
3928 pcc->bfd_mach = bfd_mach_ppc_403;
3929 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
3930 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
3933 static void init_proc_440EP(CPUPPCState *env)
3937 gen_spr_BookE(env, 0x000000000000FFFFULL);
3939 gen_spr_usprgh(env);
3940 /* Processor identification */
3941 spr_register(env, SPR_BOOKE_PIR, "PIR",
3942 SPR_NOACCESS, SPR_NOACCESS,
3943 &spr_read_generic, &spr_write_pir,
3945 /* XXX : not implemented */
3946 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
3947 SPR_NOACCESS, SPR_NOACCESS,
3948 &spr_read_generic, &spr_write_generic,
3950 /* XXX : not implemented */
3951 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
3952 SPR_NOACCESS, SPR_NOACCESS,
3953 &spr_read_generic, &spr_write_generic,
3955 /* XXX : not implemented */
3956 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
3957 SPR_NOACCESS, SPR_NOACCESS,
3958 &spr_read_generic, &spr_write_generic,
3960 /* XXX : not implemented */
3961 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
3962 SPR_NOACCESS, SPR_NOACCESS,
3963 &spr_read_generic, &spr_write_generic,
3965 /* XXX : not implemented */
3966 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
3967 SPR_NOACCESS, SPR_NOACCESS,
3968 &spr_read_generic, &spr_write_generic,
3970 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
3971 SPR_NOACCESS, SPR_NOACCESS,
3972 &spr_read_generic, &spr_write_generic,
3974 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
3975 SPR_NOACCESS, SPR_NOACCESS,
3976 &spr_read_generic, &spr_write_generic,
3978 /* XXX : not implemented */
3979 spr_register(env, SPR_440_CCR1, "CCR1",
3980 SPR_NOACCESS, SPR_NOACCESS,
3981 &spr_read_generic, &spr_write_generic,
3983 /* Memory management */
3984 #if !defined(CONFIG_USER_ONLY)
3988 env->tlb_type = TLB_EMB;
3990 init_excp_BookE(env);
3991 env->dcache_line_size = 32;
3992 env->icache_line_size = 32;
3993 ppc40x_irq_init(env_archcpu(env));
3995 SET_FIT_PERIOD(12, 16, 20, 24);
3996 SET_WDT_PERIOD(20, 24, 28, 32);
3999 POWERPC_FAMILY(440EP)(ObjectClass *oc, void *data)
4001 DeviceClass *dc = DEVICE_CLASS(oc);
4002 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4004 dc->desc = "PowerPC 440 EP";
4005 pcc->init_proc = init_proc_440EP;
4006 pcc->check_pow = check_pow_nocheck;
4007 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4008 PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL |
4009 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
4011 PPC_DCR | PPC_WRTEE | PPC_RFMCI |
4012 PPC_CACHE | PPC_CACHE_ICBI |
4013 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4014 PPC_MEM_TLBSYNC | PPC_MFTB |
4015 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4017 pcc->msr_mask = (1ull << MSR_POW) |
4029 pcc->mmu_model = POWERPC_MMU_BOOKE;
4030 pcc->excp_model = POWERPC_EXCP_BOOKE;
4031 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4032 pcc->bfd_mach = bfd_mach_ppc_403;
4033 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4034 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
4037 POWERPC_FAMILY(460EX)(ObjectClass *oc, void *data)
4039 DeviceClass *dc = DEVICE_CLASS(oc);
4040 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4042 dc->desc = "PowerPC 460 EX";
4043 pcc->init_proc = init_proc_440EP;
4044 pcc->check_pow = check_pow_nocheck;
4045 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4046 PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL |
4047 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
4049 PPC_DCR | PPC_DCRX | PPC_WRTEE | PPC_RFMCI |
4050 PPC_CACHE | PPC_CACHE_ICBI |
4051 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4052 PPC_MEM_TLBSYNC | PPC_MFTB |
4053 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4055 pcc->msr_mask = (1ull << MSR_POW) |
4067 pcc->mmu_model = POWERPC_MMU_BOOKE;
4068 pcc->excp_model = POWERPC_EXCP_BOOKE;
4069 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4070 pcc->bfd_mach = bfd_mach_ppc_403;
4071 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4072 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
4075 static void init_proc_440GP(CPUPPCState *env)
4079 gen_spr_BookE(env, 0x000000000000FFFFULL);
4081 gen_spr_usprgh(env);
4082 /* Processor identification */
4083 spr_register(env, SPR_BOOKE_PIR, "PIR",
4084 SPR_NOACCESS, SPR_NOACCESS,
4085 &spr_read_generic, &spr_write_pir,
4087 /* XXX : not implemented */
4088 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4089 SPR_NOACCESS, SPR_NOACCESS,
4090 &spr_read_generic, &spr_write_generic,
4092 /* XXX : not implemented */
4093 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4094 SPR_NOACCESS, SPR_NOACCESS,
4095 &spr_read_generic, &spr_write_generic,
4097 /* XXX : not implemented */
4098 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
4099 SPR_NOACCESS, SPR_NOACCESS,
4100 &spr_read_generic, &spr_write_generic,
4102 /* XXX : not implemented */
4103 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
4104 SPR_NOACCESS, SPR_NOACCESS,
4105 &spr_read_generic, &spr_write_generic,
4107 /* Memory management */
4108 #if !defined(CONFIG_USER_ONLY)
4112 env->tlb_type = TLB_EMB;
4114 init_excp_BookE(env);
4115 env->dcache_line_size = 32;
4116 env->icache_line_size = 32;
4117 /* XXX: TODO: allocate internal IRQ controller */
4119 SET_FIT_PERIOD(12, 16, 20, 24);
4120 SET_WDT_PERIOD(20, 24, 28, 32);
4123 POWERPC_FAMILY(440GP)(ObjectClass *oc, void *data)
4125 DeviceClass *dc = DEVICE_CLASS(oc);
4126 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4128 dc->desc = "PowerPC 440 GP";
4129 pcc->init_proc = init_proc_440GP;
4130 pcc->check_pow = check_pow_nocheck;
4131 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4132 PPC_DCR | PPC_DCRX | PPC_WRTEE | PPC_MFAPIDI |
4133 PPC_CACHE | PPC_CACHE_ICBI |
4134 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4135 PPC_MEM_TLBSYNC | PPC_TLBIVA | PPC_MFTB |
4136 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4138 pcc->msr_mask = (1ull << MSR_POW) |
4150 pcc->mmu_model = POWERPC_MMU_BOOKE;
4151 pcc->excp_model = POWERPC_EXCP_BOOKE;
4152 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4153 pcc->bfd_mach = bfd_mach_ppc_403;
4154 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4155 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
4158 static void init_proc_440x4(CPUPPCState *env)
4162 gen_spr_BookE(env, 0x000000000000FFFFULL);
4164 gen_spr_usprgh(env);
4165 /* Processor identification */
4166 spr_register(env, SPR_BOOKE_PIR, "PIR",
4167 SPR_NOACCESS, SPR_NOACCESS,
4168 &spr_read_generic, &spr_write_pir,
4170 /* XXX : not implemented */
4171 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4172 SPR_NOACCESS, SPR_NOACCESS,
4173 &spr_read_generic, &spr_write_generic,
4175 /* XXX : not implemented */
4176 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4177 SPR_NOACCESS, SPR_NOACCESS,
4178 &spr_read_generic, &spr_write_generic,
4180 /* XXX : not implemented */
4181 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
4182 SPR_NOACCESS, SPR_NOACCESS,
4183 &spr_read_generic, &spr_write_generic,
4185 /* XXX : not implemented */
4186 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
4187 SPR_NOACCESS, SPR_NOACCESS,
4188 &spr_read_generic, &spr_write_generic,
4190 /* Memory management */
4191 #if !defined(CONFIG_USER_ONLY)
4195 env->tlb_type = TLB_EMB;
4197 init_excp_BookE(env);
4198 env->dcache_line_size = 32;
4199 env->icache_line_size = 32;
4200 /* XXX: TODO: allocate internal IRQ controller */
4202 SET_FIT_PERIOD(12, 16, 20, 24);
4203 SET_WDT_PERIOD(20, 24, 28, 32);
4206 POWERPC_FAMILY(440x4)(ObjectClass *oc, void *data)
4208 DeviceClass *dc = DEVICE_CLASS(oc);
4209 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4211 dc->desc = "PowerPC 440x4";
4212 pcc->init_proc = init_proc_440x4;
4213 pcc->check_pow = check_pow_nocheck;
4214 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4215 PPC_DCR | PPC_WRTEE |
4216 PPC_CACHE | PPC_CACHE_ICBI |
4217 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4218 PPC_MEM_TLBSYNC | PPC_MFTB |
4219 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4221 pcc->msr_mask = (1ull << MSR_POW) |
4233 pcc->mmu_model = POWERPC_MMU_BOOKE;
4234 pcc->excp_model = POWERPC_EXCP_BOOKE;
4235 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4236 pcc->bfd_mach = bfd_mach_ppc_403;
4237 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4238 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
4241 static void init_proc_440x5(CPUPPCState *env)
4245 gen_spr_BookE(env, 0x000000000000FFFFULL);
4247 gen_spr_usprgh(env);
4248 /* Processor identification */
4249 spr_register(env, SPR_BOOKE_PIR, "PIR",
4250 SPR_NOACCESS, SPR_NOACCESS,
4251 &spr_read_generic, &spr_write_pir,
4253 /* XXX : not implemented */
4254 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4255 SPR_NOACCESS, SPR_NOACCESS,
4256 &spr_read_generic, &spr_write_generic,
4258 /* XXX : not implemented */
4259 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4260 SPR_NOACCESS, SPR_NOACCESS,
4261 &spr_read_generic, &spr_write_generic,
4263 /* XXX : not implemented */
4264 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
4265 SPR_NOACCESS, SPR_NOACCESS,
4266 &spr_read_generic, &spr_write_generic,
4268 /* XXX : not implemented */
4269 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
4270 SPR_NOACCESS, SPR_NOACCESS,
4271 &spr_read_generic, &spr_write_generic,
4273 /* XXX : not implemented */
4274 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
4275 SPR_NOACCESS, SPR_NOACCESS,
4276 &spr_read_generic, &spr_write_generic,
4278 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
4279 SPR_NOACCESS, SPR_NOACCESS,
4280 &spr_read_generic, &spr_write_generic,
4282 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
4283 SPR_NOACCESS, SPR_NOACCESS,
4284 &spr_read_generic, &spr_write_generic,
4286 /* XXX : not implemented */
4287 spr_register(env, SPR_440_CCR1, "CCR1",
4288 SPR_NOACCESS, SPR_NOACCESS,
4289 &spr_read_generic, &spr_write_generic,
4291 /* Memory management */
4292 #if !defined(CONFIG_USER_ONLY)
4296 env->tlb_type = TLB_EMB;
4298 init_excp_BookE(env);
4299 env->dcache_line_size = 32;
4300 env->icache_line_size = 32;
4301 ppc40x_irq_init(env_archcpu(env));
4303 SET_FIT_PERIOD(12, 16, 20, 24);
4304 SET_WDT_PERIOD(20, 24, 28, 32);
4307 POWERPC_FAMILY(440x5)(ObjectClass *oc, void *data)
4309 DeviceClass *dc = DEVICE_CLASS(oc);
4310 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4312 dc->desc = "PowerPC 440x5";
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_DCR | PPC_WRTEE | PPC_RFMCI |
4317 PPC_CACHE | PPC_CACHE_ICBI |
4318 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4319 PPC_MEM_TLBSYNC | PPC_MFTB |
4320 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4322 pcc->msr_mask = (1ull << MSR_POW) |
4334 pcc->mmu_model = POWERPC_MMU_BOOKE;
4335 pcc->excp_model = POWERPC_EXCP_BOOKE;
4336 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4337 pcc->bfd_mach = bfd_mach_ppc_403;
4338 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4339 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
4342 POWERPC_FAMILY(440x5wDFPU)(ObjectClass *oc, void *data)
4344 DeviceClass *dc = DEVICE_CLASS(oc);
4345 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4347 dc->desc = "PowerPC 440x5 with double precision FPU";
4348 pcc->init_proc = init_proc_440x5;
4349 pcc->check_pow = check_pow_nocheck;
4350 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4351 PPC_FLOAT | PPC_FLOAT_FSQRT |
4353 PPC_DCR | PPC_WRTEE | PPC_RFMCI |
4354 PPC_CACHE | PPC_CACHE_ICBI |
4355 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4356 PPC_MEM_TLBSYNC | PPC_MFTB |
4357 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4359 pcc->insns_flags2 = PPC2_FP_CVT_S64;
4360 pcc->msr_mask = (1ull << MSR_POW) |
4372 pcc->mmu_model = POWERPC_MMU_BOOKE;
4373 pcc->excp_model = POWERPC_EXCP_BOOKE;
4374 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4375 pcc->bfd_mach = bfd_mach_ppc_403;
4376 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4377 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
4380 static void init_proc_MPC5xx(CPUPPCState *env)
4384 gen_spr_5xx_8xx(env);
4386 init_excp_MPC5xx(env);
4387 env->dcache_line_size = 32;
4388 env->icache_line_size = 32;
4389 /* XXX: TODO: allocate internal IRQ controller */
4392 POWERPC_FAMILY(MPC5xx)(ObjectClass *oc, void *data)
4394 DeviceClass *dc = DEVICE_CLASS(oc);
4395 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4397 dc->desc = "Freescale 5xx cores (aka RCPU)";
4398 pcc->init_proc = init_proc_MPC5xx;
4399 pcc->check_pow = check_pow_none;
4400 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4401 PPC_MEM_EIEIO | PPC_MEM_SYNC |
4402 PPC_CACHE_ICBI | PPC_FLOAT | PPC_FLOAT_STFIWX |
4404 pcc->msr_mask = (1ull << MSR_ILE) |
4416 pcc->mmu_model = POWERPC_MMU_REAL;
4417 pcc->excp_model = POWERPC_EXCP_603;
4418 pcc->bus_model = PPC_FLAGS_INPUT_RCPU;
4419 pcc->bfd_mach = bfd_mach_ppc_505;
4420 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
4421 POWERPC_FLAG_BUS_CLK;
4424 static void init_proc_MPC8xx(CPUPPCState *env)
4428 gen_spr_5xx_8xx(env);
4430 init_excp_MPC8xx(env);
4431 env->dcache_line_size = 32;
4432 env->icache_line_size = 32;
4433 /* XXX: TODO: allocate internal IRQ controller */
4436 POWERPC_FAMILY(MPC8xx)(ObjectClass *oc, void *data)
4438 DeviceClass *dc = DEVICE_CLASS(oc);
4439 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4441 dc->desc = "Freescale 8xx cores (aka PowerQUICC)";
4442 pcc->init_proc = init_proc_MPC8xx;
4443 pcc->check_pow = check_pow_none;
4444 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4445 PPC_MEM_EIEIO | PPC_MEM_SYNC |
4446 PPC_CACHE_ICBI | PPC_MFTB;
4447 pcc->msr_mask = (1ull << MSR_ILE) |
4459 pcc->mmu_model = POWERPC_MMU_MPC8xx;
4460 pcc->excp_model = POWERPC_EXCP_603;
4461 pcc->bus_model = PPC_FLAGS_INPUT_RCPU;
4462 pcc->bfd_mach = bfd_mach_ppc_860;
4463 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
4464 POWERPC_FLAG_BUS_CLK;
4467 /* Freescale 82xx cores (aka PowerQUICC-II) */
4469 static void init_proc_G2(CPUPPCState *env)
4471 gen_spr_ne_601(env);
4473 gen_spr_G2_755(env);
4477 /* External access control */
4478 /* XXX : not implemented */
4479 spr_register(env, SPR_EAR, "EAR",
4480 SPR_NOACCESS, SPR_NOACCESS,
4481 &spr_read_generic, &spr_write_generic,
4483 /* Hardware implementation register */
4484 /* XXX : not implemented */
4485 spr_register(env, SPR_HID0, "HID0",
4486 SPR_NOACCESS, SPR_NOACCESS,
4487 &spr_read_generic, &spr_write_generic,
4489 /* XXX : not implemented */
4490 spr_register(env, SPR_HID1, "HID1",
4491 SPR_NOACCESS, SPR_NOACCESS,
4492 &spr_read_generic, &spr_write_generic,
4494 /* XXX : not implemented */
4495 spr_register(env, SPR_HID2, "HID2",
4496 SPR_NOACCESS, SPR_NOACCESS,
4497 &spr_read_generic, &spr_write_generic,
4499 /* Memory management */
4502 gen_6xx_7xx_soft_tlb(env, 64, 2);
4504 env->dcache_line_size = 32;
4505 env->icache_line_size = 32;
4506 /* Allocate hardware IRQ controller */
4507 ppc6xx_irq_init(env_archcpu(env));
4510 POWERPC_FAMILY(G2)(ObjectClass *oc, void *data)
4512 DeviceClass *dc = DEVICE_CLASS(oc);
4513 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4515 dc->desc = "PowerPC G2";
4516 pcc->init_proc = init_proc_G2;
4517 pcc->check_pow = check_pow_hid0;
4518 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4519 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4521 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4522 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4523 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4524 PPC_SEGMENT | PPC_EXTERN;
4525 pcc->msr_mask = (1ull << MSR_POW) |
4526 (1ull << MSR_TGPR) |
4540 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4541 pcc->excp_model = POWERPC_EXCP_G2;
4542 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4543 pcc->bfd_mach = bfd_mach_ppc_ec603e;
4544 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4545 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
4548 static void init_proc_G2LE(CPUPPCState *env)
4550 gen_spr_ne_601(env);
4552 gen_spr_G2_755(env);
4556 /* External access control */
4557 /* XXX : not implemented */
4558 spr_register(env, SPR_EAR, "EAR",
4559 SPR_NOACCESS, SPR_NOACCESS,
4560 &spr_read_generic, &spr_write_generic,
4562 /* Hardware implementation register */
4563 /* XXX : not implemented */
4564 spr_register(env, SPR_HID0, "HID0",
4565 SPR_NOACCESS, SPR_NOACCESS,
4566 &spr_read_generic, &spr_write_generic,
4568 /* XXX : not implemented */
4569 spr_register(env, SPR_HID1, "HID1",
4570 SPR_NOACCESS, SPR_NOACCESS,
4571 &spr_read_generic, &spr_write_generic,
4573 /* XXX : not implemented */
4574 spr_register(env, SPR_HID2, "HID2",
4575 SPR_NOACCESS, SPR_NOACCESS,
4576 &spr_read_generic, &spr_write_generic,
4579 /* Memory management */
4582 gen_6xx_7xx_soft_tlb(env, 64, 2);
4584 env->dcache_line_size = 32;
4585 env->icache_line_size = 32;
4586 /* Allocate hardware IRQ controller */
4587 ppc6xx_irq_init(env_archcpu(env));
4590 POWERPC_FAMILY(G2LE)(ObjectClass *oc, void *data)
4592 DeviceClass *dc = DEVICE_CLASS(oc);
4593 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4595 dc->desc = "PowerPC G2LE";
4596 pcc->init_proc = init_proc_G2LE;
4597 pcc->check_pow = check_pow_hid0;
4598 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4599 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4601 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4602 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4603 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4604 PPC_SEGMENT | PPC_EXTERN;
4605 pcc->msr_mask = (1ull << MSR_POW) |
4606 (1ull << MSR_TGPR) |
4622 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4623 pcc->excp_model = POWERPC_EXCP_G2;
4624 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4625 pcc->bfd_mach = bfd_mach_ppc_ec603e;
4626 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4627 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
4630 static void init_proc_e200(CPUPPCState *env)
4634 gen_spr_BookE(env, 0x000000070000FFFFULL);
4635 /* XXX : not implemented */
4636 spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
4637 &spr_read_spefscr, &spr_write_spefscr,
4638 &spr_read_spefscr, &spr_write_spefscr,
4640 /* Memory management */
4641 gen_spr_BookE206(env, 0x0000005D, NULL, 0);
4642 /* XXX : not implemented */
4643 spr_register(env, SPR_HID0, "HID0",
4644 SPR_NOACCESS, SPR_NOACCESS,
4645 &spr_read_generic, &spr_write_generic,
4647 /* XXX : not implemented */
4648 spr_register(env, SPR_HID1, "HID1",
4649 SPR_NOACCESS, SPR_NOACCESS,
4650 &spr_read_generic, &spr_write_generic,
4652 /* XXX : not implemented */
4653 spr_register(env, SPR_Exxx_ALTCTXCR, "ALTCTXCR",
4654 SPR_NOACCESS, SPR_NOACCESS,
4655 &spr_read_generic, &spr_write_generic,
4657 /* XXX : not implemented */
4658 spr_register(env, SPR_Exxx_BUCSR, "BUCSR",
4659 SPR_NOACCESS, SPR_NOACCESS,
4660 &spr_read_generic, &spr_write_generic,
4662 /* XXX : not implemented */
4663 spr_register(env, SPR_Exxx_CTXCR, "CTXCR",
4664 SPR_NOACCESS, SPR_NOACCESS,
4665 &spr_read_generic, &spr_write_generic,
4667 /* XXX : not implemented */
4668 spr_register(env, SPR_Exxx_DBCNT, "DBCNT",
4669 SPR_NOACCESS, SPR_NOACCESS,
4670 &spr_read_generic, &spr_write_generic,
4672 /* XXX : not implemented */
4673 spr_register(env, SPR_Exxx_DBCR3, "DBCR3",
4674 SPR_NOACCESS, SPR_NOACCESS,
4675 &spr_read_generic, &spr_write_generic,
4677 /* XXX : not implemented */
4678 spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0",
4679 &spr_read_generic, SPR_NOACCESS,
4680 &spr_read_generic, SPR_NOACCESS,
4682 /* XXX : not implemented */
4683 spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0",
4684 SPR_NOACCESS, SPR_NOACCESS,
4685 &spr_read_generic, &spr_write_generic,
4687 /* XXX : not implemented */
4688 spr_register(env, SPR_Exxx_L1FINV0, "L1FINV0",
4689 SPR_NOACCESS, SPR_NOACCESS,
4690 &spr_read_generic, &spr_write_generic,
4692 /* XXX : not implemented */
4693 spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG",
4694 SPR_NOACCESS, SPR_NOACCESS,
4695 &spr_read_generic, &spr_write_generic,
4697 /* XXX : not implemented */
4698 spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG",
4699 SPR_NOACCESS, SPR_NOACCESS,
4700 &spr_read_generic, &spr_write_generic,
4702 /* XXX : not implemented */
4703 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4704 SPR_NOACCESS, SPR_NOACCESS,
4705 &spr_read_generic, &spr_write_generic,
4707 /* XXX : not implemented */
4708 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4709 SPR_NOACCESS, SPR_NOACCESS,
4710 &spr_read_generic, &spr_write_generic,
4712 /* XXX : not implemented */
4713 spr_register(env, SPR_MMUCSR0, "MMUCSR0",
4714 SPR_NOACCESS, SPR_NOACCESS,
4715 &spr_read_generic, &spr_write_generic,
4716 0x00000000); /* TOFIX */
4717 spr_register(env, SPR_BOOKE_DSRR0, "DSRR0",
4718 SPR_NOACCESS, SPR_NOACCESS,
4719 &spr_read_generic, &spr_write_generic,
4721 spr_register(env, SPR_BOOKE_DSRR1, "DSRR1",
4722 SPR_NOACCESS, SPR_NOACCESS,
4723 &spr_read_generic, &spr_write_generic,
4725 #if !defined(CONFIG_USER_ONLY)
4729 env->tlb_type = TLB_EMB;
4731 init_excp_e200(env, 0xFFFF0000UL);
4732 env->dcache_line_size = 32;
4733 env->icache_line_size = 32;
4734 /* XXX: TODO: allocate internal IRQ controller */
4737 POWERPC_FAMILY(e200)(ObjectClass *oc, void *data)
4739 DeviceClass *dc = DEVICE_CLASS(oc);
4740 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4742 dc->desc = "e200 core";
4743 pcc->init_proc = init_proc_e200;
4744 pcc->check_pow = check_pow_hid0;
4746 * XXX: unimplemented instructions:
4753 * all SPE multiply-accumulate instructions
4755 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
4756 PPC_SPE | PPC_SPE_SINGLE |
4757 PPC_WRTEE | PPC_RFDI |
4758 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
4759 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4760 PPC_MEM_TLBSYNC | PPC_TLBIVAX |
4762 pcc->msr_mask = (1ull << MSR_UCLE) |
4776 pcc->mmu_model = POWERPC_MMU_BOOKE206;
4777 pcc->excp_model = POWERPC_EXCP_BOOKE;
4778 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4779 pcc->bfd_mach = bfd_mach_ppc_860;
4780 pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
4781 POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
4782 POWERPC_FLAG_BUS_CLK;
4785 static void init_proc_e300(CPUPPCState *env)
4787 gen_spr_ne_601(env);
4792 /* hardware implementation registers */
4793 /* XXX : not implemented */
4794 spr_register(env, SPR_HID0, "HID0",
4795 SPR_NOACCESS, SPR_NOACCESS,
4796 &spr_read_generic, &spr_write_generic,
4798 /* XXX : not implemented */
4799 spr_register(env, SPR_HID1, "HID1",
4800 SPR_NOACCESS, SPR_NOACCESS,
4801 &spr_read_generic, &spr_write_generic,
4803 /* XXX : not implemented */
4804 spr_register(env, SPR_HID2, "HID2",
4805 SPR_NOACCESS, SPR_NOACCESS,
4806 &spr_read_generic, &spr_write_generic,
4809 /* XXX : not implemented */
4810 spr_register(env, SPR_DABR, "DABR",
4811 SPR_NOACCESS, SPR_NOACCESS,
4812 &spr_read_generic, &spr_write_generic,
4814 /* XXX : not implemented */
4815 spr_register(env, SPR_DABR2, "DABR2",
4816 SPR_NOACCESS, SPR_NOACCESS,
4817 &spr_read_generic, &spr_write_generic,
4819 /* XXX : not implemented */
4820 spr_register(env, SPR_IABR2, "IABR2",
4821 SPR_NOACCESS, SPR_NOACCESS,
4822 &spr_read_generic, &spr_write_generic,
4824 /* XXX : not implemented */
4825 spr_register(env, SPR_IBCR, "IBCR",
4826 SPR_NOACCESS, SPR_NOACCESS,
4827 &spr_read_generic, &spr_write_generic,
4829 /* XXX : not implemented */
4830 spr_register(env, SPR_DBCR, "DBCR",
4831 SPR_NOACCESS, SPR_NOACCESS,
4832 &spr_read_generic, &spr_write_generic,
4834 /* Memory management */
4837 gen_6xx_7xx_soft_tlb(env, 64, 2);
4839 env->dcache_line_size = 32;
4840 env->icache_line_size = 32;
4841 /* Allocate hardware IRQ controller */
4842 ppc6xx_irq_init(env_archcpu(env));
4845 POWERPC_FAMILY(e300)(ObjectClass *oc, void *data)
4847 DeviceClass *dc = DEVICE_CLASS(oc);
4848 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4850 dc->desc = "e300 core";
4851 pcc->init_proc = init_proc_e300;
4852 pcc->check_pow = check_pow_hid0;
4853 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4854 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4856 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4857 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4858 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4859 PPC_SEGMENT | PPC_EXTERN;
4860 pcc->msr_mask = (1ull << MSR_POW) |
4861 (1ull << MSR_TGPR) |
4877 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4878 pcc->excp_model = POWERPC_EXCP_603;
4879 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4880 pcc->bfd_mach = bfd_mach_ppc_603;
4881 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4882 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
4885 #if !defined(CONFIG_USER_ONLY)
4886 static void spr_write_mas73(DisasContext *ctx, int sprn, int gprn)
4888 TCGv val = tcg_temp_new();
4889 tcg_gen_ext32u_tl(val, cpu_gpr[gprn]);
4890 gen_store_spr(SPR_BOOKE_MAS3, val);
4891 tcg_gen_shri_tl(val, cpu_gpr[gprn], 32);
4892 gen_store_spr(SPR_BOOKE_MAS7, val);
4896 static void spr_read_mas73(DisasContext *ctx, int gprn, int sprn)
4898 TCGv mas7 = tcg_temp_new();
4899 TCGv mas3 = tcg_temp_new();
4900 gen_load_spr(mas7, SPR_BOOKE_MAS7);
4901 tcg_gen_shli_tl(mas7, mas7, 32);
4902 gen_load_spr(mas3, SPR_BOOKE_MAS3);
4903 tcg_gen_or_tl(cpu_gpr[gprn], mas3, mas7);
4904 tcg_temp_free(mas3);
4905 tcg_temp_free(mas7);
4910 enum fsl_e500_version {
4918 static void init_proc_e500(CPUPPCState *env, int version)
4920 uint32_t tlbncfg[2];
4922 uint64_t ivpr_mask = 0xFFFF0000ULL;
4923 uint32_t l1cfg0 = 0x3800 /* 8 ways */
4924 | 0x0020; /* 32 kb */
4925 uint32_t l1cfg1 = 0x3800 /* 8 ways */
4926 | 0x0020; /* 32 kb */
4927 uint32_t mmucfg = 0;
4928 #if !defined(CONFIG_USER_ONLY)
4935 * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't
4936 * complain when accessing them.
4937 * gen_spr_BookE(env, 0x0000000F0000FD7FULL);
4943 ivor_mask = 0x0000000F0000FFFFULL;
4947 ivor_mask = 0x000003FE0000FFFFULL;
4950 ivor_mask = 0x000003FF0000FFFFULL;
4953 gen_spr_BookE(env, ivor_mask);
4954 gen_spr_usprg3(env);
4955 /* Processor identification */
4956 spr_register(env, SPR_BOOKE_PIR, "PIR",
4957 SPR_NOACCESS, SPR_NOACCESS,
4958 &spr_read_generic, &spr_write_pir,
4960 /* XXX : not implemented */
4961 spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
4962 &spr_read_spefscr, &spr_write_spefscr,
4963 &spr_read_spefscr, &spr_write_spefscr,
4965 #if !defined(CONFIG_USER_ONLY)
4966 /* Memory management */
4972 tlbncfg[0] = gen_tlbncfg(2, 1, 1, 0, 256);
4973 tlbncfg[1] = gen_tlbncfg(16, 1, 9, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16);
4976 tlbncfg[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4977 tlbncfg[1] = gen_tlbncfg(16, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16);
4981 tlbncfg[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4982 tlbncfg[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 64);
4987 tlbncfg[0] = 0x08052400;
4988 tlbncfg[1] = 0x40028040;
4991 cpu_abort(env_cpu(env), "Unknown CPU: " TARGET_FMT_lx "\n",
4999 env->dcache_line_size = 32;
5000 env->icache_line_size = 32;
5004 env->dcache_line_size = 64;
5005 env->icache_line_size = 64;
5006 l1cfg0 |= 0x1000000; /* 64 byte cache block size */
5007 l1cfg1 |= 0x1000000; /* 64 byte cache block size */
5010 env->dcache_line_size = 32;
5011 env->icache_line_size = 32;
5012 l1cfg0 |= 0x0F83820;
5013 l1cfg1 |= 0x0B83820;
5016 cpu_abort(env_cpu(env), "Unknown CPU: " TARGET_FMT_lx "\n",
5019 gen_spr_BookE206(env, 0x000000DF, tlbncfg, mmucfg);
5020 /* XXX : not implemented */
5021 spr_register(env, SPR_HID0, "HID0",
5022 SPR_NOACCESS, SPR_NOACCESS,
5023 &spr_read_generic, &spr_write_generic,
5025 /* XXX : not implemented */
5026 spr_register(env, SPR_HID1, "HID1",
5027 SPR_NOACCESS, SPR_NOACCESS,
5028 &spr_read_generic, &spr_write_generic,
5030 /* XXX : not implemented */
5031 spr_register(env, SPR_Exxx_BBEAR, "BBEAR",
5032 SPR_NOACCESS, SPR_NOACCESS,
5033 &spr_read_generic, &spr_write_generic,
5035 /* XXX : not implemented */
5036 spr_register(env, SPR_Exxx_BBTAR, "BBTAR",
5037 SPR_NOACCESS, SPR_NOACCESS,
5038 &spr_read_generic, &spr_write_generic,
5040 /* XXX : not implemented */
5041 spr_register(env, SPR_Exxx_MCAR, "MCAR",
5042 SPR_NOACCESS, SPR_NOACCESS,
5043 &spr_read_generic, &spr_write_generic,
5045 /* XXX : not implemented */
5046 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
5047 SPR_NOACCESS, SPR_NOACCESS,
5048 &spr_read_generic, &spr_write_generic,
5050 /* XXX : not implemented */
5051 spr_register(env, SPR_Exxx_NPIDR, "NPIDR",
5052 SPR_NOACCESS, SPR_NOACCESS,
5053 &spr_read_generic, &spr_write_generic,
5055 /* XXX : not implemented */
5056 spr_register(env, SPR_Exxx_BUCSR, "BUCSR",
5057 SPR_NOACCESS, SPR_NOACCESS,
5058 &spr_read_generic, &spr_write_generic,
5060 /* XXX : not implemented */
5061 spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0",
5062 &spr_read_generic, SPR_NOACCESS,
5063 &spr_read_generic, SPR_NOACCESS,
5065 spr_register(env, SPR_Exxx_L1CFG1, "L1CFG1",
5066 &spr_read_generic, SPR_NOACCESS,
5067 &spr_read_generic, SPR_NOACCESS,
5069 spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0",
5070 SPR_NOACCESS, SPR_NOACCESS,
5071 &spr_read_generic, &spr_write_e500_l1csr0,
5073 spr_register(env, SPR_Exxx_L1CSR1, "L1CSR1",
5074 SPR_NOACCESS, SPR_NOACCESS,
5075 &spr_read_generic, &spr_write_e500_l1csr1,
5077 if (version != fsl_e500v1 && version != fsl_e500v2) {
5078 spr_register(env, SPR_Exxx_L2CSR0, "L2CSR0",
5079 SPR_NOACCESS, SPR_NOACCESS,
5080 &spr_read_generic, &spr_write_e500_l2csr0,
5083 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
5084 SPR_NOACCESS, SPR_NOACCESS,
5085 &spr_read_generic, &spr_write_generic,
5087 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
5088 SPR_NOACCESS, SPR_NOACCESS,
5089 &spr_read_generic, &spr_write_generic,
5091 spr_register(env, SPR_MMUCSR0, "MMUCSR0",
5092 SPR_NOACCESS, SPR_NOACCESS,
5093 &spr_read_generic, &spr_write_booke206_mmucsr0,
5095 spr_register(env, SPR_BOOKE_EPR, "EPR",
5096 SPR_NOACCESS, SPR_NOACCESS,
5097 &spr_read_generic, SPR_NOACCESS,
5099 /* XXX better abstract into Emb.xxx features */
5100 if ((version == fsl_e5500) || (version == fsl_e6500)) {
5101 spr_register(env, SPR_BOOKE_EPCR, "EPCR",
5102 SPR_NOACCESS, SPR_NOACCESS,
5103 &spr_read_generic, &spr_write_generic,
5105 spr_register(env, SPR_BOOKE_MAS7_MAS3, "MAS7_MAS3",
5106 SPR_NOACCESS, SPR_NOACCESS,
5107 &spr_read_mas73, &spr_write_mas73,
5109 ivpr_mask = (target_ulong)~0xFFFFULL;
5112 if (version == fsl_e6500) {
5113 /* Thread identification */
5114 spr_register(env, SPR_TIR, "TIR",
5115 SPR_NOACCESS, SPR_NOACCESS,
5116 &spr_read_generic, SPR_NOACCESS,
5118 spr_register(env, SPR_BOOKE_TLB0PS, "TLB0PS",
5119 SPR_NOACCESS, SPR_NOACCESS,
5120 &spr_read_generic, SPR_NOACCESS,
5122 spr_register(env, SPR_BOOKE_TLB1PS, "TLB1PS",
5123 SPR_NOACCESS, SPR_NOACCESS,
5124 &spr_read_generic, SPR_NOACCESS,
5128 #if !defined(CONFIG_USER_ONLY)
5130 env->tlb_type = TLB_MAS;
5131 for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
5132 env->nb_tlb += booke206_tlb_size(env, i);
5136 init_excp_e200(env, ivpr_mask);
5137 /* Allocate hardware IRQ controller */
5138 ppce500_irq_init(env_archcpu(env));
5141 static void init_proc_e500v1(CPUPPCState *env)
5143 init_proc_e500(env, fsl_e500v1);
5146 POWERPC_FAMILY(e500v1)(ObjectClass *oc, void *data)
5148 DeviceClass *dc = DEVICE_CLASS(oc);
5149 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5151 dc->desc = "e500v1 core";
5152 pcc->init_proc = init_proc_e500v1;
5153 pcc->check_pow = check_pow_hid0;
5154 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
5155 PPC_SPE | PPC_SPE_SINGLE |
5156 PPC_WRTEE | PPC_RFDI |
5157 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5158 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5159 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
5160 pcc->insns_flags2 = PPC2_BOOKE206;
5161 pcc->msr_mask = (1ull << MSR_UCLE) |
5175 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5176 pcc->excp_model = POWERPC_EXCP_BOOKE;
5177 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5178 pcc->bfd_mach = bfd_mach_ppc_860;
5179 pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
5180 POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
5181 POWERPC_FLAG_BUS_CLK;
5184 static void init_proc_e500v2(CPUPPCState *env)
5186 init_proc_e500(env, fsl_e500v2);
5189 POWERPC_FAMILY(e500v2)(ObjectClass *oc, void *data)
5191 DeviceClass *dc = DEVICE_CLASS(oc);
5192 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5194 dc->desc = "e500v2 core";
5195 pcc->init_proc = init_proc_e500v2;
5196 pcc->check_pow = check_pow_hid0;
5197 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
5198 PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE |
5199 PPC_WRTEE | PPC_RFDI |
5200 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5201 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5202 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
5203 pcc->insns_flags2 = PPC2_BOOKE206;
5204 pcc->msr_mask = (1ull << MSR_UCLE) |
5218 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5219 pcc->excp_model = POWERPC_EXCP_BOOKE;
5220 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5221 pcc->bfd_mach = bfd_mach_ppc_860;
5222 pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
5223 POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
5224 POWERPC_FLAG_BUS_CLK;
5227 static void init_proc_e500mc(CPUPPCState *env)
5229 init_proc_e500(env, fsl_e500mc);
5232 POWERPC_FAMILY(e500mc)(ObjectClass *oc, void *data)
5234 DeviceClass *dc = DEVICE_CLASS(oc);
5235 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5237 dc->desc = "e500mc core";
5238 pcc->init_proc = init_proc_e500mc;
5239 pcc->check_pow = check_pow_none;
5240 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
5241 PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
5242 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5243 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5244 PPC_FLOAT | PPC_FLOAT_FRES |
5245 PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
5246 PPC_FLOAT_STFIWX | PPC_WAIT |
5247 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
5248 pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL;
5249 pcc->msr_mask = (1ull << MSR_GS) |
5250 (1ull << MSR_UCLE) |
5263 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5264 pcc->excp_model = POWERPC_EXCP_BOOKE;
5265 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5266 /* FIXME: figure out the correct flag for e500mc */
5267 pcc->bfd_mach = bfd_mach_ppc_e500;
5268 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
5269 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
5273 static void init_proc_e5500(CPUPPCState *env)
5275 init_proc_e500(env, fsl_e5500);
5278 POWERPC_FAMILY(e5500)(ObjectClass *oc, void *data)
5280 DeviceClass *dc = DEVICE_CLASS(oc);
5281 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5283 dc->desc = "e5500 core";
5284 pcc->init_proc = init_proc_e5500;
5285 pcc->check_pow = check_pow_none;
5286 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
5287 PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
5288 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5289 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5290 PPC_FLOAT | PPC_FLOAT_FRES |
5291 PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
5292 PPC_FLOAT_STFIWX | PPC_WAIT |
5293 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC |
5294 PPC_64B | PPC_POPCNTB | PPC_POPCNTWD;
5295 pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_PERM_ISA206 |
5297 pcc->msr_mask = (1ull << MSR_CM) |
5299 (1ull << MSR_UCLE) |
5312 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5313 pcc->excp_model = POWERPC_EXCP_BOOKE;
5314 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5315 /* FIXME: figure out the correct flag for e5500 */
5316 pcc->bfd_mach = bfd_mach_ppc_e500;
5317 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
5318 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
5321 static void init_proc_e6500(CPUPPCState *env)
5323 init_proc_e500(env, fsl_e6500);
5326 POWERPC_FAMILY(e6500)(ObjectClass *oc, void *data)
5328 DeviceClass *dc = DEVICE_CLASS(oc);
5329 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5331 dc->desc = "e6500 core";
5332 pcc->init_proc = init_proc_e6500;
5333 pcc->check_pow = check_pow_none;
5334 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
5335 PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
5336 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5337 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5338 PPC_FLOAT | PPC_FLOAT_FRES |
5339 PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
5340 PPC_FLOAT_STFIWX | PPC_WAIT |
5341 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC |
5342 PPC_64B | PPC_POPCNTB | PPC_POPCNTWD | PPC_ALTIVEC;
5343 pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_PERM_ISA206 |
5344 PPC2_FP_CVT_S64 | PPC2_ATOMIC_ISA206;
5345 pcc->msr_mask = (1ull << MSR_CM) |
5347 (1ull << MSR_UCLE) |
5361 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5362 pcc->excp_model = POWERPC_EXCP_BOOKE;
5363 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5364 pcc->bfd_mach = bfd_mach_ppc_e500;
5365 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
5366 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_VRE;
5371 /* Non-embedded PowerPC */
5373 #define POWERPC_MSRR_601 (0x0000000000001040ULL)
5375 static void init_proc_601(CPUPPCState *env)
5377 gen_spr_ne_601(env);
5380 /* Hardware implementation registers */
5381 /* XXX : not implemented */
5382 spr_register(env, SPR_HID0, "HID0",
5383 SPR_NOACCESS, SPR_NOACCESS,
5384 &spr_read_generic, &spr_write_hid0_601,
5386 /* XXX : not implemented */
5387 spr_register(env, SPR_HID1, "HID1",
5388 SPR_NOACCESS, SPR_NOACCESS,
5389 &spr_read_generic, &spr_write_generic,
5391 /* XXX : not implemented */
5392 spr_register(env, SPR_601_HID2, "HID2",
5393 SPR_NOACCESS, SPR_NOACCESS,
5394 &spr_read_generic, &spr_write_generic,
5396 /* XXX : not implemented */
5397 spr_register(env, SPR_601_HID5, "HID5",
5398 SPR_NOACCESS, SPR_NOACCESS,
5399 &spr_read_generic, &spr_write_generic,
5401 /* Memory management */
5404 * XXX: beware that dcache line size is 64
5405 * but dcbz uses 32 bytes "sectors"
5406 * XXX: this breaks clcs instruction !
5408 env->dcache_line_size = 32;
5409 env->icache_line_size = 64;
5410 /* Allocate hardware IRQ controller */
5411 ppc6xx_irq_init(env_archcpu(env));
5414 POWERPC_FAMILY(601)(ObjectClass *oc, void *data)
5416 DeviceClass *dc = DEVICE_CLASS(oc);
5417 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5419 dc->desc = "PowerPC 601";
5420 pcc->init_proc = init_proc_601;
5421 pcc->check_pow = check_pow_none;
5422 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
5424 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5425 PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
5426 PPC_SEGMENT | PPC_EXTERN;
5427 pcc->msr_mask = (1ull << MSR_EE) |
5437 pcc->mmu_model = POWERPC_MMU_601;
5438 #if defined(CONFIG_SOFTMMU)
5439 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5441 pcc->excp_model = POWERPC_EXCP_601;
5442 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5443 pcc->bfd_mach = bfd_mach_ppc_601;
5444 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK;
5447 #define POWERPC_MSRR_601v (0x0000000000001040ULL)
5449 static void init_proc_601v(CPUPPCState *env)
5452 /* XXX : not implemented */
5453 spr_register(env, SPR_601_HID15, "HID15",
5454 SPR_NOACCESS, SPR_NOACCESS,
5455 &spr_read_generic, &spr_write_generic,
5459 POWERPC_FAMILY(601v)(ObjectClass *oc, void *data)
5461 DeviceClass *dc = DEVICE_CLASS(oc);
5462 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5464 dc->desc = "PowerPC 601v";
5465 pcc->init_proc = init_proc_601v;
5466 pcc->check_pow = check_pow_none;
5467 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
5469 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5470 PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
5471 PPC_SEGMENT | PPC_EXTERN;
5472 pcc->msr_mask = (1ull << MSR_EE) |
5482 pcc->mmu_model = POWERPC_MMU_601;
5483 #if defined(CONFIG_SOFTMMU)
5484 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5486 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5487 pcc->bfd_mach = bfd_mach_ppc_601;
5488 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK;
5491 static void init_proc_602(CPUPPCState *env)
5493 gen_spr_ne_601(env);
5498 /* hardware implementation registers */
5499 /* XXX : not implemented */
5500 spr_register(env, SPR_HID0, "HID0",
5501 SPR_NOACCESS, SPR_NOACCESS,
5502 &spr_read_generic, &spr_write_generic,
5504 /* XXX : not implemented */
5505 spr_register(env, SPR_HID1, "HID1",
5506 SPR_NOACCESS, SPR_NOACCESS,
5507 &spr_read_generic, &spr_write_generic,
5509 /* Memory management */
5511 gen_6xx_7xx_soft_tlb(env, 64, 2);
5513 env->dcache_line_size = 32;
5514 env->icache_line_size = 32;
5515 /* Allocate hardware IRQ controller */
5516 ppc6xx_irq_init(env_archcpu(env));
5519 POWERPC_FAMILY(602)(ObjectClass *oc, void *data)
5521 DeviceClass *dc = DEVICE_CLASS(oc);
5522 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5524 dc->desc = "PowerPC 602";
5525 pcc->init_proc = init_proc_602;
5526 pcc->check_pow = check_pow_hid0;
5527 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5528 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5529 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5530 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5531 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5532 PPC_MEM_TLBIE | PPC_6xx_TLB | PPC_MEM_TLBSYNC |
5533 PPC_SEGMENT | PPC_602_SPEC;
5534 pcc->msr_mask = (1ull << MSR_VSX) |
5537 (1ull << MSR_TGPR) |
5552 /* XXX: 602 MMU is quite specific. Should add a special case */
5553 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
5554 pcc->excp_model = POWERPC_EXCP_602;
5555 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5556 pcc->bfd_mach = bfd_mach_ppc_602;
5557 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
5558 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
5561 static void init_proc_603(CPUPPCState *env)
5563 gen_spr_ne_601(env);
5568 /* hardware implementation registers */
5569 /* XXX : not implemented */
5570 spr_register(env, SPR_HID0, "HID0",
5571 SPR_NOACCESS, SPR_NOACCESS,
5572 &spr_read_generic, &spr_write_generic,
5574 /* XXX : not implemented */
5575 spr_register(env, SPR_HID1, "HID1",
5576 SPR_NOACCESS, SPR_NOACCESS,
5577 &spr_read_generic, &spr_write_generic,
5579 /* Memory management */
5581 gen_6xx_7xx_soft_tlb(env, 64, 2);
5583 env->dcache_line_size = 32;
5584 env->icache_line_size = 32;
5585 /* Allocate hardware IRQ controller */
5586 ppc6xx_irq_init(env_archcpu(env));
5589 POWERPC_FAMILY(603)(ObjectClass *oc, void *data)
5591 DeviceClass *dc = DEVICE_CLASS(oc);
5592 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5594 dc->desc = "PowerPC 603";
5595 pcc->init_proc = init_proc_603;
5596 pcc->check_pow = check_pow_hid0;
5597 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5598 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5599 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5600 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5601 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5602 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
5603 PPC_SEGMENT | PPC_EXTERN;
5604 pcc->msr_mask = (1ull << MSR_POW) |
5605 (1ull << MSR_TGPR) |
5620 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
5621 pcc->excp_model = POWERPC_EXCP_603;
5622 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5623 pcc->bfd_mach = bfd_mach_ppc_603;
5624 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
5625 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
5628 static void init_proc_603E(CPUPPCState *env)
5630 gen_spr_ne_601(env);
5635 /* hardware implementation registers */
5636 /* XXX : not implemented */
5637 spr_register(env, SPR_HID0, "HID0",
5638 SPR_NOACCESS, SPR_NOACCESS,
5639 &spr_read_generic, &spr_write_generic,
5641 /* XXX : not implemented */
5642 spr_register(env, SPR_HID1, "HID1",
5643 SPR_NOACCESS, SPR_NOACCESS,
5644 &spr_read_generic, &spr_write_generic,
5646 /* Memory management */
5648 gen_6xx_7xx_soft_tlb(env, 64, 2);
5650 env->dcache_line_size = 32;
5651 env->icache_line_size = 32;
5652 /* Allocate hardware IRQ controller */
5653 ppc6xx_irq_init(env_archcpu(env));
5656 POWERPC_FAMILY(603E)(ObjectClass *oc, void *data)
5658 DeviceClass *dc = DEVICE_CLASS(oc);
5659 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5661 dc->desc = "PowerPC 603e";
5662 pcc->init_proc = init_proc_603E;
5663 pcc->check_pow = check_pow_hid0;
5664 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5665 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5666 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5667 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5668 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5669 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
5670 PPC_SEGMENT | PPC_EXTERN;
5671 pcc->msr_mask = (1ull << MSR_POW) |
5672 (1ull << MSR_TGPR) |
5687 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
5688 pcc->excp_model = POWERPC_EXCP_603E;
5689 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5690 pcc->bfd_mach = bfd_mach_ppc_ec603e;
5691 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
5692 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
5695 static void init_proc_604(CPUPPCState *env)
5697 gen_spr_ne_601(env);
5702 /* Hardware implementation registers */
5703 /* XXX : not implemented */
5704 spr_register(env, SPR_HID0, "HID0",
5705 SPR_NOACCESS, SPR_NOACCESS,
5706 &spr_read_generic, &spr_write_generic,
5708 /* Memory management */
5711 env->dcache_line_size = 32;
5712 env->icache_line_size = 32;
5713 /* Allocate hardware IRQ controller */
5714 ppc6xx_irq_init(env_archcpu(env));
5717 POWERPC_FAMILY(604)(ObjectClass *oc, void *data)
5719 DeviceClass *dc = DEVICE_CLASS(oc);
5720 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5722 dc->desc = "PowerPC 604";
5723 pcc->init_proc = init_proc_604;
5724 pcc->check_pow = check_pow_nocheck;
5725 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5726 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5727 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5728 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5729 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5730 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5731 PPC_SEGMENT | PPC_EXTERN;
5732 pcc->msr_mask = (1ull << MSR_POW) |
5748 pcc->mmu_model = POWERPC_MMU_32B;
5749 #if defined(CONFIG_SOFTMMU)
5750 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5752 pcc->excp_model = POWERPC_EXCP_604;
5753 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5754 pcc->bfd_mach = bfd_mach_ppc_604;
5755 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5756 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
5759 static void init_proc_604E(CPUPPCState *env)
5761 gen_spr_ne_601(env);
5764 /* XXX : not implemented */
5765 spr_register(env, SPR_7XX_MMCR1, "MMCR1",
5766 SPR_NOACCESS, SPR_NOACCESS,
5767 &spr_read_generic, &spr_write_generic,
5769 /* XXX : not implemented */
5770 spr_register(env, SPR_7XX_PMC3, "PMC3",
5771 SPR_NOACCESS, SPR_NOACCESS,
5772 &spr_read_generic, &spr_write_generic,
5774 /* XXX : not implemented */
5775 spr_register(env, SPR_7XX_PMC4, "PMC4",
5776 SPR_NOACCESS, SPR_NOACCESS,
5777 &spr_read_generic, &spr_write_generic,
5781 /* Hardware implementation registers */
5782 /* XXX : not implemented */
5783 spr_register(env, SPR_HID0, "HID0",
5784 SPR_NOACCESS, SPR_NOACCESS,
5785 &spr_read_generic, &spr_write_generic,
5787 /* XXX : not implemented */
5788 spr_register(env, SPR_HID1, "HID1",
5789 SPR_NOACCESS, SPR_NOACCESS,
5790 &spr_read_generic, &spr_write_generic,
5792 /* Memory management */
5795 env->dcache_line_size = 32;
5796 env->icache_line_size = 32;
5797 /* Allocate hardware IRQ controller */
5798 ppc6xx_irq_init(env_archcpu(env));
5801 POWERPC_FAMILY(604E)(ObjectClass *oc, void *data)
5803 DeviceClass *dc = DEVICE_CLASS(oc);
5804 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5806 dc->desc = "PowerPC 604E";
5807 pcc->init_proc = init_proc_604E;
5808 pcc->check_pow = check_pow_nocheck;
5809 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5810 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5811 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5812 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5813 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5814 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5815 PPC_SEGMENT | PPC_EXTERN;
5816 pcc->msr_mask = (1ull << MSR_POW) |
5832 pcc->mmu_model = POWERPC_MMU_32B;
5833 #if defined(CONFIG_SOFTMMU)
5834 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5836 pcc->excp_model = POWERPC_EXCP_604;
5837 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5838 pcc->bfd_mach = bfd_mach_ppc_604;
5839 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5840 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
5843 static void init_proc_740(CPUPPCState *env)
5845 gen_spr_ne_601(env);
5850 /* Thermal management */
5852 /* Hardware implementation registers */
5853 /* XXX : not implemented */
5854 spr_register(env, SPR_HID0, "HID0",
5855 SPR_NOACCESS, SPR_NOACCESS,
5856 &spr_read_generic, &spr_write_generic,
5858 /* XXX : not implemented */
5859 spr_register(env, SPR_HID1, "HID1",
5860 SPR_NOACCESS, SPR_NOACCESS,
5861 &spr_read_generic, &spr_write_generic,
5863 /* Memory management */
5866 env->dcache_line_size = 32;
5867 env->icache_line_size = 32;
5868 /* Allocate hardware IRQ controller */
5869 ppc6xx_irq_init(env_archcpu(env));
5872 POWERPC_FAMILY(740)(ObjectClass *oc, void *data)
5874 DeviceClass *dc = DEVICE_CLASS(oc);
5875 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5877 dc->desc = "PowerPC 740";
5878 pcc->init_proc = init_proc_740;
5879 pcc->check_pow = check_pow_hid0;
5880 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5881 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5882 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5883 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5884 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5885 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5886 PPC_SEGMENT | PPC_EXTERN;
5887 pcc->msr_mask = (1ull << MSR_POW) |
5903 pcc->mmu_model = POWERPC_MMU_32B;
5904 #if defined(CONFIG_SOFTMMU)
5905 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5907 pcc->excp_model = POWERPC_EXCP_7x0;
5908 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5909 pcc->bfd_mach = bfd_mach_ppc_750;
5910 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5911 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
5914 static void init_proc_750(CPUPPCState *env)
5916 gen_spr_ne_601(env);
5919 /* XXX : not implemented */
5920 spr_register(env, SPR_L2CR, "L2CR",
5921 SPR_NOACCESS, SPR_NOACCESS,
5922 &spr_read_generic, spr_access_nop,
5926 /* Thermal management */
5928 /* Hardware implementation registers */
5929 /* XXX : not implemented */
5930 spr_register(env, SPR_HID0, "HID0",
5931 SPR_NOACCESS, SPR_NOACCESS,
5932 &spr_read_generic, &spr_write_generic,
5934 /* XXX : not implemented */
5935 spr_register(env, SPR_HID1, "HID1",
5936 SPR_NOACCESS, SPR_NOACCESS,
5937 &spr_read_generic, &spr_write_generic,
5939 /* Memory management */
5942 * XXX: high BATs are also present but are known to be bugged on
5946 env->dcache_line_size = 32;
5947 env->icache_line_size = 32;
5948 /* Allocate hardware IRQ controller */
5949 ppc6xx_irq_init(env_archcpu(env));
5952 POWERPC_FAMILY(750)(ObjectClass *oc, void *data)
5954 DeviceClass *dc = DEVICE_CLASS(oc);
5955 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5957 dc->desc = "PowerPC 750";
5958 pcc->init_proc = init_proc_750;
5959 pcc->check_pow = check_pow_hid0;
5960 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5961 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5962 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5963 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5964 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5965 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5966 PPC_SEGMENT | PPC_EXTERN;
5967 pcc->msr_mask = (1ull << MSR_POW) |
5983 pcc->mmu_model = POWERPC_MMU_32B;
5984 #if defined(CONFIG_SOFTMMU)
5985 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5987 pcc->excp_model = POWERPC_EXCP_7x0;
5988 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5989 pcc->bfd_mach = bfd_mach_ppc_750;
5990 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5991 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
5994 static void init_proc_750cl(CPUPPCState *env)
5996 gen_spr_ne_601(env);
5999 /* XXX : not implemented */
6000 spr_register(env, SPR_L2CR, "L2CR",
6001 SPR_NOACCESS, SPR_NOACCESS,
6002 &spr_read_generic, spr_access_nop,
6006 /* Thermal management */
6007 /* Those registers are fake on 750CL */
6008 spr_register(env, SPR_THRM1, "THRM1",
6009 SPR_NOACCESS, SPR_NOACCESS,
6010 &spr_read_generic, &spr_write_generic,
6012 spr_register(env, SPR_THRM2, "THRM2",
6013 SPR_NOACCESS, SPR_NOACCESS,
6014 &spr_read_generic, &spr_write_generic,
6016 spr_register(env, SPR_THRM3, "THRM3",
6017 SPR_NOACCESS, SPR_NOACCESS,
6018 &spr_read_generic, &spr_write_generic,
6020 /* XXX: not implemented */
6021 spr_register(env, SPR_750_TDCL, "TDCL",
6022 SPR_NOACCESS, SPR_NOACCESS,
6023 &spr_read_generic, &spr_write_generic,
6025 spr_register(env, SPR_750_TDCH, "TDCH",
6026 SPR_NOACCESS, SPR_NOACCESS,
6027 &spr_read_generic, &spr_write_generic,
6030 /* XXX : not implemented */
6031 spr_register(env, SPR_750_WPAR, "WPAR",
6032 SPR_NOACCESS, SPR_NOACCESS,
6033 &spr_read_generic, &spr_write_generic,
6035 spr_register(env, SPR_750_DMAL, "DMAL",
6036 SPR_NOACCESS, SPR_NOACCESS,
6037 &spr_read_generic, &spr_write_generic,
6039 spr_register(env, SPR_750_DMAU, "DMAU",
6040 SPR_NOACCESS, SPR_NOACCESS,
6041 &spr_read_generic, &spr_write_generic,
6043 /* Hardware implementation registers */
6044 /* XXX : not implemented */
6045 spr_register(env, SPR_HID0, "HID0",
6046 SPR_NOACCESS, SPR_NOACCESS,
6047 &spr_read_generic, &spr_write_generic,
6049 /* XXX : not implemented */
6050 spr_register(env, SPR_HID1, "HID1",
6051 SPR_NOACCESS, SPR_NOACCESS,
6052 &spr_read_generic, &spr_write_generic,
6054 /* XXX : not implemented */
6055 spr_register(env, SPR_750CL_HID2, "HID2",
6056 SPR_NOACCESS, SPR_NOACCESS,
6057 &spr_read_generic, &spr_write_generic,
6059 /* XXX : not implemented */
6060 spr_register(env, SPR_750CL_HID4, "HID4",
6061 SPR_NOACCESS, SPR_NOACCESS,
6062 &spr_read_generic, &spr_write_generic,
6064 /* Quantization registers */
6065 /* XXX : not implemented */
6066 spr_register(env, SPR_750_GQR0, "GQR0",
6067 SPR_NOACCESS, SPR_NOACCESS,
6068 &spr_read_generic, &spr_write_generic,
6070 /* XXX : not implemented */
6071 spr_register(env, SPR_750_GQR1, "GQR1",
6072 SPR_NOACCESS, SPR_NOACCESS,
6073 &spr_read_generic, &spr_write_generic,
6075 /* XXX : not implemented */
6076 spr_register(env, SPR_750_GQR2, "GQR2",
6077 SPR_NOACCESS, SPR_NOACCESS,
6078 &spr_read_generic, &spr_write_generic,
6080 /* XXX : not implemented */
6081 spr_register(env, SPR_750_GQR3, "GQR3",
6082 SPR_NOACCESS, SPR_NOACCESS,
6083 &spr_read_generic, &spr_write_generic,
6085 /* XXX : not implemented */
6086 spr_register(env, SPR_750_GQR4, "GQR4",
6087 SPR_NOACCESS, SPR_NOACCESS,
6088 &spr_read_generic, &spr_write_generic,
6090 /* XXX : not implemented */
6091 spr_register(env, SPR_750_GQR5, "GQR5",
6092 SPR_NOACCESS, SPR_NOACCESS,
6093 &spr_read_generic, &spr_write_generic,
6095 /* XXX : not implemented */
6096 spr_register(env, SPR_750_GQR6, "GQR6",
6097 SPR_NOACCESS, SPR_NOACCESS,
6098 &spr_read_generic, &spr_write_generic,
6100 /* XXX : not implemented */
6101 spr_register(env, SPR_750_GQR7, "GQR7",
6102 SPR_NOACCESS, SPR_NOACCESS,
6103 &spr_read_generic, &spr_write_generic,
6105 /* Memory management */
6107 /* PowerPC 750cl has 8 DBATs and 8 IBATs */
6109 init_excp_750cl(env);
6110 env->dcache_line_size = 32;
6111 env->icache_line_size = 32;
6112 /* Allocate hardware IRQ controller */
6113 ppc6xx_irq_init(env_archcpu(env));
6116 POWERPC_FAMILY(750cl)(ObjectClass *oc, void *data)
6118 DeviceClass *dc = DEVICE_CLASS(oc);
6119 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6121 dc->desc = "PowerPC 750 CL";
6122 pcc->init_proc = init_proc_750cl;
6123 pcc->check_pow = check_pow_hid0;
6125 * XXX: not implemented:
6126 * cache lock instructions:
6128 * floating point paired instructions
6163 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6164 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6165 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6166 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6167 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6168 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6169 PPC_SEGMENT | PPC_EXTERN;
6170 pcc->msr_mask = (1ull << MSR_POW) |
6186 pcc->mmu_model = POWERPC_MMU_32B;
6187 #if defined(CONFIG_SOFTMMU)
6188 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6190 pcc->excp_model = POWERPC_EXCP_7x0;
6191 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6192 pcc->bfd_mach = bfd_mach_ppc_750;
6193 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6194 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
6197 static void init_proc_750cx(CPUPPCState *env)
6199 gen_spr_ne_601(env);
6202 /* XXX : not implemented */
6203 spr_register(env, SPR_L2CR, "L2CR",
6204 SPR_NOACCESS, SPR_NOACCESS,
6205 &spr_read_generic, spr_access_nop,
6209 /* Thermal management */
6211 /* This register is not implemented but is present for compatibility */
6212 spr_register(env, SPR_SDA, "SDA",
6213 SPR_NOACCESS, SPR_NOACCESS,
6214 &spr_read_generic, &spr_write_generic,
6216 /* Hardware implementation registers */
6217 /* XXX : not implemented */
6218 spr_register(env, SPR_HID0, "HID0",
6219 SPR_NOACCESS, SPR_NOACCESS,
6220 &spr_read_generic, &spr_write_generic,
6222 /* XXX : not implemented */
6223 spr_register(env, SPR_HID1, "HID1",
6224 SPR_NOACCESS, SPR_NOACCESS,
6225 &spr_read_generic, &spr_write_generic,
6227 /* Memory management */
6229 /* PowerPC 750cx has 8 DBATs and 8 IBATs */
6231 init_excp_750cx(env);
6232 env->dcache_line_size = 32;
6233 env->icache_line_size = 32;
6234 /* Allocate hardware IRQ controller */
6235 ppc6xx_irq_init(env_archcpu(env));
6238 POWERPC_FAMILY(750cx)(ObjectClass *oc, void *data)
6240 DeviceClass *dc = DEVICE_CLASS(oc);
6241 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6243 dc->desc = "PowerPC 750CX";
6244 pcc->init_proc = init_proc_750cx;
6245 pcc->check_pow = check_pow_hid0;
6246 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6247 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6248 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6249 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6250 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6251 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6252 PPC_SEGMENT | PPC_EXTERN;
6253 pcc->msr_mask = (1ull << MSR_POW) |
6269 pcc->mmu_model = POWERPC_MMU_32B;
6270 #if defined(CONFIG_SOFTMMU)
6271 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6273 pcc->excp_model = POWERPC_EXCP_7x0;
6274 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6275 pcc->bfd_mach = bfd_mach_ppc_750;
6276 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6277 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
6280 static void init_proc_750fx(CPUPPCState *env)
6282 gen_spr_ne_601(env);
6285 /* XXX : not implemented */
6286 spr_register(env, SPR_L2CR, "L2CR",
6287 SPR_NOACCESS, SPR_NOACCESS,
6288 &spr_read_generic, spr_access_nop,
6292 /* Thermal management */
6294 /* XXX : not implemented */
6295 spr_register(env, SPR_750_THRM4, "THRM4",
6296 SPR_NOACCESS, SPR_NOACCESS,
6297 &spr_read_generic, &spr_write_generic,
6299 /* Hardware implementation registers */
6300 /* XXX : not implemented */
6301 spr_register(env, SPR_HID0, "HID0",
6302 SPR_NOACCESS, SPR_NOACCESS,
6303 &spr_read_generic, &spr_write_generic,
6305 /* XXX : not implemented */
6306 spr_register(env, SPR_HID1, "HID1",
6307 SPR_NOACCESS, SPR_NOACCESS,
6308 &spr_read_generic, &spr_write_generic,
6310 /* XXX : not implemented */
6311 spr_register(env, SPR_750FX_HID2, "HID2",
6312 SPR_NOACCESS, SPR_NOACCESS,
6313 &spr_read_generic, &spr_write_generic,
6315 /* Memory management */
6317 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6320 env->dcache_line_size = 32;
6321 env->icache_line_size = 32;
6322 /* Allocate hardware IRQ controller */
6323 ppc6xx_irq_init(env_archcpu(env));
6326 POWERPC_FAMILY(750fx)(ObjectClass *oc, void *data)
6328 DeviceClass *dc = DEVICE_CLASS(oc);
6329 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6331 dc->desc = "PowerPC 750FX";
6332 pcc->init_proc = init_proc_750fx;
6333 pcc->check_pow = check_pow_hid0;
6334 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6335 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6336 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6337 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6338 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6339 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6340 PPC_SEGMENT | PPC_EXTERN;
6341 pcc->msr_mask = (1ull << MSR_POW) |
6357 pcc->mmu_model = POWERPC_MMU_32B;
6358 #if defined(CONFIG_SOFTMMU)
6359 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6361 pcc->excp_model = POWERPC_EXCP_7x0;
6362 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6363 pcc->bfd_mach = bfd_mach_ppc_750;
6364 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6365 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
6368 static void init_proc_750gx(CPUPPCState *env)
6370 gen_spr_ne_601(env);
6373 /* XXX : not implemented (XXX: different from 750fx) */
6374 spr_register(env, SPR_L2CR, "L2CR",
6375 SPR_NOACCESS, SPR_NOACCESS,
6376 &spr_read_generic, spr_access_nop,
6380 /* Thermal management */
6382 /* XXX : not implemented */
6383 spr_register(env, SPR_750_THRM4, "THRM4",
6384 SPR_NOACCESS, SPR_NOACCESS,
6385 &spr_read_generic, &spr_write_generic,
6387 /* Hardware implementation registers */
6388 /* XXX : not implemented (XXX: different from 750fx) */
6389 spr_register(env, SPR_HID0, "HID0",
6390 SPR_NOACCESS, SPR_NOACCESS,
6391 &spr_read_generic, &spr_write_generic,
6393 /* XXX : not implemented */
6394 spr_register(env, SPR_HID1, "HID1",
6395 SPR_NOACCESS, SPR_NOACCESS,
6396 &spr_read_generic, &spr_write_generic,
6398 /* XXX : not implemented (XXX: different from 750fx) */
6399 spr_register(env, SPR_750FX_HID2, "HID2",
6400 SPR_NOACCESS, SPR_NOACCESS,
6401 &spr_read_generic, &spr_write_generic,
6403 /* Memory management */
6405 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6408 env->dcache_line_size = 32;
6409 env->icache_line_size = 32;
6410 /* Allocate hardware IRQ controller */
6411 ppc6xx_irq_init(env_archcpu(env));
6414 POWERPC_FAMILY(750gx)(ObjectClass *oc, void *data)
6416 DeviceClass *dc = DEVICE_CLASS(oc);
6417 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6419 dc->desc = "PowerPC 750GX";
6420 pcc->init_proc = init_proc_750gx;
6421 pcc->check_pow = check_pow_hid0;
6422 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6423 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6424 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6425 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6426 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6427 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6428 PPC_SEGMENT | PPC_EXTERN;
6429 pcc->msr_mask = (1ull << MSR_POW) |
6445 pcc->mmu_model = POWERPC_MMU_32B;
6446 #if defined(CONFIG_SOFTMMU)
6447 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6449 pcc->excp_model = POWERPC_EXCP_7x0;
6450 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6451 pcc->bfd_mach = bfd_mach_ppc_750;
6452 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6453 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
6456 static void init_proc_745(CPUPPCState *env)
6458 gen_spr_ne_601(env);
6461 gen_spr_G2_755(env);
6464 /* Thermal management */
6466 /* Hardware implementation registers */
6467 /* XXX : not implemented */
6468 spr_register(env, SPR_HID0, "HID0",
6469 SPR_NOACCESS, SPR_NOACCESS,
6470 &spr_read_generic, &spr_write_generic,
6472 /* XXX : not implemented */
6473 spr_register(env, SPR_HID1, "HID1",
6474 SPR_NOACCESS, SPR_NOACCESS,
6475 &spr_read_generic, &spr_write_generic,
6477 /* XXX : not implemented */
6478 spr_register(env, SPR_HID2, "HID2",
6479 SPR_NOACCESS, SPR_NOACCESS,
6480 &spr_read_generic, &spr_write_generic,
6482 /* Memory management */
6485 gen_6xx_7xx_soft_tlb(env, 64, 2);
6487 env->dcache_line_size = 32;
6488 env->icache_line_size = 32;
6489 /* Allocate hardware IRQ controller */
6490 ppc6xx_irq_init(env_archcpu(env));
6493 POWERPC_FAMILY(745)(ObjectClass *oc, void *data)
6495 DeviceClass *dc = DEVICE_CLASS(oc);
6496 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6498 dc->desc = "PowerPC 745";
6499 pcc->init_proc = init_proc_745;
6500 pcc->check_pow = check_pow_hid0;
6501 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6502 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6503 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6504 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6505 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6506 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
6507 PPC_SEGMENT | PPC_EXTERN;
6508 pcc->msr_mask = (1ull << MSR_POW) |
6524 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
6525 pcc->excp_model = POWERPC_EXCP_7x5;
6526 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6527 pcc->bfd_mach = bfd_mach_ppc_750;
6528 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6529 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
6532 static void init_proc_755(CPUPPCState *env)
6534 gen_spr_ne_601(env);
6537 gen_spr_G2_755(env);
6540 /* L2 cache control */
6541 /* XXX : not implemented */
6542 spr_register(env, SPR_L2CR, "L2CR",
6543 SPR_NOACCESS, SPR_NOACCESS,
6544 &spr_read_generic, spr_access_nop,
6546 /* XXX : not implemented */
6547 spr_register(env, SPR_L2PMCR, "L2PMCR",
6548 SPR_NOACCESS, SPR_NOACCESS,
6549 &spr_read_generic, &spr_write_generic,
6551 /* Thermal management */
6553 /* Hardware implementation registers */
6554 /* XXX : not implemented */
6555 spr_register(env, SPR_HID0, "HID0",
6556 SPR_NOACCESS, SPR_NOACCESS,
6557 &spr_read_generic, &spr_write_generic,
6559 /* XXX : not implemented */
6560 spr_register(env, SPR_HID1, "HID1",
6561 SPR_NOACCESS, SPR_NOACCESS,
6562 &spr_read_generic, &spr_write_generic,
6564 /* XXX : not implemented */
6565 spr_register(env, SPR_HID2, "HID2",
6566 SPR_NOACCESS, SPR_NOACCESS,
6567 &spr_read_generic, &spr_write_generic,
6569 /* Memory management */
6572 gen_6xx_7xx_soft_tlb(env, 64, 2);
6574 env->dcache_line_size = 32;
6575 env->icache_line_size = 32;
6576 /* Allocate hardware IRQ controller */
6577 ppc6xx_irq_init(env_archcpu(env));
6580 POWERPC_FAMILY(755)(ObjectClass *oc, void *data)
6582 DeviceClass *dc = DEVICE_CLASS(oc);
6583 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6585 dc->desc = "PowerPC 755";
6586 pcc->init_proc = init_proc_755;
6587 pcc->check_pow = check_pow_hid0;
6588 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6589 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6590 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6591 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6592 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6593 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
6594 PPC_SEGMENT | PPC_EXTERN;
6595 pcc->msr_mask = (1ull << MSR_POW) |
6611 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
6612 pcc->excp_model = POWERPC_EXCP_7x5;
6613 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6614 pcc->bfd_mach = bfd_mach_ppc_750;
6615 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6616 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
6619 static void init_proc_7400(CPUPPCState *env)
6621 gen_spr_ne_601(env);
6626 /* 74xx specific SPR */
6628 /* XXX : not implemented */
6629 spr_register(env, SPR_UBAMR, "UBAMR",
6630 &spr_read_ureg, SPR_NOACCESS,
6631 &spr_read_ureg, SPR_NOACCESS,
6633 /* XXX: this seems not implemented on all revisions. */
6634 /* XXX : not implemented */
6635 spr_register(env, SPR_MSSCR1, "MSSCR1",
6636 SPR_NOACCESS, SPR_NOACCESS,
6637 &spr_read_generic, &spr_write_generic,
6639 /* Thermal management */
6641 /* Memory management */
6643 init_excp_7400(env);
6644 env->dcache_line_size = 32;
6645 env->icache_line_size = 32;
6646 /* Allocate hardware IRQ controller */
6647 ppc6xx_irq_init(env_archcpu(env));
6650 POWERPC_FAMILY(7400)(ObjectClass *oc, void *data)
6652 DeviceClass *dc = DEVICE_CLASS(oc);
6653 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6655 dc->desc = "PowerPC 7400 (aka G4)";
6656 pcc->init_proc = init_proc_7400;
6657 pcc->check_pow = check_pow_hid0;
6658 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6659 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6660 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6662 PPC_CACHE | PPC_CACHE_ICBI |
6663 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6664 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6665 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6667 PPC_SEGMENT | PPC_EXTERN |
6669 pcc->msr_mask = (1ull << MSR_VR) |
6686 pcc->mmu_model = POWERPC_MMU_32B;
6687 #if defined(CONFIG_SOFTMMU)
6688 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6690 pcc->excp_model = POWERPC_EXCP_74xx;
6691 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6692 pcc->bfd_mach = bfd_mach_ppc_7400;
6693 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6694 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6695 POWERPC_FLAG_BUS_CLK;
6698 static void init_proc_7410(CPUPPCState *env)
6700 gen_spr_ne_601(env);
6705 /* 74xx specific SPR */
6707 /* XXX : not implemented */
6708 spr_register(env, SPR_UBAMR, "UBAMR",
6709 &spr_read_ureg, SPR_NOACCESS,
6710 &spr_read_ureg, SPR_NOACCESS,
6712 /* Thermal management */
6715 /* XXX : not implemented */
6716 spr_register(env, SPR_L2PMCR, "L2PMCR",
6717 SPR_NOACCESS, SPR_NOACCESS,
6718 &spr_read_generic, &spr_write_generic,
6721 /* XXX : not implemented */
6722 spr_register(env, SPR_LDSTDB, "LDSTDB",
6723 SPR_NOACCESS, SPR_NOACCESS,
6724 &spr_read_generic, &spr_write_generic,
6726 /* Memory management */
6728 init_excp_7400(env);
6729 env->dcache_line_size = 32;
6730 env->icache_line_size = 32;
6731 /* Allocate hardware IRQ controller */
6732 ppc6xx_irq_init(env_archcpu(env));
6735 POWERPC_FAMILY(7410)(ObjectClass *oc, void *data)
6737 DeviceClass *dc = DEVICE_CLASS(oc);
6738 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6740 dc->desc = "PowerPC 7410 (aka G4)";
6741 pcc->init_proc = init_proc_7410;
6742 pcc->check_pow = check_pow_hid0;
6743 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6744 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6745 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6747 PPC_CACHE | PPC_CACHE_ICBI |
6748 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6749 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6750 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6752 PPC_SEGMENT | PPC_EXTERN |
6754 pcc->msr_mask = (1ull << MSR_VR) |
6771 pcc->mmu_model = POWERPC_MMU_32B;
6772 #if defined(CONFIG_SOFTMMU)
6773 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6775 pcc->excp_model = POWERPC_EXCP_74xx;
6776 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6777 pcc->bfd_mach = bfd_mach_ppc_7400;
6778 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6779 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6780 POWERPC_FLAG_BUS_CLK;
6783 static void init_proc_7440(CPUPPCState *env)
6785 gen_spr_ne_601(env);
6790 /* 74xx specific SPR */
6792 /* XXX : not implemented */
6793 spr_register(env, SPR_UBAMR, "UBAMR",
6794 &spr_read_ureg, SPR_NOACCESS,
6795 &spr_read_ureg, SPR_NOACCESS,
6798 /* XXX : not implemented */
6799 spr_register(env, SPR_LDSTCR, "LDSTCR",
6800 SPR_NOACCESS, SPR_NOACCESS,
6801 &spr_read_generic, &spr_write_generic,
6804 /* XXX : not implemented */
6805 spr_register(env, SPR_ICTRL, "ICTRL",
6806 SPR_NOACCESS, SPR_NOACCESS,
6807 &spr_read_generic, &spr_write_generic,
6810 /* XXX : not implemented */
6811 spr_register(env, SPR_MSSSR0, "MSSSR0",
6812 SPR_NOACCESS, SPR_NOACCESS,
6813 &spr_read_generic, &spr_write_generic,
6816 /* XXX : not implemented */
6817 spr_register(env, SPR_7XX_PMC5, "PMC5",
6818 SPR_NOACCESS, SPR_NOACCESS,
6819 &spr_read_generic, &spr_write_generic,
6821 /* XXX : not implemented */
6822 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
6823 &spr_read_ureg, SPR_NOACCESS,
6824 &spr_read_ureg, SPR_NOACCESS,
6826 /* XXX : not implemented */
6827 spr_register(env, SPR_7XX_PMC6, "PMC6",
6828 SPR_NOACCESS, SPR_NOACCESS,
6829 &spr_read_generic, &spr_write_generic,
6831 /* XXX : not implemented */
6832 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
6833 &spr_read_ureg, SPR_NOACCESS,
6834 &spr_read_ureg, SPR_NOACCESS,
6836 /* Memory management */
6838 gen_74xx_soft_tlb(env, 128, 2);
6839 init_excp_7450(env);
6840 env->dcache_line_size = 32;
6841 env->icache_line_size = 32;
6842 /* Allocate hardware IRQ controller */
6843 ppc6xx_irq_init(env_archcpu(env));
6846 POWERPC_FAMILY(7440)(ObjectClass *oc, void *data)
6848 DeviceClass *dc = DEVICE_CLASS(oc);
6849 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6851 dc->desc = "PowerPC 7440 (aka G4)";
6852 pcc->init_proc = init_proc_7440;
6853 pcc->check_pow = check_pow_hid0_74xx;
6854 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6855 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6856 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6858 PPC_CACHE | PPC_CACHE_ICBI |
6859 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6860 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6861 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6862 PPC_MEM_TLBIA | PPC_74xx_TLB |
6863 PPC_SEGMENT | PPC_EXTERN |
6865 pcc->msr_mask = (1ull << MSR_VR) |
6882 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
6883 pcc->excp_model = POWERPC_EXCP_74xx;
6884 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6885 pcc->bfd_mach = bfd_mach_ppc_7400;
6886 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6887 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6888 POWERPC_FLAG_BUS_CLK;
6891 static void init_proc_7450(CPUPPCState *env)
6893 gen_spr_ne_601(env);
6898 /* 74xx specific SPR */
6900 /* Level 3 cache control */
6903 /* XXX : not implemented */
6904 spr_register(env, SPR_L3ITCR1, "L3ITCR1",
6905 SPR_NOACCESS, SPR_NOACCESS,
6906 &spr_read_generic, &spr_write_generic,
6909 /* XXX : not implemented */
6910 spr_register(env, SPR_L3ITCR2, "L3ITCR2",
6911 SPR_NOACCESS, SPR_NOACCESS,
6912 &spr_read_generic, &spr_write_generic,
6915 /* XXX : not implemented */
6916 spr_register(env, SPR_L3ITCR3, "L3ITCR3",
6917 SPR_NOACCESS, SPR_NOACCESS,
6918 &spr_read_generic, &spr_write_generic,
6921 /* XXX : not implemented */
6922 spr_register(env, SPR_L3OHCR, "L3OHCR",
6923 SPR_NOACCESS, SPR_NOACCESS,
6924 &spr_read_generic, &spr_write_generic,
6926 /* XXX : not implemented */
6927 spr_register(env, SPR_UBAMR, "UBAMR",
6928 &spr_read_ureg, SPR_NOACCESS,
6929 &spr_read_ureg, SPR_NOACCESS,
6932 /* XXX : not implemented */
6933 spr_register(env, SPR_LDSTCR, "LDSTCR",
6934 SPR_NOACCESS, SPR_NOACCESS,
6935 &spr_read_generic, &spr_write_generic,
6938 /* XXX : not implemented */
6939 spr_register(env, SPR_ICTRL, "ICTRL",
6940 SPR_NOACCESS, SPR_NOACCESS,
6941 &spr_read_generic, &spr_write_generic,
6944 /* XXX : not implemented */
6945 spr_register(env, SPR_MSSSR0, "MSSSR0",
6946 SPR_NOACCESS, SPR_NOACCESS,
6947 &spr_read_generic, &spr_write_generic,
6950 /* XXX : not implemented */
6951 spr_register(env, SPR_7XX_PMC5, "PMC5",
6952 SPR_NOACCESS, SPR_NOACCESS,
6953 &spr_read_generic, &spr_write_generic,
6955 /* XXX : not implemented */
6956 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
6957 &spr_read_ureg, SPR_NOACCESS,
6958 &spr_read_ureg, SPR_NOACCESS,
6960 /* XXX : not implemented */
6961 spr_register(env, SPR_7XX_PMC6, "PMC6",
6962 SPR_NOACCESS, SPR_NOACCESS,
6963 &spr_read_generic, &spr_write_generic,
6965 /* XXX : not implemented */
6966 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
6967 &spr_read_ureg, SPR_NOACCESS,
6968 &spr_read_ureg, SPR_NOACCESS,
6970 /* Memory management */
6972 gen_74xx_soft_tlb(env, 128, 2);
6973 init_excp_7450(env);
6974 env->dcache_line_size = 32;
6975 env->icache_line_size = 32;
6976 /* Allocate hardware IRQ controller */
6977 ppc6xx_irq_init(env_archcpu(env));
6980 POWERPC_FAMILY(7450)(ObjectClass *oc, void *data)
6982 DeviceClass *dc = DEVICE_CLASS(oc);
6983 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6985 dc->desc = "PowerPC 7450 (aka G4)";
6986 pcc->init_proc = init_proc_7450;
6987 pcc->check_pow = check_pow_hid0_74xx;
6988 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6989 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6990 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6992 PPC_CACHE | PPC_CACHE_ICBI |
6993 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6994 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6995 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6996 PPC_MEM_TLBIA | PPC_74xx_TLB |
6997 PPC_SEGMENT | PPC_EXTERN |
6999 pcc->msr_mask = (1ull << MSR_VR) |
7016 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
7017 pcc->excp_model = POWERPC_EXCP_74xx;
7018 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7019 pcc->bfd_mach = bfd_mach_ppc_7400;
7020 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7021 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7022 POWERPC_FLAG_BUS_CLK;
7025 static void init_proc_7445(CPUPPCState *env)
7027 gen_spr_ne_601(env);
7032 /* 74xx specific SPR */
7035 /* XXX : not implemented */
7036 spr_register(env, SPR_LDSTCR, "LDSTCR",
7037 SPR_NOACCESS, SPR_NOACCESS,
7038 &spr_read_generic, &spr_write_generic,
7041 /* XXX : not implemented */
7042 spr_register(env, SPR_ICTRL, "ICTRL",
7043 SPR_NOACCESS, SPR_NOACCESS,
7044 &spr_read_generic, &spr_write_generic,
7047 /* XXX : not implemented */
7048 spr_register(env, SPR_MSSSR0, "MSSSR0",
7049 SPR_NOACCESS, SPR_NOACCESS,
7050 &spr_read_generic, &spr_write_generic,
7053 /* XXX : not implemented */
7054 spr_register(env, SPR_7XX_PMC5, "PMC5",
7055 SPR_NOACCESS, SPR_NOACCESS,
7056 &spr_read_generic, &spr_write_generic,
7058 /* XXX : not implemented */
7059 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
7060 &spr_read_ureg, SPR_NOACCESS,
7061 &spr_read_ureg, SPR_NOACCESS,
7063 /* XXX : not implemented */
7064 spr_register(env, SPR_7XX_PMC6, "PMC6",
7065 SPR_NOACCESS, SPR_NOACCESS,
7066 &spr_read_generic, &spr_write_generic,
7068 /* XXX : not implemented */
7069 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
7070 &spr_read_ureg, SPR_NOACCESS,
7071 &spr_read_ureg, SPR_NOACCESS,
7074 spr_register(env, SPR_SPRG4, "SPRG4",
7075 SPR_NOACCESS, SPR_NOACCESS,
7076 &spr_read_generic, &spr_write_generic,
7078 spr_register(env, SPR_USPRG4, "USPRG4",
7079 &spr_read_ureg, SPR_NOACCESS,
7080 &spr_read_ureg, SPR_NOACCESS,
7082 spr_register(env, SPR_SPRG5, "SPRG5",
7083 SPR_NOACCESS, SPR_NOACCESS,
7084 &spr_read_generic, &spr_write_generic,
7086 spr_register(env, SPR_USPRG5, "USPRG5",
7087 &spr_read_ureg, SPR_NOACCESS,
7088 &spr_read_ureg, SPR_NOACCESS,
7090 spr_register(env, SPR_SPRG6, "SPRG6",
7091 SPR_NOACCESS, SPR_NOACCESS,
7092 &spr_read_generic, &spr_write_generic,
7094 spr_register(env, SPR_USPRG6, "USPRG6",
7095 &spr_read_ureg, SPR_NOACCESS,
7096 &spr_read_ureg, SPR_NOACCESS,
7098 spr_register(env, SPR_SPRG7, "SPRG7",
7099 SPR_NOACCESS, SPR_NOACCESS,
7100 &spr_read_generic, &spr_write_generic,
7102 spr_register(env, SPR_USPRG7, "USPRG7",
7103 &spr_read_ureg, SPR_NOACCESS,
7104 &spr_read_ureg, SPR_NOACCESS,
7106 /* Memory management */
7109 gen_74xx_soft_tlb(env, 128, 2);
7110 init_excp_7450(env);
7111 env->dcache_line_size = 32;
7112 env->icache_line_size = 32;
7113 /* Allocate hardware IRQ controller */
7114 ppc6xx_irq_init(env_archcpu(env));
7117 POWERPC_FAMILY(7445)(ObjectClass *oc, void *data)
7119 DeviceClass *dc = DEVICE_CLASS(oc);
7120 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7122 dc->desc = "PowerPC 7445 (aka G4)";
7123 pcc->init_proc = init_proc_7445;
7124 pcc->check_pow = check_pow_hid0_74xx;
7125 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7126 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7127 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7129 PPC_CACHE | PPC_CACHE_ICBI |
7130 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7131 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7132 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7133 PPC_MEM_TLBIA | PPC_74xx_TLB |
7134 PPC_SEGMENT | PPC_EXTERN |
7136 pcc->msr_mask = (1ull << MSR_VR) |
7153 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
7154 pcc->excp_model = POWERPC_EXCP_74xx;
7155 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7156 pcc->bfd_mach = bfd_mach_ppc_7400;
7157 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7158 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7159 POWERPC_FLAG_BUS_CLK;
7162 static void init_proc_7455(CPUPPCState *env)
7164 gen_spr_ne_601(env);
7169 /* 74xx specific SPR */
7171 /* Level 3 cache control */
7174 /* XXX : not implemented */
7175 spr_register(env, SPR_LDSTCR, "LDSTCR",
7176 SPR_NOACCESS, SPR_NOACCESS,
7177 &spr_read_generic, &spr_write_generic,
7180 /* XXX : not implemented */
7181 spr_register(env, SPR_ICTRL, "ICTRL",
7182 SPR_NOACCESS, SPR_NOACCESS,
7183 &spr_read_generic, &spr_write_generic,
7186 /* XXX : not implemented */
7187 spr_register(env, SPR_MSSSR0, "MSSSR0",
7188 SPR_NOACCESS, SPR_NOACCESS,
7189 &spr_read_generic, &spr_write_generic,
7192 /* XXX : not implemented */
7193 spr_register(env, SPR_7XX_PMC5, "PMC5",
7194 SPR_NOACCESS, SPR_NOACCESS,
7195 &spr_read_generic, &spr_write_generic,
7197 /* XXX : not implemented */
7198 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
7199 &spr_read_ureg, SPR_NOACCESS,
7200 &spr_read_ureg, SPR_NOACCESS,
7202 /* XXX : not implemented */
7203 spr_register(env, SPR_7XX_PMC6, "PMC6",
7204 SPR_NOACCESS, SPR_NOACCESS,
7205 &spr_read_generic, &spr_write_generic,
7207 /* XXX : not implemented */
7208 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
7209 &spr_read_ureg, SPR_NOACCESS,
7210 &spr_read_ureg, SPR_NOACCESS,
7213 spr_register(env, SPR_SPRG4, "SPRG4",
7214 SPR_NOACCESS, SPR_NOACCESS,
7215 &spr_read_generic, &spr_write_generic,
7217 spr_register(env, SPR_USPRG4, "USPRG4",
7218 &spr_read_ureg, SPR_NOACCESS,
7219 &spr_read_ureg, SPR_NOACCESS,
7221 spr_register(env, SPR_SPRG5, "SPRG5",
7222 SPR_NOACCESS, SPR_NOACCESS,
7223 &spr_read_generic, &spr_write_generic,
7225 spr_register(env, SPR_USPRG5, "USPRG5",
7226 &spr_read_ureg, SPR_NOACCESS,
7227 &spr_read_ureg, SPR_NOACCESS,
7229 spr_register(env, SPR_SPRG6, "SPRG6",
7230 SPR_NOACCESS, SPR_NOACCESS,
7231 &spr_read_generic, &spr_write_generic,
7233 spr_register(env, SPR_USPRG6, "USPRG6",
7234 &spr_read_ureg, SPR_NOACCESS,
7235 &spr_read_ureg, SPR_NOACCESS,
7237 spr_register(env, SPR_SPRG7, "SPRG7",
7238 SPR_NOACCESS, SPR_NOACCESS,
7239 &spr_read_generic, &spr_write_generic,
7241 spr_register(env, SPR_USPRG7, "USPRG7",
7242 &spr_read_ureg, SPR_NOACCESS,
7243 &spr_read_ureg, SPR_NOACCESS,
7245 /* Memory management */
7248 gen_74xx_soft_tlb(env, 128, 2);
7249 init_excp_7450(env);
7250 env->dcache_line_size = 32;
7251 env->icache_line_size = 32;
7252 /* Allocate hardware IRQ controller */
7253 ppc6xx_irq_init(env_archcpu(env));
7256 POWERPC_FAMILY(7455)(ObjectClass *oc, void *data)
7258 DeviceClass *dc = DEVICE_CLASS(oc);
7259 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7261 dc->desc = "PowerPC 7455 (aka G4)";
7262 pcc->init_proc = init_proc_7455;
7263 pcc->check_pow = check_pow_hid0_74xx;
7264 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7265 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7266 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7268 PPC_CACHE | PPC_CACHE_ICBI |
7269 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7270 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7271 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7272 PPC_MEM_TLBIA | PPC_74xx_TLB |
7273 PPC_SEGMENT | PPC_EXTERN |
7275 pcc->msr_mask = (1ull << MSR_VR) |
7292 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
7293 pcc->excp_model = POWERPC_EXCP_74xx;
7294 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7295 pcc->bfd_mach = bfd_mach_ppc_7400;
7296 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7297 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7298 POWERPC_FLAG_BUS_CLK;
7301 static void init_proc_7457(CPUPPCState *env)
7303 gen_spr_ne_601(env);
7308 /* 74xx specific SPR */
7310 /* Level 3 cache control */
7313 /* XXX : not implemented */
7314 spr_register(env, SPR_L3ITCR1, "L3ITCR1",
7315 SPR_NOACCESS, SPR_NOACCESS,
7316 &spr_read_generic, &spr_write_generic,
7319 /* XXX : not implemented */
7320 spr_register(env, SPR_L3ITCR2, "L3ITCR2",
7321 SPR_NOACCESS, SPR_NOACCESS,
7322 &spr_read_generic, &spr_write_generic,
7325 /* XXX : not implemented */
7326 spr_register(env, SPR_L3ITCR3, "L3ITCR3",
7327 SPR_NOACCESS, SPR_NOACCESS,
7328 &spr_read_generic, &spr_write_generic,
7331 /* XXX : not implemented */
7332 spr_register(env, SPR_L3OHCR, "L3OHCR",
7333 SPR_NOACCESS, SPR_NOACCESS,
7334 &spr_read_generic, &spr_write_generic,
7337 /* XXX : not implemented */
7338 spr_register(env, SPR_LDSTCR, "LDSTCR",
7339 SPR_NOACCESS, SPR_NOACCESS,
7340 &spr_read_generic, &spr_write_generic,
7343 /* XXX : not implemented */
7344 spr_register(env, SPR_ICTRL, "ICTRL",
7345 SPR_NOACCESS, SPR_NOACCESS,
7346 &spr_read_generic, &spr_write_generic,
7349 /* XXX : not implemented */
7350 spr_register(env, SPR_MSSSR0, "MSSSR0",
7351 SPR_NOACCESS, SPR_NOACCESS,
7352 &spr_read_generic, &spr_write_generic,
7355 /* XXX : not implemented */
7356 spr_register(env, SPR_7XX_PMC5, "PMC5",
7357 SPR_NOACCESS, SPR_NOACCESS,
7358 &spr_read_generic, &spr_write_generic,
7360 /* XXX : not implemented */
7361 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
7362 &spr_read_ureg, SPR_NOACCESS,
7363 &spr_read_ureg, SPR_NOACCESS,
7365 /* XXX : not implemented */
7366 spr_register(env, SPR_7XX_PMC6, "PMC6",
7367 SPR_NOACCESS, SPR_NOACCESS,
7368 &spr_read_generic, &spr_write_generic,
7370 /* XXX : not implemented */
7371 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
7372 &spr_read_ureg, SPR_NOACCESS,
7373 &spr_read_ureg, SPR_NOACCESS,
7376 spr_register(env, SPR_SPRG4, "SPRG4",
7377 SPR_NOACCESS, SPR_NOACCESS,
7378 &spr_read_generic, &spr_write_generic,
7380 spr_register(env, SPR_USPRG4, "USPRG4",
7381 &spr_read_ureg, SPR_NOACCESS,
7382 &spr_read_ureg, SPR_NOACCESS,
7384 spr_register(env, SPR_SPRG5, "SPRG5",
7385 SPR_NOACCESS, SPR_NOACCESS,
7386 &spr_read_generic, &spr_write_generic,
7388 spr_register(env, SPR_USPRG5, "USPRG5",
7389 &spr_read_ureg, SPR_NOACCESS,
7390 &spr_read_ureg, SPR_NOACCESS,
7392 spr_register(env, SPR_SPRG6, "SPRG6",
7393 SPR_NOACCESS, SPR_NOACCESS,
7394 &spr_read_generic, &spr_write_generic,
7396 spr_register(env, SPR_USPRG6, "USPRG6",
7397 &spr_read_ureg, SPR_NOACCESS,
7398 &spr_read_ureg, SPR_NOACCESS,
7400 spr_register(env, SPR_SPRG7, "SPRG7",
7401 SPR_NOACCESS, SPR_NOACCESS,
7402 &spr_read_generic, &spr_write_generic,
7404 spr_register(env, SPR_USPRG7, "USPRG7",
7405 &spr_read_ureg, SPR_NOACCESS,
7406 &spr_read_ureg, SPR_NOACCESS,
7408 /* Memory management */
7411 gen_74xx_soft_tlb(env, 128, 2);
7412 init_excp_7450(env);
7413 env->dcache_line_size = 32;
7414 env->icache_line_size = 32;
7415 /* Allocate hardware IRQ controller */
7416 ppc6xx_irq_init(env_archcpu(env));
7419 POWERPC_FAMILY(7457)(ObjectClass *oc, void *data)
7421 DeviceClass *dc = DEVICE_CLASS(oc);
7422 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7424 dc->desc = "PowerPC 7457 (aka G4)";
7425 pcc->init_proc = init_proc_7457;
7426 pcc->check_pow = check_pow_hid0_74xx;
7427 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7428 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7429 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7431 PPC_CACHE | PPC_CACHE_ICBI |
7432 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7433 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7434 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7435 PPC_MEM_TLBIA | PPC_74xx_TLB |
7436 PPC_SEGMENT | PPC_EXTERN |
7438 pcc->msr_mask = (1ull << MSR_VR) |
7455 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
7456 pcc->excp_model = POWERPC_EXCP_74xx;
7457 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7458 pcc->bfd_mach = bfd_mach_ppc_7400;
7459 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7460 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7461 POWERPC_FLAG_BUS_CLK;
7464 static void init_proc_e600(CPUPPCState *env)
7466 gen_spr_ne_601(env);
7471 /* 74xx specific SPR */
7473 /* XXX : not implemented */
7474 spr_register(env, SPR_UBAMR, "UBAMR",
7475 &spr_read_ureg, SPR_NOACCESS,
7476 &spr_read_ureg, SPR_NOACCESS,
7478 /* XXX : not implemented */
7479 spr_register(env, SPR_LDSTCR, "LDSTCR",
7480 SPR_NOACCESS, SPR_NOACCESS,
7481 &spr_read_generic, &spr_write_generic,
7483 /* XXX : not implemented */
7484 spr_register(env, SPR_ICTRL, "ICTRL",
7485 SPR_NOACCESS, SPR_NOACCESS,
7486 &spr_read_generic, &spr_write_generic,
7488 /* XXX : not implemented */
7489 spr_register(env, SPR_MSSSR0, "MSSSR0",
7490 SPR_NOACCESS, SPR_NOACCESS,
7491 &spr_read_generic, &spr_write_generic,
7493 /* XXX : not implemented */
7494 spr_register(env, SPR_7XX_PMC5, "PMC5",
7495 SPR_NOACCESS, SPR_NOACCESS,
7496 &spr_read_generic, &spr_write_generic,
7498 /* XXX : not implemented */
7499 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
7500 &spr_read_ureg, SPR_NOACCESS,
7501 &spr_read_ureg, SPR_NOACCESS,
7503 /* XXX : not implemented */
7504 spr_register(env, SPR_7XX_PMC6, "PMC6",
7505 SPR_NOACCESS, SPR_NOACCESS,
7506 &spr_read_generic, &spr_write_generic,
7508 /* XXX : not implemented */
7509 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
7510 &spr_read_ureg, SPR_NOACCESS,
7511 &spr_read_ureg, SPR_NOACCESS,
7514 spr_register(env, SPR_SPRG4, "SPRG4",
7515 SPR_NOACCESS, SPR_NOACCESS,
7516 &spr_read_generic, &spr_write_generic,
7518 spr_register(env, SPR_USPRG4, "USPRG4",
7519 &spr_read_ureg, SPR_NOACCESS,
7520 &spr_read_ureg, SPR_NOACCESS,
7522 spr_register(env, SPR_SPRG5, "SPRG5",
7523 SPR_NOACCESS, SPR_NOACCESS,
7524 &spr_read_generic, &spr_write_generic,
7526 spr_register(env, SPR_USPRG5, "USPRG5",
7527 &spr_read_ureg, SPR_NOACCESS,
7528 &spr_read_ureg, SPR_NOACCESS,
7530 spr_register(env, SPR_SPRG6, "SPRG6",
7531 SPR_NOACCESS, SPR_NOACCESS,
7532 &spr_read_generic, &spr_write_generic,
7534 spr_register(env, SPR_USPRG6, "USPRG6",
7535 &spr_read_ureg, SPR_NOACCESS,
7536 &spr_read_ureg, SPR_NOACCESS,
7538 spr_register(env, SPR_SPRG7, "SPRG7",
7539 SPR_NOACCESS, SPR_NOACCESS,
7540 &spr_read_generic, &spr_write_generic,
7542 spr_register(env, SPR_USPRG7, "USPRG7",
7543 &spr_read_ureg, SPR_NOACCESS,
7544 &spr_read_ureg, SPR_NOACCESS,
7546 /* Memory management */
7549 gen_74xx_soft_tlb(env, 128, 2);
7550 init_excp_7450(env);
7551 env->dcache_line_size = 32;
7552 env->icache_line_size = 32;
7553 /* Allocate hardware IRQ controller */
7554 ppc6xx_irq_init(env_archcpu(env));
7557 POWERPC_FAMILY(e600)(ObjectClass *oc, void *data)
7559 DeviceClass *dc = DEVICE_CLASS(oc);
7560 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7562 dc->desc = "PowerPC e600";
7563 pcc->init_proc = init_proc_e600;
7564 pcc->check_pow = check_pow_hid0_74xx;
7565 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7566 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7567 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7569 PPC_CACHE | PPC_CACHE_ICBI |
7570 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7571 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7572 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7573 PPC_MEM_TLBIA | PPC_74xx_TLB |
7574 PPC_SEGMENT | PPC_EXTERN |
7576 pcc->insns_flags2 = PPC_NONE;
7577 pcc->msr_mask = (1ull << MSR_VR) |
7594 pcc->mmu_model = POWERPC_MMU_32B;
7595 #if defined(CONFIG_SOFTMMU)
7596 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
7598 pcc->excp_model = POWERPC_EXCP_74xx;
7599 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7600 pcc->bfd_mach = bfd_mach_ppc_7400;
7601 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7602 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7603 POWERPC_FLAG_BUS_CLK;
7606 #if defined(TARGET_PPC64)
7607 #if defined(CONFIG_USER_ONLY)
7608 #define POWERPC970_HID5_INIT 0x00000080
7610 #define POWERPC970_HID5_INIT 0x00000000
7613 static void gen_fscr_facility_check(DisasContext *ctx, int facility_sprn,
7614 int bit, int sprn, int cause)
7616 TCGv_i32 t1 = tcg_const_i32(bit);
7617 TCGv_i32 t2 = tcg_const_i32(sprn);
7618 TCGv_i32 t3 = tcg_const_i32(cause);
7620 gen_helper_fscr_facility_check(cpu_env, t1, t2, t3);
7622 tcg_temp_free_i32(t3);
7623 tcg_temp_free_i32(t2);
7624 tcg_temp_free_i32(t1);
7627 static void gen_msr_facility_check(DisasContext *ctx, int facility_sprn,
7628 int bit, int sprn, int cause)
7630 TCGv_i32 t1 = tcg_const_i32(bit);
7631 TCGv_i32 t2 = tcg_const_i32(sprn);
7632 TCGv_i32 t3 = tcg_const_i32(cause);
7634 gen_helper_msr_facility_check(cpu_env, t1, t2, t3);
7636 tcg_temp_free_i32(t3);
7637 tcg_temp_free_i32(t2);
7638 tcg_temp_free_i32(t1);
7641 static void spr_read_prev_upper32(DisasContext *ctx, int gprn, int sprn)
7643 TCGv spr_up = tcg_temp_new();
7644 TCGv spr = tcg_temp_new();
7646 gen_load_spr(spr, sprn - 1);
7647 tcg_gen_shri_tl(spr_up, spr, 32);
7648 tcg_gen_ext32u_tl(cpu_gpr[gprn], spr_up);
7651 tcg_temp_free(spr_up);
7654 static void spr_write_prev_upper32(DisasContext *ctx, int sprn, int gprn)
7656 TCGv spr = tcg_temp_new();
7658 gen_load_spr(spr, sprn - 1);
7659 tcg_gen_deposit_tl(spr, spr, cpu_gpr[gprn], 32, 32);
7660 gen_store_spr(sprn - 1, spr);
7665 static int check_pow_970(CPUPPCState *env)
7667 if (env->spr[SPR_HID0] & (HID0_DEEPNAP | HID0_DOZE | HID0_NAP)) {
7674 static void gen_spr_970_hid(CPUPPCState *env)
7676 /* Hardware implementation registers */
7677 /* XXX : not implemented */
7678 spr_register(env, SPR_HID0, "HID0",
7679 SPR_NOACCESS, SPR_NOACCESS,
7680 &spr_read_generic, &spr_write_clear,
7682 spr_register(env, SPR_HID1, "HID1",
7683 SPR_NOACCESS, SPR_NOACCESS,
7684 &spr_read_generic, &spr_write_generic,
7686 spr_register(env, SPR_970_HID5, "HID5",
7687 SPR_NOACCESS, SPR_NOACCESS,
7688 &spr_read_generic, &spr_write_generic,
7689 POWERPC970_HID5_INIT);
7692 static void gen_spr_970_hior(CPUPPCState *env)
7694 spr_register(env, SPR_HIOR, "SPR_HIOR",
7695 SPR_NOACCESS, SPR_NOACCESS,
7696 &spr_read_hior, &spr_write_hior,
7700 static void gen_spr_book3s_ctrl(CPUPPCState *env)
7702 spr_register(env, SPR_CTRL, "SPR_CTRL",
7703 SPR_NOACCESS, SPR_NOACCESS,
7704 SPR_NOACCESS, &spr_write_generic,
7706 spr_register(env, SPR_UCTRL, "SPR_UCTRL",
7707 &spr_read_ureg, SPR_NOACCESS,
7708 &spr_read_ureg, SPR_NOACCESS,
7712 static void gen_spr_book3s_altivec(CPUPPCState *env)
7714 if (!(env->insns_flags & PPC_ALTIVEC)) {
7718 spr_register_kvm(env, SPR_VRSAVE, "VRSAVE",
7719 &spr_read_generic, &spr_write_generic,
7720 &spr_read_generic, &spr_write_generic,
7721 KVM_REG_PPC_VRSAVE, 0x00000000);
7724 * Can't find information on what this should be on reset. This
7725 * value is the one used by 74xx processors.
7727 vscr_init(env, 0x00010000);
7730 static void gen_spr_book3s_dbg(CPUPPCState *env)
7733 * TODO: different specs define different scopes for these,
7734 * will have to address this:
7735 * 970: super/write and super/read
7736 * powerisa 2.03..2.04: hypv/write and super/read.
7737 * powerisa 2.05 and newer: hypv/write and hypv/read.
7739 spr_register_kvm(env, SPR_DABR, "DABR",
7740 SPR_NOACCESS, SPR_NOACCESS,
7741 &spr_read_generic, &spr_write_generic,
7742 KVM_REG_PPC_DABR, 0x00000000);
7743 spr_register_kvm(env, SPR_DABRX, "DABRX",
7744 SPR_NOACCESS, SPR_NOACCESS,
7745 &spr_read_generic, &spr_write_generic,
7746 KVM_REG_PPC_DABRX, 0x00000000);
7749 static void gen_spr_book3s_207_dbg(CPUPPCState *env)
7751 spr_register_kvm_hv(env, SPR_DAWR, "DAWR",
7752 SPR_NOACCESS, SPR_NOACCESS,
7753 SPR_NOACCESS, SPR_NOACCESS,
7754 &spr_read_generic, &spr_write_generic,
7755 KVM_REG_PPC_DAWR, 0x00000000);
7756 spr_register_kvm_hv(env, SPR_DAWRX, "DAWRX",
7757 SPR_NOACCESS, SPR_NOACCESS,
7758 SPR_NOACCESS, SPR_NOACCESS,
7759 &spr_read_generic, &spr_write_generic,
7760 KVM_REG_PPC_DAWRX, 0x00000000);
7761 spr_register_kvm_hv(env, SPR_CIABR, "CIABR",
7762 SPR_NOACCESS, SPR_NOACCESS,
7763 SPR_NOACCESS, SPR_NOACCESS,
7764 &spr_read_generic, &spr_write_generic,
7765 KVM_REG_PPC_CIABR, 0x00000000);
7768 static void gen_spr_970_dbg(CPUPPCState *env)
7771 spr_register(env, SPR_IABR, "IABR",
7772 SPR_NOACCESS, SPR_NOACCESS,
7773 &spr_read_generic, &spr_write_generic,
7777 static void gen_spr_book3s_pmu_sup(CPUPPCState *env)
7779 spr_register_kvm(env, SPR_POWER_MMCR0, "MMCR0",
7780 SPR_NOACCESS, SPR_NOACCESS,
7781 &spr_read_generic, &spr_write_generic,
7782 KVM_REG_PPC_MMCR0, 0x00000000);
7783 spr_register_kvm(env, SPR_POWER_MMCR1, "MMCR1",
7784 SPR_NOACCESS, SPR_NOACCESS,
7785 &spr_read_generic, &spr_write_generic,
7786 KVM_REG_PPC_MMCR1, 0x00000000);
7787 spr_register_kvm(env, SPR_POWER_MMCRA, "MMCRA",
7788 SPR_NOACCESS, SPR_NOACCESS,
7789 &spr_read_generic, &spr_write_generic,
7790 KVM_REG_PPC_MMCRA, 0x00000000);
7791 spr_register_kvm(env, SPR_POWER_PMC1, "PMC1",
7792 SPR_NOACCESS, SPR_NOACCESS,
7793 &spr_read_generic, &spr_write_generic,
7794 KVM_REG_PPC_PMC1, 0x00000000);
7795 spr_register_kvm(env, SPR_POWER_PMC2, "PMC2",
7796 SPR_NOACCESS, SPR_NOACCESS,
7797 &spr_read_generic, &spr_write_generic,
7798 KVM_REG_PPC_PMC2, 0x00000000);
7799 spr_register_kvm(env, SPR_POWER_PMC3, "PMC3",
7800 SPR_NOACCESS, SPR_NOACCESS,
7801 &spr_read_generic, &spr_write_generic,
7802 KVM_REG_PPC_PMC3, 0x00000000);
7803 spr_register_kvm(env, SPR_POWER_PMC4, "PMC4",
7804 SPR_NOACCESS, SPR_NOACCESS,
7805 &spr_read_generic, &spr_write_generic,
7806 KVM_REG_PPC_PMC4, 0x00000000);
7807 spr_register_kvm(env, SPR_POWER_PMC5, "PMC5",
7808 SPR_NOACCESS, SPR_NOACCESS,
7809 &spr_read_generic, &spr_write_generic,
7810 KVM_REG_PPC_PMC5, 0x00000000);
7811 spr_register_kvm(env, SPR_POWER_PMC6, "PMC6",
7812 SPR_NOACCESS, SPR_NOACCESS,
7813 &spr_read_generic, &spr_write_generic,
7814 KVM_REG_PPC_PMC6, 0x00000000);
7815 spr_register_kvm(env, SPR_POWER_SIAR, "SIAR",
7816 SPR_NOACCESS, SPR_NOACCESS,
7817 &spr_read_generic, &spr_write_generic,
7818 KVM_REG_PPC_SIAR, 0x00000000);
7819 spr_register_kvm(env, SPR_POWER_SDAR, "SDAR",
7820 SPR_NOACCESS, SPR_NOACCESS,
7821 &spr_read_generic, &spr_write_generic,
7822 KVM_REG_PPC_SDAR, 0x00000000);
7825 static void gen_spr_book3s_pmu_user(CPUPPCState *env)
7827 spr_register(env, SPR_POWER_UMMCR0, "UMMCR0",
7828 &spr_read_ureg, SPR_NOACCESS,
7829 &spr_read_ureg, &spr_write_ureg,
7831 spr_register(env, SPR_POWER_UMMCR1, "UMMCR1",
7832 &spr_read_ureg, SPR_NOACCESS,
7833 &spr_read_ureg, &spr_write_ureg,
7835 spr_register(env, SPR_POWER_UMMCRA, "UMMCRA",
7836 &spr_read_ureg, SPR_NOACCESS,
7837 &spr_read_ureg, &spr_write_ureg,
7839 spr_register(env, SPR_POWER_UPMC1, "UPMC1",
7840 &spr_read_ureg, SPR_NOACCESS,
7841 &spr_read_ureg, &spr_write_ureg,
7843 spr_register(env, SPR_POWER_UPMC2, "UPMC2",
7844 &spr_read_ureg, SPR_NOACCESS,
7845 &spr_read_ureg, &spr_write_ureg,
7847 spr_register(env, SPR_POWER_UPMC3, "UPMC3",
7848 &spr_read_ureg, SPR_NOACCESS,
7849 &spr_read_ureg, &spr_write_ureg,
7851 spr_register(env, SPR_POWER_UPMC4, "UPMC4",
7852 &spr_read_ureg, SPR_NOACCESS,
7853 &spr_read_ureg, &spr_write_ureg,
7855 spr_register(env, SPR_POWER_UPMC5, "UPMC5",
7856 &spr_read_ureg, SPR_NOACCESS,
7857 &spr_read_ureg, &spr_write_ureg,
7859 spr_register(env, SPR_POWER_UPMC6, "UPMC6",
7860 &spr_read_ureg, SPR_NOACCESS,
7861 &spr_read_ureg, &spr_write_ureg,
7863 spr_register(env, SPR_POWER_USIAR, "USIAR",
7864 &spr_read_ureg, SPR_NOACCESS,
7865 &spr_read_ureg, &spr_write_ureg,
7867 spr_register(env, SPR_POWER_USDAR, "USDAR",
7868 &spr_read_ureg, SPR_NOACCESS,
7869 &spr_read_ureg, &spr_write_ureg,
7873 static void gen_spr_970_pmu_sup(CPUPPCState *env)
7875 spr_register_kvm(env, SPR_970_PMC7, "PMC7",
7876 SPR_NOACCESS, SPR_NOACCESS,
7877 &spr_read_generic, &spr_write_generic,
7878 KVM_REG_PPC_PMC7, 0x00000000);
7879 spr_register_kvm(env, SPR_970_PMC8, "PMC8",
7880 SPR_NOACCESS, SPR_NOACCESS,
7881 &spr_read_generic, &spr_write_generic,
7882 KVM_REG_PPC_PMC8, 0x00000000);
7885 static void gen_spr_970_pmu_user(CPUPPCState *env)
7887 spr_register(env, SPR_970_UPMC7, "UPMC7",
7888 &spr_read_ureg, SPR_NOACCESS,
7889 &spr_read_ureg, &spr_write_ureg,
7891 spr_register(env, SPR_970_UPMC8, "UPMC8",
7892 &spr_read_ureg, SPR_NOACCESS,
7893 &spr_read_ureg, &spr_write_ureg,
7897 static void gen_spr_power8_pmu_sup(CPUPPCState *env)
7899 spr_register_kvm(env, SPR_POWER_MMCR2, "MMCR2",
7900 SPR_NOACCESS, SPR_NOACCESS,
7901 &spr_read_generic, &spr_write_generic,
7902 KVM_REG_PPC_MMCR2, 0x00000000);
7903 spr_register_kvm(env, SPR_POWER_MMCRS, "MMCRS",
7904 SPR_NOACCESS, SPR_NOACCESS,
7905 &spr_read_generic, &spr_write_generic,
7906 KVM_REG_PPC_MMCRS, 0x00000000);
7907 spr_register_kvm(env, SPR_POWER_SIER, "SIER",
7908 SPR_NOACCESS, SPR_NOACCESS,
7909 &spr_read_generic, &spr_write_generic,
7910 KVM_REG_PPC_SIER, 0x00000000);
7911 spr_register_kvm(env, SPR_POWER_SPMC1, "SPMC1",
7912 SPR_NOACCESS, SPR_NOACCESS,
7913 &spr_read_generic, &spr_write_generic,
7914 KVM_REG_PPC_SPMC1, 0x00000000);
7915 spr_register_kvm(env, SPR_POWER_SPMC2, "SPMC2",
7916 SPR_NOACCESS, SPR_NOACCESS,
7917 &spr_read_generic, &spr_write_generic,
7918 KVM_REG_PPC_SPMC2, 0x00000000);
7919 spr_register_kvm(env, SPR_TACR, "TACR",
7920 SPR_NOACCESS, SPR_NOACCESS,
7921 &spr_read_generic, &spr_write_generic,
7922 KVM_REG_PPC_TACR, 0x00000000);
7923 spr_register_kvm(env, SPR_TCSCR, "TCSCR",
7924 SPR_NOACCESS, SPR_NOACCESS,
7925 &spr_read_generic, &spr_write_generic,
7926 KVM_REG_PPC_TCSCR, 0x00000000);
7927 spr_register_kvm(env, SPR_CSIGR, "CSIGR",
7928 SPR_NOACCESS, SPR_NOACCESS,
7929 &spr_read_generic, &spr_write_generic,
7930 KVM_REG_PPC_CSIGR, 0x00000000);
7933 static void gen_spr_power8_pmu_user(CPUPPCState *env)
7935 spr_register(env, SPR_POWER_UMMCR2, "UMMCR2",
7936 &spr_read_ureg, SPR_NOACCESS,
7937 &spr_read_ureg, &spr_write_ureg,
7939 spr_register(env, SPR_POWER_USIER, "USIER",
7940 &spr_read_generic, SPR_NOACCESS,
7941 &spr_read_generic, &spr_write_generic,
7945 static void gen_spr_power5p_ear(CPUPPCState *env)
7947 /* External access control */
7948 spr_register(env, SPR_EAR, "EAR",
7949 SPR_NOACCESS, SPR_NOACCESS,
7950 &spr_read_generic, &spr_write_generic,
7954 static void gen_spr_power5p_tb(CPUPPCState *env)
7956 /* TBU40 (High 40 bits of the Timebase register */
7957 spr_register_hv(env, SPR_TBU40, "TBU40",
7958 SPR_NOACCESS, SPR_NOACCESS,
7959 SPR_NOACCESS, SPR_NOACCESS,
7960 SPR_NOACCESS, &spr_write_tbu40,
7964 #if !defined(CONFIG_USER_ONLY)
7965 static void spr_write_hmer(DisasContext *ctx, int sprn, int gprn)
7967 TCGv hmer = tcg_temp_new();
7969 gen_load_spr(hmer, sprn);
7970 tcg_gen_and_tl(hmer, cpu_gpr[gprn], hmer);
7971 gen_store_spr(sprn, hmer);
7972 spr_store_dump_spr(sprn);
7973 tcg_temp_free(hmer);
7976 static void spr_write_lpcr(DisasContext *ctx, int sprn, int gprn)
7978 gen_helper_store_lpcr(cpu_env, cpu_gpr[gprn]);
7980 #endif /* !defined(CONFIG_USER_ONLY) */
7982 static void gen_spr_970_lpar(CPUPPCState *env)
7984 #if !defined(CONFIG_USER_ONLY)
7986 * PPC970: HID4 covers things later controlled by the LPCR and
7987 * RMOR in later CPUs, but with a different encoding. We only
7988 * support the 970 in "Apple mode" which has all hypervisor
7989 * facilities disabled by strapping, so we can basically just
7992 spr_register(env, SPR_970_HID4, "HID4",
7993 SPR_NOACCESS, SPR_NOACCESS,
7994 &spr_read_generic, &spr_write_generic,
7999 static void gen_spr_power5p_lpar(CPUPPCState *env)
8001 #if !defined(CONFIG_USER_ONLY)
8002 /* Logical partitionning */
8003 spr_register_kvm_hv(env, SPR_LPCR, "LPCR",
8004 SPR_NOACCESS, SPR_NOACCESS,
8005 SPR_NOACCESS, SPR_NOACCESS,
8006 &spr_read_generic, &spr_write_lpcr,
8007 KVM_REG_PPC_LPCR, LPCR_LPES0 | LPCR_LPES1);
8008 spr_register_hv(env, SPR_HDEC, "HDEC",
8009 SPR_NOACCESS, SPR_NOACCESS,
8010 SPR_NOACCESS, SPR_NOACCESS,
8011 &spr_read_hdecr, &spr_write_hdecr, 0);
8015 static void gen_spr_book3s_ids(CPUPPCState *env)
8017 /* FIXME: Will need to deal with thread vs core only SPRs */
8019 /* Processor identification */
8020 spr_register_hv(env, SPR_PIR, "PIR",
8021 SPR_NOACCESS, SPR_NOACCESS,
8022 &spr_read_generic, SPR_NOACCESS,
8023 &spr_read_generic, NULL,
8025 spr_register_hv(env, SPR_HID0, "HID0",
8026 SPR_NOACCESS, SPR_NOACCESS,
8027 SPR_NOACCESS, SPR_NOACCESS,
8028 &spr_read_generic, &spr_write_generic,
8030 spr_register_hv(env, SPR_TSCR, "TSCR",
8031 SPR_NOACCESS, SPR_NOACCESS,
8032 SPR_NOACCESS, SPR_NOACCESS,
8033 &spr_read_generic, &spr_write_generic,
8035 spr_register_hv(env, SPR_HMER, "HMER",
8036 SPR_NOACCESS, SPR_NOACCESS,
8037 SPR_NOACCESS, SPR_NOACCESS,
8038 &spr_read_generic, &spr_write_hmer,
8040 spr_register_hv(env, SPR_HMEER, "HMEER",
8041 SPR_NOACCESS, SPR_NOACCESS,
8042 SPR_NOACCESS, SPR_NOACCESS,
8043 &spr_read_generic, &spr_write_generic,
8045 spr_register_hv(env, SPR_TFMR, "TFMR",
8046 SPR_NOACCESS, SPR_NOACCESS,
8047 SPR_NOACCESS, SPR_NOACCESS,
8048 &spr_read_generic, &spr_write_generic,
8050 spr_register_hv(env, SPR_LPIDR, "LPIDR",
8051 SPR_NOACCESS, SPR_NOACCESS,
8052 SPR_NOACCESS, SPR_NOACCESS,
8053 &spr_read_generic, &spr_write_lpidr,
8055 spr_register_hv(env, SPR_HFSCR, "HFSCR",
8056 SPR_NOACCESS, SPR_NOACCESS,
8057 SPR_NOACCESS, SPR_NOACCESS,
8058 &spr_read_generic, &spr_write_generic,
8060 spr_register_hv(env, SPR_MMCRC, "MMCRC",
8061 SPR_NOACCESS, SPR_NOACCESS,
8062 SPR_NOACCESS, SPR_NOACCESS,
8063 &spr_read_generic, &spr_write_generic,
8065 spr_register_hv(env, SPR_MMCRH, "MMCRH",
8066 SPR_NOACCESS, SPR_NOACCESS,
8067 SPR_NOACCESS, SPR_NOACCESS,
8068 &spr_read_generic, &spr_write_generic,
8070 spr_register_hv(env, SPR_HSPRG0, "HSPRG0",
8071 SPR_NOACCESS, SPR_NOACCESS,
8072 SPR_NOACCESS, SPR_NOACCESS,
8073 &spr_read_generic, &spr_write_generic,
8075 spr_register_hv(env, SPR_HSPRG1, "HSPRG1",
8076 SPR_NOACCESS, SPR_NOACCESS,
8077 SPR_NOACCESS, SPR_NOACCESS,
8078 &spr_read_generic, &spr_write_generic,
8080 spr_register_hv(env, SPR_HSRR0, "HSRR0",
8081 SPR_NOACCESS, SPR_NOACCESS,
8082 SPR_NOACCESS, SPR_NOACCESS,
8083 &spr_read_generic, &spr_write_generic,
8085 spr_register_hv(env, SPR_HSRR1, "HSRR1",
8086 SPR_NOACCESS, SPR_NOACCESS,
8087 SPR_NOACCESS, SPR_NOACCESS,
8088 &spr_read_generic, &spr_write_generic,
8090 spr_register_hv(env, SPR_HDAR, "HDAR",
8091 SPR_NOACCESS, SPR_NOACCESS,
8092 SPR_NOACCESS, SPR_NOACCESS,
8093 &spr_read_generic, &spr_write_generic,
8095 spr_register_hv(env, SPR_HDSISR, "HDSISR",
8096 SPR_NOACCESS, SPR_NOACCESS,
8097 SPR_NOACCESS, SPR_NOACCESS,
8098 &spr_read_generic, &spr_write_generic,
8100 spr_register_hv(env, SPR_HRMOR, "HRMOR",
8101 SPR_NOACCESS, SPR_NOACCESS,
8102 SPR_NOACCESS, SPR_NOACCESS,
8103 &spr_read_generic, &spr_write_generic,
8107 static void gen_spr_rmor(CPUPPCState *env)
8109 spr_register_hv(env, SPR_RMOR, "RMOR",
8110 SPR_NOACCESS, SPR_NOACCESS,
8111 SPR_NOACCESS, SPR_NOACCESS,
8112 &spr_read_generic, &spr_write_generic,
8116 static void gen_spr_power8_ids(CPUPPCState *env)
8118 /* Thread identification */
8119 spr_register(env, SPR_TIR, "TIR",
8120 SPR_NOACCESS, SPR_NOACCESS,
8121 &spr_read_generic, SPR_NOACCESS,
8125 static void gen_spr_book3s_purr(CPUPPCState *env)
8127 #if !defined(CONFIG_USER_ONLY)
8128 /* PURR & SPURR: Hack - treat these as aliases for the TB for now */
8129 spr_register_kvm_hv(env, SPR_PURR, "PURR",
8130 &spr_read_purr, SPR_NOACCESS,
8131 &spr_read_purr, SPR_NOACCESS,
8132 &spr_read_purr, &spr_write_purr,
8133 KVM_REG_PPC_PURR, 0x00000000);
8134 spr_register_kvm_hv(env, SPR_SPURR, "SPURR",
8135 &spr_read_purr, SPR_NOACCESS,
8136 &spr_read_purr, SPR_NOACCESS,
8137 &spr_read_purr, &spr_write_purr,
8138 KVM_REG_PPC_SPURR, 0x00000000);
8142 static void gen_spr_power6_dbg(CPUPPCState *env)
8144 #if !defined(CONFIG_USER_ONLY)
8145 spr_register(env, SPR_CFAR, "SPR_CFAR",
8146 SPR_NOACCESS, SPR_NOACCESS,
8147 &spr_read_cfar, &spr_write_cfar,
8152 static void gen_spr_power5p_common(CPUPPCState *env)
8154 spr_register_kvm(env, SPR_PPR, "PPR",
8155 &spr_read_generic, &spr_write_generic,
8156 &spr_read_generic, &spr_write_generic,
8157 KVM_REG_PPC_PPR, 0x00000000);
8160 static void gen_spr_power6_common(CPUPPCState *env)
8162 #if !defined(CONFIG_USER_ONLY)
8163 spr_register_kvm(env, SPR_DSCR, "SPR_DSCR",
8164 SPR_NOACCESS, SPR_NOACCESS,
8165 &spr_read_generic, &spr_write_generic,
8166 KVM_REG_PPC_DSCR, 0x00000000);
8169 * Register PCR to report POWERPC_EXCP_PRIV_REG instead of
8170 * POWERPC_EXCP_INVAL_SPR in userspace. Permit hypervisor access.
8172 spr_register_hv(env, SPR_PCR, "PCR",
8173 SPR_NOACCESS, SPR_NOACCESS,
8174 SPR_NOACCESS, SPR_NOACCESS,
8175 &spr_read_generic, &spr_write_pcr,
8179 static void spr_read_tar(DisasContext *ctx, int gprn, int sprn)
8181 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_TAR, sprn, FSCR_IC_TAR);
8182 spr_read_generic(ctx, gprn, sprn);
8185 static void spr_write_tar(DisasContext *ctx, int sprn, int gprn)
8187 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_TAR, sprn, FSCR_IC_TAR);
8188 spr_write_generic(ctx, sprn, gprn);
8191 static void gen_spr_power8_tce_address_control(CPUPPCState *env)
8193 spr_register_kvm(env, SPR_TAR, "TAR",
8194 &spr_read_tar, &spr_write_tar,
8195 &spr_read_generic, &spr_write_generic,
8196 KVM_REG_PPC_TAR, 0x00000000);
8199 static void spr_read_tm(DisasContext *ctx, int gprn, int sprn)
8201 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8202 spr_read_generic(ctx, gprn, sprn);
8205 static void spr_write_tm(DisasContext *ctx, int sprn, int gprn)
8207 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8208 spr_write_generic(ctx, sprn, gprn);
8211 static void spr_read_tm_upper32(DisasContext *ctx, int gprn, int sprn)
8213 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8214 spr_read_prev_upper32(ctx, gprn, sprn);
8217 static void spr_write_tm_upper32(DisasContext *ctx, int sprn, int gprn)
8219 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8220 spr_write_prev_upper32(ctx, sprn, gprn);
8223 static void gen_spr_power8_tm(CPUPPCState *env)
8225 spr_register_kvm(env, SPR_TFHAR, "TFHAR",
8226 &spr_read_tm, &spr_write_tm,
8227 &spr_read_tm, &spr_write_tm,
8228 KVM_REG_PPC_TFHAR, 0x00000000);
8229 spr_register_kvm(env, SPR_TFIAR, "TFIAR",
8230 &spr_read_tm, &spr_write_tm,
8231 &spr_read_tm, &spr_write_tm,
8232 KVM_REG_PPC_TFIAR, 0x00000000);
8233 spr_register_kvm(env, SPR_TEXASR, "TEXASR",
8234 &spr_read_tm, &spr_write_tm,
8235 &spr_read_tm, &spr_write_tm,
8236 KVM_REG_PPC_TEXASR, 0x00000000);
8237 spr_register(env, SPR_TEXASRU, "TEXASRU",
8238 &spr_read_tm_upper32, &spr_write_tm_upper32,
8239 &spr_read_tm_upper32, &spr_write_tm_upper32,
8243 static void spr_read_ebb(DisasContext *ctx, int gprn, int sprn)
8245 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8246 spr_read_generic(ctx, gprn, sprn);
8249 static void spr_write_ebb(DisasContext *ctx, int sprn, int gprn)
8251 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8252 spr_write_generic(ctx, sprn, gprn);
8255 static void spr_read_ebb_upper32(DisasContext *ctx, int gprn, int sprn)
8257 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8258 spr_read_prev_upper32(ctx, gprn, sprn);
8261 static void spr_write_ebb_upper32(DisasContext *ctx, int sprn, int gprn)
8263 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8264 spr_write_prev_upper32(ctx, sprn, gprn);
8267 static void gen_spr_power8_ebb(CPUPPCState *env)
8269 spr_register(env, SPR_BESCRS, "BESCRS",
8270 &spr_read_ebb, &spr_write_ebb,
8271 &spr_read_generic, &spr_write_generic,
8273 spr_register(env, SPR_BESCRSU, "BESCRSU",
8274 &spr_read_ebb_upper32, &spr_write_ebb_upper32,
8275 &spr_read_prev_upper32, &spr_write_prev_upper32,
8277 spr_register(env, SPR_BESCRR, "BESCRR",
8278 &spr_read_ebb, &spr_write_ebb,
8279 &spr_read_generic, &spr_write_generic,
8281 spr_register(env, SPR_BESCRRU, "BESCRRU",
8282 &spr_read_ebb_upper32, &spr_write_ebb_upper32,
8283 &spr_read_prev_upper32, &spr_write_prev_upper32,
8285 spr_register_kvm(env, SPR_EBBHR, "EBBHR",
8286 &spr_read_ebb, &spr_write_ebb,
8287 &spr_read_generic, &spr_write_generic,
8288 KVM_REG_PPC_EBBHR, 0x00000000);
8289 spr_register_kvm(env, SPR_EBBRR, "EBBRR",
8290 &spr_read_ebb, &spr_write_ebb,
8291 &spr_read_generic, &spr_write_generic,
8292 KVM_REG_PPC_EBBRR, 0x00000000);
8293 spr_register_kvm(env, SPR_BESCR, "BESCR",
8294 &spr_read_ebb, &spr_write_ebb,
8295 &spr_read_generic, &spr_write_generic,
8296 KVM_REG_PPC_BESCR, 0x00000000);
8299 /* Virtual Time Base */
8300 static void gen_spr_vtb(CPUPPCState *env)
8302 spr_register_kvm_hv(env, SPR_VTB, "VTB",
8303 SPR_NOACCESS, SPR_NOACCESS,
8304 &spr_read_vtb, SPR_NOACCESS,
8305 &spr_read_vtb, &spr_write_vtb,
8306 KVM_REG_PPC_VTB, 0x00000000);
8309 static void gen_spr_power8_fscr(CPUPPCState *env)
8311 #if defined(CONFIG_USER_ONLY)
8312 target_ulong initval = 1ULL << FSCR_TAR;
8314 target_ulong initval = 0;
8316 spr_register_kvm(env, SPR_FSCR, "FSCR",
8317 SPR_NOACCESS, SPR_NOACCESS,
8318 &spr_read_generic, &spr_write_generic,
8319 KVM_REG_PPC_FSCR, initval);
8322 static void gen_spr_power8_pspb(CPUPPCState *env)
8324 spr_register_kvm(env, SPR_PSPB, "PSPB",
8325 SPR_NOACCESS, SPR_NOACCESS,
8326 &spr_read_generic, &spr_write_generic32,
8327 KVM_REG_PPC_PSPB, 0);
8330 static void gen_spr_power8_dpdes(CPUPPCState *env)
8332 #if !defined(CONFIG_USER_ONLY)
8333 /* Directed Privileged Door-bell Exception State, used for IPI */
8334 spr_register_kvm_hv(env, SPR_DPDES, "DPDES",
8335 SPR_NOACCESS, SPR_NOACCESS,
8336 &spr_read_dpdes, SPR_NOACCESS,
8337 &spr_read_dpdes, &spr_write_dpdes,
8338 KVM_REG_PPC_DPDES, 0x00000000);
8342 static void gen_spr_power8_ic(CPUPPCState *env)
8344 #if !defined(CONFIG_USER_ONLY)
8345 spr_register_hv(env, SPR_IC, "IC",
8346 SPR_NOACCESS, SPR_NOACCESS,
8347 &spr_read_generic, SPR_NOACCESS,
8348 &spr_read_generic, &spr_write_generic,
8353 static void gen_spr_power8_book4(CPUPPCState *env)
8355 /* Add a number of P8 book4 registers */
8356 #if !defined(CONFIG_USER_ONLY)
8357 spr_register_kvm(env, SPR_ACOP, "ACOP",
8358 SPR_NOACCESS, SPR_NOACCESS,
8359 &spr_read_generic, &spr_write_generic,
8360 KVM_REG_PPC_ACOP, 0);
8361 spr_register_kvm(env, SPR_BOOKS_PID, "PID",
8362 SPR_NOACCESS, SPR_NOACCESS,
8363 &spr_read_generic, &spr_write_pidr,
8364 KVM_REG_PPC_PID, 0);
8365 spr_register_kvm(env, SPR_WORT, "WORT",
8366 SPR_NOACCESS, SPR_NOACCESS,
8367 &spr_read_generic, &spr_write_generic,
8368 KVM_REG_PPC_WORT, 0);
8372 static void gen_spr_power7_book4(CPUPPCState *env)
8374 /* Add a number of P7 book4 registers */
8375 #if !defined(CONFIG_USER_ONLY)
8376 spr_register_kvm(env, SPR_ACOP, "ACOP",
8377 SPR_NOACCESS, SPR_NOACCESS,
8378 &spr_read_generic, &spr_write_generic,
8379 KVM_REG_PPC_ACOP, 0);
8380 spr_register_kvm(env, SPR_BOOKS_PID, "PID",
8381 SPR_NOACCESS, SPR_NOACCESS,
8382 &spr_read_generic, &spr_write_generic,
8383 KVM_REG_PPC_PID, 0);
8387 static void gen_spr_power8_rpr(CPUPPCState *env)
8389 #if !defined(CONFIG_USER_ONLY)
8390 spr_register_hv(env, SPR_RPR, "RPR",
8391 SPR_NOACCESS, SPR_NOACCESS,
8392 SPR_NOACCESS, SPR_NOACCESS,
8393 &spr_read_generic, &spr_write_generic,
8394 0x00000103070F1F3F);
8398 static void gen_spr_power9_mmu(CPUPPCState *env)
8400 #if !defined(CONFIG_USER_ONLY)
8401 /* Partition Table Control */
8402 spr_register_kvm_hv(env, SPR_PTCR, "PTCR",
8403 SPR_NOACCESS, SPR_NOACCESS,
8404 SPR_NOACCESS, SPR_NOACCESS,
8405 &spr_read_generic, &spr_write_ptcr,
8406 KVM_REG_PPC_PTCR, 0x00000000);
8407 /* Address Segment Descriptor Register */
8408 spr_register_hv(env, SPR_ASDR, "ASDR",
8409 SPR_NOACCESS, SPR_NOACCESS,
8410 SPR_NOACCESS, SPR_NOACCESS,
8411 &spr_read_generic, &spr_write_generic,
8412 0x0000000000000000);
8416 static void init_proc_book3s_common(CPUPPCState *env)
8418 gen_spr_ne_601(env);
8420 gen_spr_usprg3(env);
8421 gen_spr_book3s_altivec(env);
8422 gen_spr_book3s_pmu_sup(env);
8423 gen_spr_book3s_pmu_user(env);
8424 gen_spr_book3s_ctrl(env);
8427 static void init_proc_970(CPUPPCState *env)
8429 /* Common Registers */
8430 init_proc_book3s_common(env);
8432 gen_spr_book3s_dbg(env);
8434 /* 970 Specific Registers */
8435 gen_spr_970_hid(env);
8436 gen_spr_970_hior(env);
8438 gen_spr_970_pmu_sup(env);
8439 gen_spr_970_pmu_user(env);
8440 gen_spr_970_lpar(env);
8441 gen_spr_970_dbg(env);
8444 env->dcache_line_size = 128;
8445 env->icache_line_size = 128;
8447 /* Allocate hardware IRQ controller */
8449 ppc970_irq_init(env_archcpu(env));
8452 POWERPC_FAMILY(970)(ObjectClass *oc, void *data)
8454 DeviceClass *dc = DEVICE_CLASS(oc);
8455 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8457 dc->desc = "PowerPC 970";
8458 pcc->init_proc = init_proc_970;
8459 pcc->check_pow = check_pow_970;
8460 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
8461 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8462 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
8464 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8465 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8466 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
8467 PPC_64B | PPC_ALTIVEC |
8468 PPC_SEGMENT_64B | PPC_SLBI;
8469 pcc->insns_flags2 = PPC2_FP_CVT_S64;
8470 pcc->msr_mask = (1ull << MSR_SF) |
8485 pcc->mmu_model = POWERPC_MMU_64B;
8486 #if defined(CONFIG_SOFTMMU)
8487 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
8488 pcc->hash64_opts = &ppc_hash64_opts_basic;
8490 pcc->excp_model = POWERPC_EXCP_970;
8491 pcc->bus_model = PPC_FLAGS_INPUT_970;
8492 pcc->bfd_mach = bfd_mach_ppc64;
8493 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8494 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8495 POWERPC_FLAG_BUS_CLK;
8496 pcc->l1_dcache_size = 0x8000;
8497 pcc->l1_icache_size = 0x10000;
8500 static void init_proc_power5plus(CPUPPCState *env)
8502 /* Common Registers */
8503 init_proc_book3s_common(env);
8505 gen_spr_book3s_dbg(env);
8507 /* POWER5+ Specific Registers */
8508 gen_spr_970_hid(env);
8509 gen_spr_970_hior(env);
8511 gen_spr_970_pmu_sup(env);
8512 gen_spr_970_pmu_user(env);
8513 gen_spr_power5p_common(env);
8514 gen_spr_power5p_lpar(env);
8515 gen_spr_power5p_ear(env);
8516 gen_spr_power5p_tb(env);
8519 env->dcache_line_size = 128;
8520 env->icache_line_size = 128;
8522 /* Allocate hardware IRQ controller */
8524 ppc970_irq_init(env_archcpu(env));
8527 POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data)
8529 DeviceClass *dc = DEVICE_CLASS(oc);
8530 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8532 dc->fw_name = "PowerPC,POWER5";
8533 dc->desc = "POWER5+";
8534 pcc->init_proc = init_proc_power5plus;
8535 pcc->check_pow = check_pow_970;
8536 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
8537 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8538 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
8540 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8541 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8542 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
8544 PPC_SEGMENT_64B | PPC_SLBI;
8545 pcc->insns_flags2 = PPC2_FP_CVT_S64;
8546 pcc->msr_mask = (1ull << MSR_SF) |
8561 pcc->lpcr_mask = LPCR_RMLS | LPCR_ILE | LPCR_LPES0 | LPCR_LPES1 |
8562 LPCR_RMI | LPCR_HDICE;
8563 pcc->mmu_model = POWERPC_MMU_2_03;
8564 #if defined(CONFIG_SOFTMMU)
8565 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
8566 pcc->hash64_opts = &ppc_hash64_opts_basic;
8567 pcc->lrg_decr_bits = 32;
8569 pcc->excp_model = POWERPC_EXCP_970;
8570 pcc->bus_model = PPC_FLAGS_INPUT_970;
8571 pcc->bfd_mach = bfd_mach_ppc64;
8572 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8573 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8574 POWERPC_FLAG_BUS_CLK;
8575 pcc->l1_dcache_size = 0x8000;
8576 pcc->l1_icache_size = 0x10000;
8579 static void init_proc_POWER7(CPUPPCState *env)
8581 /* Common Registers */
8582 init_proc_book3s_common(env);
8584 gen_spr_book3s_dbg(env);
8586 /* POWER7 Specific Registers */
8587 gen_spr_book3s_ids(env);
8590 gen_spr_book3s_purr(env);
8591 gen_spr_power5p_common(env);
8592 gen_spr_power5p_lpar(env);
8593 gen_spr_power5p_ear(env);
8594 gen_spr_power5p_tb(env);
8595 gen_spr_power6_common(env);
8596 gen_spr_power6_dbg(env);
8597 gen_spr_power7_book4(env);
8600 env->dcache_line_size = 128;
8601 env->icache_line_size = 128;
8603 /* Allocate hardware IRQ controller */
8604 init_excp_POWER7(env);
8605 ppcPOWER7_irq_init(env_archcpu(env));
8608 static bool ppc_pvr_match_power7(PowerPCCPUClass *pcc, uint32_t pvr)
8610 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7P_BASE) {
8613 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7_BASE) {
8619 static bool cpu_has_work_POWER7(CPUState *cs)
8621 PowerPCCPU *cpu = POWERPC_CPU(cs);
8622 CPUPPCState *env = &cpu->env;
8625 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
8628 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
8629 (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) {
8632 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
8633 (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) {
8636 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
8637 (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
8640 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
8641 (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
8644 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
8649 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
8653 POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
8655 DeviceClass *dc = DEVICE_CLASS(oc);
8656 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8657 CPUClass *cc = CPU_CLASS(oc);
8659 dc->fw_name = "PowerPC,POWER7";
8660 dc->desc = "POWER7";
8661 pcc->pvr_match = ppc_pvr_match_power7;
8662 pcc->pcr_mask = PCR_VEC_DIS | PCR_VSX_DIS | PCR_COMPAT_2_05;
8663 pcc->pcr_supported = PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
8664 pcc->init_proc = init_proc_POWER7;
8665 pcc->check_pow = check_pow_nocheck;
8666 cc->has_work = cpu_has_work_POWER7;
8667 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
8668 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8669 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
8670 PPC_FLOAT_FRSQRTES |
8673 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8674 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8675 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
8676 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
8677 PPC_SEGMENT_64B | PPC_SLBI |
8678 PPC_POPCNTB | PPC_POPCNTWD |
8680 pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
8681 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
8682 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
8683 PPC2_FP_TST_ISA206 | PPC2_FP_CVT_S64 |
8685 pcc->msr_mask = (1ull << MSR_SF) |
8701 pcc->lpcr_mask = LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_DPFD |
8702 LPCR_VRMASD | LPCR_RMLS | LPCR_ILE |
8703 LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2 |
8704 LPCR_MER | LPCR_TC |
8705 LPCR_LPES0 | LPCR_LPES1 | LPCR_HDICE;
8706 pcc->lpcr_pm = LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2;
8707 pcc->mmu_model = POWERPC_MMU_2_06;
8708 #if defined(CONFIG_SOFTMMU)
8709 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
8710 pcc->hash64_opts = &ppc_hash64_opts_POWER7;
8711 pcc->lrg_decr_bits = 32;
8713 pcc->excp_model = POWERPC_EXCP_POWER7;
8714 pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
8715 pcc->bfd_mach = bfd_mach_ppc64;
8716 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8717 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8718 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
8720 pcc->l1_dcache_size = 0x8000;
8721 pcc->l1_icache_size = 0x8000;
8722 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
8725 static void init_proc_POWER8(CPUPPCState *env)
8727 /* Common Registers */
8728 init_proc_book3s_common(env);
8730 gen_spr_book3s_207_dbg(env);
8732 /* POWER8 Specific Registers */
8733 gen_spr_book3s_ids(env);
8737 gen_spr_book3s_purr(env);
8738 gen_spr_power5p_common(env);
8739 gen_spr_power5p_lpar(env);
8740 gen_spr_power5p_ear(env);
8741 gen_spr_power5p_tb(env);
8742 gen_spr_power6_common(env);
8743 gen_spr_power6_dbg(env);
8744 gen_spr_power8_tce_address_control(env);
8745 gen_spr_power8_ids(env);
8746 gen_spr_power8_ebb(env);
8747 gen_spr_power8_fscr(env);
8748 gen_spr_power8_pmu_sup(env);
8749 gen_spr_power8_pmu_user(env);
8750 gen_spr_power8_tm(env);
8751 gen_spr_power8_pspb(env);
8752 gen_spr_power8_dpdes(env);
8754 gen_spr_power8_ic(env);
8755 gen_spr_power8_book4(env);
8756 gen_spr_power8_rpr(env);
8759 env->dcache_line_size = 128;
8760 env->icache_line_size = 128;
8762 /* Allocate hardware IRQ controller */
8763 init_excp_POWER8(env);
8764 ppcPOWER7_irq_init(env_archcpu(env));
8767 static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, uint32_t pvr)
8769 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8NVL_BASE) {
8772 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8E_BASE) {
8775 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8_BASE) {
8781 static bool cpu_has_work_POWER8(CPUState *cs)
8783 PowerPCCPU *cpu = POWERPC_CPU(cs);
8784 CPUPPCState *env = &cpu->env;
8787 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
8790 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
8791 (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) {
8794 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
8795 (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) {
8798 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
8799 (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
8802 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
8803 (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
8806 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
8807 (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) {
8810 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
8811 (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) {
8814 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
8819 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
8823 POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
8825 DeviceClass *dc = DEVICE_CLASS(oc);
8826 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8827 CPUClass *cc = CPU_CLASS(oc);
8829 dc->fw_name = "PowerPC,POWER8";
8830 dc->desc = "POWER8";
8831 pcc->pvr_match = ppc_pvr_match_power8;
8832 pcc->pcr_mask = PCR_TM_DIS | PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
8833 pcc->pcr_supported = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
8834 pcc->init_proc = init_proc_POWER8;
8835 pcc->check_pow = check_pow_nocheck;
8836 cc->has_work = cpu_has_work_POWER8;
8837 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
8838 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8839 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
8840 PPC_FLOAT_FRSQRTES |
8843 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8844 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8845 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
8846 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
8847 PPC_SEGMENT_64B | PPC_SLBI |
8848 PPC_POPCNTB | PPC_POPCNTWD |
8850 pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
8851 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
8852 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
8853 PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
8854 PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
8855 PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
8856 PPC2_TM | PPC2_PM_ISA206;
8857 pcc->msr_mask = (1ull << MSR_SF) |
8877 pcc->lpcr_mask = LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV |
8878 LPCR_DPFD | LPCR_VRMASD | LPCR_RMLS | LPCR_ILE |
8879 LPCR_AIL | LPCR_ONL | LPCR_P8_PECE0 | LPCR_P8_PECE1 |
8880 LPCR_P8_PECE2 | LPCR_P8_PECE3 | LPCR_P8_PECE4 |
8881 LPCR_MER | LPCR_TC | LPCR_LPES0 | LPCR_HDICE;
8882 pcc->lpcr_pm = LPCR_P8_PECE0 | LPCR_P8_PECE1 | LPCR_P8_PECE2 |
8883 LPCR_P8_PECE3 | LPCR_P8_PECE4;
8884 pcc->mmu_model = POWERPC_MMU_2_07;
8885 #if defined(CONFIG_SOFTMMU)
8886 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
8887 pcc->hash64_opts = &ppc_hash64_opts_POWER7;
8888 pcc->lrg_decr_bits = 32;
8889 pcc->n_host_threads = 8;
8891 pcc->excp_model = POWERPC_EXCP_POWER8;
8892 pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
8893 pcc->bfd_mach = bfd_mach_ppc64;
8894 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8895 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8896 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
8897 POWERPC_FLAG_VSX | POWERPC_FLAG_TM;
8898 pcc->l1_dcache_size = 0x8000;
8899 pcc->l1_icache_size = 0x8000;
8900 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
8903 #ifdef CONFIG_SOFTMMU
8905 * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
8906 * Encoded as array of int_32s in the form:
8907 * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
8909 * y -> radix mode supported page size (encoded as a shift)
8911 static struct ppc_radix_page_info POWER9_radix_page_info = {
8914 0x0000000c, /* 4K - enc: 0x0 */
8915 0xa0000010, /* 64K - enc: 0x5 */
8916 0x20000015, /* 2M - enc: 0x1 */
8917 0x4000001e /* 1G - enc: 0x2 */
8920 #endif /* CONFIG_SOFTMMU */
8922 static void init_proc_POWER9(CPUPPCState *env)
8924 /* Common Registers */
8925 init_proc_book3s_common(env);
8926 gen_spr_book3s_207_dbg(env);
8928 /* POWER8 Specific Registers */
8929 gen_spr_book3s_ids(env);
8932 gen_spr_book3s_purr(env);
8933 gen_spr_power5p_common(env);
8934 gen_spr_power5p_lpar(env);
8935 gen_spr_power5p_ear(env);
8936 gen_spr_power5p_tb(env);
8937 gen_spr_power6_common(env);
8938 gen_spr_power6_dbg(env);
8939 gen_spr_power8_tce_address_control(env);
8940 gen_spr_power8_ids(env);
8941 gen_spr_power8_ebb(env);
8942 gen_spr_power8_fscr(env);
8943 gen_spr_power8_pmu_sup(env);
8944 gen_spr_power8_pmu_user(env);
8945 gen_spr_power8_tm(env);
8946 gen_spr_power8_pspb(env);
8947 gen_spr_power8_dpdes(env);
8949 gen_spr_power8_ic(env);
8950 gen_spr_power8_book4(env);
8951 gen_spr_power8_rpr(env);
8952 gen_spr_power9_mmu(env);
8954 /* POWER9 Specific registers */
8955 spr_register_kvm(env, SPR_TIDR, "TIDR", NULL, NULL,
8956 spr_read_generic, spr_write_generic,
8957 KVM_REG_PPC_TIDR, 0);
8959 /* FIXME: Filter fields properly based on privilege level */
8960 spr_register_kvm_hv(env, SPR_PSSCR, "PSSCR", NULL, NULL, NULL, NULL,
8961 spr_read_generic, spr_write_generic,
8962 KVM_REG_PPC_PSSCR, 0);
8965 env->dcache_line_size = 128;
8966 env->icache_line_size = 128;
8968 /* Allocate hardware IRQ controller */
8969 init_excp_POWER9(env);
8970 ppcPOWER9_irq_init(env_archcpu(env));
8973 static bool ppc_pvr_match_power9(PowerPCCPUClass *pcc, uint32_t pvr)
8975 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER9_BASE) {
8981 static bool cpu_has_work_POWER9(CPUState *cs)
8983 PowerPCCPU *cpu = POWERPC_CPU(cs);
8984 CPUPPCState *env = &cpu->env;
8987 uint64_t psscr = env->spr[SPR_PSSCR];
8989 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
8993 /* If EC is clear, just return true on any pending interrupt */
8994 if (!(psscr & PSSCR_EC)) {
8997 /* External Exception */
8998 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
8999 (env->spr[SPR_LPCR] & LPCR_EEE)) {
9000 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
9001 if (heic == 0 || !msr_hv || msr_pr) {
9005 /* Decrementer Exception */
9006 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
9007 (env->spr[SPR_LPCR] & LPCR_DEE)) {
9010 /* Machine Check or Hypervisor Maintenance Exception */
9011 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK |
9012 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) {
9015 /* Privileged Doorbell Exception */
9016 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
9017 (env->spr[SPR_LPCR] & LPCR_PDEE)) {
9020 /* Hypervisor Doorbell Exception */
9021 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
9022 (env->spr[SPR_LPCR] & LPCR_HDEE)) {
9025 /* Hypervisor virtualization exception */
9026 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) &&
9027 (env->spr[SPR_LPCR] & LPCR_HVEE)) {
9030 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
9035 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
9039 POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
9041 DeviceClass *dc = DEVICE_CLASS(oc);
9042 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
9043 CPUClass *cc = CPU_CLASS(oc);
9045 dc->fw_name = "PowerPC,POWER9";
9046 dc->desc = "POWER9";
9047 pcc->pvr_match = ppc_pvr_match_power9;
9048 pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07;
9049 pcc->pcr_supported = PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 |
9051 pcc->init_proc = init_proc_POWER9;
9052 pcc->check_pow = check_pow_nocheck;
9053 cc->has_work = cpu_has_work_POWER9;
9054 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
9055 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
9056 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
9057 PPC_FLOAT_FRSQRTES |
9060 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
9061 PPC_MEM_SYNC | PPC_MEM_EIEIO |
9063 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
9064 PPC_SEGMENT_64B | PPC_SLBI |
9065 PPC_POPCNTB | PPC_POPCNTWD |
9067 pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
9068 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
9069 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
9070 PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
9071 PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
9072 PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
9073 PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL;
9074 pcc->msr_mask = (1ull << MSR_SF) |
9092 pcc->lpcr_mask = LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD |
9093 (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL |
9094 LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR | LPCR_LD |
9095 (LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE | LPCR_EEE |
9096 LPCR_DEE | LPCR_OEE))
9097 | LPCR_MER | LPCR_GTSE | LPCR_TC |
9098 LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE | LPCR_HDICE;
9099 pcc->lpcr_pm = LPCR_PDEE | LPCR_HDEE | LPCR_EEE | LPCR_DEE | LPCR_OEE;
9100 pcc->mmu_model = POWERPC_MMU_3_00;
9101 #if defined(CONFIG_SOFTMMU)
9102 pcc->handle_mmu_fault = ppc64_v3_handle_mmu_fault;
9103 /* segment page size remain the same */
9104 pcc->hash64_opts = &ppc_hash64_opts_POWER7;
9105 pcc->radix_page_info = &POWER9_radix_page_info;
9106 pcc->lrg_decr_bits = 56;
9107 pcc->n_host_threads = 4;
9109 pcc->excp_model = POWERPC_EXCP_POWER9;
9110 pcc->bus_model = PPC_FLAGS_INPUT_POWER9;
9111 pcc->bfd_mach = bfd_mach_ppc64;
9112 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
9113 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
9114 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
9115 POWERPC_FLAG_VSX | POWERPC_FLAG_TM | POWERPC_FLAG_SCV;
9116 pcc->l1_dcache_size = 0x8000;
9117 pcc->l1_icache_size = 0x8000;
9118 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
9121 #ifdef CONFIG_SOFTMMU
9123 * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
9124 * Encoded as array of int_32s in the form:
9125 * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
9127 * y -> radix mode supported page size (encoded as a shift)
9129 static struct ppc_radix_page_info POWER10_radix_page_info = {
9132 0x0000000c, /* 4K - enc: 0x0 */
9133 0xa0000010, /* 64K - enc: 0x5 */
9134 0x20000015, /* 2M - enc: 0x1 */
9135 0x4000001e /* 1G - enc: 0x2 */
9138 #endif /* CONFIG_SOFTMMU */
9140 static void init_proc_POWER10(CPUPPCState *env)
9142 /* Common Registers */
9143 init_proc_book3s_common(env);
9144 gen_spr_book3s_207_dbg(env);
9146 /* POWER8 Specific Registers */
9147 gen_spr_book3s_ids(env);
9150 gen_spr_book3s_purr(env);
9151 gen_spr_power5p_common(env);
9152 gen_spr_power5p_lpar(env);
9153 gen_spr_power5p_ear(env);
9154 gen_spr_power6_common(env);
9155 gen_spr_power6_dbg(env);
9156 gen_spr_power8_tce_address_control(env);
9157 gen_spr_power8_ids(env);
9158 gen_spr_power8_ebb(env);
9159 gen_spr_power8_fscr(env);
9160 gen_spr_power8_pmu_sup(env);
9161 gen_spr_power8_pmu_user(env);
9162 gen_spr_power8_tm(env);
9163 gen_spr_power8_pspb(env);
9165 gen_spr_power8_ic(env);
9166 gen_spr_power8_book4(env);
9167 gen_spr_power8_rpr(env);
9168 gen_spr_power9_mmu(env);
9170 /* FIXME: Filter fields properly based on privilege level */
9171 spr_register_kvm_hv(env, SPR_PSSCR, "PSSCR", NULL, NULL, NULL, NULL,
9172 spr_read_generic, spr_write_generic,
9173 KVM_REG_PPC_PSSCR, 0);
9176 env->dcache_line_size = 128;
9177 env->icache_line_size = 128;
9179 /* Allocate hardware IRQ controller */
9180 init_excp_POWER10(env);
9181 ppcPOWER9_irq_init(env_archcpu(env));
9184 static bool ppc_pvr_match_power10(PowerPCCPUClass *pcc, uint32_t pvr)
9186 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER10_BASE) {
9192 static bool cpu_has_work_POWER10(CPUState *cs)
9194 PowerPCCPU *cpu = POWERPC_CPU(cs);
9195 CPUPPCState *env = &cpu->env;
9198 uint64_t psscr = env->spr[SPR_PSSCR];
9200 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
9204 /* If EC is clear, just return true on any pending interrupt */
9205 if (!(psscr & PSSCR_EC)) {
9208 /* External Exception */
9209 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
9210 (env->spr[SPR_LPCR] & LPCR_EEE)) {
9211 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
9212 if (heic == 0 || !msr_hv || msr_pr) {
9216 /* Decrementer Exception */
9217 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
9218 (env->spr[SPR_LPCR] & LPCR_DEE)) {
9221 /* Machine Check or Hypervisor Maintenance Exception */
9222 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK |
9223 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) {
9226 /* Privileged Doorbell Exception */
9227 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
9228 (env->spr[SPR_LPCR] & LPCR_PDEE)) {
9231 /* Hypervisor Doorbell Exception */
9232 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
9233 (env->spr[SPR_LPCR] & LPCR_HDEE)) {
9236 /* Hypervisor virtualization exception */
9237 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) &&
9238 (env->spr[SPR_LPCR] & LPCR_HVEE)) {
9241 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
9246 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
9250 POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data)
9252 DeviceClass *dc = DEVICE_CLASS(oc);
9253 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
9254 CPUClass *cc = CPU_CLASS(oc);
9256 dc->fw_name = "PowerPC,POWER10";
9257 dc->desc = "POWER10";
9258 pcc->pvr_match = ppc_pvr_match_power10;
9259 pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07 |
9261 pcc->pcr_supported = PCR_COMPAT_3_10 | PCR_COMPAT_3_00 | PCR_COMPAT_2_07 |
9262 PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
9263 pcc->init_proc = init_proc_POWER10;
9264 pcc->check_pow = check_pow_nocheck;
9265 cc->has_work = cpu_has_work_POWER10;
9266 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
9267 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
9268 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
9269 PPC_FLOAT_FRSQRTES |
9272 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
9273 PPC_MEM_SYNC | PPC_MEM_EIEIO |
9275 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
9276 PPC_SEGMENT_64B | PPC_SLBI |
9277 PPC_POPCNTB | PPC_POPCNTWD |
9279 pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
9280 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
9281 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
9282 PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
9283 PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
9284 PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
9285 PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL | PPC2_ISA310;
9286 pcc->msr_mask = (1ull << MSR_SF) |
9304 pcc->lpcr_mask = LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD |
9305 (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL |
9306 LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR | LPCR_LD |
9307 (LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE | LPCR_EEE |
9308 LPCR_DEE | LPCR_OEE))
9309 | LPCR_MER | LPCR_GTSE | LPCR_TC |
9310 LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE | LPCR_HDICE;
9311 pcc->lpcr_pm = LPCR_PDEE | LPCR_HDEE | LPCR_EEE | LPCR_DEE | LPCR_OEE;
9312 pcc->mmu_model = POWERPC_MMU_3_00;
9313 #if defined(CONFIG_SOFTMMU)
9314 pcc->handle_mmu_fault = ppc64_v3_handle_mmu_fault;
9315 /* segment page size remain the same */
9316 pcc->hash64_opts = &ppc_hash64_opts_POWER7;
9317 pcc->radix_page_info = &POWER10_radix_page_info;
9318 pcc->lrg_decr_bits = 56;
9320 pcc->excp_model = POWERPC_EXCP_POWER9;
9321 pcc->bus_model = PPC_FLAGS_INPUT_POWER9;
9322 pcc->bfd_mach = bfd_mach_ppc64;
9323 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
9324 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
9325 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
9326 POWERPC_FLAG_VSX | POWERPC_FLAG_TM;
9327 pcc->l1_dcache_size = 0x8000;
9328 pcc->l1_icache_size = 0x8000;
9329 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
9332 #if !defined(CONFIG_USER_ONLY)
9333 void cpu_ppc_set_vhyp(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp)
9335 CPUPPCState *env = &cpu->env;
9340 * With a virtual hypervisor mode we never allow the CPU to go
9341 * hypervisor mode itself
9343 env->msr_mask &= ~MSR_HVB;
9346 #endif /* !defined(CONFIG_USER_ONLY) */
9348 #endif /* defined(TARGET_PPC64) */
9350 /*****************************************************************************/
9351 /* Generic CPU instantiation routine */
9352 static void init_ppc_proc(PowerPCCPU *cpu)
9354 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
9355 CPUPPCState *env = &cpu->env;
9356 #if !defined(CONFIG_USER_ONLY)
9359 env->irq_inputs = NULL;
9360 /* Set all exception vectors to an invalid address */
9361 for (i = 0; i < POWERPC_EXCP_NB; i++) {
9362 env->excp_vectors[i] = (target_ulong)(-1ULL);
9364 env->ivor_mask = 0x00000000;
9365 env->ivpr_mask = 0x00000000;
9366 /* Default MMU definitions */
9370 env->tlb_type = TLB_NONE;
9372 /* Register SPR common to all PowerPC implementations */
9373 gen_spr_generic(env);
9374 spr_register(env, SPR_PVR, "PVR",
9375 /* Linux permits userspace to read PVR */
9376 #if defined(CONFIG_LINUX_USER)
9382 &spr_read_generic, SPR_NOACCESS,
9384 /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
9385 if (pcc->svr != POWERPC_SVR_NONE) {
9386 if (pcc->svr & POWERPC_SVR_E500) {
9387 spr_register(env, SPR_E500_SVR, "SVR",
9388 SPR_NOACCESS, SPR_NOACCESS,
9389 &spr_read_generic, SPR_NOACCESS,
9390 pcc->svr & ~POWERPC_SVR_E500);
9392 spr_register(env, SPR_SVR, "SVR",
9393 SPR_NOACCESS, SPR_NOACCESS,
9394 &spr_read_generic, SPR_NOACCESS,
9398 /* PowerPC implementation specific initialisations (SPRs, timers, ...) */
9399 (*pcc->init_proc)(env);
9401 #if !defined(CONFIG_USER_ONLY)
9402 ppc_gdb_gen_spr_xml(cpu);
9405 /* MSR bits & flags consistency checks */
9406 if (env->msr_mask & (1 << 25)) {
9407 switch (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
9408 case POWERPC_FLAG_SPE:
9409 case POWERPC_FLAG_VRE:
9412 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9413 "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n");
9416 } else if (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
9417 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9418 "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n");
9421 if (env->msr_mask & (1 << 17)) {
9422 switch (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
9423 case POWERPC_FLAG_TGPR:
9424 case POWERPC_FLAG_CE:
9427 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9428 "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n");
9431 } else if (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
9432 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9433 "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n");
9436 if (env->msr_mask & (1 << 10)) {
9437 switch (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
9438 POWERPC_FLAG_UBLE)) {
9439 case POWERPC_FLAG_SE:
9440 case POWERPC_FLAG_DWE:
9441 case POWERPC_FLAG_UBLE:
9444 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9445 "Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE or "
9446 "POWERPC_FLAG_UBLE\n");
9449 } else if (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
9450 POWERPC_FLAG_UBLE)) {
9451 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9452 "Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE nor "
9453 "POWERPC_FLAG_UBLE\n");
9456 if (env->msr_mask & (1 << 9)) {
9457 switch (env->flags & (POWERPC_FLAG_BE | POWERPC_FLAG_DE)) {
9458 case POWERPC_FLAG_BE:
9459 case POWERPC_FLAG_DE:
9462 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9463 "Should define POWERPC_FLAG_BE or POWERPC_FLAG_DE\n");
9466 } else if (env->flags & (POWERPC_FLAG_BE | POWERPC_FLAG_DE)) {
9467 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9468 "Should not define POWERPC_FLAG_BE nor POWERPC_FLAG_DE\n");
9471 if (env->msr_mask & (1 << 2)) {
9472 switch (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
9473 case POWERPC_FLAG_PX:
9474 case POWERPC_FLAG_PMM:
9477 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9478 "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n");
9481 } else if (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
9482 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9483 "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
9486 if ((env->flags & (POWERPC_FLAG_RTC_CLK | POWERPC_FLAG_BUS_CLK)) == 0) {
9487 fprintf(stderr, "PowerPC flags inconsistency\n"
9488 "Should define the time-base and decrementer clock source\n");
9491 /* Allocate TLBs buffer when needed */
9492 #if !defined(CONFIG_USER_ONLY)
9493 if (env->nb_tlb != 0) {
9494 int nb_tlb = env->nb_tlb;
9495 if (env->id_tlbs != 0) {
9498 switch (env->tlb_type) {
9500 env->tlb.tlb6 = g_new0(ppc6xx_tlb_t, nb_tlb);
9503 env->tlb.tlbe = g_new0(ppcemb_tlb_t, nb_tlb);
9506 env->tlb.tlbm = g_new0(ppcmas_tlb_t, nb_tlb);
9509 /* Pre-compute some useful values */
9510 env->tlb_per_way = env->nb_tlb / env->nb_ways;
9512 if (env->irq_inputs == NULL) {
9513 warn_report("no internal IRQ controller registered."
9514 " Attempt QEMU to crash very soon !");
9517 if (env->check_pow == NULL) {
9518 warn_report("no power management check handler registered."
9519 " Attempt QEMU to crash very soon !");
9523 #if defined(PPC_DUMP_CPU)
9524 static void dump_ppc_sprs(CPUPPCState *env)
9527 #if !defined(CONFIG_USER_ONLY)
9533 printf("Special purpose registers:\n");
9534 for (i = 0; i < 32; i++) {
9535 for (j = 0; j < 32; j++) {
9537 spr = &env->spr_cb[n];
9538 uw = spr->uea_write != NULL && spr->uea_write != SPR_NOACCESS;
9539 ur = spr->uea_read != NULL && spr->uea_read != SPR_NOACCESS;
9540 #if !defined(CONFIG_USER_ONLY)
9541 sw = spr->oea_write != NULL && spr->oea_write != SPR_NOACCESS;
9542 sr = spr->oea_read != NULL && spr->oea_read != SPR_NOACCESS;
9543 if (sw || sr || uw || ur) {
9544 printf("SPR: %4d (%03x) %-8s s%c%c u%c%c\n",
9545 (i << 5) | j, (i << 5) | j, spr->name,
9546 sw ? 'w' : '-', sr ? 'r' : '-',
9547 uw ? 'w' : '-', ur ? 'r' : '-');
9551 printf("SPR: %4d (%03x) %-8s u%c%c\n",
9552 (i << 5) | j, (i << 5) | j, spr->name,
9553 uw ? 'w' : '-', ur ? 'r' : '-');
9563 /*****************************************************************************/
9567 PPC_DIRECT = 0, /* Opcode routine */
9568 PPC_INDIRECT = 1, /* Indirect opcode table */
9571 #define PPC_OPCODE_MASK 0x3
9573 static inline int is_indirect_opcode(void *handler)
9575 return ((uintptr_t)handler & PPC_OPCODE_MASK) == PPC_INDIRECT;
9578 static inline opc_handler_t **ind_table(void *handler)
9580 return (opc_handler_t **)((uintptr_t)handler & ~PPC_OPCODE_MASK);
9583 /* Instruction table creation */
9584 /* Opcodes tables creation */
9585 static void fill_new_table(opc_handler_t **table, int len)
9589 for (i = 0; i < len; i++) {
9590 table[i] = &invalid_handler;
9594 static int create_new_table(opc_handler_t **table, unsigned char idx)
9596 opc_handler_t **tmp;
9598 tmp = g_new(opc_handler_t *, PPC_CPU_INDIRECT_OPCODES_LEN);
9599 fill_new_table(tmp, PPC_CPU_INDIRECT_OPCODES_LEN);
9600 table[idx] = (opc_handler_t *)((uintptr_t)tmp | PPC_INDIRECT);
9605 static int insert_in_table(opc_handler_t **table, unsigned char idx,
9606 opc_handler_t *handler)
9608 if (table[idx] != &invalid_handler) {
9611 table[idx] = handler;
9616 static int register_direct_insn(opc_handler_t **ppc_opcodes,
9617 unsigned char idx, opc_handler_t *handler)
9619 if (insert_in_table(ppc_opcodes, idx, handler) < 0) {
9620 printf("*** ERROR: opcode %02x already assigned in main "
9621 "opcode table\n", idx);
9622 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9623 printf(" Registered handler '%s' - new handler '%s'\n",
9624 ppc_opcodes[idx]->oname, handler->oname);
9632 static int register_ind_in_table(opc_handler_t **table,
9633 unsigned char idx1, unsigned char idx2,
9634 opc_handler_t *handler)
9636 if (table[idx1] == &invalid_handler) {
9637 if (create_new_table(table, idx1) < 0) {
9638 printf("*** ERROR: unable to create indirect table "
9639 "idx=%02x\n", idx1);
9643 if (!is_indirect_opcode(table[idx1])) {
9644 printf("*** ERROR: idx %02x already assigned to a direct "
9646 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9647 printf(" Registered handler '%s' - new handler '%s'\n",
9648 ind_table(table[idx1])[idx2]->oname, handler->oname);
9653 if (handler != NULL &&
9654 insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) {
9655 printf("*** ERROR: opcode %02x already assigned in "
9656 "opcode table %02x\n", idx2, idx1);
9657 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9658 printf(" Registered handler '%s' - new handler '%s'\n",
9659 ind_table(table[idx1])[idx2]->oname, handler->oname);
9667 static int register_ind_insn(opc_handler_t **ppc_opcodes,
9668 unsigned char idx1, unsigned char idx2,
9669 opc_handler_t *handler)
9671 return register_ind_in_table(ppc_opcodes, idx1, idx2, handler);
9674 static int register_dblind_insn(opc_handler_t **ppc_opcodes,
9675 unsigned char idx1, unsigned char idx2,
9676 unsigned char idx3, opc_handler_t *handler)
9678 if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
9679 printf("*** ERROR: unable to join indirect table idx "
9680 "[%02x-%02x]\n", idx1, idx2);
9683 if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3,
9685 printf("*** ERROR: unable to insert opcode "
9686 "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
9693 static int register_trplind_insn(opc_handler_t **ppc_opcodes,
9694 unsigned char idx1, unsigned char idx2,
9695 unsigned char idx3, unsigned char idx4,
9696 opc_handler_t *handler)
9698 opc_handler_t **table;
9700 if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
9701 printf("*** ERROR: unable to join indirect table idx "
9702 "[%02x-%02x]\n", idx1, idx2);
9705 table = ind_table(ppc_opcodes[idx1]);
9706 if (register_ind_in_table(table, idx2, idx3, NULL) < 0) {
9707 printf("*** ERROR: unable to join 2nd-level indirect table idx "
9708 "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
9711 table = ind_table(table[idx2]);
9712 if (register_ind_in_table(table, idx3, idx4, handler) < 0) {
9713 printf("*** ERROR: unable to insert opcode "
9714 "[%02x-%02x-%02x-%02x]\n", idx1, idx2, idx3, idx4);
9719 static int register_insn(opc_handler_t **ppc_opcodes, opcode_t *insn)
9721 if (insn->opc2 != 0xFF) {
9722 if (insn->opc3 != 0xFF) {
9723 if (insn->opc4 != 0xFF) {
9724 if (register_trplind_insn(ppc_opcodes, insn->opc1, insn->opc2,
9725 insn->opc3, insn->opc4,
9726 &insn->handler) < 0) {
9730 if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2,
9731 insn->opc3, &insn->handler) < 0) {
9736 if (register_ind_insn(ppc_opcodes, insn->opc1,
9737 insn->opc2, &insn->handler) < 0) {
9742 if (register_direct_insn(ppc_opcodes, insn->opc1, &insn->handler) < 0) {
9750 static int test_opcode_table(opc_handler_t **table, int len)
9754 for (i = 0, count = 0; i < len; i++) {
9755 /* Consistency fixup */
9756 if (table[i] == NULL) {
9757 table[i] = &invalid_handler;
9759 if (table[i] != &invalid_handler) {
9760 if (is_indirect_opcode(table[i])) {
9761 tmp = test_opcode_table(ind_table(table[i]),
9762 PPC_CPU_INDIRECT_OPCODES_LEN);
9765 table[i] = &invalid_handler;
9778 static void fix_opcode_tables(opc_handler_t **ppc_opcodes)
9780 if (test_opcode_table(ppc_opcodes, PPC_CPU_OPCODES_LEN) == 0) {
9781 printf("*** WARNING: no opcode defined !\n");
9785 /*****************************************************************************/
9786 static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp)
9788 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
9791 fill_new_table(cpu->opcodes, PPC_CPU_OPCODES_LEN);
9792 for (opc = opcodes; opc < &opcodes[ARRAY_SIZE(opcodes)]; opc++) {
9793 if (((opc->handler.type & pcc->insns_flags) != 0) ||
9794 ((opc->handler.type2 & pcc->insns_flags2) != 0)) {
9795 if (register_insn(cpu->opcodes, opc) < 0) {
9796 error_setg(errp, "ERROR initializing PowerPC instruction "
9797 "0x%02x 0x%02x 0x%02x", opc->opc1, opc->opc2,
9803 fix_opcode_tables(cpu->opcodes);
9808 #if defined(PPC_DUMP_CPU)
9809 static void dump_ppc_insns(CPUPPCState *env)
9811 opc_handler_t **table, *handler;
9813 uint8_t opc1, opc2, opc3, opc4;
9815 printf("Instructions set:\n");
9816 /* opc1 is 6 bits long */
9817 for (opc1 = 0x00; opc1 < PPC_CPU_OPCODES_LEN; opc1++) {
9818 table = env->opcodes;
9819 handler = table[opc1];
9820 if (is_indirect_opcode(handler)) {
9821 /* opc2 is 5 bits long */
9822 for (opc2 = 0; opc2 < PPC_CPU_INDIRECT_OPCODES_LEN; opc2++) {
9823 table = env->opcodes;
9824 handler = env->opcodes[opc1];
9825 table = ind_table(handler);
9826 handler = table[opc2];
9827 if (is_indirect_opcode(handler)) {
9828 table = ind_table(handler);
9829 /* opc3 is 5 bits long */
9830 for (opc3 = 0; opc3 < PPC_CPU_INDIRECT_OPCODES_LEN;
9832 handler = table[opc3];
9833 if (is_indirect_opcode(handler)) {
9834 table = ind_table(handler);
9835 /* opc4 is 5 bits long */
9836 for (opc4 = 0; opc4 < PPC_CPU_INDIRECT_OPCODES_LEN;
9838 handler = table[opc4];
9839 if (handler->handler != &gen_invalid) {
9840 printf("INSN: %02x %02x %02x %02x -- "
9841 "(%02d %04d %02d) : %s\n",
9842 opc1, opc2, opc3, opc4,
9843 opc1, (opc3 << 5) | opc2, opc4,
9848 if (handler->handler != &gen_invalid) {
9849 /* Special hack to properly dump SPE insns */
9850 p = strchr(handler->oname, '_');
9852 printf("INSN: %02x %02x %02x (%02d %04d) : "
9854 opc1, opc2, opc3, opc1,
9859 if ((p - handler->oname) != strlen(q)
9860 || (memcmp(handler->oname, q, strlen(q))
9862 /* First instruction */
9863 printf("INSN: %02x %02x %02x"
9864 "(%02d %04d) : %.*s\n",
9865 opc1, opc2 << 1, opc3, opc1,
9866 (opc3 << 6) | (opc2 << 1),
9867 (int)(p - handler->oname),
9870 if (strcmp(p + 1, q) != 0) {
9871 /* Second instruction */
9872 printf("INSN: %02x %02x %02x "
9873 "(%02d %04d) : %s\n", opc1,
9874 (opc2 << 1) | 1, opc3, opc1,
9875 (opc3 << 6) | (opc2 << 1) | 1,
9883 if (handler->handler != &gen_invalid) {
9884 printf("INSN: %02x %02x -- (%02d %04d) : %s\n",
9885 opc1, opc2, opc1, opc2, handler->oname);
9890 if (handler->handler != &gen_invalid) {
9891 printf("INSN: %02x -- -- (%02d ----) : %s\n",
9892 opc1, opc1, handler->oname);
9899 static bool avr_need_swap(CPUPPCState *env)
9901 #ifdef HOST_WORDS_BIGENDIAN
9908 #if !defined(CONFIG_USER_ONLY)
9909 static int gdb_find_spr_idx(CPUPPCState *env, int n)
9913 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
9914 ppc_spr_t *spr = &env->spr_cb[i];
9916 if (spr->name && spr->gdb_id == n) {
9923 static int gdb_get_spr_reg(CPUPPCState *env, GByteArray *buf, int n)
9928 reg = gdb_find_spr_idx(env, n);
9933 len = TARGET_LONG_SIZE;
9934 gdb_get_regl(buf, env->spr[reg]);
9935 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, len), len);
9939 static int gdb_set_spr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
9944 reg = gdb_find_spr_idx(env, n);
9949 len = TARGET_LONG_SIZE;
9950 ppc_maybe_bswap_register(env, mem_buf, len);
9951 env->spr[reg] = ldn_p(mem_buf, len);
9957 static int gdb_get_float_reg(CPUPPCState *env, GByteArray *buf, int n)
9961 gdb_get_reg64(buf, *cpu_fpr_ptr(env, n));
9962 mem_buf = gdb_get_reg_ptr(buf, 8);
9963 ppc_maybe_bswap_register(env, mem_buf, 8);
9967 gdb_get_reg32(buf, env->fpscr);
9968 mem_buf = gdb_get_reg_ptr(buf, 4);
9969 ppc_maybe_bswap_register(env, mem_buf, 4);
9975 static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
9978 ppc_maybe_bswap_register(env, mem_buf, 8);
9979 *cpu_fpr_ptr(env, n) = ldq_p(mem_buf);
9983 ppc_maybe_bswap_register(env, mem_buf, 4);
9984 helper_store_fpscr(env, ldl_p(mem_buf), 0xffffffff);
9990 static int gdb_get_avr_reg(CPUPPCState *env, GByteArray *buf, int n)
9995 ppc_avr_t *avr = cpu_avr_ptr(env, n);
9996 if (!avr_need_swap(env)) {
9997 gdb_get_reg128(buf, avr->u64[0] , avr->u64[1]);
9999 gdb_get_reg128(buf, avr->u64[1] , avr->u64[0]);
10001 mem_buf = gdb_get_reg_ptr(buf, 16);
10002 ppc_maybe_bswap_register(env, mem_buf, 8);
10003 ppc_maybe_bswap_register(env, mem_buf + 8, 8);
10007 gdb_get_reg32(buf, helper_mfvscr(env));
10008 mem_buf = gdb_get_reg_ptr(buf, 4);
10009 ppc_maybe_bswap_register(env, mem_buf, 4);
10013 gdb_get_reg32(buf, (uint32_t)env->spr[SPR_VRSAVE]);
10014 mem_buf = gdb_get_reg_ptr(buf, 4);
10015 ppc_maybe_bswap_register(env, mem_buf, 4);
10021 static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
10024 ppc_avr_t *avr = cpu_avr_ptr(env, n);
10025 ppc_maybe_bswap_register(env, mem_buf, 8);
10026 ppc_maybe_bswap_register(env, mem_buf + 8, 8);
10027 if (!avr_need_swap(env)) {
10028 avr->u64[0] = ldq_p(mem_buf);
10029 avr->u64[1] = ldq_p(mem_buf + 8);
10031 avr->u64[1] = ldq_p(mem_buf);
10032 avr->u64[0] = ldq_p(mem_buf + 8);
10037 ppc_maybe_bswap_register(env, mem_buf, 4);
10038 helper_mtvscr(env, ldl_p(mem_buf));
10042 ppc_maybe_bswap_register(env, mem_buf, 4);
10043 env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf);
10049 static int gdb_get_spe_reg(CPUPPCState *env, GByteArray *buf, int n)
10052 #if defined(TARGET_PPC64)
10053 gdb_get_reg32(buf, env->gpr[n] >> 32);
10054 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
10056 gdb_get_reg32(buf, env->gprh[n]);
10061 gdb_get_reg64(buf, env->spe_acc);
10062 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
10066 gdb_get_reg32(buf, env->spe_fscr);
10067 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
10073 static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
10076 #if defined(TARGET_PPC64)
10077 target_ulong lo = (uint32_t)env->gpr[n];
10080 ppc_maybe_bswap_register(env, mem_buf, 4);
10082 hi = (target_ulong)ldl_p(mem_buf) << 32;
10083 env->gpr[n] = lo | hi;
10085 env->gprh[n] = ldl_p(mem_buf);
10090 ppc_maybe_bswap_register(env, mem_buf, 8);
10091 env->spe_acc = ldq_p(mem_buf);
10095 ppc_maybe_bswap_register(env, mem_buf, 4);
10096 env->spe_fscr = ldl_p(mem_buf);
10102 static int gdb_get_vsx_reg(CPUPPCState *env, GByteArray *buf, int n)
10105 gdb_get_reg64(buf, *cpu_vsrl_ptr(env, n));
10106 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
10112 static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
10115 ppc_maybe_bswap_register(env, mem_buf, 8);
10116 *cpu_vsrl_ptr(env, n) = ldq_p(mem_buf);
10122 static int ppc_fixup_cpu(PowerPCCPU *cpu)
10124 CPUPPCState *env = &cpu->env;
10127 * TCG doesn't (yet) emulate some groups of instructions that are
10128 * implemented on some otherwise supported CPUs (e.g. VSX and
10129 * decimal floating point instructions on POWER7). We remove
10130 * unsupported instruction groups from the cpu state's instruction
10131 * masks and hope the guest can cope. For at least the pseries
10132 * machine, the unavailability of these instructions can be
10133 * advertised to the guest via the device tree.
10135 if ((env->insns_flags & ~PPC_TCG_INSNS)
10136 || (env->insns_flags2 & ~PPC_TCG_INSNS2)) {
10137 warn_report("Disabling some instructions which are not "
10138 "emulated by TCG (0x%" PRIx64 ", 0x%" PRIx64 ")",
10139 env->insns_flags & ~PPC_TCG_INSNS,
10140 env->insns_flags2 & ~PPC_TCG_INSNS2);
10142 env->insns_flags &= PPC_TCG_INSNS;
10143 env->insns_flags2 &= PPC_TCG_INSNS2;
10147 static void ppc_cpu_realize(DeviceState *dev, Error **errp)
10149 CPUState *cs = CPU(dev);
10150 PowerPCCPU *cpu = POWERPC_CPU(dev);
10151 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
10152 Error *local_err = NULL;
10154 cpu_exec_realizefn(cs, &local_err);
10155 if (local_err != NULL) {
10156 error_propagate(errp, local_err);
10159 if (cpu->vcpu_id == UNASSIGNED_CPU_INDEX) {
10160 cpu->vcpu_id = cs->cpu_index;
10163 if (tcg_enabled()) {
10164 if (ppc_fixup_cpu(cpu) != 0) {
10165 error_setg(errp, "Unable to emulate selected CPU with TCG");
10170 create_ppc_opcodes(cpu, &local_err);
10171 if (local_err != NULL) {
10172 error_propagate(errp, local_err);
10175 init_ppc_proc(cpu);
10177 if (pcc->insns_flags & PPC_FLOAT) {
10178 gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
10179 33, "power-fpu.xml", 0);
10181 if (pcc->insns_flags & PPC_ALTIVEC) {
10182 gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
10183 34, "power-altivec.xml", 0);
10185 if (pcc->insns_flags & PPC_SPE) {
10186 gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
10187 34, "power-spe.xml", 0);
10189 if (pcc->insns_flags2 & PPC2_VSX) {
10190 gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg,
10191 32, "power-vsx.xml", 0);
10193 #ifndef CONFIG_USER_ONLY
10194 gdb_register_coprocessor(cs, gdb_get_spr_reg, gdb_set_spr_reg,
10195 pcc->gdb_num_sprs, "power-spr.xml", 0);
10197 qemu_init_vcpu(cs);
10199 pcc->parent_realize(dev, errp);
10201 #if defined(PPC_DUMP_CPU)
10203 CPUPPCState *env = &cpu->env;
10204 const char *mmu_model, *excp_model, *bus_model;
10205 switch (env->mmu_model) {
10206 case POWERPC_MMU_32B:
10207 mmu_model = "PowerPC 32";
10209 case POWERPC_MMU_SOFT_6xx:
10210 mmu_model = "PowerPC 6xx/7xx with software driven TLBs";
10212 case POWERPC_MMU_SOFT_74xx:
10213 mmu_model = "PowerPC 74xx with software driven TLBs";
10215 case POWERPC_MMU_SOFT_4xx:
10216 mmu_model = "PowerPC 4xx with software driven TLBs";
10218 case POWERPC_MMU_SOFT_4xx_Z:
10219 mmu_model = "PowerPC 4xx with software driven TLBs "
10220 "and zones protections";
10222 case POWERPC_MMU_REAL:
10223 mmu_model = "PowerPC real mode only";
10225 case POWERPC_MMU_MPC8xx:
10226 mmu_model = "PowerPC MPC8xx";
10228 case POWERPC_MMU_BOOKE:
10229 mmu_model = "PowerPC BookE";
10231 case POWERPC_MMU_BOOKE206:
10232 mmu_model = "PowerPC BookE 2.06";
10234 case POWERPC_MMU_601:
10235 mmu_model = "PowerPC 601";
10237 #if defined(TARGET_PPC64)
10238 case POWERPC_MMU_64B:
10239 mmu_model = "PowerPC 64";
10243 mmu_model = "Unknown or invalid";
10246 switch (env->excp_model) {
10247 case POWERPC_EXCP_STD:
10248 excp_model = "PowerPC";
10250 case POWERPC_EXCP_40x:
10251 excp_model = "PowerPC 40x";
10253 case POWERPC_EXCP_601:
10254 excp_model = "PowerPC 601";
10256 case POWERPC_EXCP_602:
10257 excp_model = "PowerPC 602";
10259 case POWERPC_EXCP_603:
10260 excp_model = "PowerPC 603";
10262 case POWERPC_EXCP_603E:
10263 excp_model = "PowerPC 603e";
10265 case POWERPC_EXCP_604:
10266 excp_model = "PowerPC 604";
10268 case POWERPC_EXCP_7x0:
10269 excp_model = "PowerPC 740/750";
10271 case POWERPC_EXCP_7x5:
10272 excp_model = "PowerPC 745/755";
10274 case POWERPC_EXCP_74xx:
10275 excp_model = "PowerPC 74xx";
10277 case POWERPC_EXCP_BOOKE:
10278 excp_model = "PowerPC BookE";
10280 #if defined(TARGET_PPC64)
10281 case POWERPC_EXCP_970:
10282 excp_model = "PowerPC 970";
10286 excp_model = "Unknown or invalid";
10289 switch (env->bus_model) {
10290 case PPC_FLAGS_INPUT_6xx:
10291 bus_model = "PowerPC 6xx";
10293 case PPC_FLAGS_INPUT_BookE:
10294 bus_model = "PowerPC BookE";
10296 case PPC_FLAGS_INPUT_405:
10297 bus_model = "PowerPC 405";
10299 case PPC_FLAGS_INPUT_401:
10300 bus_model = "PowerPC 401/403";
10302 case PPC_FLAGS_INPUT_RCPU:
10303 bus_model = "RCPU / MPC8xx";
10305 #if defined(TARGET_PPC64)
10306 case PPC_FLAGS_INPUT_970:
10307 bus_model = "PowerPC 970";
10311 bus_model = "Unknown or invalid";
10314 printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64 "\n"
10315 " MMU model : %s\n",
10316 object_class_get_name(OBJECT_CLASS(pcc)),
10317 pcc->pvr, pcc->msr_mask, mmu_model);
10318 #if !defined(CONFIG_USER_ONLY)
10319 if (env->tlb.tlb6) {
10320 printf(" %d %s TLB in %d ways\n",
10321 env->nb_tlb, env->id_tlbs ? "splitted" : "merged",
10325 printf(" Exceptions model : %s\n"
10326 " Bus model : %s\n",
10327 excp_model, bus_model);
10328 printf(" MSR features :\n");
10329 if (env->flags & POWERPC_FLAG_SPE) {
10330 printf(" signal processing engine enable"
10332 } else if (env->flags & POWERPC_FLAG_VRE) {
10333 printf(" vector processor enable\n");
10335 if (env->flags & POWERPC_FLAG_TGPR) {
10336 printf(" temporary GPRs\n");
10337 } else if (env->flags & POWERPC_FLAG_CE) {
10338 printf(" critical input enable\n");
10340 if (env->flags & POWERPC_FLAG_SE) {
10341 printf(" single-step trace mode\n");
10342 } else if (env->flags & POWERPC_FLAG_DWE) {
10343 printf(" debug wait enable\n");
10344 } else if (env->flags & POWERPC_FLAG_UBLE) {
10345 printf(" user BTB lock enable\n");
10347 if (env->flags & POWERPC_FLAG_BE) {
10348 printf(" branch-step trace mode\n");
10349 } else if (env->flags & POWERPC_FLAG_DE) {
10350 printf(" debug interrupt enable\n");
10352 if (env->flags & POWERPC_FLAG_PX) {
10353 printf(" inclusive protection\n");
10354 } else if (env->flags & POWERPC_FLAG_PMM) {
10355 printf(" performance monitor mark\n");
10357 if (env->flags == POWERPC_FLAG_NONE) {
10360 printf(" Time-base/decrementer clock source: %s\n",
10361 env->flags & POWERPC_FLAG_RTC_CLK ? "RTC clock" : "bus clock");
10362 dump_ppc_insns(env);
10363 dump_ppc_sprs(env);
10370 cpu_exec_unrealizefn(cs);
10373 static void ppc_cpu_unrealize(DeviceState *dev)
10375 PowerPCCPU *cpu = POWERPC_CPU(dev);
10376 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
10377 opc_handler_t **table, **table_2;
10380 pcc->parent_unrealize(dev);
10382 cpu_remove_sync(CPU(cpu));
10384 for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) {
10385 if (cpu->opcodes[i] == &invalid_handler) {
10388 if (is_indirect_opcode(cpu->opcodes[i])) {
10389 table = ind_table(cpu->opcodes[i]);
10390 for (j = 0; j < PPC_CPU_INDIRECT_OPCODES_LEN; j++) {
10391 if (table[j] == &invalid_handler) {
10394 if (is_indirect_opcode(table[j])) {
10395 table_2 = ind_table(table[j]);
10396 for (k = 0; k < PPC_CPU_INDIRECT_OPCODES_LEN; k++) {
10397 if (table_2[k] != &invalid_handler &&
10398 is_indirect_opcode(table_2[k])) {
10399 g_free((opc_handler_t *)((uintptr_t)table_2[k] &
10403 g_free((opc_handler_t *)((uintptr_t)table[j] &
10407 g_free((opc_handler_t *)((uintptr_t)cpu->opcodes[i] &
10413 static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b)
10415 ObjectClass *oc = (ObjectClass *)a;
10416 uint32_t pvr = *(uint32_t *)b;
10417 PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
10419 /* -cpu host does a PVR lookup during construction */
10420 if (unlikely(strcmp(object_class_get_name(oc),
10421 TYPE_HOST_POWERPC_CPU) == 0)) {
10425 return pcc->pvr == pvr ? 0 : -1;
10428 PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr)
10430 GSList *list, *item;
10431 PowerPCCPUClass *pcc = NULL;
10433 list = object_class_get_list(TYPE_POWERPC_CPU, false);
10434 item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr);
10435 if (item != NULL) {
10436 pcc = POWERPC_CPU_CLASS(item->data);
10438 g_slist_free(list);
10443 static gint ppc_cpu_compare_class_pvr_mask(gconstpointer a, gconstpointer b)
10445 ObjectClass *oc = (ObjectClass *)a;
10446 uint32_t pvr = *(uint32_t *)b;
10447 PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
10449 /* -cpu host does a PVR lookup during construction */
10450 if (unlikely(strcmp(object_class_get_name(oc),
10451 TYPE_HOST_POWERPC_CPU) == 0)) {
10455 if (pcc->pvr_match(pcc, pvr)) {
10462 PowerPCCPUClass *ppc_cpu_class_by_pvr_mask(uint32_t pvr)
10464 GSList *list, *item;
10465 PowerPCCPUClass *pcc = NULL;
10467 list = object_class_get_list(TYPE_POWERPC_CPU, true);
10468 item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr_mask);
10469 if (item != NULL) {
10470 pcc = POWERPC_CPU_CLASS(item->data);
10472 g_slist_free(list);
10477 static const char *ppc_cpu_lookup_alias(const char *alias)
10481 for (ai = 0; ppc_cpu_aliases[ai].alias != NULL; ai++) {
10482 if (strcmp(ppc_cpu_aliases[ai].alias, alias) == 0) {
10483 return ppc_cpu_aliases[ai].model;
10490 static ObjectClass *ppc_cpu_class_by_name(const char *name)
10492 char *cpu_model, *typename;
10498 * Lookup by PVR if cpu_model is valid 8 digit hex number (excl:
10499 * 0x prefix if present)
10501 if (!qemu_strtoul(name, &p, 16, &pvr)) {
10502 int len = p - name;
10503 len = (len == 10) && (name[1] == 'x') ? len - 2 : len;
10504 if ((len == 8) && (*p == '\0')) {
10505 return OBJECT_CLASS(ppc_cpu_class_by_pvr(pvr));
10509 cpu_model = g_ascii_strdown(name, -1);
10510 p = ppc_cpu_lookup_alias(cpu_model);
10513 cpu_model = g_strdup(p);
10516 typename = g_strdup_printf("%s" POWERPC_CPU_TYPE_SUFFIX, cpu_model);
10517 oc = object_class_by_name(typename);
10524 PowerPCCPUClass *ppc_cpu_get_family_class(PowerPCCPUClass *pcc)
10526 ObjectClass *oc = OBJECT_CLASS(pcc);
10528 while (oc && !object_class_is_abstract(oc)) {
10529 oc = object_class_get_parent(oc);
10533 return POWERPC_CPU_CLASS(oc);
10536 /* Sort by PVR, ordering special case "host" last. */
10537 static gint ppc_cpu_list_compare(gconstpointer a, gconstpointer b)
10539 ObjectClass *oc_a = (ObjectClass *)a;
10540 ObjectClass *oc_b = (ObjectClass *)b;
10541 PowerPCCPUClass *pcc_a = POWERPC_CPU_CLASS(oc_a);
10542 PowerPCCPUClass *pcc_b = POWERPC_CPU_CLASS(oc_b);
10543 const char *name_a = object_class_get_name(oc_a);
10544 const char *name_b = object_class_get_name(oc_b);
10546 if (strcmp(name_a, TYPE_HOST_POWERPC_CPU) == 0) {
10548 } else if (strcmp(name_b, TYPE_HOST_POWERPC_CPU) == 0) {
10551 /* Avoid an integer overflow during subtraction */
10552 if (pcc_a->pvr < pcc_b->pvr) {
10554 } else if (pcc_a->pvr > pcc_b->pvr) {
10562 static void ppc_cpu_list_entry(gpointer data, gpointer user_data)
10564 ObjectClass *oc = data;
10565 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
10566 DeviceClass *family = DEVICE_CLASS(ppc_cpu_get_family_class(pcc));
10567 const char *typename = object_class_get_name(oc);
10571 if (unlikely(strcmp(typename, TYPE_HOST_POWERPC_CPU) == 0)) {
10575 name = g_strndup(typename,
10576 strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX));
10577 qemu_printf("PowerPC %-16s PVR %08x\n", name, pcc->pvr);
10578 for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
10579 PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
10580 ObjectClass *alias_oc = ppc_cpu_class_by_name(alias->model);
10582 if (alias_oc != oc) {
10586 * If running with KVM, we might update the family alias later, so
10587 * avoid printing the wrong alias here and use "preferred" instead
10589 if (strcmp(alias->alias, family->desc) == 0) {
10590 qemu_printf("PowerPC %-16s (alias for preferred %s CPU)\n",
10591 alias->alias, family->desc);
10593 qemu_printf("PowerPC %-16s (alias for %s)\n",
10594 alias->alias, name);
10600 void ppc_cpu_list(void)
10604 list = object_class_get_list(TYPE_POWERPC_CPU, false);
10605 list = g_slist_sort(list, ppc_cpu_list_compare);
10606 g_slist_foreach(list, ppc_cpu_list_entry, NULL);
10607 g_slist_free(list);
10611 qemu_printf("PowerPC %-16s\n", "host");
10615 static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
10617 ObjectClass *oc = data;
10618 CpuDefinitionInfoList **first = user_data;
10619 const char *typename;
10620 CpuDefinitionInfo *info;
10622 typename = object_class_get_name(oc);
10623 info = g_malloc0(sizeof(*info));
10624 info->name = g_strndup(typename,
10625 strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX));
10627 QAPI_LIST_PREPEND(*first, info);
10630 CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
10632 CpuDefinitionInfoList *cpu_list = NULL;
10636 list = object_class_get_list(TYPE_POWERPC_CPU, false);
10637 g_slist_foreach(list, ppc_cpu_defs_entry, &cpu_list);
10638 g_slist_free(list);
10640 for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
10641 PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
10643 CpuDefinitionInfo *info;
10645 oc = ppc_cpu_class_by_name(alias->model);
10650 info = g_malloc0(sizeof(*info));
10651 info->name = g_strdup(alias->alias);
10652 info->q_typename = g_strdup(object_class_get_name(oc));
10654 QAPI_LIST_PREPEND(cpu_list, info);
10660 static void ppc_cpu_set_pc(CPUState *cs, vaddr value)
10662 PowerPCCPU *cpu = POWERPC_CPU(cs);
10664 cpu->env.nip = value;
10667 static bool ppc_cpu_has_work(CPUState *cs)
10669 PowerPCCPU *cpu = POWERPC_CPU(cs);
10670 CPUPPCState *env = &cpu->env;
10672 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
10675 static void ppc_cpu_reset(DeviceState *dev)
10677 CPUState *s = CPU(dev);
10678 PowerPCCPU *cpu = POWERPC_CPU(s);
10679 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
10680 CPUPPCState *env = &cpu->env;
10684 pcc->parent_reset(dev);
10686 msr = (target_ulong)0;
10687 msr |= (target_ulong)MSR_HVB;
10688 msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
10689 msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
10690 msr |= (target_ulong)1 << MSR_EP;
10691 #if defined(DO_SINGLE_STEP) && 0
10692 /* Single step trace mode */
10693 msr |= (target_ulong)1 << MSR_SE;
10694 msr |= (target_ulong)1 << MSR_BE;
10696 #if defined(CONFIG_USER_ONLY)
10697 msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
10698 msr |= (target_ulong)1 << MSR_FE0; /* Allow floating point exceptions */
10699 msr |= (target_ulong)1 << MSR_FE1;
10700 msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
10701 msr |= (target_ulong)1 << MSR_VSX; /* Allow VSX usage */
10702 msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
10703 msr |= (target_ulong)1 << MSR_PR;
10704 #if defined(TARGET_PPC64)
10705 msr |= (target_ulong)1 << MSR_TM; /* Transactional memory */
10707 #if !defined(TARGET_WORDS_BIGENDIAN)
10708 msr |= (target_ulong)1 << MSR_LE; /* Little-endian user mode */
10709 if (!((env->msr_mask >> MSR_LE) & 1)) {
10710 fprintf(stderr, "Selected CPU does not support little-endian.\n");
10716 #if defined(TARGET_PPC64)
10717 if (mmu_is_64bit(env->mmu_model)) {
10718 msr |= (1ULL << MSR_SF);
10722 hreg_store_msr(env, msr, 1);
10724 #if !defined(CONFIG_USER_ONLY)
10725 env->nip = env->hreset_vector | env->excp_prefix;
10726 if (env->mmu_model != POWERPC_MMU_REAL) {
10727 ppc_tlb_invalidate_all(env);
10731 hreg_compute_hflags(env);
10732 env->reserve_addr = (target_ulong)-1ULL;
10733 /* Be sure no exception or interrupt is pending */
10734 env->pending_interrupts = 0;
10735 s->exception_index = POWERPC_EXCP_NONE;
10736 env->error_code = 0;
10737 ppc_irq_reset(cpu);
10739 /* tininess for underflow is detected before rounding */
10740 set_float_detect_tininess(float_tininess_before_rounding,
10743 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
10744 ppc_spr_t *spr = &env->spr_cb[i];
10749 env->spr[i] = spr->default_value;
10753 #ifndef CONFIG_USER_ONLY
10755 static bool ppc_cpu_is_big_endian(CPUState *cs)
10757 PowerPCCPU *cpu = POWERPC_CPU(cs);
10758 CPUPPCState *env = &cpu->env;
10760 cpu_synchronize_state(cs);
10766 static void ppc_cpu_exec_enter(CPUState *cs)
10768 PowerPCCPU *cpu = POWERPC_CPU(cs);
10771 PPCVirtualHypervisorClass *vhc =
10772 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
10773 vhc->cpu_exec_enter(cpu->vhyp, cpu);
10777 static void ppc_cpu_exec_exit(CPUState *cs)
10779 PowerPCCPU *cpu = POWERPC_CPU(cs);
10782 PPCVirtualHypervisorClass *vhc =
10783 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
10784 vhc->cpu_exec_exit(cpu->vhyp, cpu);
10787 #endif /* CONFIG_TCG */
10789 #endif /* !CONFIG_USER_ONLY */
10791 static void ppc_cpu_instance_init(Object *obj)
10793 PowerPCCPU *cpu = POWERPC_CPU(obj);
10794 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
10795 CPUPPCState *env = &cpu->env;
10797 cpu_set_cpustate_pointers(cpu);
10798 cpu->vcpu_id = UNASSIGNED_CPU_INDEX;
10800 env->msr_mask = pcc->msr_mask;
10801 env->mmu_model = pcc->mmu_model;
10802 env->excp_model = pcc->excp_model;
10803 env->bus_model = pcc->bus_model;
10804 env->insns_flags = pcc->insns_flags;
10805 env->insns_flags2 = pcc->insns_flags2;
10806 env->flags = pcc->flags;
10807 env->bfd_mach = pcc->bfd_mach;
10808 env->check_pow = pcc->check_pow;
10811 * Mark HV mode as supported if the CPU has an MSR_HV bit in the
10812 * msr_mask. The mask can later be cleared by PAPR mode but the hv
10813 * mode support will remain, thus enforcing that we cannot use
10814 * priv. instructions in guest in PAPR mode. For 970 we currently
10815 * simply don't set HV in msr_mask thus simulating an "Apple mode"
10816 * 970. If we ever want to support 970 HV mode, we'll have to add
10817 * a processor attribute of some sort.
10819 #if !defined(CONFIG_USER_ONLY)
10820 env->has_hv_mode = !!(env->msr_mask & MSR_HVB);
10823 ppc_hash64_init(cpu);
10826 static void ppc_cpu_instance_finalize(Object *obj)
10828 PowerPCCPU *cpu = POWERPC_CPU(obj);
10830 ppc_hash64_finalize(cpu);
10833 static bool ppc_pvr_match_default(PowerPCCPUClass *pcc, uint32_t pvr)
10835 return pcc->pvr == pvr;
10838 static gchar *ppc_gdb_arch_name(CPUState *cs)
10840 #if defined(TARGET_PPC64)
10841 return g_strdup("powerpc:common64");
10843 return g_strdup("powerpc:common");
10847 static void ppc_disas_set_info(CPUState *cs, disassemble_info *info)
10849 PowerPCCPU *cpu = POWERPC_CPU(cs);
10850 CPUPPCState *env = &cpu->env;
10852 if ((env->hflags >> MSR_LE) & 1) {
10853 info->endian = BFD_ENDIAN_LITTLE;
10855 info->mach = env->bfd_mach;
10856 if (!env->bfd_mach) {
10857 #ifdef TARGET_PPC64
10858 info->mach = bfd_mach_ppc64;
10860 info->mach = bfd_mach_ppc;
10863 info->disassembler_options = (char *)"any";
10864 info->print_insn = print_insn_ppc;
10866 info->cap_arch = CS_ARCH_PPC;
10867 #ifdef TARGET_PPC64
10868 info->cap_mode = CS_MODE_64;
10872 static Property ppc_cpu_properties[] = {
10873 DEFINE_PROP_BOOL("pre-2.8-migration", PowerPCCPU, pre_2_8_migration, false),
10874 DEFINE_PROP_BOOL("pre-2.10-migration", PowerPCCPU, pre_2_10_migration,
10876 DEFINE_PROP_BOOL("pre-3.0-migration", PowerPCCPU, pre_3_0_migration,
10878 DEFINE_PROP_END_OF_LIST(),
10882 #include "hw/core/tcg-cpu-ops.h"
10884 static struct TCGCPUOps ppc_tcg_ops = {
10885 .initialize = ppc_translate_init,
10886 .cpu_exec_interrupt = ppc_cpu_exec_interrupt,
10887 .tlb_fill = ppc_cpu_tlb_fill,
10889 #ifndef CONFIG_USER_ONLY
10890 .do_interrupt = ppc_cpu_do_interrupt,
10891 .cpu_exec_enter = ppc_cpu_exec_enter,
10892 .cpu_exec_exit = ppc_cpu_exec_exit,
10893 .do_unaligned_access = ppc_cpu_do_unaligned_access,
10894 #endif /* !CONFIG_USER_ONLY */
10896 #endif /* CONFIG_TCG */
10898 static void ppc_cpu_class_init(ObjectClass *oc, void *data)
10900 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
10901 CPUClass *cc = CPU_CLASS(oc);
10902 DeviceClass *dc = DEVICE_CLASS(oc);
10904 device_class_set_parent_realize(dc, ppc_cpu_realize,
10905 &pcc->parent_realize);
10906 device_class_set_parent_unrealize(dc, ppc_cpu_unrealize,
10907 &pcc->parent_unrealize);
10908 pcc->pvr_match = ppc_pvr_match_default;
10909 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_always;
10910 device_class_set_props(dc, ppc_cpu_properties);
10912 device_class_set_parent_reset(dc, ppc_cpu_reset, &pcc->parent_reset);
10914 cc->class_by_name = ppc_cpu_class_by_name;
10915 cc->has_work = ppc_cpu_has_work;
10916 cc->dump_state = ppc_cpu_dump_state;
10917 cc->dump_statistics = ppc_cpu_dump_statistics;
10918 cc->set_pc = ppc_cpu_set_pc;
10919 cc->gdb_read_register = ppc_cpu_gdb_read_register;
10920 cc->gdb_write_register = ppc_cpu_gdb_write_register;
10921 #ifndef CONFIG_USER_ONLY
10922 cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
10923 cc->vmsd = &vmstate_ppc_cpu;
10925 #if defined(CONFIG_SOFTMMU)
10926 cc->write_elf64_note = ppc64_cpu_write_elf64_note;
10927 cc->write_elf32_note = ppc32_cpu_write_elf32_note;
10930 cc->gdb_num_core_regs = 71;
10931 #ifndef CONFIG_USER_ONLY
10932 cc->gdb_get_dynamic_xml = ppc_gdb_get_dynamic_xml;
10934 #ifdef USE_APPLE_GDB
10935 cc->gdb_read_register = ppc_cpu_gdb_read_register_apple;
10936 cc->gdb_write_register = ppc_cpu_gdb_write_register_apple;
10937 cc->gdb_num_core_regs = 71 + 32;
10940 cc->gdb_arch_name = ppc_gdb_arch_name;
10941 #if defined(TARGET_PPC64)
10942 cc->gdb_core_xml_file = "power64-core.xml";
10944 cc->gdb_core_xml_file = "power-core.xml";
10946 #ifndef CONFIG_USER_ONLY
10947 cc->virtio_is_big_endian = ppc_cpu_is_big_endian;
10949 cc->disas_set_info = ppc_disas_set_info;
10951 dc->fw_name = "PowerPC,UNKNOWN";
10954 cc->tcg_ops = &ppc_tcg_ops;
10955 #endif /* CONFIG_TCG */
10958 static const TypeInfo ppc_cpu_type_info = {
10959 .name = TYPE_POWERPC_CPU,
10960 .parent = TYPE_CPU,
10961 .instance_size = sizeof(PowerPCCPU),
10962 .instance_align = __alignof__(PowerPCCPU),
10963 .instance_init = ppc_cpu_instance_init,
10964 .instance_finalize = ppc_cpu_instance_finalize,
10966 .class_size = sizeof(PowerPCCPUClass),
10967 .class_init = ppc_cpu_class_init,
10970 #ifndef CONFIG_USER_ONLY
10971 static const TypeInfo ppc_vhyp_type_info = {
10972 .name = TYPE_PPC_VIRTUAL_HYPERVISOR,
10973 .parent = TYPE_INTERFACE,
10974 .class_size = sizeof(PPCVirtualHypervisorClass),
10978 static void ppc_cpu_register_types(void)
10980 type_register_static(&ppc_cpu_type_info);
10981 #ifndef CONFIG_USER_ONLY
10982 type_register_static(&ppc_vhyp_type_info);
10986 type_init(ppc_cpu_register_types)