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_DEBUG_SPR */
46 /* #define PPC_DUMP_SPR_ACCESSES */
47 /* #define USE_APPLE_GDB */
51 * do nothing but store/retrieve spr value
53 static void spr_load_dump_spr(int sprn)
55 #ifdef PPC_DUMP_SPR_ACCESSES
56 TCGv_i32 t0 = tcg_const_i32(sprn);
57 gen_helper_load_dump_spr(cpu_env, t0);
58 tcg_temp_free_i32(t0);
62 static void spr_read_generic(DisasContext *ctx, int gprn, int sprn)
64 gen_load_spr(cpu_gpr[gprn], sprn);
65 spr_load_dump_spr(sprn);
68 static void spr_store_dump_spr(int sprn)
70 #ifdef PPC_DUMP_SPR_ACCESSES
71 TCGv_i32 t0 = tcg_const_i32(sprn);
72 gen_helper_store_dump_spr(cpu_env, t0);
73 tcg_temp_free_i32(t0);
77 static void spr_write_generic(DisasContext *ctx, int sprn, int gprn)
79 gen_store_spr(sprn, cpu_gpr[gprn]);
80 spr_store_dump_spr(sprn);
83 #if !defined(CONFIG_USER_ONLY)
84 static void spr_write_generic32(DisasContext *ctx, int sprn, int gprn)
87 TCGv t0 = tcg_temp_new();
88 tcg_gen_ext32u_tl(t0, cpu_gpr[gprn]);
89 gen_store_spr(sprn, t0);
91 spr_store_dump_spr(sprn);
93 spr_write_generic(ctx, sprn, gprn);
97 static void spr_write_clear(DisasContext *ctx, int sprn, int gprn)
99 TCGv t0 = tcg_temp_new();
100 TCGv t1 = tcg_temp_new();
101 gen_load_spr(t0, sprn);
102 tcg_gen_neg_tl(t1, cpu_gpr[gprn]);
103 tcg_gen_and_tl(t0, t0, t1);
104 gen_store_spr(sprn, t0);
109 static void spr_access_nop(DisasContext *ctx, int sprn, int gprn)
115 /* SPR common to all PowerPC */
117 static void spr_read_xer(DisasContext *ctx, int gprn, int sprn)
119 gen_read_xer(ctx, cpu_gpr[gprn]);
122 static void spr_write_xer(DisasContext *ctx, int sprn, int gprn)
124 gen_write_xer(cpu_gpr[gprn]);
128 static void spr_read_lr(DisasContext *ctx, int gprn, int sprn)
130 tcg_gen_mov_tl(cpu_gpr[gprn], cpu_lr);
133 static void spr_write_lr(DisasContext *ctx, int sprn, int gprn)
135 tcg_gen_mov_tl(cpu_lr, cpu_gpr[gprn]);
139 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
140 static void spr_read_cfar(DisasContext *ctx, int gprn, int sprn)
142 tcg_gen_mov_tl(cpu_gpr[gprn], cpu_cfar);
145 static void spr_write_cfar(DisasContext *ctx, int sprn, int gprn)
147 tcg_gen_mov_tl(cpu_cfar, cpu_gpr[gprn]);
149 #endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
152 static void spr_read_ctr(DisasContext *ctx, int gprn, int sprn)
154 tcg_gen_mov_tl(cpu_gpr[gprn], cpu_ctr);
157 static void spr_write_ctr(DisasContext *ctx, int sprn, int gprn)
159 tcg_gen_mov_tl(cpu_ctr, cpu_gpr[gprn]);
162 /* User read access to SPR */
168 static void spr_read_ureg(DisasContext *ctx, int gprn, int sprn)
170 gen_load_spr(cpu_gpr[gprn], sprn + 0x10);
173 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
174 static void spr_write_ureg(DisasContext *ctx, int sprn, int gprn)
176 gen_store_spr(sprn + 0x10, cpu_gpr[gprn]);
180 /* SPR common to all non-embedded PowerPC */
182 #if !defined(CONFIG_USER_ONLY)
183 static void spr_read_decr(DisasContext *ctx, int gprn, int sprn)
185 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
188 gen_helper_load_decr(cpu_gpr[gprn], cpu_env);
189 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
190 gen_stop_exception(ctx);
194 static void spr_write_decr(DisasContext *ctx, int sprn, int gprn)
196 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
199 gen_helper_store_decr(cpu_env, cpu_gpr[gprn]);
200 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
201 gen_stop_exception(ctx);
206 /* SPR common to all non-embedded PowerPC, except 601 */
208 static void spr_read_tbl(DisasContext *ctx, int gprn, int sprn)
210 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
213 gen_helper_load_tbl(cpu_gpr[gprn], cpu_env);
214 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
216 gen_stop_exception(ctx);
220 static void spr_read_tbu(DisasContext *ctx, int gprn, int sprn)
222 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
225 gen_helper_load_tbu(cpu_gpr[gprn], cpu_env);
226 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
228 gen_stop_exception(ctx);
233 static void spr_read_atbl(DisasContext *ctx, int gprn, int sprn)
235 gen_helper_load_atbl(cpu_gpr[gprn], cpu_env);
239 static void spr_read_atbu(DisasContext *ctx, int gprn, int sprn)
241 gen_helper_load_atbu(cpu_gpr[gprn], cpu_env);
244 #if !defined(CONFIG_USER_ONLY)
245 static void spr_write_tbl(DisasContext *ctx, int sprn, int gprn)
247 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
250 gen_helper_store_tbl(cpu_env, cpu_gpr[gprn]);
251 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
253 gen_stop_exception(ctx);
257 static void spr_write_tbu(DisasContext *ctx, int sprn, int gprn)
259 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
262 gen_helper_store_tbu(cpu_env, cpu_gpr[gprn]);
263 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
265 gen_stop_exception(ctx);
270 static void spr_write_atbl(DisasContext *ctx, int sprn, int gprn)
272 gen_helper_store_atbl(cpu_env, cpu_gpr[gprn]);
276 static void spr_write_atbu(DisasContext *ctx, int sprn, int gprn)
278 gen_helper_store_atbu(cpu_env, cpu_gpr[gprn]);
281 #if defined(TARGET_PPC64)
283 static void spr_read_purr(DisasContext *ctx, int gprn, int sprn)
285 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
288 gen_helper_load_purr(cpu_gpr[gprn], cpu_env);
289 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
290 gen_stop_exception(ctx);
294 static void spr_write_purr(DisasContext *ctx, int sprn, int gprn)
296 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
299 gen_helper_store_purr(cpu_env, cpu_gpr[gprn]);
300 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
301 gen_stop_exception(ctx);
306 static void spr_read_hdecr(DisasContext *ctx, int gprn, int sprn)
308 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
311 gen_helper_load_hdecr(cpu_gpr[gprn], cpu_env);
312 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
314 gen_stop_exception(ctx);
318 static void spr_write_hdecr(DisasContext *ctx, int sprn, int gprn)
320 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
323 gen_helper_store_hdecr(cpu_env, cpu_gpr[gprn]);
324 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
326 gen_stop_exception(ctx);
330 static void spr_read_vtb(DisasContext *ctx, int gprn, int sprn)
332 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
335 gen_helper_load_vtb(cpu_gpr[gprn], cpu_env);
336 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
337 gen_stop_exception(ctx);
341 static void spr_write_vtb(DisasContext *ctx, int sprn, int gprn)
343 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
346 gen_helper_store_vtb(cpu_env, cpu_gpr[gprn]);
347 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
348 gen_stop_exception(ctx);
352 static void spr_write_tbu40(DisasContext *ctx, int sprn, int gprn)
354 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
357 gen_helper_store_tbu40(cpu_env, cpu_gpr[gprn]);
358 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
359 gen_stop_exception(ctx);
366 #if !defined(CONFIG_USER_ONLY)
367 /* IBAT0U...IBAT0U */
368 /* IBAT0L...IBAT7L */
369 static void spr_read_ibat(DisasContext *ctx, int gprn, int sprn)
371 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env,
372 offsetof(CPUPPCState,
373 IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2]));
376 static void spr_read_ibat_h(DisasContext *ctx, int gprn, int sprn)
378 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env,
379 offsetof(CPUPPCState,
380 IBAT[sprn & 1][((sprn - SPR_IBAT4U) / 2) + 4]));
383 static void spr_write_ibatu(DisasContext *ctx, int sprn, int gprn)
385 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2);
386 gen_helper_store_ibatu(cpu_env, t0, cpu_gpr[gprn]);
387 tcg_temp_free_i32(t0);
390 static void spr_write_ibatu_h(DisasContext *ctx, int sprn, int gprn)
392 TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_IBAT4U) / 2) + 4);
393 gen_helper_store_ibatu(cpu_env, t0, cpu_gpr[gprn]);
394 tcg_temp_free_i32(t0);
397 static void spr_write_ibatl(DisasContext *ctx, int sprn, int gprn)
399 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0L) / 2);
400 gen_helper_store_ibatl(cpu_env, t0, cpu_gpr[gprn]);
401 tcg_temp_free_i32(t0);
404 static void spr_write_ibatl_h(DisasContext *ctx, int sprn, int gprn)
406 TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_IBAT4L) / 2) + 4);
407 gen_helper_store_ibatl(cpu_env, t0, cpu_gpr[gprn]);
408 tcg_temp_free_i32(t0);
411 /* DBAT0U...DBAT7U */
412 /* DBAT0L...DBAT7L */
413 static void spr_read_dbat(DisasContext *ctx, int gprn, int sprn)
415 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env,
416 offsetof(CPUPPCState,
417 DBAT[sprn & 1][(sprn - SPR_DBAT0U) / 2]));
420 static void spr_read_dbat_h(DisasContext *ctx, int gprn, int sprn)
422 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env,
423 offsetof(CPUPPCState,
424 DBAT[sprn & 1][((sprn - SPR_DBAT4U) / 2) + 4]));
427 static void spr_write_dbatu(DisasContext *ctx, int sprn, int gprn)
429 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_DBAT0U) / 2);
430 gen_helper_store_dbatu(cpu_env, t0, cpu_gpr[gprn]);
431 tcg_temp_free_i32(t0);
434 static void spr_write_dbatu_h(DisasContext *ctx, int sprn, int gprn)
436 TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_DBAT4U) / 2) + 4);
437 gen_helper_store_dbatu(cpu_env, t0, cpu_gpr[gprn]);
438 tcg_temp_free_i32(t0);
441 static void spr_write_dbatl(DisasContext *ctx, int sprn, int gprn)
443 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_DBAT0L) / 2);
444 gen_helper_store_dbatl(cpu_env, t0, cpu_gpr[gprn]);
445 tcg_temp_free_i32(t0);
448 static void spr_write_dbatl_h(DisasContext *ctx, int sprn, int gprn)
450 TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_DBAT4L) / 2) + 4);
451 gen_helper_store_dbatl(cpu_env, t0, cpu_gpr[gprn]);
452 tcg_temp_free_i32(t0);
456 static void spr_write_sdr1(DisasContext *ctx, int sprn, int gprn)
458 gen_helper_store_sdr1(cpu_env, cpu_gpr[gprn]);
461 #if defined(TARGET_PPC64)
462 /* 64 bits PowerPC specific SPRs */
464 static void spr_write_pidr(DisasContext *ctx, int sprn, int gprn)
466 gen_helper_store_pidr(cpu_env, cpu_gpr[gprn]);
469 static void spr_write_lpidr(DisasContext *ctx, int sprn, int gprn)
471 gen_helper_store_lpidr(cpu_env, cpu_gpr[gprn]);
474 static void spr_read_hior(DisasContext *ctx, int gprn, int sprn)
476 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, excp_prefix));
479 static void spr_write_hior(DisasContext *ctx, int sprn, int gprn)
481 TCGv t0 = tcg_temp_new();
482 tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0x3FFFFF00000ULL);
483 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, excp_prefix));
486 static void spr_write_ptcr(DisasContext *ctx, int sprn, int gprn)
488 gen_helper_store_ptcr(cpu_env, cpu_gpr[gprn]);
491 static void spr_write_pcr(DisasContext *ctx, int sprn, int gprn)
493 gen_helper_store_pcr(cpu_env, cpu_gpr[gprn]);
497 static void spr_read_dpdes(DisasContext *ctx, int gprn, int sprn)
499 gen_helper_load_dpdes(cpu_gpr[gprn], cpu_env);
502 static void spr_write_dpdes(DisasContext *ctx, int sprn, int gprn)
504 gen_helper_store_dpdes(cpu_env, cpu_gpr[gprn]);
509 /* PowerPC 601 specific registers */
511 static void spr_read_601_rtcl(DisasContext *ctx, int gprn, int sprn)
513 gen_helper_load_601_rtcl(cpu_gpr[gprn], cpu_env);
516 static void spr_read_601_rtcu(DisasContext *ctx, int gprn, int sprn)
518 gen_helper_load_601_rtcu(cpu_gpr[gprn], cpu_env);
521 #if !defined(CONFIG_USER_ONLY)
522 static void spr_write_601_rtcu(DisasContext *ctx, int sprn, int gprn)
524 gen_helper_store_601_rtcu(cpu_env, cpu_gpr[gprn]);
527 static void spr_write_601_rtcl(DisasContext *ctx, int sprn, int gprn)
529 gen_helper_store_601_rtcl(cpu_env, cpu_gpr[gprn]);
532 static void spr_write_hid0_601(DisasContext *ctx, int sprn, int gprn)
534 gen_helper_store_hid0_601(cpu_env, cpu_gpr[gprn]);
535 /* Must stop the translation as endianness may have changed */
536 gen_stop_exception(ctx);
541 #if !defined(CONFIG_USER_ONLY)
542 static void spr_read_601_ubat(DisasContext *ctx, int gprn, int sprn)
544 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env,
545 offsetof(CPUPPCState,
546 IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2]));
549 static void spr_write_601_ubatu(DisasContext *ctx, int sprn, int gprn)
551 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2);
552 gen_helper_store_601_batl(cpu_env, t0, cpu_gpr[gprn]);
553 tcg_temp_free_i32(t0);
556 static void spr_write_601_ubatl(DisasContext *ctx, int sprn, int gprn)
558 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2);
559 gen_helper_store_601_batu(cpu_env, t0, cpu_gpr[gprn]);
560 tcg_temp_free_i32(t0);
564 /* PowerPC 40x specific registers */
565 #if !defined(CONFIG_USER_ONLY)
566 static void spr_read_40x_pit(DisasContext *ctx, int gprn, int sprn)
568 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
571 gen_helper_load_40x_pit(cpu_gpr[gprn], cpu_env);
572 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
573 gen_stop_exception(ctx);
577 static void spr_write_40x_pit(DisasContext *ctx, int sprn, int gprn)
579 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
582 gen_helper_store_40x_pit(cpu_env, cpu_gpr[gprn]);
583 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
584 gen_stop_exception(ctx);
588 static void spr_write_40x_dbcr0(DisasContext *ctx, int sprn, int gprn)
590 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
593 gen_store_spr(sprn, cpu_gpr[gprn]);
594 gen_helper_store_40x_dbcr0(cpu_env, cpu_gpr[gprn]);
595 /* We must stop translation as we may have rebooted */
596 gen_stop_exception(ctx);
597 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
598 gen_stop_exception(ctx);
602 static void spr_write_40x_sler(DisasContext *ctx, int sprn, int gprn)
604 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
607 gen_helper_store_40x_sler(cpu_env, cpu_gpr[gprn]);
608 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
609 gen_stop_exception(ctx);
613 static void spr_write_booke_tcr(DisasContext *ctx, int sprn, int gprn)
615 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
618 gen_helper_store_booke_tcr(cpu_env, cpu_gpr[gprn]);
619 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
620 gen_stop_exception(ctx);
624 static void spr_write_booke_tsr(DisasContext *ctx, int sprn, int gprn)
626 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
629 gen_helper_store_booke_tsr(cpu_env, cpu_gpr[gprn]);
630 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
631 gen_stop_exception(ctx);
636 /* PowerPC 403 specific registers */
637 /* PBL1 / PBU1 / PBL2 / PBU2 */
638 #if !defined(CONFIG_USER_ONLY)
639 static void spr_read_403_pbr(DisasContext *ctx, int gprn, int sprn)
641 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env,
642 offsetof(CPUPPCState, pb[sprn - SPR_403_PBL1]));
645 static void spr_write_403_pbr(DisasContext *ctx, int sprn, int gprn)
647 TCGv_i32 t0 = tcg_const_i32(sprn - SPR_403_PBL1);
648 gen_helper_store_403_pbr(cpu_env, t0, cpu_gpr[gprn]);
649 tcg_temp_free_i32(t0);
652 static void spr_write_pir(DisasContext *ctx, int sprn, int gprn)
654 TCGv t0 = tcg_temp_new();
655 tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0xF);
656 gen_store_spr(SPR_PIR, t0);
661 /* SPE specific registers */
662 static void spr_read_spefscr(DisasContext *ctx, int gprn, int sprn)
664 TCGv_i32 t0 = tcg_temp_new_i32();
665 tcg_gen_ld_i32(t0, cpu_env, offsetof(CPUPPCState, spe_fscr));
666 tcg_gen_extu_i32_tl(cpu_gpr[gprn], t0);
667 tcg_temp_free_i32(t0);
670 static void spr_write_spefscr(DisasContext *ctx, int sprn, int gprn)
672 TCGv_i32 t0 = tcg_temp_new_i32();
673 tcg_gen_trunc_tl_i32(t0, cpu_gpr[gprn]);
674 tcg_gen_st_i32(t0, cpu_env, offsetof(CPUPPCState, spe_fscr));
675 tcg_temp_free_i32(t0);
678 #if !defined(CONFIG_USER_ONLY)
679 /* Callback used to write the exception vector base */
680 static void spr_write_excp_prefix(DisasContext *ctx, int sprn, int gprn)
682 TCGv t0 = tcg_temp_new();
683 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUPPCState, ivpr_mask));
684 tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]);
685 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, excp_prefix));
686 gen_store_spr(sprn, t0);
690 static void spr_write_excp_vector(DisasContext *ctx, int sprn, int gprn)
694 if (sprn >= SPR_BOOKE_IVOR0 && sprn <= SPR_BOOKE_IVOR15) {
695 sprn_offs = sprn - SPR_BOOKE_IVOR0;
696 } else if (sprn >= SPR_BOOKE_IVOR32 && sprn <= SPR_BOOKE_IVOR37) {
697 sprn_offs = sprn - SPR_BOOKE_IVOR32 + 32;
698 } else if (sprn >= SPR_BOOKE_IVOR38 && sprn <= SPR_BOOKE_IVOR42) {
699 sprn_offs = sprn - SPR_BOOKE_IVOR38 + 38;
701 printf("Trying to write an unknown exception vector %d %03x\n",
703 gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
707 TCGv t0 = tcg_temp_new();
708 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUPPCState, ivor_mask));
709 tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]);
710 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, excp_vectors[sprn_offs]));
711 gen_store_spr(sprn, t0);
716 static inline void vscr_init(CPUPPCState *env, uint32_t val)
718 /* Altivec always uses round-to-nearest */
719 set_float_rounding_mode(float_round_nearest_even, &env->vec_status);
720 helper_mtvscr(env, val);
726 * Register an SPR with all the callbacks required for tcg,
727 * and the ID number for KVM.
729 * The reason for the conditional compilation is that the tcg functions
730 * may be compiled out, and the system kvm header may not be available
731 * for supplying the ID numbers. This is ugly, but the best we can do.
735 # define USR_ARG(X) X,
736 # ifdef CONFIG_USER_ONLY
739 # define SYS_ARG(X) X,
746 # define KVM_ARG(X) X,
751 typedef void spr_callback(DisasContext *, int, int);
753 static void _spr_register(CPUPPCState *env, int num, const char *name,
754 USR_ARG(spr_callback *uea_read)
755 USR_ARG(spr_callback *uea_write)
756 SYS_ARG(spr_callback *oea_read)
757 SYS_ARG(spr_callback *oea_write)
758 SYS_ARG(spr_callback *hea_read)
759 SYS_ARG(spr_callback *hea_write)
760 KVM_ARG(uint64_t one_reg_id)
761 target_ulong initial_value)
763 ppc_spr_t *spr = &env->spr_cb[num];
765 /* No SPR should be registered twice. */
766 assert(spr->name == NULL);
767 assert(name != NULL);
770 spr->default_value = initial_value;
771 env->spr[num] = initial_value;
774 spr->uea_read = uea_read;
775 spr->uea_write = uea_write;
776 # ifndef CONFIG_USER_ONLY
777 spr->oea_read = oea_read;
778 spr->oea_write = oea_write;
779 spr->hea_read = hea_read;
780 spr->hea_write = hea_write;
784 spr->one_reg_id = one_reg_id;
788 /* spr_register_kvm_hv passes all required arguments. */
789 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
790 oea_read, oea_write, hea_read, hea_write, \
791 one_reg_id, initial_value) \
792 _spr_register(env, num, name, \
793 USR_ARG(uea_read) USR_ARG(uea_write) \
794 SYS_ARG(oea_read) SYS_ARG(oea_write) \
795 SYS_ARG(hea_read) SYS_ARG(hea_write) \
796 KVM_ARG(one_reg_id) initial_value)
798 /* spr_register_kvm duplicates the oea callbacks to the hea callbacks. */
799 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
800 oea_read, oea_write, one_reg_id, ival) \
801 spr_register_kvm_hv(env, num, name, uea_read, uea_write, oea_read, \
802 oea_write, oea_read, oea_write, one_reg_id, ival)
804 /* spr_register_hv and spr_register are similar, except there is no kvm id. */
805 #define spr_register_hv(env, num, name, uea_read, uea_write, \
806 oea_read, oea_write, hea_read, hea_write, ival) \
807 spr_register_kvm_hv(env, num, name, uea_read, uea_write, oea_read, \
808 oea_write, hea_read, hea_write, 0, ival)
810 #define spr_register(env, num, name, uea_read, uea_write, \
811 oea_read, oea_write, ival) \
812 spr_register_kvm(env, num, name, uea_read, uea_write, \
813 oea_read, oea_write, 0, ival)
815 /* Generic PowerPC SPRs */
816 static void gen_spr_generic(CPUPPCState *env)
818 /* Integer processing */
819 spr_register(env, SPR_XER, "XER",
820 &spr_read_xer, &spr_write_xer,
821 &spr_read_xer, &spr_write_xer,
824 spr_register(env, SPR_LR, "LR",
825 &spr_read_lr, &spr_write_lr,
826 &spr_read_lr, &spr_write_lr,
828 spr_register(env, SPR_CTR, "CTR",
829 &spr_read_ctr, &spr_write_ctr,
830 &spr_read_ctr, &spr_write_ctr,
832 /* Interrupt processing */
833 spr_register(env, SPR_SRR0, "SRR0",
834 SPR_NOACCESS, SPR_NOACCESS,
835 &spr_read_generic, &spr_write_generic,
837 spr_register(env, SPR_SRR1, "SRR1",
838 SPR_NOACCESS, SPR_NOACCESS,
839 &spr_read_generic, &spr_write_generic,
841 /* Processor control */
842 spr_register(env, SPR_SPRG0, "SPRG0",
843 SPR_NOACCESS, SPR_NOACCESS,
844 &spr_read_generic, &spr_write_generic,
846 spr_register(env, SPR_SPRG1, "SPRG1",
847 SPR_NOACCESS, SPR_NOACCESS,
848 &spr_read_generic, &spr_write_generic,
850 spr_register(env, SPR_SPRG2, "SPRG2",
851 SPR_NOACCESS, SPR_NOACCESS,
852 &spr_read_generic, &spr_write_generic,
854 spr_register(env, SPR_SPRG3, "SPRG3",
855 SPR_NOACCESS, SPR_NOACCESS,
856 &spr_read_generic, &spr_write_generic,
860 /* SPR common to all non-embedded PowerPC, including 601 */
861 static void gen_spr_ne_601(CPUPPCState *env)
863 /* Exception processing */
864 spr_register_kvm(env, SPR_DSISR, "DSISR",
865 SPR_NOACCESS, SPR_NOACCESS,
866 &spr_read_generic, &spr_write_generic,
867 KVM_REG_PPC_DSISR, 0x00000000);
868 spr_register_kvm(env, SPR_DAR, "DAR",
869 SPR_NOACCESS, SPR_NOACCESS,
870 &spr_read_generic, &spr_write_generic,
871 KVM_REG_PPC_DAR, 0x00000000);
873 spr_register(env, SPR_DECR, "DECR",
874 SPR_NOACCESS, SPR_NOACCESS,
875 &spr_read_decr, &spr_write_decr,
879 /* Storage Description Register 1 */
880 static void gen_spr_sdr1(CPUPPCState *env)
882 #ifndef CONFIG_USER_ONLY
883 if (env->has_hv_mode) {
885 * SDR1 is a hypervisor resource on CPUs which have a
888 spr_register_hv(env, SPR_SDR1, "SDR1",
889 SPR_NOACCESS, SPR_NOACCESS,
890 SPR_NOACCESS, SPR_NOACCESS,
891 &spr_read_generic, &spr_write_sdr1,
894 spr_register(env, SPR_SDR1, "SDR1",
895 SPR_NOACCESS, SPR_NOACCESS,
896 &spr_read_generic, &spr_write_sdr1,
903 static void gen_low_BATs(CPUPPCState *env)
905 #if !defined(CONFIG_USER_ONLY)
906 spr_register(env, SPR_IBAT0U, "IBAT0U",
907 SPR_NOACCESS, SPR_NOACCESS,
908 &spr_read_ibat, &spr_write_ibatu,
910 spr_register(env, SPR_IBAT0L, "IBAT0L",
911 SPR_NOACCESS, SPR_NOACCESS,
912 &spr_read_ibat, &spr_write_ibatl,
914 spr_register(env, SPR_IBAT1U, "IBAT1U",
915 SPR_NOACCESS, SPR_NOACCESS,
916 &spr_read_ibat, &spr_write_ibatu,
918 spr_register(env, SPR_IBAT1L, "IBAT1L",
919 SPR_NOACCESS, SPR_NOACCESS,
920 &spr_read_ibat, &spr_write_ibatl,
922 spr_register(env, SPR_IBAT2U, "IBAT2U",
923 SPR_NOACCESS, SPR_NOACCESS,
924 &spr_read_ibat, &spr_write_ibatu,
926 spr_register(env, SPR_IBAT2L, "IBAT2L",
927 SPR_NOACCESS, SPR_NOACCESS,
928 &spr_read_ibat, &spr_write_ibatl,
930 spr_register(env, SPR_IBAT3U, "IBAT3U",
931 SPR_NOACCESS, SPR_NOACCESS,
932 &spr_read_ibat, &spr_write_ibatu,
934 spr_register(env, SPR_IBAT3L, "IBAT3L",
935 SPR_NOACCESS, SPR_NOACCESS,
936 &spr_read_ibat, &spr_write_ibatl,
938 spr_register(env, SPR_DBAT0U, "DBAT0U",
939 SPR_NOACCESS, SPR_NOACCESS,
940 &spr_read_dbat, &spr_write_dbatu,
942 spr_register(env, SPR_DBAT0L, "DBAT0L",
943 SPR_NOACCESS, SPR_NOACCESS,
944 &spr_read_dbat, &spr_write_dbatl,
946 spr_register(env, SPR_DBAT1U, "DBAT1U",
947 SPR_NOACCESS, SPR_NOACCESS,
948 &spr_read_dbat, &spr_write_dbatu,
950 spr_register(env, SPR_DBAT1L, "DBAT1L",
951 SPR_NOACCESS, SPR_NOACCESS,
952 &spr_read_dbat, &spr_write_dbatl,
954 spr_register(env, SPR_DBAT2U, "DBAT2U",
955 SPR_NOACCESS, SPR_NOACCESS,
956 &spr_read_dbat, &spr_write_dbatu,
958 spr_register(env, SPR_DBAT2L, "DBAT2L",
959 SPR_NOACCESS, SPR_NOACCESS,
960 &spr_read_dbat, &spr_write_dbatl,
962 spr_register(env, SPR_DBAT3U, "DBAT3U",
963 SPR_NOACCESS, SPR_NOACCESS,
964 &spr_read_dbat, &spr_write_dbatu,
966 spr_register(env, SPR_DBAT3L, "DBAT3L",
967 SPR_NOACCESS, SPR_NOACCESS,
968 &spr_read_dbat, &spr_write_dbatl,
975 static void gen_high_BATs(CPUPPCState *env)
977 #if !defined(CONFIG_USER_ONLY)
978 spr_register(env, SPR_IBAT4U, "IBAT4U",
979 SPR_NOACCESS, SPR_NOACCESS,
980 &spr_read_ibat_h, &spr_write_ibatu_h,
982 spr_register(env, SPR_IBAT4L, "IBAT4L",
983 SPR_NOACCESS, SPR_NOACCESS,
984 &spr_read_ibat_h, &spr_write_ibatl_h,
986 spr_register(env, SPR_IBAT5U, "IBAT5U",
987 SPR_NOACCESS, SPR_NOACCESS,
988 &spr_read_ibat_h, &spr_write_ibatu_h,
990 spr_register(env, SPR_IBAT5L, "IBAT5L",
991 SPR_NOACCESS, SPR_NOACCESS,
992 &spr_read_ibat_h, &spr_write_ibatl_h,
994 spr_register(env, SPR_IBAT6U, "IBAT6U",
995 SPR_NOACCESS, SPR_NOACCESS,
996 &spr_read_ibat_h, &spr_write_ibatu_h,
998 spr_register(env, SPR_IBAT6L, "IBAT6L",
999 SPR_NOACCESS, SPR_NOACCESS,
1000 &spr_read_ibat_h, &spr_write_ibatl_h,
1002 spr_register(env, SPR_IBAT7U, "IBAT7U",
1003 SPR_NOACCESS, SPR_NOACCESS,
1004 &spr_read_ibat_h, &spr_write_ibatu_h,
1006 spr_register(env, SPR_IBAT7L, "IBAT7L",
1007 SPR_NOACCESS, SPR_NOACCESS,
1008 &spr_read_ibat_h, &spr_write_ibatl_h,
1010 spr_register(env, SPR_DBAT4U, "DBAT4U",
1011 SPR_NOACCESS, SPR_NOACCESS,
1012 &spr_read_dbat_h, &spr_write_dbatu_h,
1014 spr_register(env, SPR_DBAT4L, "DBAT4L",
1015 SPR_NOACCESS, SPR_NOACCESS,
1016 &spr_read_dbat_h, &spr_write_dbatl_h,
1018 spr_register(env, SPR_DBAT5U, "DBAT5U",
1019 SPR_NOACCESS, SPR_NOACCESS,
1020 &spr_read_dbat_h, &spr_write_dbatu_h,
1022 spr_register(env, SPR_DBAT5L, "DBAT5L",
1023 SPR_NOACCESS, SPR_NOACCESS,
1024 &spr_read_dbat_h, &spr_write_dbatl_h,
1026 spr_register(env, SPR_DBAT6U, "DBAT6U",
1027 SPR_NOACCESS, SPR_NOACCESS,
1028 &spr_read_dbat_h, &spr_write_dbatu_h,
1030 spr_register(env, SPR_DBAT6L, "DBAT6L",
1031 SPR_NOACCESS, SPR_NOACCESS,
1032 &spr_read_dbat_h, &spr_write_dbatl_h,
1034 spr_register(env, SPR_DBAT7U, "DBAT7U",
1035 SPR_NOACCESS, SPR_NOACCESS,
1036 &spr_read_dbat_h, &spr_write_dbatu_h,
1038 spr_register(env, SPR_DBAT7L, "DBAT7L",
1039 SPR_NOACCESS, SPR_NOACCESS,
1040 &spr_read_dbat_h, &spr_write_dbatl_h,
1046 /* Generic PowerPC time base */
1047 static void gen_tbl(CPUPPCState *env)
1049 spr_register(env, SPR_VTBL, "TBL",
1050 &spr_read_tbl, SPR_NOACCESS,
1051 &spr_read_tbl, SPR_NOACCESS,
1053 spr_register(env, SPR_TBL, "TBL",
1054 &spr_read_tbl, SPR_NOACCESS,
1055 &spr_read_tbl, &spr_write_tbl,
1057 spr_register(env, SPR_VTBU, "TBU",
1058 &spr_read_tbu, SPR_NOACCESS,
1059 &spr_read_tbu, SPR_NOACCESS,
1061 spr_register(env, SPR_TBU, "TBU",
1062 &spr_read_tbu, SPR_NOACCESS,
1063 &spr_read_tbu, &spr_write_tbu,
1067 /* Softare table search registers */
1068 static void gen_6xx_7xx_soft_tlb(CPUPPCState *env, int nb_tlbs, int nb_ways)
1070 #if !defined(CONFIG_USER_ONLY)
1071 env->nb_tlb = nb_tlbs;
1072 env->nb_ways = nb_ways;
1074 env->tlb_type = TLB_6XX;
1075 spr_register(env, SPR_DMISS, "DMISS",
1076 SPR_NOACCESS, SPR_NOACCESS,
1077 &spr_read_generic, SPR_NOACCESS,
1079 spr_register(env, SPR_DCMP, "DCMP",
1080 SPR_NOACCESS, SPR_NOACCESS,
1081 &spr_read_generic, SPR_NOACCESS,
1083 spr_register(env, SPR_HASH1, "HASH1",
1084 SPR_NOACCESS, SPR_NOACCESS,
1085 &spr_read_generic, SPR_NOACCESS,
1087 spr_register(env, SPR_HASH2, "HASH2",
1088 SPR_NOACCESS, SPR_NOACCESS,
1089 &spr_read_generic, SPR_NOACCESS,
1091 spr_register(env, SPR_IMISS, "IMISS",
1092 SPR_NOACCESS, SPR_NOACCESS,
1093 &spr_read_generic, SPR_NOACCESS,
1095 spr_register(env, SPR_ICMP, "ICMP",
1096 SPR_NOACCESS, SPR_NOACCESS,
1097 &spr_read_generic, SPR_NOACCESS,
1099 spr_register(env, SPR_RPA, "RPA",
1100 SPR_NOACCESS, SPR_NOACCESS,
1101 &spr_read_generic, &spr_write_generic,
1106 /* SPR common to MPC755 and G2 */
1107 static void gen_spr_G2_755(CPUPPCState *env)
1110 spr_register(env, SPR_SPRG4, "SPRG4",
1111 SPR_NOACCESS, SPR_NOACCESS,
1112 &spr_read_generic, &spr_write_generic,
1114 spr_register(env, SPR_SPRG5, "SPRG5",
1115 SPR_NOACCESS, SPR_NOACCESS,
1116 &spr_read_generic, &spr_write_generic,
1118 spr_register(env, SPR_SPRG6, "SPRG6",
1119 SPR_NOACCESS, SPR_NOACCESS,
1120 &spr_read_generic, &spr_write_generic,
1122 spr_register(env, SPR_SPRG7, "SPRG7",
1123 SPR_NOACCESS, SPR_NOACCESS,
1124 &spr_read_generic, &spr_write_generic,
1128 /* SPR common to all 7xx PowerPC implementations */
1129 static void gen_spr_7xx(CPUPPCState *env)
1132 /* XXX : not implemented */
1133 spr_register_kvm(env, SPR_DABR, "DABR",
1134 SPR_NOACCESS, SPR_NOACCESS,
1135 &spr_read_generic, &spr_write_generic,
1136 KVM_REG_PPC_DABR, 0x00000000);
1137 /* XXX : not implemented */
1138 spr_register(env, SPR_IABR, "IABR",
1139 SPR_NOACCESS, SPR_NOACCESS,
1140 &spr_read_generic, &spr_write_generic,
1142 /* Cache management */
1143 /* XXX : not implemented */
1144 spr_register(env, SPR_ICTC, "ICTC",
1145 SPR_NOACCESS, SPR_NOACCESS,
1146 &spr_read_generic, &spr_write_generic,
1148 /* Performance monitors */
1149 /* XXX : not implemented */
1150 spr_register(env, SPR_7XX_MMCR0, "MMCR0",
1151 SPR_NOACCESS, SPR_NOACCESS,
1152 &spr_read_generic, &spr_write_generic,
1154 /* XXX : not implemented */
1155 spr_register(env, SPR_7XX_MMCR1, "MMCR1",
1156 SPR_NOACCESS, SPR_NOACCESS,
1157 &spr_read_generic, &spr_write_generic,
1159 /* XXX : not implemented */
1160 spr_register(env, SPR_7XX_PMC1, "PMC1",
1161 SPR_NOACCESS, SPR_NOACCESS,
1162 &spr_read_generic, &spr_write_generic,
1164 /* XXX : not implemented */
1165 spr_register(env, SPR_7XX_PMC2, "PMC2",
1166 SPR_NOACCESS, SPR_NOACCESS,
1167 &spr_read_generic, &spr_write_generic,
1169 /* XXX : not implemented */
1170 spr_register(env, SPR_7XX_PMC3, "PMC3",
1171 SPR_NOACCESS, SPR_NOACCESS,
1172 &spr_read_generic, &spr_write_generic,
1174 /* XXX : not implemented */
1175 spr_register(env, SPR_7XX_PMC4, "PMC4",
1176 SPR_NOACCESS, SPR_NOACCESS,
1177 &spr_read_generic, &spr_write_generic,
1179 /* XXX : not implemented */
1180 spr_register(env, SPR_7XX_SIAR, "SIAR",
1181 SPR_NOACCESS, SPR_NOACCESS,
1182 &spr_read_generic, SPR_NOACCESS,
1184 /* XXX : not implemented */
1185 spr_register(env, SPR_7XX_UMMCR0, "UMMCR0",
1186 &spr_read_ureg, SPR_NOACCESS,
1187 &spr_read_ureg, SPR_NOACCESS,
1189 /* XXX : not implemented */
1190 spr_register(env, SPR_7XX_UMMCR1, "UMMCR1",
1191 &spr_read_ureg, SPR_NOACCESS,
1192 &spr_read_ureg, SPR_NOACCESS,
1194 /* XXX : not implemented */
1195 spr_register(env, SPR_7XX_UPMC1, "UPMC1",
1196 &spr_read_ureg, SPR_NOACCESS,
1197 &spr_read_ureg, SPR_NOACCESS,
1199 /* XXX : not implemented */
1200 spr_register(env, SPR_7XX_UPMC2, "UPMC2",
1201 &spr_read_ureg, SPR_NOACCESS,
1202 &spr_read_ureg, SPR_NOACCESS,
1204 /* XXX : not implemented */
1205 spr_register(env, SPR_7XX_UPMC3, "UPMC3",
1206 &spr_read_ureg, SPR_NOACCESS,
1207 &spr_read_ureg, SPR_NOACCESS,
1209 /* XXX : not implemented */
1210 spr_register(env, SPR_7XX_UPMC4, "UPMC4",
1211 &spr_read_ureg, SPR_NOACCESS,
1212 &spr_read_ureg, SPR_NOACCESS,
1214 /* XXX : not implemented */
1215 spr_register(env, SPR_7XX_USIAR, "USIAR",
1216 &spr_read_ureg, SPR_NOACCESS,
1217 &spr_read_ureg, SPR_NOACCESS,
1219 /* External access control */
1220 /* XXX : not implemented */
1221 spr_register(env, SPR_EAR, "EAR",
1222 SPR_NOACCESS, SPR_NOACCESS,
1223 &spr_read_generic, &spr_write_generic,
1228 #ifndef CONFIG_USER_ONLY
1229 static void spr_write_amr(DisasContext *ctx, int sprn, int gprn)
1231 TCGv t0 = tcg_temp_new();
1232 TCGv t1 = tcg_temp_new();
1233 TCGv t2 = tcg_temp_new();
1236 * Note, the HV=1 PR=0 case is handled earlier by simply using
1237 * spr_write_generic for HV mode in the SPR table
1240 /* Build insertion mask into t1 based on context */
1242 gen_load_spr(t1, SPR_UAMOR);
1244 gen_load_spr(t1, SPR_AMOR);
1247 /* Mask new bits into t2 */
1248 tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]);
1250 /* Load AMR and clear new bits in t0 */
1251 gen_load_spr(t0, SPR_AMR);
1252 tcg_gen_andc_tl(t0, t0, t1);
1254 /* Or'in new bits and write it out */
1255 tcg_gen_or_tl(t0, t0, t2);
1256 gen_store_spr(SPR_AMR, t0);
1257 spr_store_dump_spr(SPR_AMR);
1264 static void spr_write_uamor(DisasContext *ctx, int sprn, int gprn)
1266 TCGv t0 = tcg_temp_new();
1267 TCGv t1 = tcg_temp_new();
1268 TCGv t2 = tcg_temp_new();
1271 * Note, the HV=1 case is handled earlier by simply using
1272 * spr_write_generic for HV mode in the SPR table
1275 /* Build insertion mask into t1 based on context */
1276 gen_load_spr(t1, SPR_AMOR);
1278 /* Mask new bits into t2 */
1279 tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]);
1281 /* Load AMR and clear new bits in t0 */
1282 gen_load_spr(t0, SPR_UAMOR);
1283 tcg_gen_andc_tl(t0, t0, t1);
1285 /* Or'in new bits and write it out */
1286 tcg_gen_or_tl(t0, t0, t2);
1287 gen_store_spr(SPR_UAMOR, t0);
1288 spr_store_dump_spr(SPR_UAMOR);
1295 static void spr_write_iamr(DisasContext *ctx, int sprn, int gprn)
1297 TCGv t0 = tcg_temp_new();
1298 TCGv t1 = tcg_temp_new();
1299 TCGv t2 = tcg_temp_new();
1302 * Note, the HV=1 case is handled earlier by simply using
1303 * spr_write_generic for HV mode in the SPR table
1306 /* Build insertion mask into t1 based on context */
1307 gen_load_spr(t1, SPR_AMOR);
1309 /* Mask new bits into t2 */
1310 tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]);
1312 /* Load AMR and clear new bits in t0 */
1313 gen_load_spr(t0, SPR_IAMR);
1314 tcg_gen_andc_tl(t0, t0, t1);
1316 /* Or'in new bits and write it out */
1317 tcg_gen_or_tl(t0, t0, t2);
1318 gen_store_spr(SPR_IAMR, t0);
1319 spr_store_dump_spr(SPR_IAMR);
1325 #endif /* CONFIG_USER_ONLY */
1327 static void gen_spr_amr(CPUPPCState *env)
1329 #ifndef CONFIG_USER_ONLY
1331 * Virtual Page Class Key protection
1333 * The AMR is accessible either via SPR 13 or SPR 29. 13 is
1334 * userspace accessible, 29 is privileged. So we only need to set
1335 * the kvm ONE_REG id on one of them, we use 29
1337 spr_register(env, SPR_UAMR, "UAMR",
1338 &spr_read_generic, &spr_write_amr,
1339 &spr_read_generic, &spr_write_amr,
1341 spr_register_kvm_hv(env, SPR_AMR, "AMR",
1342 SPR_NOACCESS, SPR_NOACCESS,
1343 &spr_read_generic, &spr_write_amr,
1344 &spr_read_generic, &spr_write_generic,
1345 KVM_REG_PPC_AMR, 0);
1346 spr_register_kvm_hv(env, SPR_UAMOR, "UAMOR",
1347 SPR_NOACCESS, SPR_NOACCESS,
1348 &spr_read_generic, &spr_write_uamor,
1349 &spr_read_generic, &spr_write_generic,
1350 KVM_REG_PPC_UAMOR, 0);
1351 spr_register_hv(env, SPR_AMOR, "AMOR",
1352 SPR_NOACCESS, SPR_NOACCESS,
1353 SPR_NOACCESS, SPR_NOACCESS,
1354 &spr_read_generic, &spr_write_generic,
1356 #endif /* !CONFIG_USER_ONLY */
1359 static void gen_spr_iamr(CPUPPCState *env)
1361 #ifndef CONFIG_USER_ONLY
1362 spr_register_kvm_hv(env, SPR_IAMR, "IAMR",
1363 SPR_NOACCESS, SPR_NOACCESS,
1364 &spr_read_generic, &spr_write_iamr,
1365 &spr_read_generic, &spr_write_generic,
1366 KVM_REG_PPC_IAMR, 0);
1367 #endif /* !CONFIG_USER_ONLY */
1369 #endif /* TARGET_PPC64 */
1371 #ifndef CONFIG_USER_ONLY
1372 static void spr_read_thrm(DisasContext *ctx, int gprn, int sprn)
1374 gen_helper_fixup_thrm(cpu_env);
1375 gen_load_spr(cpu_gpr[gprn], sprn);
1376 spr_load_dump_spr(sprn);
1378 #endif /* !CONFIG_USER_ONLY */
1380 static void gen_spr_thrm(CPUPPCState *env)
1382 /* Thermal management */
1383 /* XXX : not implemented */
1384 spr_register(env, SPR_THRM1, "THRM1",
1385 SPR_NOACCESS, SPR_NOACCESS,
1386 &spr_read_thrm, &spr_write_generic,
1388 /* XXX : not implemented */
1389 spr_register(env, SPR_THRM2, "THRM2",
1390 SPR_NOACCESS, SPR_NOACCESS,
1391 &spr_read_thrm, &spr_write_generic,
1393 /* XXX : not implemented */
1394 spr_register(env, SPR_THRM3, "THRM3",
1395 SPR_NOACCESS, SPR_NOACCESS,
1396 &spr_read_thrm, &spr_write_generic,
1400 /* SPR specific to PowerPC 604 implementation */
1401 static void gen_spr_604(CPUPPCState *env)
1403 /* Processor identification */
1404 spr_register(env, SPR_PIR, "PIR",
1405 SPR_NOACCESS, SPR_NOACCESS,
1406 &spr_read_generic, &spr_write_pir,
1409 /* XXX : not implemented */
1410 spr_register(env, SPR_IABR, "IABR",
1411 SPR_NOACCESS, SPR_NOACCESS,
1412 &spr_read_generic, &spr_write_generic,
1414 /* XXX : not implemented */
1415 spr_register_kvm(env, SPR_DABR, "DABR",
1416 SPR_NOACCESS, SPR_NOACCESS,
1417 &spr_read_generic, &spr_write_generic,
1418 KVM_REG_PPC_DABR, 0x00000000);
1419 /* Performance counters */
1420 /* XXX : not implemented */
1421 spr_register(env, SPR_7XX_MMCR0, "MMCR0",
1422 SPR_NOACCESS, SPR_NOACCESS,
1423 &spr_read_generic, &spr_write_generic,
1425 /* XXX : not implemented */
1426 spr_register(env, SPR_7XX_PMC1, "PMC1",
1427 SPR_NOACCESS, SPR_NOACCESS,
1428 &spr_read_generic, &spr_write_generic,
1430 /* XXX : not implemented */
1431 spr_register(env, SPR_7XX_PMC2, "PMC2",
1432 SPR_NOACCESS, SPR_NOACCESS,
1433 &spr_read_generic, &spr_write_generic,
1435 /* XXX : not implemented */
1436 spr_register(env, SPR_7XX_SIAR, "SIAR",
1437 SPR_NOACCESS, SPR_NOACCESS,
1438 &spr_read_generic, SPR_NOACCESS,
1440 /* XXX : not implemented */
1441 spr_register(env, SPR_SDA, "SDA",
1442 SPR_NOACCESS, SPR_NOACCESS,
1443 &spr_read_generic, SPR_NOACCESS,
1445 /* External access control */
1446 /* XXX : not implemented */
1447 spr_register(env, SPR_EAR, "EAR",
1448 SPR_NOACCESS, SPR_NOACCESS,
1449 &spr_read_generic, &spr_write_generic,
1453 /* SPR specific to PowerPC 603 implementation */
1454 static void gen_spr_603(CPUPPCState *env)
1456 /* External access control */
1457 /* XXX : not implemented */
1458 spr_register(env, SPR_EAR, "EAR",
1459 SPR_NOACCESS, SPR_NOACCESS,
1460 &spr_read_generic, &spr_write_generic,
1463 /* XXX : not implemented */
1464 spr_register(env, SPR_IABR, "IABR",
1465 SPR_NOACCESS, SPR_NOACCESS,
1466 &spr_read_generic, &spr_write_generic,
1471 /* SPR specific to PowerPC G2 implementation */
1472 static void gen_spr_G2(CPUPPCState *env)
1474 /* Memory base address */
1476 /* XXX : not implemented */
1477 spr_register(env, SPR_MBAR, "MBAR",
1478 SPR_NOACCESS, SPR_NOACCESS,
1479 &spr_read_generic, &spr_write_generic,
1481 /* Exception processing */
1482 spr_register(env, SPR_BOOKE_CSRR0, "CSRR0",
1483 SPR_NOACCESS, SPR_NOACCESS,
1484 &spr_read_generic, &spr_write_generic,
1486 spr_register(env, SPR_BOOKE_CSRR1, "CSRR1",
1487 SPR_NOACCESS, SPR_NOACCESS,
1488 &spr_read_generic, &spr_write_generic,
1491 /* XXX : not implemented */
1492 spr_register(env, SPR_DABR, "DABR",
1493 SPR_NOACCESS, SPR_NOACCESS,
1494 &spr_read_generic, &spr_write_generic,
1496 /* XXX : not implemented */
1497 spr_register(env, SPR_DABR2, "DABR2",
1498 SPR_NOACCESS, SPR_NOACCESS,
1499 &spr_read_generic, &spr_write_generic,
1501 /* XXX : not implemented */
1502 spr_register(env, SPR_IABR, "IABR",
1503 SPR_NOACCESS, SPR_NOACCESS,
1504 &spr_read_generic, &spr_write_generic,
1506 /* XXX : not implemented */
1507 spr_register(env, SPR_IABR2, "IABR2",
1508 SPR_NOACCESS, SPR_NOACCESS,
1509 &spr_read_generic, &spr_write_generic,
1511 /* XXX : not implemented */
1512 spr_register(env, SPR_IBCR, "IBCR",
1513 SPR_NOACCESS, SPR_NOACCESS,
1514 &spr_read_generic, &spr_write_generic,
1516 /* XXX : not implemented */
1517 spr_register(env, SPR_DBCR, "DBCR",
1518 SPR_NOACCESS, SPR_NOACCESS,
1519 &spr_read_generic, &spr_write_generic,
1523 /* SPR specific to PowerPC 602 implementation */
1524 static void gen_spr_602(CPUPPCState *env)
1527 /* XXX : not implemented */
1528 spr_register(env, SPR_SER, "SER",
1529 SPR_NOACCESS, SPR_NOACCESS,
1530 &spr_read_generic, &spr_write_generic,
1532 /* XXX : not implemented */
1533 spr_register(env, SPR_SEBR, "SEBR",
1534 SPR_NOACCESS, SPR_NOACCESS,
1535 &spr_read_generic, &spr_write_generic,
1537 /* XXX : not implemented */
1538 spr_register(env, SPR_ESASRR, "ESASRR",
1539 SPR_NOACCESS, SPR_NOACCESS,
1540 &spr_read_generic, &spr_write_generic,
1542 /* Floating point status */
1543 /* XXX : not implemented */
1544 spr_register(env, SPR_SP, "SP",
1545 SPR_NOACCESS, SPR_NOACCESS,
1546 &spr_read_generic, &spr_write_generic,
1548 /* XXX : not implemented */
1549 spr_register(env, SPR_LT, "LT",
1550 SPR_NOACCESS, SPR_NOACCESS,
1551 &spr_read_generic, &spr_write_generic,
1553 /* Watchdog timer */
1554 /* XXX : not implemented */
1555 spr_register(env, SPR_TCR, "TCR",
1556 SPR_NOACCESS, SPR_NOACCESS,
1557 &spr_read_generic, &spr_write_generic,
1559 /* Interrupt base */
1560 spr_register(env, SPR_IBR, "IBR",
1561 SPR_NOACCESS, SPR_NOACCESS,
1562 &spr_read_generic, &spr_write_generic,
1564 /* XXX : not implemented */
1565 spr_register(env, SPR_IABR, "IABR",
1566 SPR_NOACCESS, SPR_NOACCESS,
1567 &spr_read_generic, &spr_write_generic,
1571 /* SPR specific to PowerPC 601 implementation */
1572 static void gen_spr_601(CPUPPCState *env)
1574 /* Multiplication/division register */
1576 spr_register(env, SPR_MQ, "MQ",
1577 &spr_read_generic, &spr_write_generic,
1578 &spr_read_generic, &spr_write_generic,
1581 spr_register(env, SPR_601_RTCU, "RTCU",
1582 SPR_NOACCESS, SPR_NOACCESS,
1583 SPR_NOACCESS, &spr_write_601_rtcu,
1585 spr_register(env, SPR_601_VRTCU, "RTCU",
1586 &spr_read_601_rtcu, SPR_NOACCESS,
1587 &spr_read_601_rtcu, SPR_NOACCESS,
1589 spr_register(env, SPR_601_RTCL, "RTCL",
1590 SPR_NOACCESS, SPR_NOACCESS,
1591 SPR_NOACCESS, &spr_write_601_rtcl,
1593 spr_register(env, SPR_601_VRTCL, "RTCL",
1594 &spr_read_601_rtcl, SPR_NOACCESS,
1595 &spr_read_601_rtcl, SPR_NOACCESS,
1599 spr_register(env, SPR_601_UDECR, "UDECR",
1600 &spr_read_decr, SPR_NOACCESS,
1601 &spr_read_decr, SPR_NOACCESS,
1604 /* External access control */
1605 /* XXX : not implemented */
1606 spr_register(env, SPR_EAR, "EAR",
1607 SPR_NOACCESS, SPR_NOACCESS,
1608 &spr_read_generic, &spr_write_generic,
1610 /* Memory management */
1611 #if !defined(CONFIG_USER_ONLY)
1612 spr_register(env, SPR_IBAT0U, "IBAT0U",
1613 SPR_NOACCESS, SPR_NOACCESS,
1614 &spr_read_601_ubat, &spr_write_601_ubatu,
1616 spr_register(env, SPR_IBAT0L, "IBAT0L",
1617 SPR_NOACCESS, SPR_NOACCESS,
1618 &spr_read_601_ubat, &spr_write_601_ubatl,
1620 spr_register(env, SPR_IBAT1U, "IBAT1U",
1621 SPR_NOACCESS, SPR_NOACCESS,
1622 &spr_read_601_ubat, &spr_write_601_ubatu,
1624 spr_register(env, SPR_IBAT1L, "IBAT1L",
1625 SPR_NOACCESS, SPR_NOACCESS,
1626 &spr_read_601_ubat, &spr_write_601_ubatl,
1628 spr_register(env, SPR_IBAT2U, "IBAT2U",
1629 SPR_NOACCESS, SPR_NOACCESS,
1630 &spr_read_601_ubat, &spr_write_601_ubatu,
1632 spr_register(env, SPR_IBAT2L, "IBAT2L",
1633 SPR_NOACCESS, SPR_NOACCESS,
1634 &spr_read_601_ubat, &spr_write_601_ubatl,
1636 spr_register(env, SPR_IBAT3U, "IBAT3U",
1637 SPR_NOACCESS, SPR_NOACCESS,
1638 &spr_read_601_ubat, &spr_write_601_ubatu,
1640 spr_register(env, SPR_IBAT3L, "IBAT3L",
1641 SPR_NOACCESS, SPR_NOACCESS,
1642 &spr_read_601_ubat, &spr_write_601_ubatl,
1648 static void gen_spr_74xx(CPUPPCState *env)
1650 /* Processor identification */
1651 spr_register(env, SPR_PIR, "PIR",
1652 SPR_NOACCESS, SPR_NOACCESS,
1653 &spr_read_generic, &spr_write_pir,
1655 /* XXX : not implemented */
1656 spr_register(env, SPR_74XX_MMCR2, "MMCR2",
1657 SPR_NOACCESS, SPR_NOACCESS,
1658 &spr_read_generic, &spr_write_generic,
1660 /* XXX : not implemented */
1661 spr_register(env, SPR_74XX_UMMCR2, "UMMCR2",
1662 &spr_read_ureg, SPR_NOACCESS,
1663 &spr_read_ureg, SPR_NOACCESS,
1665 /* XXX: not implemented */
1666 spr_register(env, SPR_BAMR, "BAMR",
1667 SPR_NOACCESS, SPR_NOACCESS,
1668 &spr_read_generic, &spr_write_generic,
1670 /* XXX : not implemented */
1671 spr_register(env, SPR_MSSCR0, "MSSCR0",
1672 SPR_NOACCESS, SPR_NOACCESS,
1673 &spr_read_generic, &spr_write_generic,
1675 /* Hardware implementation registers */
1676 /* XXX : not implemented */
1677 spr_register(env, SPR_HID0, "HID0",
1678 SPR_NOACCESS, SPR_NOACCESS,
1679 &spr_read_generic, &spr_write_generic,
1681 /* XXX : not implemented */
1682 spr_register(env, SPR_HID1, "HID1",
1683 SPR_NOACCESS, SPR_NOACCESS,
1684 &spr_read_generic, &spr_write_generic,
1687 spr_register(env, SPR_VRSAVE, "VRSAVE",
1688 &spr_read_generic, &spr_write_generic,
1689 &spr_read_generic, &spr_write_generic,
1691 /* XXX : not implemented */
1692 spr_register(env, SPR_L2CR, "L2CR",
1693 SPR_NOACCESS, SPR_NOACCESS,
1694 &spr_read_generic, spr_access_nop,
1696 /* Not strictly an SPR */
1697 vscr_init(env, 0x00010000);
1700 static void gen_l3_ctrl(CPUPPCState *env)
1703 /* XXX : not implemented */
1704 spr_register(env, SPR_L3CR, "L3CR",
1705 SPR_NOACCESS, SPR_NOACCESS,
1706 &spr_read_generic, &spr_write_generic,
1709 /* XXX : not implemented */
1710 spr_register(env, SPR_L3ITCR0, "L3ITCR0",
1711 SPR_NOACCESS, SPR_NOACCESS,
1712 &spr_read_generic, &spr_write_generic,
1715 /* XXX : not implemented */
1716 spr_register(env, SPR_L3PM, "L3PM",
1717 SPR_NOACCESS, SPR_NOACCESS,
1718 &spr_read_generic, &spr_write_generic,
1722 static void gen_74xx_soft_tlb(CPUPPCState *env, int nb_tlbs, int nb_ways)
1724 #if !defined(CONFIG_USER_ONLY)
1725 env->nb_tlb = nb_tlbs;
1726 env->nb_ways = nb_ways;
1728 env->tlb_type = TLB_6XX;
1729 /* XXX : not implemented */
1730 spr_register(env, SPR_PTEHI, "PTEHI",
1731 SPR_NOACCESS, SPR_NOACCESS,
1732 &spr_read_generic, &spr_write_generic,
1734 /* XXX : not implemented */
1735 spr_register(env, SPR_PTELO, "PTELO",
1736 SPR_NOACCESS, SPR_NOACCESS,
1737 &spr_read_generic, &spr_write_generic,
1739 /* XXX : not implemented */
1740 spr_register(env, SPR_TLBMISS, "TLBMISS",
1741 SPR_NOACCESS, SPR_NOACCESS,
1742 &spr_read_generic, &spr_write_generic,
1747 #if !defined(CONFIG_USER_ONLY)
1748 static void spr_write_e500_l1csr0(DisasContext *ctx, int sprn, int gprn)
1750 TCGv t0 = tcg_temp_new();
1752 tcg_gen_andi_tl(t0, cpu_gpr[gprn], L1CSR0_DCE | L1CSR0_CPE);
1753 gen_store_spr(sprn, t0);
1757 static void spr_write_e500_l1csr1(DisasContext *ctx, int sprn, int gprn)
1759 TCGv t0 = tcg_temp_new();
1761 tcg_gen_andi_tl(t0, cpu_gpr[gprn], L1CSR1_ICE | L1CSR1_CPE);
1762 gen_store_spr(sprn, t0);
1766 static void spr_write_e500_l2csr0(DisasContext *ctx, int sprn, int gprn)
1768 TCGv t0 = tcg_temp_new();
1770 tcg_gen_andi_tl(t0, cpu_gpr[gprn],
1771 ~(E500_L2CSR0_L2FI | E500_L2CSR0_L2FL | E500_L2CSR0_L2LFC));
1772 gen_store_spr(sprn, t0);
1776 static void spr_write_booke206_mmucsr0(DisasContext *ctx, int sprn, int gprn)
1778 gen_helper_booke206_tlbflush(cpu_env, cpu_gpr[gprn]);
1781 static void spr_write_booke_pid(DisasContext *ctx, int sprn, int gprn)
1783 TCGv_i32 t0 = tcg_const_i32(sprn);
1784 gen_helper_booke_setpid(cpu_env, t0, cpu_gpr[gprn]);
1785 tcg_temp_free_i32(t0);
1787 static void spr_write_eplc(DisasContext *ctx, int sprn, int gprn)
1789 gen_helper_booke_set_eplc(cpu_env, cpu_gpr[gprn]);
1791 static void spr_write_epsc(DisasContext *ctx, int sprn, int gprn)
1793 gen_helper_booke_set_epsc(cpu_env, cpu_gpr[gprn]);
1798 static void gen_spr_usprg3(CPUPPCState *env)
1800 spr_register(env, SPR_USPRG3, "USPRG3",
1801 &spr_read_ureg, SPR_NOACCESS,
1802 &spr_read_ureg, SPR_NOACCESS,
1806 static void gen_spr_usprgh(CPUPPCState *env)
1808 spr_register(env, SPR_USPRG4, "USPRG4",
1809 &spr_read_ureg, SPR_NOACCESS,
1810 &spr_read_ureg, SPR_NOACCESS,
1812 spr_register(env, SPR_USPRG5, "USPRG5",
1813 &spr_read_ureg, SPR_NOACCESS,
1814 &spr_read_ureg, SPR_NOACCESS,
1816 spr_register(env, SPR_USPRG6, "USPRG6",
1817 &spr_read_ureg, SPR_NOACCESS,
1818 &spr_read_ureg, SPR_NOACCESS,
1820 spr_register(env, SPR_USPRG7, "USPRG7",
1821 &spr_read_ureg, SPR_NOACCESS,
1822 &spr_read_ureg, SPR_NOACCESS,
1826 /* PowerPC BookE SPR */
1827 static void gen_spr_BookE(CPUPPCState *env, uint64_t ivor_mask)
1829 const char *ivor_names[64] = {
1830 "IVOR0", "IVOR1", "IVOR2", "IVOR3",
1831 "IVOR4", "IVOR5", "IVOR6", "IVOR7",
1832 "IVOR8", "IVOR9", "IVOR10", "IVOR11",
1833 "IVOR12", "IVOR13", "IVOR14", "IVOR15",
1834 "IVOR16", "IVOR17", "IVOR18", "IVOR19",
1835 "IVOR20", "IVOR21", "IVOR22", "IVOR23",
1836 "IVOR24", "IVOR25", "IVOR26", "IVOR27",
1837 "IVOR28", "IVOR29", "IVOR30", "IVOR31",
1838 "IVOR32", "IVOR33", "IVOR34", "IVOR35",
1839 "IVOR36", "IVOR37", "IVOR38", "IVOR39",
1840 "IVOR40", "IVOR41", "IVOR42", "IVOR43",
1841 "IVOR44", "IVOR45", "IVOR46", "IVOR47",
1842 "IVOR48", "IVOR49", "IVOR50", "IVOR51",
1843 "IVOR52", "IVOR53", "IVOR54", "IVOR55",
1844 "IVOR56", "IVOR57", "IVOR58", "IVOR59",
1845 "IVOR60", "IVOR61", "IVOR62", "IVOR63",
1847 #define SPR_BOOKE_IVORxx (-1)
1848 int ivor_sprn[64] = {
1849 SPR_BOOKE_IVOR0, SPR_BOOKE_IVOR1, SPR_BOOKE_IVOR2, SPR_BOOKE_IVOR3,
1850 SPR_BOOKE_IVOR4, SPR_BOOKE_IVOR5, SPR_BOOKE_IVOR6, SPR_BOOKE_IVOR7,
1851 SPR_BOOKE_IVOR8, SPR_BOOKE_IVOR9, SPR_BOOKE_IVOR10, SPR_BOOKE_IVOR11,
1852 SPR_BOOKE_IVOR12, SPR_BOOKE_IVOR13, SPR_BOOKE_IVOR14, SPR_BOOKE_IVOR15,
1853 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1854 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1855 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1856 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1857 SPR_BOOKE_IVOR32, SPR_BOOKE_IVOR33, SPR_BOOKE_IVOR34, SPR_BOOKE_IVOR35,
1858 SPR_BOOKE_IVOR36, SPR_BOOKE_IVOR37, SPR_BOOKE_IVOR38, SPR_BOOKE_IVOR39,
1859 SPR_BOOKE_IVOR40, SPR_BOOKE_IVOR41, SPR_BOOKE_IVOR42, SPR_BOOKE_IVORxx,
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_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1868 /* Interrupt processing */
1869 spr_register(env, SPR_BOOKE_CSRR0, "CSRR0",
1870 SPR_NOACCESS, SPR_NOACCESS,
1871 &spr_read_generic, &spr_write_generic,
1873 spr_register(env, SPR_BOOKE_CSRR1, "CSRR1",
1874 SPR_NOACCESS, SPR_NOACCESS,
1875 &spr_read_generic, &spr_write_generic,
1878 /* XXX : not implemented */
1879 spr_register(env, SPR_BOOKE_IAC1, "IAC1",
1880 SPR_NOACCESS, SPR_NOACCESS,
1881 &spr_read_generic, &spr_write_generic,
1883 /* XXX : not implemented */
1884 spr_register(env, SPR_BOOKE_IAC2, "IAC2",
1885 SPR_NOACCESS, SPR_NOACCESS,
1886 &spr_read_generic, &spr_write_generic,
1888 /* XXX : not implemented */
1889 spr_register(env, SPR_BOOKE_DAC1, "DAC1",
1890 SPR_NOACCESS, SPR_NOACCESS,
1891 &spr_read_generic, &spr_write_generic,
1893 /* XXX : not implemented */
1894 spr_register(env, SPR_BOOKE_DAC2, "DAC2",
1895 SPR_NOACCESS, SPR_NOACCESS,
1896 &spr_read_generic, &spr_write_generic,
1898 /* XXX : not implemented */
1899 spr_register(env, SPR_BOOKE_DBCR0, "DBCR0",
1900 SPR_NOACCESS, SPR_NOACCESS,
1901 &spr_read_generic, &spr_write_40x_dbcr0,
1903 /* XXX : not implemented */
1904 spr_register(env, SPR_BOOKE_DBCR1, "DBCR1",
1905 SPR_NOACCESS, SPR_NOACCESS,
1906 &spr_read_generic, &spr_write_generic,
1908 /* XXX : not implemented */
1909 spr_register(env, SPR_BOOKE_DBCR2, "DBCR2",
1910 SPR_NOACCESS, SPR_NOACCESS,
1911 &spr_read_generic, &spr_write_generic,
1913 spr_register(env, SPR_BOOKE_DSRR0, "DSRR0",
1914 SPR_NOACCESS, SPR_NOACCESS,
1915 &spr_read_generic, &spr_write_generic,
1917 spr_register(env, SPR_BOOKE_DSRR1, "DSRR1",
1918 SPR_NOACCESS, SPR_NOACCESS,
1919 &spr_read_generic, &spr_write_generic,
1921 /* XXX : not implemented */
1922 spr_register(env, SPR_BOOKE_DBSR, "DBSR",
1923 SPR_NOACCESS, SPR_NOACCESS,
1924 &spr_read_generic, &spr_write_clear,
1926 spr_register(env, SPR_BOOKE_DEAR, "DEAR",
1927 SPR_NOACCESS, SPR_NOACCESS,
1928 &spr_read_generic, &spr_write_generic,
1930 spr_register(env, SPR_BOOKE_ESR, "ESR",
1931 SPR_NOACCESS, SPR_NOACCESS,
1932 &spr_read_generic, &spr_write_generic,
1934 spr_register(env, SPR_BOOKE_IVPR, "IVPR",
1935 SPR_NOACCESS, SPR_NOACCESS,
1936 &spr_read_generic, &spr_write_excp_prefix,
1938 /* Exception vectors */
1939 for (i = 0; i < 64; i++) {
1940 if (ivor_mask & (1ULL << i)) {
1941 if (ivor_sprn[i] == SPR_BOOKE_IVORxx) {
1942 fprintf(stderr, "ERROR: IVOR %d SPR is not defined\n", i);
1945 spr_register(env, ivor_sprn[i], ivor_names[i],
1946 SPR_NOACCESS, SPR_NOACCESS,
1947 &spr_read_generic, &spr_write_excp_vector,
1951 spr_register(env, SPR_BOOKE_PID, "PID",
1952 SPR_NOACCESS, SPR_NOACCESS,
1953 &spr_read_generic, &spr_write_booke_pid,
1955 spr_register(env, SPR_BOOKE_TCR, "TCR",
1956 SPR_NOACCESS, SPR_NOACCESS,
1957 &spr_read_generic, &spr_write_booke_tcr,
1959 spr_register(env, SPR_BOOKE_TSR, "TSR",
1960 SPR_NOACCESS, SPR_NOACCESS,
1961 &spr_read_generic, &spr_write_booke_tsr,
1964 spr_register(env, SPR_DECR, "DECR",
1965 SPR_NOACCESS, SPR_NOACCESS,
1966 &spr_read_decr, &spr_write_decr,
1968 spr_register(env, SPR_BOOKE_DECAR, "DECAR",
1969 SPR_NOACCESS, SPR_NOACCESS,
1970 SPR_NOACCESS, &spr_write_generic,
1973 spr_register(env, SPR_USPRG0, "USPRG0",
1974 &spr_read_generic, &spr_write_generic,
1975 &spr_read_generic, &spr_write_generic,
1977 spr_register(env, SPR_SPRG4, "SPRG4",
1978 SPR_NOACCESS, SPR_NOACCESS,
1979 &spr_read_generic, &spr_write_generic,
1981 spr_register(env, SPR_SPRG5, "SPRG5",
1982 SPR_NOACCESS, SPR_NOACCESS,
1983 &spr_read_generic, &spr_write_generic,
1985 spr_register(env, SPR_SPRG6, "SPRG6",
1986 SPR_NOACCESS, SPR_NOACCESS,
1987 &spr_read_generic, &spr_write_generic,
1989 spr_register(env, SPR_SPRG7, "SPRG7",
1990 SPR_NOACCESS, SPR_NOACCESS,
1991 &spr_read_generic, &spr_write_generic,
1993 spr_register(env, SPR_BOOKE_SPRG8, "SPRG8",
1994 SPR_NOACCESS, SPR_NOACCESS,
1995 &spr_read_generic, &spr_write_generic,
1997 spr_register(env, SPR_BOOKE_SPRG9, "SPRG9",
1998 SPR_NOACCESS, SPR_NOACCESS,
1999 &spr_read_generic, &spr_write_generic,
2003 static inline uint32_t gen_tlbncfg(uint32_t assoc, uint32_t minsize,
2004 uint32_t maxsize, uint32_t flags,
2007 return (assoc << TLBnCFG_ASSOC_SHIFT) |
2008 (minsize << TLBnCFG_MINSIZE_SHIFT) |
2009 (maxsize << TLBnCFG_MAXSIZE_SHIFT) |
2013 /* BookE 2.06 storage control registers */
2014 static void gen_spr_BookE206(CPUPPCState *env, uint32_t mas_mask,
2015 uint32_t *tlbncfg, uint32_t mmucfg)
2017 #if !defined(CONFIG_USER_ONLY)
2018 const char *mas_names[8] = {
2019 "MAS0", "MAS1", "MAS2", "MAS3", "MAS4", "MAS5", "MAS6", "MAS7",
2022 SPR_BOOKE_MAS0, SPR_BOOKE_MAS1, SPR_BOOKE_MAS2, SPR_BOOKE_MAS3,
2023 SPR_BOOKE_MAS4, SPR_BOOKE_MAS5, SPR_BOOKE_MAS6, SPR_BOOKE_MAS7,
2027 /* TLB assist registers */
2028 /* XXX : not implemented */
2029 for (i = 0; i < 8; i++) {
2030 void (*uea_write)(DisasContext *ctx, int sprn, int gprn) =
2031 &spr_write_generic32;
2032 if (i == 2 && (mas_mask & (1 << i)) && (env->insns_flags & PPC_64B)) {
2033 uea_write = &spr_write_generic;
2035 if (mas_mask & (1 << i)) {
2036 spr_register(env, mas_sprn[i], mas_names[i],
2037 SPR_NOACCESS, SPR_NOACCESS,
2038 &spr_read_generic, uea_write,
2042 if (env->nb_pids > 1) {
2043 /* XXX : not implemented */
2044 spr_register(env, SPR_BOOKE_PID1, "PID1",
2045 SPR_NOACCESS, SPR_NOACCESS,
2046 &spr_read_generic, &spr_write_booke_pid,
2049 if (env->nb_pids > 2) {
2050 /* XXX : not implemented */
2051 spr_register(env, SPR_BOOKE_PID2, "PID2",
2052 SPR_NOACCESS, SPR_NOACCESS,
2053 &spr_read_generic, &spr_write_booke_pid,
2057 spr_register(env, SPR_BOOKE_EPLC, "EPLC",
2058 SPR_NOACCESS, SPR_NOACCESS,
2059 &spr_read_generic, &spr_write_eplc,
2061 spr_register(env, SPR_BOOKE_EPSC, "EPSC",
2062 SPR_NOACCESS, SPR_NOACCESS,
2063 &spr_read_generic, &spr_write_epsc,
2066 /* XXX : not implemented */
2067 spr_register(env, SPR_MMUCFG, "MMUCFG",
2068 SPR_NOACCESS, SPR_NOACCESS,
2069 &spr_read_generic, SPR_NOACCESS,
2071 switch (env->nb_ways) {
2073 spr_register(env, SPR_BOOKE_TLB3CFG, "TLB3CFG",
2074 SPR_NOACCESS, SPR_NOACCESS,
2075 &spr_read_generic, SPR_NOACCESS,
2079 spr_register(env, SPR_BOOKE_TLB2CFG, "TLB2CFG",
2080 SPR_NOACCESS, SPR_NOACCESS,
2081 &spr_read_generic, SPR_NOACCESS,
2085 spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG",
2086 SPR_NOACCESS, SPR_NOACCESS,
2087 &spr_read_generic, SPR_NOACCESS,
2091 spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG",
2092 SPR_NOACCESS, SPR_NOACCESS,
2093 &spr_read_generic, SPR_NOACCESS,
2102 gen_spr_usprgh(env);
2105 /* SPR specific to PowerPC 440 implementation */
2106 static void gen_spr_440(CPUPPCState *env)
2109 /* XXX : not implemented */
2110 spr_register(env, SPR_440_DNV0, "DNV0",
2111 SPR_NOACCESS, SPR_NOACCESS,
2112 &spr_read_generic, &spr_write_generic,
2114 /* XXX : not implemented */
2115 spr_register(env, SPR_440_DNV1, "DNV1",
2116 SPR_NOACCESS, SPR_NOACCESS,
2117 &spr_read_generic, &spr_write_generic,
2119 /* XXX : not implemented */
2120 spr_register(env, SPR_440_DNV2, "DNV2",
2121 SPR_NOACCESS, SPR_NOACCESS,
2122 &spr_read_generic, &spr_write_generic,
2124 /* XXX : not implemented */
2125 spr_register(env, SPR_440_DNV3, "DNV3",
2126 SPR_NOACCESS, SPR_NOACCESS,
2127 &spr_read_generic, &spr_write_generic,
2129 /* XXX : not implemented */
2130 spr_register(env, SPR_440_DTV0, "DTV0",
2131 SPR_NOACCESS, SPR_NOACCESS,
2132 &spr_read_generic, &spr_write_generic,
2134 /* XXX : not implemented */
2135 spr_register(env, SPR_440_DTV1, "DTV1",
2136 SPR_NOACCESS, SPR_NOACCESS,
2137 &spr_read_generic, &spr_write_generic,
2139 /* XXX : not implemented */
2140 spr_register(env, SPR_440_DTV2, "DTV2",
2141 SPR_NOACCESS, SPR_NOACCESS,
2142 &spr_read_generic, &spr_write_generic,
2144 /* XXX : not implemented */
2145 spr_register(env, SPR_440_DTV3, "DTV3",
2146 SPR_NOACCESS, SPR_NOACCESS,
2147 &spr_read_generic, &spr_write_generic,
2149 /* XXX : not implemented */
2150 spr_register(env, SPR_440_DVLIM, "DVLIM",
2151 SPR_NOACCESS, SPR_NOACCESS,
2152 &spr_read_generic, &spr_write_generic,
2154 /* XXX : not implemented */
2155 spr_register(env, SPR_440_INV0, "INV0",
2156 SPR_NOACCESS, SPR_NOACCESS,
2157 &spr_read_generic, &spr_write_generic,
2159 /* XXX : not implemented */
2160 spr_register(env, SPR_440_INV1, "INV1",
2161 SPR_NOACCESS, SPR_NOACCESS,
2162 &spr_read_generic, &spr_write_generic,
2164 /* XXX : not implemented */
2165 spr_register(env, SPR_440_INV2, "INV2",
2166 SPR_NOACCESS, SPR_NOACCESS,
2167 &spr_read_generic, &spr_write_generic,
2169 /* XXX : not implemented */
2170 spr_register(env, SPR_440_INV3, "INV3",
2171 SPR_NOACCESS, SPR_NOACCESS,
2172 &spr_read_generic, &spr_write_generic,
2174 /* XXX : not implemented */
2175 spr_register(env, SPR_440_ITV0, "ITV0",
2176 SPR_NOACCESS, SPR_NOACCESS,
2177 &spr_read_generic, &spr_write_generic,
2179 /* XXX : not implemented */
2180 spr_register(env, SPR_440_ITV1, "ITV1",
2181 SPR_NOACCESS, SPR_NOACCESS,
2182 &spr_read_generic, &spr_write_generic,
2184 /* XXX : not implemented */
2185 spr_register(env, SPR_440_ITV2, "ITV2",
2186 SPR_NOACCESS, SPR_NOACCESS,
2187 &spr_read_generic, &spr_write_generic,
2189 /* XXX : not implemented */
2190 spr_register(env, SPR_440_ITV3, "ITV3",
2191 SPR_NOACCESS, SPR_NOACCESS,
2192 &spr_read_generic, &spr_write_generic,
2194 /* XXX : not implemented */
2195 spr_register(env, SPR_440_IVLIM, "IVLIM",
2196 SPR_NOACCESS, SPR_NOACCESS,
2197 &spr_read_generic, &spr_write_generic,
2200 /* XXX : not implemented */
2201 spr_register(env, SPR_BOOKE_DCDBTRH, "DCDBTRH",
2202 SPR_NOACCESS, SPR_NOACCESS,
2203 &spr_read_generic, SPR_NOACCESS,
2205 /* XXX : not implemented */
2206 spr_register(env, SPR_BOOKE_DCDBTRL, "DCDBTRL",
2207 SPR_NOACCESS, SPR_NOACCESS,
2208 &spr_read_generic, SPR_NOACCESS,
2210 /* XXX : not implemented */
2211 spr_register(env, SPR_BOOKE_ICDBDR, "ICDBDR",
2212 SPR_NOACCESS, SPR_NOACCESS,
2213 &spr_read_generic, SPR_NOACCESS,
2215 /* XXX : not implemented */
2216 spr_register(env, SPR_BOOKE_ICDBTRH, "ICDBTRH",
2217 SPR_NOACCESS, SPR_NOACCESS,
2218 &spr_read_generic, SPR_NOACCESS,
2220 /* XXX : not implemented */
2221 spr_register(env, SPR_BOOKE_ICDBTRL, "ICDBTRL",
2222 SPR_NOACCESS, SPR_NOACCESS,
2223 &spr_read_generic, SPR_NOACCESS,
2225 /* XXX : not implemented */
2226 spr_register(env, SPR_440_DBDR, "DBDR",
2227 SPR_NOACCESS, SPR_NOACCESS,
2228 &spr_read_generic, &spr_write_generic,
2230 /* Processor control */
2231 spr_register(env, SPR_4xx_CCR0, "CCR0",
2232 SPR_NOACCESS, SPR_NOACCESS,
2233 &spr_read_generic, &spr_write_generic,
2235 spr_register(env, SPR_440_RSTCFG, "RSTCFG",
2236 SPR_NOACCESS, SPR_NOACCESS,
2237 &spr_read_generic, SPR_NOACCESS,
2239 /* Storage control */
2240 spr_register(env, SPR_440_MMUCR, "MMUCR",
2241 SPR_NOACCESS, SPR_NOACCESS,
2242 &spr_read_generic, &spr_write_generic,
2246 /* SPR shared between PowerPC 40x implementations */
2247 static void gen_spr_40x(CPUPPCState *env)
2250 /* not emulated, as QEMU do not emulate caches */
2251 spr_register(env, SPR_40x_DCCR, "DCCR",
2252 SPR_NOACCESS, SPR_NOACCESS,
2253 &spr_read_generic, &spr_write_generic,
2255 /* not emulated, as QEMU do not emulate caches */
2256 spr_register(env, SPR_40x_ICCR, "ICCR",
2257 SPR_NOACCESS, SPR_NOACCESS,
2258 &spr_read_generic, &spr_write_generic,
2260 /* not emulated, as QEMU do not emulate caches */
2261 spr_register(env, SPR_BOOKE_ICDBDR, "ICDBDR",
2262 SPR_NOACCESS, SPR_NOACCESS,
2263 &spr_read_generic, SPR_NOACCESS,
2266 spr_register(env, SPR_40x_DEAR, "DEAR",
2267 SPR_NOACCESS, SPR_NOACCESS,
2268 &spr_read_generic, &spr_write_generic,
2270 spr_register(env, SPR_40x_ESR, "ESR",
2271 SPR_NOACCESS, SPR_NOACCESS,
2272 &spr_read_generic, &spr_write_generic,
2274 spr_register(env, SPR_40x_EVPR, "EVPR",
2275 SPR_NOACCESS, SPR_NOACCESS,
2276 &spr_read_generic, &spr_write_excp_prefix,
2278 spr_register(env, SPR_40x_SRR2, "SRR2",
2279 &spr_read_generic, &spr_write_generic,
2280 &spr_read_generic, &spr_write_generic,
2282 spr_register(env, SPR_40x_SRR3, "SRR3",
2283 &spr_read_generic, &spr_write_generic,
2284 &spr_read_generic, &spr_write_generic,
2287 spr_register(env, SPR_40x_PIT, "PIT",
2288 SPR_NOACCESS, SPR_NOACCESS,
2289 &spr_read_40x_pit, &spr_write_40x_pit,
2291 spr_register(env, SPR_40x_TCR, "TCR",
2292 SPR_NOACCESS, SPR_NOACCESS,
2293 &spr_read_generic, &spr_write_booke_tcr,
2295 spr_register(env, SPR_40x_TSR, "TSR",
2296 SPR_NOACCESS, SPR_NOACCESS,
2297 &spr_read_generic, &spr_write_booke_tsr,
2301 /* SPR specific to PowerPC 405 implementation */
2302 static void gen_spr_405(CPUPPCState *env)
2305 spr_register(env, SPR_40x_PID, "PID",
2306 SPR_NOACCESS, SPR_NOACCESS,
2307 &spr_read_generic, &spr_write_generic,
2309 spr_register(env, SPR_4xx_CCR0, "CCR0",
2310 SPR_NOACCESS, SPR_NOACCESS,
2311 &spr_read_generic, &spr_write_generic,
2313 /* Debug interface */
2314 /* XXX : not implemented */
2315 spr_register(env, SPR_40x_DBCR0, "DBCR0",
2316 SPR_NOACCESS, SPR_NOACCESS,
2317 &spr_read_generic, &spr_write_40x_dbcr0,
2319 /* XXX : not implemented */
2320 spr_register(env, SPR_405_DBCR1, "DBCR1",
2321 SPR_NOACCESS, SPR_NOACCESS,
2322 &spr_read_generic, &spr_write_generic,
2324 /* XXX : not implemented */
2325 spr_register(env, SPR_40x_DBSR, "DBSR",
2326 SPR_NOACCESS, SPR_NOACCESS,
2327 &spr_read_generic, &spr_write_clear,
2328 /* Last reset was system reset */
2330 /* XXX : not implemented */
2331 spr_register(env, SPR_40x_DAC1, "DAC1",
2332 SPR_NOACCESS, SPR_NOACCESS,
2333 &spr_read_generic, &spr_write_generic,
2335 spr_register(env, SPR_40x_DAC2, "DAC2",
2336 SPR_NOACCESS, SPR_NOACCESS,
2337 &spr_read_generic, &spr_write_generic,
2339 /* XXX : not implemented */
2340 spr_register(env, SPR_405_DVC1, "DVC1",
2341 SPR_NOACCESS, SPR_NOACCESS,
2342 &spr_read_generic, &spr_write_generic,
2344 /* XXX : not implemented */
2345 spr_register(env, SPR_405_DVC2, "DVC2",
2346 SPR_NOACCESS, SPR_NOACCESS,
2347 &spr_read_generic, &spr_write_generic,
2349 /* XXX : not implemented */
2350 spr_register(env, SPR_40x_IAC1, "IAC1",
2351 SPR_NOACCESS, SPR_NOACCESS,
2352 &spr_read_generic, &spr_write_generic,
2354 spr_register(env, SPR_40x_IAC2, "IAC2",
2355 SPR_NOACCESS, SPR_NOACCESS,
2356 &spr_read_generic, &spr_write_generic,
2358 /* XXX : not implemented */
2359 spr_register(env, SPR_405_IAC3, "IAC3",
2360 SPR_NOACCESS, SPR_NOACCESS,
2361 &spr_read_generic, &spr_write_generic,
2363 /* XXX : not implemented */
2364 spr_register(env, SPR_405_IAC4, "IAC4",
2365 SPR_NOACCESS, SPR_NOACCESS,
2366 &spr_read_generic, &spr_write_generic,
2368 /* Storage control */
2369 /* XXX: TODO: not implemented */
2370 spr_register(env, SPR_405_SLER, "SLER",
2371 SPR_NOACCESS, SPR_NOACCESS,
2372 &spr_read_generic, &spr_write_40x_sler,
2374 spr_register(env, SPR_40x_ZPR, "ZPR",
2375 SPR_NOACCESS, SPR_NOACCESS,
2376 &spr_read_generic, &spr_write_generic,
2378 /* XXX : not implemented */
2379 spr_register(env, SPR_405_SU0R, "SU0R",
2380 SPR_NOACCESS, SPR_NOACCESS,
2381 &spr_read_generic, &spr_write_generic,
2384 spr_register(env, SPR_USPRG0, "USPRG0",
2385 &spr_read_ureg, SPR_NOACCESS,
2386 &spr_read_ureg, SPR_NOACCESS,
2388 spr_register(env, SPR_SPRG4, "SPRG4",
2389 SPR_NOACCESS, SPR_NOACCESS,
2390 &spr_read_generic, &spr_write_generic,
2392 spr_register(env, SPR_SPRG5, "SPRG5",
2393 SPR_NOACCESS, SPR_NOACCESS,
2394 spr_read_generic, &spr_write_generic,
2396 spr_register(env, SPR_SPRG6, "SPRG6",
2397 SPR_NOACCESS, SPR_NOACCESS,
2398 spr_read_generic, &spr_write_generic,
2400 spr_register(env, SPR_SPRG7, "SPRG7",
2401 SPR_NOACCESS, SPR_NOACCESS,
2402 spr_read_generic, &spr_write_generic,
2404 gen_spr_usprgh(env);
2407 /* SPR shared between PowerPC 401 & 403 implementations */
2408 static void gen_spr_401_403(CPUPPCState *env)
2411 spr_register(env, SPR_403_VTBL, "TBL",
2412 &spr_read_tbl, SPR_NOACCESS,
2413 &spr_read_tbl, SPR_NOACCESS,
2415 spr_register(env, SPR_403_TBL, "TBL",
2416 SPR_NOACCESS, SPR_NOACCESS,
2417 SPR_NOACCESS, &spr_write_tbl,
2419 spr_register(env, SPR_403_VTBU, "TBU",
2420 &spr_read_tbu, SPR_NOACCESS,
2421 &spr_read_tbu, SPR_NOACCESS,
2423 spr_register(env, SPR_403_TBU, "TBU",
2424 SPR_NOACCESS, SPR_NOACCESS,
2425 SPR_NOACCESS, &spr_write_tbu,
2428 /* not emulated, as QEMU do not emulate caches */
2429 spr_register(env, SPR_403_CDBCR, "CDBCR",
2430 SPR_NOACCESS, SPR_NOACCESS,
2431 &spr_read_generic, &spr_write_generic,
2435 /* SPR specific to PowerPC 401 implementation */
2436 static void gen_spr_401(CPUPPCState *env)
2438 /* Debug interface */
2439 /* XXX : not implemented */
2440 spr_register(env, SPR_40x_DBCR0, "DBCR",
2441 SPR_NOACCESS, SPR_NOACCESS,
2442 &spr_read_generic, &spr_write_40x_dbcr0,
2444 /* XXX : not implemented */
2445 spr_register(env, SPR_40x_DBSR, "DBSR",
2446 SPR_NOACCESS, SPR_NOACCESS,
2447 &spr_read_generic, &spr_write_clear,
2448 /* Last reset was system reset */
2450 /* XXX : not implemented */
2451 spr_register(env, SPR_40x_DAC1, "DAC",
2452 SPR_NOACCESS, SPR_NOACCESS,
2453 &spr_read_generic, &spr_write_generic,
2455 /* XXX : not implemented */
2456 spr_register(env, SPR_40x_IAC1, "IAC",
2457 SPR_NOACCESS, SPR_NOACCESS,
2458 &spr_read_generic, &spr_write_generic,
2460 /* Storage control */
2461 /* XXX: TODO: not implemented */
2462 spr_register(env, SPR_405_SLER, "SLER",
2463 SPR_NOACCESS, SPR_NOACCESS,
2464 &spr_read_generic, &spr_write_40x_sler,
2466 /* not emulated, as QEMU never does speculative access */
2467 spr_register(env, SPR_40x_SGR, "SGR",
2468 SPR_NOACCESS, SPR_NOACCESS,
2469 &spr_read_generic, &spr_write_generic,
2471 /* not emulated, as QEMU do not emulate caches */
2472 spr_register(env, SPR_40x_DCWR, "DCWR",
2473 SPR_NOACCESS, SPR_NOACCESS,
2474 &spr_read_generic, &spr_write_generic,
2478 static void gen_spr_401x2(CPUPPCState *env)
2481 spr_register(env, SPR_40x_PID, "PID",
2482 SPR_NOACCESS, SPR_NOACCESS,
2483 &spr_read_generic, &spr_write_generic,
2485 spr_register(env, SPR_40x_ZPR, "ZPR",
2486 SPR_NOACCESS, SPR_NOACCESS,
2487 &spr_read_generic, &spr_write_generic,
2491 /* SPR specific to PowerPC 403 implementation */
2492 static void gen_spr_403(CPUPPCState *env)
2494 /* Debug interface */
2495 /* XXX : not implemented */
2496 spr_register(env, SPR_40x_DBCR0, "DBCR0",
2497 SPR_NOACCESS, SPR_NOACCESS,
2498 &spr_read_generic, &spr_write_40x_dbcr0,
2500 /* XXX : not implemented */
2501 spr_register(env, SPR_40x_DBSR, "DBSR",
2502 SPR_NOACCESS, SPR_NOACCESS,
2503 &spr_read_generic, &spr_write_clear,
2504 /* Last reset was system reset */
2506 /* XXX : not implemented */
2507 spr_register(env, SPR_40x_DAC1, "DAC1",
2508 SPR_NOACCESS, SPR_NOACCESS,
2509 &spr_read_generic, &spr_write_generic,
2511 /* XXX : not implemented */
2512 spr_register(env, SPR_40x_DAC2, "DAC2",
2513 SPR_NOACCESS, SPR_NOACCESS,
2514 &spr_read_generic, &spr_write_generic,
2516 /* XXX : not implemented */
2517 spr_register(env, SPR_40x_IAC1, "IAC1",
2518 SPR_NOACCESS, SPR_NOACCESS,
2519 &spr_read_generic, &spr_write_generic,
2521 /* XXX : not implemented */
2522 spr_register(env, SPR_40x_IAC2, "IAC2",
2523 SPR_NOACCESS, SPR_NOACCESS,
2524 &spr_read_generic, &spr_write_generic,
2528 static void gen_spr_403_real(CPUPPCState *env)
2530 spr_register(env, SPR_403_PBL1, "PBL1",
2531 SPR_NOACCESS, SPR_NOACCESS,
2532 &spr_read_403_pbr, &spr_write_403_pbr,
2534 spr_register(env, SPR_403_PBU1, "PBU1",
2535 SPR_NOACCESS, SPR_NOACCESS,
2536 &spr_read_403_pbr, &spr_write_403_pbr,
2538 spr_register(env, SPR_403_PBL2, "PBL2",
2539 SPR_NOACCESS, SPR_NOACCESS,
2540 &spr_read_403_pbr, &spr_write_403_pbr,
2542 spr_register(env, SPR_403_PBU2, "PBU2",
2543 SPR_NOACCESS, SPR_NOACCESS,
2544 &spr_read_403_pbr, &spr_write_403_pbr,
2548 static void gen_spr_403_mmu(CPUPPCState *env)
2551 spr_register(env, SPR_40x_PID, "PID",
2552 SPR_NOACCESS, SPR_NOACCESS,
2553 &spr_read_generic, &spr_write_generic,
2555 spr_register(env, SPR_40x_ZPR, "ZPR",
2556 SPR_NOACCESS, SPR_NOACCESS,
2557 &spr_read_generic, &spr_write_generic,
2561 /* SPR specific to PowerPC compression coprocessor extension */
2562 static void gen_spr_compress(CPUPPCState *env)
2564 /* XXX : not implemented */
2565 spr_register(env, SPR_401_SKR, "SKR",
2566 SPR_NOACCESS, SPR_NOACCESS,
2567 &spr_read_generic, &spr_write_generic,
2571 static void gen_spr_5xx_8xx(CPUPPCState *env)
2573 /* Exception processing */
2574 spr_register_kvm(env, SPR_DSISR, "DSISR",
2575 SPR_NOACCESS, SPR_NOACCESS,
2576 &spr_read_generic, &spr_write_generic,
2577 KVM_REG_PPC_DSISR, 0x00000000);
2578 spr_register_kvm(env, SPR_DAR, "DAR",
2579 SPR_NOACCESS, SPR_NOACCESS,
2580 &spr_read_generic, &spr_write_generic,
2581 KVM_REG_PPC_DAR, 0x00000000);
2583 spr_register(env, SPR_DECR, "DECR",
2584 SPR_NOACCESS, SPR_NOACCESS,
2585 &spr_read_decr, &spr_write_decr,
2587 /* XXX : not implemented */
2588 spr_register(env, SPR_MPC_EIE, "EIE",
2589 SPR_NOACCESS, SPR_NOACCESS,
2590 &spr_read_generic, &spr_write_generic,
2592 /* XXX : not implemented */
2593 spr_register(env, SPR_MPC_EID, "EID",
2594 SPR_NOACCESS, SPR_NOACCESS,
2595 &spr_read_generic, &spr_write_generic,
2597 /* XXX : not implemented */
2598 spr_register(env, SPR_MPC_NRI, "NRI",
2599 SPR_NOACCESS, SPR_NOACCESS,
2600 &spr_read_generic, &spr_write_generic,
2602 /* XXX : not implemented */
2603 spr_register(env, SPR_MPC_CMPA, "CMPA",
2604 SPR_NOACCESS, SPR_NOACCESS,
2605 &spr_read_generic, &spr_write_generic,
2607 /* XXX : not implemented */
2608 spr_register(env, SPR_MPC_CMPB, "CMPB",
2609 SPR_NOACCESS, SPR_NOACCESS,
2610 &spr_read_generic, &spr_write_generic,
2612 /* XXX : not implemented */
2613 spr_register(env, SPR_MPC_CMPC, "CMPC",
2614 SPR_NOACCESS, SPR_NOACCESS,
2615 &spr_read_generic, &spr_write_generic,
2617 /* XXX : not implemented */
2618 spr_register(env, SPR_MPC_CMPD, "CMPD",
2619 SPR_NOACCESS, SPR_NOACCESS,
2620 &spr_read_generic, &spr_write_generic,
2622 /* XXX : not implemented */
2623 spr_register(env, SPR_MPC_ECR, "ECR",
2624 SPR_NOACCESS, SPR_NOACCESS,
2625 &spr_read_generic, &spr_write_generic,
2627 /* XXX : not implemented */
2628 spr_register(env, SPR_MPC_DER, "DER",
2629 SPR_NOACCESS, SPR_NOACCESS,
2630 &spr_read_generic, &spr_write_generic,
2632 /* XXX : not implemented */
2633 spr_register(env, SPR_MPC_COUNTA, "COUNTA",
2634 SPR_NOACCESS, SPR_NOACCESS,
2635 &spr_read_generic, &spr_write_generic,
2637 /* XXX : not implemented */
2638 spr_register(env, SPR_MPC_COUNTB, "COUNTB",
2639 SPR_NOACCESS, SPR_NOACCESS,
2640 &spr_read_generic, &spr_write_generic,
2642 /* XXX : not implemented */
2643 spr_register(env, SPR_MPC_CMPE, "CMPE",
2644 SPR_NOACCESS, SPR_NOACCESS,
2645 &spr_read_generic, &spr_write_generic,
2647 /* XXX : not implemented */
2648 spr_register(env, SPR_MPC_CMPF, "CMPF",
2649 SPR_NOACCESS, SPR_NOACCESS,
2650 &spr_read_generic, &spr_write_generic,
2652 /* XXX : not implemented */
2653 spr_register(env, SPR_MPC_CMPG, "CMPG",
2654 SPR_NOACCESS, SPR_NOACCESS,
2655 &spr_read_generic, &spr_write_generic,
2657 /* XXX : not implemented */
2658 spr_register(env, SPR_MPC_CMPH, "CMPH",
2659 SPR_NOACCESS, SPR_NOACCESS,
2660 &spr_read_generic, &spr_write_generic,
2662 /* XXX : not implemented */
2663 spr_register(env, SPR_MPC_LCTRL1, "LCTRL1",
2664 SPR_NOACCESS, SPR_NOACCESS,
2665 &spr_read_generic, &spr_write_generic,
2667 /* XXX : not implemented */
2668 spr_register(env, SPR_MPC_LCTRL2, "LCTRL2",
2669 SPR_NOACCESS, SPR_NOACCESS,
2670 &spr_read_generic, &spr_write_generic,
2672 /* XXX : not implemented */
2673 spr_register(env, SPR_MPC_BAR, "BAR",
2674 SPR_NOACCESS, SPR_NOACCESS,
2675 &spr_read_generic, &spr_write_generic,
2677 /* XXX : not implemented */
2678 spr_register(env, SPR_MPC_DPDR, "DPDR",
2679 SPR_NOACCESS, SPR_NOACCESS,
2680 &spr_read_generic, &spr_write_generic,
2682 /* XXX : not implemented */
2683 spr_register(env, SPR_MPC_IMMR, "IMMR",
2684 SPR_NOACCESS, SPR_NOACCESS,
2685 &spr_read_generic, &spr_write_generic,
2689 static void gen_spr_5xx(CPUPPCState *env)
2691 /* XXX : not implemented */
2692 spr_register(env, SPR_RCPU_MI_GRA, "MI_GRA",
2693 SPR_NOACCESS, SPR_NOACCESS,
2694 &spr_read_generic, &spr_write_generic,
2696 /* XXX : not implemented */
2697 spr_register(env, SPR_RCPU_L2U_GRA, "L2U_GRA",
2698 SPR_NOACCESS, SPR_NOACCESS,
2699 &spr_read_generic, &spr_write_generic,
2701 /* XXX : not implemented */
2702 spr_register(env, SPR_RPCU_BBCMCR, "L2U_BBCMCR",
2703 SPR_NOACCESS, SPR_NOACCESS,
2704 &spr_read_generic, &spr_write_generic,
2706 /* XXX : not implemented */
2707 spr_register(env, SPR_RCPU_L2U_MCR, "L2U_MCR",
2708 SPR_NOACCESS, SPR_NOACCESS,
2709 &spr_read_generic, &spr_write_generic,
2711 /* XXX : not implemented */
2712 spr_register(env, SPR_RCPU_MI_RBA0, "MI_RBA0",
2713 SPR_NOACCESS, SPR_NOACCESS,
2714 &spr_read_generic, &spr_write_generic,
2716 /* XXX : not implemented */
2717 spr_register(env, SPR_RCPU_MI_RBA1, "MI_RBA1",
2718 SPR_NOACCESS, SPR_NOACCESS,
2719 &spr_read_generic, &spr_write_generic,
2721 /* XXX : not implemented */
2722 spr_register(env, SPR_RCPU_MI_RBA2, "MI_RBA2",
2723 SPR_NOACCESS, SPR_NOACCESS,
2724 &spr_read_generic, &spr_write_generic,
2726 /* XXX : not implemented */
2727 spr_register(env, SPR_RCPU_MI_RBA3, "MI_RBA3",
2728 SPR_NOACCESS, SPR_NOACCESS,
2729 &spr_read_generic, &spr_write_generic,
2731 /* XXX : not implemented */
2732 spr_register(env, SPR_RCPU_L2U_RBA0, "L2U_RBA0",
2733 SPR_NOACCESS, SPR_NOACCESS,
2734 &spr_read_generic, &spr_write_generic,
2736 /* XXX : not implemented */
2737 spr_register(env, SPR_RCPU_L2U_RBA1, "L2U_RBA1",
2738 SPR_NOACCESS, SPR_NOACCESS,
2739 &spr_read_generic, &spr_write_generic,
2741 /* XXX : not implemented */
2742 spr_register(env, SPR_RCPU_L2U_RBA2, "L2U_RBA2",
2743 SPR_NOACCESS, SPR_NOACCESS,
2744 &spr_read_generic, &spr_write_generic,
2746 /* XXX : not implemented */
2747 spr_register(env, SPR_RCPU_L2U_RBA3, "L2U_RBA3",
2748 SPR_NOACCESS, SPR_NOACCESS,
2749 &spr_read_generic, &spr_write_generic,
2751 /* XXX : not implemented */
2752 spr_register(env, SPR_RCPU_MI_RA0, "MI_RA0",
2753 SPR_NOACCESS, SPR_NOACCESS,
2754 &spr_read_generic, &spr_write_generic,
2756 /* XXX : not implemented */
2757 spr_register(env, SPR_RCPU_MI_RA1, "MI_RA1",
2758 SPR_NOACCESS, SPR_NOACCESS,
2759 &spr_read_generic, &spr_write_generic,
2761 /* XXX : not implemented */
2762 spr_register(env, SPR_RCPU_MI_RA2, "MI_RA2",
2763 SPR_NOACCESS, SPR_NOACCESS,
2764 &spr_read_generic, &spr_write_generic,
2766 /* XXX : not implemented */
2767 spr_register(env, SPR_RCPU_MI_RA3, "MI_RA3",
2768 SPR_NOACCESS, SPR_NOACCESS,
2769 &spr_read_generic, &spr_write_generic,
2771 /* XXX : not implemented */
2772 spr_register(env, SPR_RCPU_L2U_RA0, "L2U_RA0",
2773 SPR_NOACCESS, SPR_NOACCESS,
2774 &spr_read_generic, &spr_write_generic,
2776 /* XXX : not implemented */
2777 spr_register(env, SPR_RCPU_L2U_RA1, "L2U_RA1",
2778 SPR_NOACCESS, SPR_NOACCESS,
2779 &spr_read_generic, &spr_write_generic,
2781 /* XXX : not implemented */
2782 spr_register(env, SPR_RCPU_L2U_RA2, "L2U_RA2",
2783 SPR_NOACCESS, SPR_NOACCESS,
2784 &spr_read_generic, &spr_write_generic,
2786 /* XXX : not implemented */
2787 spr_register(env, SPR_RCPU_L2U_RA3, "L2U_RA3",
2788 SPR_NOACCESS, SPR_NOACCESS,
2789 &spr_read_generic, &spr_write_generic,
2791 /* XXX : not implemented */
2792 spr_register(env, SPR_RCPU_FPECR, "FPECR",
2793 SPR_NOACCESS, SPR_NOACCESS,
2794 &spr_read_generic, &spr_write_generic,
2798 static void gen_spr_8xx(CPUPPCState *env)
2800 /* XXX : not implemented */
2801 spr_register(env, SPR_MPC_IC_CST, "IC_CST",
2802 SPR_NOACCESS, SPR_NOACCESS,
2803 &spr_read_generic, &spr_write_generic,
2805 /* XXX : not implemented */
2806 spr_register(env, SPR_MPC_IC_ADR, "IC_ADR",
2807 SPR_NOACCESS, SPR_NOACCESS,
2808 &spr_read_generic, &spr_write_generic,
2810 /* XXX : not implemented */
2811 spr_register(env, SPR_MPC_IC_DAT, "IC_DAT",
2812 SPR_NOACCESS, SPR_NOACCESS,
2813 &spr_read_generic, &spr_write_generic,
2815 /* XXX : not implemented */
2816 spr_register(env, SPR_MPC_DC_CST, "DC_CST",
2817 SPR_NOACCESS, SPR_NOACCESS,
2818 &spr_read_generic, &spr_write_generic,
2820 /* XXX : not implemented */
2821 spr_register(env, SPR_MPC_DC_ADR, "DC_ADR",
2822 SPR_NOACCESS, SPR_NOACCESS,
2823 &spr_read_generic, &spr_write_generic,
2825 /* XXX : not implemented */
2826 spr_register(env, SPR_MPC_DC_DAT, "DC_DAT",
2827 SPR_NOACCESS, SPR_NOACCESS,
2828 &spr_read_generic, &spr_write_generic,
2830 /* XXX : not implemented */
2831 spr_register(env, SPR_MPC_MI_CTR, "MI_CTR",
2832 SPR_NOACCESS, SPR_NOACCESS,
2833 &spr_read_generic, &spr_write_generic,
2835 /* XXX : not implemented */
2836 spr_register(env, SPR_MPC_MI_AP, "MI_AP",
2837 SPR_NOACCESS, SPR_NOACCESS,
2838 &spr_read_generic, &spr_write_generic,
2840 /* XXX : not implemented */
2841 spr_register(env, SPR_MPC_MI_EPN, "MI_EPN",
2842 SPR_NOACCESS, SPR_NOACCESS,
2843 &spr_read_generic, &spr_write_generic,
2845 /* XXX : not implemented */
2846 spr_register(env, SPR_MPC_MI_TWC, "MI_TWC",
2847 SPR_NOACCESS, SPR_NOACCESS,
2848 &spr_read_generic, &spr_write_generic,
2850 /* XXX : not implemented */
2851 spr_register(env, SPR_MPC_MI_RPN, "MI_RPN",
2852 SPR_NOACCESS, SPR_NOACCESS,
2853 &spr_read_generic, &spr_write_generic,
2855 /* XXX : not implemented */
2856 spr_register(env, SPR_MPC_MI_DBCAM, "MI_DBCAM",
2857 SPR_NOACCESS, SPR_NOACCESS,
2858 &spr_read_generic, &spr_write_generic,
2860 /* XXX : not implemented */
2861 spr_register(env, SPR_MPC_MI_DBRAM0, "MI_DBRAM0",
2862 SPR_NOACCESS, SPR_NOACCESS,
2863 &spr_read_generic, &spr_write_generic,
2865 /* XXX : not implemented */
2866 spr_register(env, SPR_MPC_MI_DBRAM1, "MI_DBRAM1",
2867 SPR_NOACCESS, SPR_NOACCESS,
2868 &spr_read_generic, &spr_write_generic,
2870 /* XXX : not implemented */
2871 spr_register(env, SPR_MPC_MD_CTR, "MD_CTR",
2872 SPR_NOACCESS, SPR_NOACCESS,
2873 &spr_read_generic, &spr_write_generic,
2875 /* XXX : not implemented */
2876 spr_register(env, SPR_MPC_MD_CASID, "MD_CASID",
2877 SPR_NOACCESS, SPR_NOACCESS,
2878 &spr_read_generic, &spr_write_generic,
2880 /* XXX : not implemented */
2881 spr_register(env, SPR_MPC_MD_AP, "MD_AP",
2882 SPR_NOACCESS, SPR_NOACCESS,
2883 &spr_read_generic, &spr_write_generic,
2885 /* XXX : not implemented */
2886 spr_register(env, SPR_MPC_MD_EPN, "MD_EPN",
2887 SPR_NOACCESS, SPR_NOACCESS,
2888 &spr_read_generic, &spr_write_generic,
2890 /* XXX : not implemented */
2891 spr_register(env, SPR_MPC_MD_TWB, "MD_TWB",
2892 SPR_NOACCESS, SPR_NOACCESS,
2893 &spr_read_generic, &spr_write_generic,
2895 /* XXX : not implemented */
2896 spr_register(env, SPR_MPC_MD_TWC, "MD_TWC",
2897 SPR_NOACCESS, SPR_NOACCESS,
2898 &spr_read_generic, &spr_write_generic,
2900 /* XXX : not implemented */
2901 spr_register(env, SPR_MPC_MD_RPN, "MD_RPN",
2902 SPR_NOACCESS, SPR_NOACCESS,
2903 &spr_read_generic, &spr_write_generic,
2905 /* XXX : not implemented */
2906 spr_register(env, SPR_MPC_MD_TW, "MD_TW",
2907 SPR_NOACCESS, SPR_NOACCESS,
2908 &spr_read_generic, &spr_write_generic,
2910 /* XXX : not implemented */
2911 spr_register(env, SPR_MPC_MD_DBCAM, "MD_DBCAM",
2912 SPR_NOACCESS, SPR_NOACCESS,
2913 &spr_read_generic, &spr_write_generic,
2915 /* XXX : not implemented */
2916 spr_register(env, SPR_MPC_MD_DBRAM0, "MD_DBRAM0",
2917 SPR_NOACCESS, SPR_NOACCESS,
2918 &spr_read_generic, &spr_write_generic,
2920 /* XXX : not implemented */
2921 spr_register(env, SPR_MPC_MD_DBRAM1, "MD_DBRAM1",
2922 SPR_NOACCESS, SPR_NOACCESS,
2923 &spr_read_generic, &spr_write_generic,
2928 * AMR => SPR 29 (Power 2.04)
2929 * CTRL => SPR 136 (Power 2.04)
2930 * CTRL => SPR 152 (Power 2.04)
2931 * SCOMC => SPR 276 (64 bits ?)
2932 * SCOMD => SPR 277 (64 bits ?)
2933 * TBU40 => SPR 286 (Power 2.04 hypv)
2934 * HSPRG0 => SPR 304 (Power 2.04 hypv)
2935 * HSPRG1 => SPR 305 (Power 2.04 hypv)
2936 * HDSISR => SPR 306 (Power 2.04 hypv)
2937 * HDAR => SPR 307 (Power 2.04 hypv)
2938 * PURR => SPR 309 (Power 2.04 hypv)
2939 * HDEC => SPR 310 (Power 2.04 hypv)
2940 * HIOR => SPR 311 (hypv)
2941 * RMOR => SPR 312 (970)
2942 * HRMOR => SPR 313 (Power 2.04 hypv)
2943 * HSRR0 => SPR 314 (Power 2.04 hypv)
2944 * HSRR1 => SPR 315 (Power 2.04 hypv)
2945 * LPIDR => SPR 317 (970)
2946 * EPR => SPR 702 (Power 2.04 emb)
2947 * perf => 768-783 (Power 2.04)
2948 * perf => 784-799 (Power 2.04)
2949 * PPR => SPR 896 (Power 2.04)
2950 * DABRX => 1015 (Power 2.04 hypv)
2951 * FPECR => SPR 1022 (?)
2952 * ... and more (thermal management, performance counters, ...)
2955 /*****************************************************************************/
2956 /* Exception vectors models */
2957 static void init_excp_4xx_real(CPUPPCState *env)
2959 #if !defined(CONFIG_USER_ONLY)
2960 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000100;
2961 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
2962 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
2963 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
2964 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
2965 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
2966 env->excp_vectors[POWERPC_EXCP_PIT] = 0x00001000;
2967 env->excp_vectors[POWERPC_EXCP_FIT] = 0x00001010;
2968 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001020;
2969 env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000;
2970 env->ivor_mask = 0x0000FFF0UL;
2971 env->ivpr_mask = 0xFFFF0000UL;
2972 /* Hardware reset vector */
2973 env->hreset_vector = 0xFFFFFFFCUL;
2977 static void init_excp_4xx_softmmu(CPUPPCState *env)
2979 #if !defined(CONFIG_USER_ONLY)
2980 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000100;
2981 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
2982 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
2983 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
2984 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
2985 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
2986 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
2987 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
2988 env->excp_vectors[POWERPC_EXCP_PIT] = 0x00001000;
2989 env->excp_vectors[POWERPC_EXCP_FIT] = 0x00001010;
2990 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001020;
2991 env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001100;
2992 env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001200;
2993 env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000;
2994 env->ivor_mask = 0x0000FFF0UL;
2995 env->ivpr_mask = 0xFFFF0000UL;
2996 /* Hardware reset vector */
2997 env->hreset_vector = 0xFFFFFFFCUL;
3001 static void init_excp_MPC5xx(CPUPPCState *env)
3003 #if !defined(CONFIG_USER_ONLY)
3004 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3005 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3006 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3007 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3008 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3009 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000900;
3010 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3011 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3012 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3013 env->excp_vectors[POWERPC_EXCP_FPA] = 0x00000E00;
3014 env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001000;
3015 env->excp_vectors[POWERPC_EXCP_DABR] = 0x00001C00;
3016 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001C00;
3017 env->excp_vectors[POWERPC_EXCP_MEXTBR] = 0x00001E00;
3018 env->excp_vectors[POWERPC_EXCP_NMEXTBR] = 0x00001F00;
3019 env->ivor_mask = 0x0000FFF0UL;
3020 env->ivpr_mask = 0xFFFF0000UL;
3021 /* Hardware reset vector */
3022 env->hreset_vector = 0x00000100UL;
3026 static void init_excp_MPC8xx(CPUPPCState *env)
3028 #if !defined(CONFIG_USER_ONLY)
3029 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3030 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3031 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3032 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3033 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3034 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3035 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3036 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000900;
3037 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3038 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3039 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3040 env->excp_vectors[POWERPC_EXCP_FPA] = 0x00000E00;
3041 env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001000;
3042 env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001100;
3043 env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001200;
3044 env->excp_vectors[POWERPC_EXCP_ITLBE] = 0x00001300;
3045 env->excp_vectors[POWERPC_EXCP_DTLBE] = 0x00001400;
3046 env->excp_vectors[POWERPC_EXCP_DABR] = 0x00001C00;
3047 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001C00;
3048 env->excp_vectors[POWERPC_EXCP_MEXTBR] = 0x00001E00;
3049 env->excp_vectors[POWERPC_EXCP_NMEXTBR] = 0x00001F00;
3050 env->ivor_mask = 0x0000FFF0UL;
3051 env->ivpr_mask = 0xFFFF0000UL;
3052 /* Hardware reset vector */
3053 env->hreset_vector = 0x00000100UL;
3057 static void init_excp_G2(CPUPPCState *env)
3059 #if !defined(CONFIG_USER_ONLY)
3060 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3061 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3062 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3063 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3064 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3065 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3066 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3067 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3068 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3069 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000A00;
3070 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3071 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3072 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
3073 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
3074 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
3075 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3076 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3077 /* Hardware reset vector */
3078 env->hreset_vector = 0x00000100UL;
3082 static void init_excp_e200(CPUPPCState *env, target_ulong ivpr_mask)
3084 #if !defined(CONFIG_USER_ONLY)
3085 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000FFC;
3086 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000000;
3087 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000000;
3088 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000000;
3089 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000000;
3090 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000000;
3091 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000000;
3092 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000000;
3093 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000000;
3094 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000000;
3095 env->excp_vectors[POWERPC_EXCP_APU] = 0x00000000;
3096 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000000;
3097 env->excp_vectors[POWERPC_EXCP_FIT] = 0x00000000;
3098 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00000000;
3099 env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00000000;
3100 env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00000000;
3101 env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00000000;
3102 env->excp_vectors[POWERPC_EXCP_SPEU] = 0x00000000;
3103 env->excp_vectors[POWERPC_EXCP_EFPDI] = 0x00000000;
3104 env->excp_vectors[POWERPC_EXCP_EFPRI] = 0x00000000;
3105 env->ivor_mask = 0x0000FFF7UL;
3106 env->ivpr_mask = ivpr_mask;
3107 /* Hardware reset vector */
3108 env->hreset_vector = 0xFFFFFFFCUL;
3112 static void init_excp_BookE(CPUPPCState *env)
3114 #if !defined(CONFIG_USER_ONLY)
3115 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000000;
3116 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000000;
3117 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000000;
3118 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000000;
3119 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000000;
3120 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000000;
3121 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000000;
3122 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000000;
3123 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000000;
3124 env->excp_vectors[POWERPC_EXCP_APU] = 0x00000000;
3125 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000000;
3126 env->excp_vectors[POWERPC_EXCP_FIT] = 0x00000000;
3127 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00000000;
3128 env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00000000;
3129 env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00000000;
3130 env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00000000;
3131 env->ivor_mask = 0x0000FFF0UL;
3132 env->ivpr_mask = 0xFFFF0000UL;
3133 /* Hardware reset vector */
3134 env->hreset_vector = 0xFFFFFFFCUL;
3138 static void init_excp_601(CPUPPCState *env)
3140 #if !defined(CONFIG_USER_ONLY)
3141 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3142 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3143 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3144 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3145 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3146 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3147 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3148 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3149 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3150 env->excp_vectors[POWERPC_EXCP_IO] = 0x00000A00;
3151 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3152 env->excp_vectors[POWERPC_EXCP_RUNM] = 0x00002000;
3153 /* Hardware reset vector */
3154 env->hreset_vector = 0x00000100UL;
3158 static void init_excp_602(CPUPPCState *env)
3160 #if !defined(CONFIG_USER_ONLY)
3161 /* XXX: exception prefix has a special behavior on 602 */
3162 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3163 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3164 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3165 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3166 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3167 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3168 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3169 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3170 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3171 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3172 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3173 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
3174 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
3175 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
3176 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3177 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3178 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001500;
3179 env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001600;
3180 /* Hardware reset vector */
3181 env->hreset_vector = 0x00000100UL;
3185 static void init_excp_603(CPUPPCState *env)
3187 #if !defined(CONFIG_USER_ONLY)
3188 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3189 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3190 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3191 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3192 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3193 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3194 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3195 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3196 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3197 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3198 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3199 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
3200 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
3201 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
3202 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3203 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3204 /* Hardware reset vector */
3205 env->hreset_vector = 0x00000100UL;
3209 static void init_excp_604(CPUPPCState *env)
3211 #if !defined(CONFIG_USER_ONLY)
3212 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3213 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3214 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3215 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3216 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3217 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3218 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3219 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3220 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3221 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3222 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3223 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3224 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3225 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3226 /* Hardware reset vector */
3227 env->hreset_vector = 0x00000100UL;
3231 static void init_excp_7x0(CPUPPCState *env)
3233 #if !defined(CONFIG_USER_ONLY)
3234 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3235 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3236 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3237 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3238 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3239 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3240 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3241 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3242 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3243 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3244 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3245 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3246 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3247 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3248 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
3249 /* Hardware reset vector */
3250 env->hreset_vector = 0x00000100UL;
3254 static void init_excp_750cl(CPUPPCState *env)
3256 #if !defined(CONFIG_USER_ONLY)
3257 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3258 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3259 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3260 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3261 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3262 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3263 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3264 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3265 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3266 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3267 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3268 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3269 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3270 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3271 /* Hardware reset vector */
3272 env->hreset_vector = 0x00000100UL;
3276 static void init_excp_750cx(CPUPPCState *env)
3278 #if !defined(CONFIG_USER_ONLY)
3279 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3280 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3281 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3282 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3283 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3284 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3285 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3286 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3287 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3288 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3289 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3290 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3291 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3292 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
3293 /* Hardware reset vector */
3294 env->hreset_vector = 0x00000100UL;
3298 /* XXX: Check if this is correct */
3299 static void init_excp_7x5(CPUPPCState *env)
3301 #if !defined(CONFIG_USER_ONLY)
3302 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3303 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3304 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3305 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3306 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3307 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3308 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3309 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3310 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3311 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3312 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3313 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3314 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
3315 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
3316 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
3317 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3318 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3319 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
3320 /* Hardware reset vector */
3321 env->hreset_vector = 0x00000100UL;
3325 static void init_excp_7400(CPUPPCState *env)
3327 #if !defined(CONFIG_USER_ONLY)
3328 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3329 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3330 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3331 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3332 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3333 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3334 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3335 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3336 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3337 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3338 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3339 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3340 env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
3341 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3342 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3343 env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600;
3344 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
3345 /* Hardware reset vector */
3346 env->hreset_vector = 0x00000100UL;
3350 static void init_excp_7450(CPUPPCState *env)
3352 #if !defined(CONFIG_USER_ONLY)
3353 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3354 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3355 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3356 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3357 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3358 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3359 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3360 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3361 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3362 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3363 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3364 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3365 env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
3366 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
3367 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
3368 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
3369 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3370 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3371 env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600;
3372 /* Hardware reset vector */
3373 env->hreset_vector = 0x00000100UL;
3377 #if defined(TARGET_PPC64)
3378 static void init_excp_970(CPUPPCState *env)
3380 #if !defined(CONFIG_USER_ONLY)
3381 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3382 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3383 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3384 env->excp_vectors[POWERPC_EXCP_DSEG] = 0x00000380;
3385 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3386 env->excp_vectors[POWERPC_EXCP_ISEG] = 0x00000480;
3387 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3388 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3389 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3390 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3391 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3392 env->excp_vectors[POWERPC_EXCP_HDECR] = 0x00000980;
3393 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3394 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3395 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3396 env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
3397 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3398 env->excp_vectors[POWERPC_EXCP_MAINT] = 0x00001600;
3399 env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001700;
3400 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001800;
3401 /* Hardware reset vector */
3402 env->hreset_vector = 0x0000000000000100ULL;
3406 static void init_excp_POWER7(CPUPPCState *env)
3408 #if !defined(CONFIG_USER_ONLY)
3409 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3410 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3411 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3412 env->excp_vectors[POWERPC_EXCP_DSEG] = 0x00000380;
3413 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3414 env->excp_vectors[POWERPC_EXCP_ISEG] = 0x00000480;
3415 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3416 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3417 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3418 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3419 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3420 env->excp_vectors[POWERPC_EXCP_HDECR] = 0x00000980;
3421 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3422 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3423 env->excp_vectors[POWERPC_EXCP_HDSI] = 0x00000E00;
3424 env->excp_vectors[POWERPC_EXCP_HISI] = 0x00000E20;
3425 env->excp_vectors[POWERPC_EXCP_HV_EMU] = 0x00000E40;
3426 env->excp_vectors[POWERPC_EXCP_HV_MAINT] = 0x00000E60;
3427 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3428 env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
3429 env->excp_vectors[POWERPC_EXCP_VSXU] = 0x00000F40;
3430 /* Hardware reset vector */
3431 env->hreset_vector = 0x0000000000000100ULL;
3435 static void init_excp_POWER8(CPUPPCState *env)
3437 init_excp_POWER7(env);
3439 #if !defined(CONFIG_USER_ONLY)
3440 env->excp_vectors[POWERPC_EXCP_SDOOR] = 0x00000A00;
3441 env->excp_vectors[POWERPC_EXCP_FU] = 0x00000F60;
3442 env->excp_vectors[POWERPC_EXCP_HV_FU] = 0x00000F80;
3443 env->excp_vectors[POWERPC_EXCP_SDOOR_HV] = 0x00000E80;
3447 static void init_excp_POWER9(CPUPPCState *env)
3449 init_excp_POWER8(env);
3451 #if !defined(CONFIG_USER_ONLY)
3452 env->excp_vectors[POWERPC_EXCP_HVIRT] = 0x00000EA0;
3453 env->excp_vectors[POWERPC_EXCP_SYSCALL_VECTORED] = 0x00017000;
3457 static void init_excp_POWER10(CPUPPCState *env)
3459 init_excp_POWER9(env);
3464 /*****************************************************************************/
3465 /* Power management enable checks */
3466 static int check_pow_none(CPUPPCState *env)
3471 static int check_pow_nocheck(CPUPPCState *env)
3476 static int check_pow_hid0(CPUPPCState *env)
3478 if (env->spr[SPR_HID0] & 0x00E00000) {
3485 static int check_pow_hid0_74xx(CPUPPCState *env)
3487 if (env->spr[SPR_HID0] & 0x00600000) {
3494 static bool ppc_cpu_interrupts_big_endian_always(PowerPCCPU *cpu)
3500 static bool ppc_cpu_interrupts_big_endian_lpcr(PowerPCCPU *cpu)
3502 return !(cpu->env.spr[SPR_LPCR] & LPCR_ILE);
3506 /*****************************************************************************/
3507 /* PowerPC implementations definitions */
3509 #define POWERPC_FAMILY(_name) \
3511 glue(glue(ppc_, _name), _cpu_family_class_init)(ObjectClass *, void *); \
3513 static const TypeInfo \
3514 glue(glue(ppc_, _name), _cpu_family_type_info) = { \
3515 .name = stringify(_name) "-family-" TYPE_POWERPC_CPU, \
3516 .parent = TYPE_POWERPC_CPU, \
3518 .class_init = glue(glue(ppc_, _name), _cpu_family_class_init), \
3521 static void glue(glue(ppc_, _name), _cpu_family_register_types)(void) \
3523 type_register_static( \
3524 &glue(glue(ppc_, _name), _cpu_family_type_info)); \
3527 type_init(glue(glue(ppc_, _name), _cpu_family_register_types)) \
3529 static void glue(glue(ppc_, _name), _cpu_family_class_init)
3531 static void init_proc_401(CPUPPCState *env)
3534 gen_spr_401_403(env);
3536 init_excp_4xx_real(env);
3537 env->dcache_line_size = 32;
3538 env->icache_line_size = 32;
3539 /* Allocate hardware IRQ controller */
3540 ppc40x_irq_init(env_archcpu(env));
3542 SET_FIT_PERIOD(12, 16, 20, 24);
3543 SET_WDT_PERIOD(16, 20, 24, 28);
3546 POWERPC_FAMILY(401)(ObjectClass *oc, void *data)
3548 DeviceClass *dc = DEVICE_CLASS(oc);
3549 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3551 dc->desc = "PowerPC 401";
3552 pcc->init_proc = init_proc_401;
3553 pcc->check_pow = check_pow_nocheck;
3554 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3555 PPC_WRTEE | PPC_DCR |
3556 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3558 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3559 PPC_4xx_COMMON | PPC_40x_EXCP;
3560 pcc->msr_mask = (1ull << MSR_KEY) |
3569 pcc->mmu_model = POWERPC_MMU_REAL;
3570 pcc->excp_model = POWERPC_EXCP_40x;
3571 pcc->bus_model = PPC_FLAGS_INPUT_401;
3572 pcc->bfd_mach = bfd_mach_ppc_403;
3573 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3574 POWERPC_FLAG_BUS_CLK;
3577 static void init_proc_401x2(CPUPPCState *env)
3580 gen_spr_401_403(env);
3582 gen_spr_compress(env);
3583 /* Memory management */
3584 #if !defined(CONFIG_USER_ONLY)
3588 env->tlb_type = TLB_EMB;
3590 init_excp_4xx_softmmu(env);
3591 env->dcache_line_size = 32;
3592 env->icache_line_size = 32;
3593 /* Allocate hardware IRQ controller */
3594 ppc40x_irq_init(env_archcpu(env));
3596 SET_FIT_PERIOD(12, 16, 20, 24);
3597 SET_WDT_PERIOD(16, 20, 24, 28);
3600 POWERPC_FAMILY(401x2)(ObjectClass *oc, void *data)
3602 DeviceClass *dc = DEVICE_CLASS(oc);
3603 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3605 dc->desc = "PowerPC 401x2";
3606 pcc->init_proc = init_proc_401x2;
3607 pcc->check_pow = check_pow_nocheck;
3608 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
3609 PPC_DCR | PPC_WRTEE |
3610 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3611 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3612 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3613 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3614 PPC_4xx_COMMON | PPC_40x_EXCP;
3615 pcc->msr_mask = (1ull << 20) |
3627 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3628 pcc->excp_model = POWERPC_EXCP_40x;
3629 pcc->bus_model = PPC_FLAGS_INPUT_401;
3630 pcc->bfd_mach = bfd_mach_ppc_403;
3631 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3632 POWERPC_FLAG_BUS_CLK;
3635 static void init_proc_401x3(CPUPPCState *env)
3638 gen_spr_401_403(env);
3641 gen_spr_compress(env);
3642 init_excp_4xx_softmmu(env);
3643 env->dcache_line_size = 32;
3644 env->icache_line_size = 32;
3645 /* Allocate hardware IRQ controller */
3646 ppc40x_irq_init(env_archcpu(env));
3648 SET_FIT_PERIOD(12, 16, 20, 24);
3649 SET_WDT_PERIOD(16, 20, 24, 28);
3652 POWERPC_FAMILY(401x3)(ObjectClass *oc, void *data)
3654 DeviceClass *dc = DEVICE_CLASS(oc);
3655 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3657 dc->desc = "PowerPC 401x3";
3658 pcc->init_proc = init_proc_401x3;
3659 pcc->check_pow = check_pow_nocheck;
3660 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
3661 PPC_DCR | PPC_WRTEE |
3662 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3663 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3664 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3665 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3666 PPC_4xx_COMMON | PPC_40x_EXCP;
3667 pcc->msr_mask = (1ull << 20) |
3680 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3681 pcc->excp_model = POWERPC_EXCP_40x;
3682 pcc->bus_model = PPC_FLAGS_INPUT_401;
3683 pcc->bfd_mach = bfd_mach_ppc_403;
3684 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3685 POWERPC_FLAG_BUS_CLK;
3688 static void init_proc_IOP480(CPUPPCState *env)
3691 gen_spr_401_403(env);
3693 gen_spr_compress(env);
3694 /* Memory management */
3695 #if !defined(CONFIG_USER_ONLY)
3699 env->tlb_type = TLB_EMB;
3701 init_excp_4xx_softmmu(env);
3702 env->dcache_line_size = 32;
3703 env->icache_line_size = 32;
3704 /* Allocate hardware IRQ controller */
3705 ppc40x_irq_init(env_archcpu(env));
3707 SET_FIT_PERIOD(8, 12, 16, 20);
3708 SET_WDT_PERIOD(16, 20, 24, 28);
3711 POWERPC_FAMILY(IOP480)(ObjectClass *oc, void *data)
3713 DeviceClass *dc = DEVICE_CLASS(oc);
3714 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3716 dc->desc = "IOP480";
3717 pcc->init_proc = init_proc_IOP480;
3718 pcc->check_pow = check_pow_nocheck;
3719 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3720 PPC_DCR | PPC_WRTEE |
3721 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3722 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3723 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3724 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3725 PPC_4xx_COMMON | PPC_40x_EXCP;
3726 pcc->msr_mask = (1ull << 20) |
3738 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3739 pcc->excp_model = POWERPC_EXCP_40x;
3740 pcc->bus_model = PPC_FLAGS_INPUT_401;
3741 pcc->bfd_mach = bfd_mach_ppc_403;
3742 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3743 POWERPC_FLAG_BUS_CLK;
3746 static void init_proc_403(CPUPPCState *env)
3749 gen_spr_401_403(env);
3751 gen_spr_403_real(env);
3752 init_excp_4xx_real(env);
3753 env->dcache_line_size = 32;
3754 env->icache_line_size = 32;
3755 /* Allocate hardware IRQ controller */
3756 ppc40x_irq_init(env_archcpu(env));
3758 SET_FIT_PERIOD(8, 12, 16, 20);
3759 SET_WDT_PERIOD(16, 20, 24, 28);
3762 POWERPC_FAMILY(403)(ObjectClass *oc, void *data)
3764 DeviceClass *dc = DEVICE_CLASS(oc);
3765 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3767 dc->desc = "PowerPC 403";
3768 pcc->init_proc = init_proc_403;
3769 pcc->check_pow = check_pow_nocheck;
3770 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3771 PPC_DCR | PPC_WRTEE |
3772 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3774 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3775 PPC_4xx_COMMON | PPC_40x_EXCP;
3776 pcc->msr_mask = (1ull << MSR_POW) |
3785 pcc->mmu_model = POWERPC_MMU_REAL;
3786 pcc->excp_model = POWERPC_EXCP_40x;
3787 pcc->bus_model = PPC_FLAGS_INPUT_401;
3788 pcc->bfd_mach = bfd_mach_ppc_403;
3789 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_PX |
3790 POWERPC_FLAG_BUS_CLK;
3793 static void init_proc_403GCX(CPUPPCState *env)
3796 gen_spr_401_403(env);
3798 gen_spr_403_real(env);
3799 gen_spr_403_mmu(env);
3800 /* Bus access control */
3801 /* not emulated, as QEMU never does speculative access */
3802 spr_register(env, SPR_40x_SGR, "SGR",
3803 SPR_NOACCESS, SPR_NOACCESS,
3804 &spr_read_generic, &spr_write_generic,
3806 /* not emulated, as QEMU do not emulate caches */
3807 spr_register(env, SPR_40x_DCWR, "DCWR",
3808 SPR_NOACCESS, SPR_NOACCESS,
3809 &spr_read_generic, &spr_write_generic,
3811 /* Memory management */
3812 #if !defined(CONFIG_USER_ONLY)
3816 env->tlb_type = TLB_EMB;
3818 init_excp_4xx_softmmu(env);
3819 env->dcache_line_size = 32;
3820 env->icache_line_size = 32;
3821 /* Allocate hardware IRQ controller */
3822 ppc40x_irq_init(env_archcpu(env));
3824 SET_FIT_PERIOD(8, 12, 16, 20);
3825 SET_WDT_PERIOD(16, 20, 24, 28);
3828 POWERPC_FAMILY(403GCX)(ObjectClass *oc, void *data)
3830 DeviceClass *dc = DEVICE_CLASS(oc);
3831 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3833 dc->desc = "PowerPC 403 GCX";
3834 pcc->init_proc = init_proc_403GCX;
3835 pcc->check_pow = check_pow_nocheck;
3836 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3837 PPC_DCR | PPC_WRTEE |
3838 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3840 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3841 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3842 PPC_4xx_COMMON | PPC_40x_EXCP;
3843 pcc->msr_mask = (1ull << MSR_POW) |
3852 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3853 pcc->excp_model = POWERPC_EXCP_40x;
3854 pcc->bus_model = PPC_FLAGS_INPUT_401;
3855 pcc->bfd_mach = bfd_mach_ppc_403;
3856 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_PX |
3857 POWERPC_FLAG_BUS_CLK;
3860 static void init_proc_405(CPUPPCState *env)
3866 /* Bus access control */
3867 /* not emulated, as QEMU never does speculative access */
3868 spr_register(env, SPR_40x_SGR, "SGR",
3869 SPR_NOACCESS, SPR_NOACCESS,
3870 &spr_read_generic, &spr_write_generic,
3872 /* not emulated, as QEMU do not emulate caches */
3873 spr_register(env, SPR_40x_DCWR, "DCWR",
3874 SPR_NOACCESS, SPR_NOACCESS,
3875 &spr_read_generic, &spr_write_generic,
3877 /* Memory management */
3878 #if !defined(CONFIG_USER_ONLY)
3882 env->tlb_type = TLB_EMB;
3884 init_excp_4xx_softmmu(env);
3885 env->dcache_line_size = 32;
3886 env->icache_line_size = 32;
3887 /* Allocate hardware IRQ controller */
3888 ppc40x_irq_init(env_archcpu(env));
3890 SET_FIT_PERIOD(8, 12, 16, 20);
3891 SET_WDT_PERIOD(16, 20, 24, 28);
3894 POWERPC_FAMILY(405)(ObjectClass *oc, void *data)
3896 DeviceClass *dc = DEVICE_CLASS(oc);
3897 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3899 dc->desc = "PowerPC 405";
3900 pcc->init_proc = init_proc_405;
3901 pcc->check_pow = check_pow_nocheck;
3902 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
3903 PPC_DCR | PPC_WRTEE |
3904 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3905 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3906 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3907 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3908 PPC_4xx_COMMON | PPC_405_MAC | PPC_40x_EXCP;
3909 pcc->msr_mask = (1ull << MSR_POW) |
3918 pcc->mmu_model = POWERPC_MMU_SOFT_4xx;
3919 pcc->excp_model = POWERPC_EXCP_40x;
3920 pcc->bus_model = PPC_FLAGS_INPUT_405;
3921 pcc->bfd_mach = bfd_mach_ppc_403;
3922 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
3923 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
3926 static void init_proc_440EP(CPUPPCState *env)
3930 gen_spr_BookE(env, 0x000000000000FFFFULL);
3932 gen_spr_usprgh(env);
3933 /* Processor identification */
3934 spr_register(env, SPR_BOOKE_PIR, "PIR",
3935 SPR_NOACCESS, SPR_NOACCESS,
3936 &spr_read_generic, &spr_write_pir,
3938 /* XXX : not implemented */
3939 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
3940 SPR_NOACCESS, SPR_NOACCESS,
3941 &spr_read_generic, &spr_write_generic,
3943 /* XXX : not implemented */
3944 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
3945 SPR_NOACCESS, SPR_NOACCESS,
3946 &spr_read_generic, &spr_write_generic,
3948 /* XXX : not implemented */
3949 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
3950 SPR_NOACCESS, SPR_NOACCESS,
3951 &spr_read_generic, &spr_write_generic,
3953 /* XXX : not implemented */
3954 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
3955 SPR_NOACCESS, SPR_NOACCESS,
3956 &spr_read_generic, &spr_write_generic,
3958 /* XXX : not implemented */
3959 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
3960 SPR_NOACCESS, SPR_NOACCESS,
3961 &spr_read_generic, &spr_write_generic,
3963 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
3964 SPR_NOACCESS, SPR_NOACCESS,
3965 &spr_read_generic, &spr_write_generic,
3967 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
3968 SPR_NOACCESS, SPR_NOACCESS,
3969 &spr_read_generic, &spr_write_generic,
3971 /* XXX : not implemented */
3972 spr_register(env, SPR_440_CCR1, "CCR1",
3973 SPR_NOACCESS, SPR_NOACCESS,
3974 &spr_read_generic, &spr_write_generic,
3976 /* Memory management */
3977 #if !defined(CONFIG_USER_ONLY)
3981 env->tlb_type = TLB_EMB;
3983 init_excp_BookE(env);
3984 env->dcache_line_size = 32;
3985 env->icache_line_size = 32;
3986 ppc40x_irq_init(env_archcpu(env));
3988 SET_FIT_PERIOD(12, 16, 20, 24);
3989 SET_WDT_PERIOD(20, 24, 28, 32);
3992 POWERPC_FAMILY(440EP)(ObjectClass *oc, void *data)
3994 DeviceClass *dc = DEVICE_CLASS(oc);
3995 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3997 dc->desc = "PowerPC 440 EP";
3998 pcc->init_proc = init_proc_440EP;
3999 pcc->check_pow = check_pow_nocheck;
4000 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4001 PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL |
4002 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
4004 PPC_DCR | PPC_WRTEE | PPC_RFMCI |
4005 PPC_CACHE | PPC_CACHE_ICBI |
4006 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4007 PPC_MEM_TLBSYNC | PPC_MFTB |
4008 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4010 pcc->msr_mask = (1ull << MSR_POW) |
4022 pcc->mmu_model = POWERPC_MMU_BOOKE;
4023 pcc->excp_model = POWERPC_EXCP_BOOKE;
4024 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4025 pcc->bfd_mach = bfd_mach_ppc_403;
4026 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4027 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
4030 POWERPC_FAMILY(460EX)(ObjectClass *oc, void *data)
4032 DeviceClass *dc = DEVICE_CLASS(oc);
4033 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4035 dc->desc = "PowerPC 460 EX";
4036 pcc->init_proc = init_proc_440EP;
4037 pcc->check_pow = check_pow_nocheck;
4038 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4039 PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL |
4040 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
4042 PPC_DCR | PPC_DCRX | PPC_WRTEE | PPC_RFMCI |
4043 PPC_CACHE | PPC_CACHE_ICBI |
4044 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4045 PPC_MEM_TLBSYNC | PPC_MFTB |
4046 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4048 pcc->msr_mask = (1ull << MSR_POW) |
4060 pcc->mmu_model = POWERPC_MMU_BOOKE;
4061 pcc->excp_model = POWERPC_EXCP_BOOKE;
4062 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4063 pcc->bfd_mach = bfd_mach_ppc_403;
4064 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4065 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
4068 static void init_proc_440GP(CPUPPCState *env)
4072 gen_spr_BookE(env, 0x000000000000FFFFULL);
4074 gen_spr_usprgh(env);
4075 /* Processor identification */
4076 spr_register(env, SPR_BOOKE_PIR, "PIR",
4077 SPR_NOACCESS, SPR_NOACCESS,
4078 &spr_read_generic, &spr_write_pir,
4080 /* XXX : not implemented */
4081 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4082 SPR_NOACCESS, SPR_NOACCESS,
4083 &spr_read_generic, &spr_write_generic,
4085 /* XXX : not implemented */
4086 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4087 SPR_NOACCESS, SPR_NOACCESS,
4088 &spr_read_generic, &spr_write_generic,
4090 /* XXX : not implemented */
4091 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
4092 SPR_NOACCESS, SPR_NOACCESS,
4093 &spr_read_generic, &spr_write_generic,
4095 /* XXX : not implemented */
4096 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
4097 SPR_NOACCESS, SPR_NOACCESS,
4098 &spr_read_generic, &spr_write_generic,
4100 /* Memory management */
4101 #if !defined(CONFIG_USER_ONLY)
4105 env->tlb_type = TLB_EMB;
4107 init_excp_BookE(env);
4108 env->dcache_line_size = 32;
4109 env->icache_line_size = 32;
4110 /* XXX: TODO: allocate internal IRQ controller */
4112 SET_FIT_PERIOD(12, 16, 20, 24);
4113 SET_WDT_PERIOD(20, 24, 28, 32);
4116 POWERPC_FAMILY(440GP)(ObjectClass *oc, void *data)
4118 DeviceClass *dc = DEVICE_CLASS(oc);
4119 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4121 dc->desc = "PowerPC 440 GP";
4122 pcc->init_proc = init_proc_440GP;
4123 pcc->check_pow = check_pow_nocheck;
4124 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4125 PPC_DCR | PPC_DCRX | PPC_WRTEE | PPC_MFAPIDI |
4126 PPC_CACHE | PPC_CACHE_ICBI |
4127 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4128 PPC_MEM_TLBSYNC | PPC_TLBIVA | PPC_MFTB |
4129 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4131 pcc->msr_mask = (1ull << MSR_POW) |
4143 pcc->mmu_model = POWERPC_MMU_BOOKE;
4144 pcc->excp_model = POWERPC_EXCP_BOOKE;
4145 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4146 pcc->bfd_mach = bfd_mach_ppc_403;
4147 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4148 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
4151 static void init_proc_440x4(CPUPPCState *env)
4155 gen_spr_BookE(env, 0x000000000000FFFFULL);
4157 gen_spr_usprgh(env);
4158 /* Processor identification */
4159 spr_register(env, SPR_BOOKE_PIR, "PIR",
4160 SPR_NOACCESS, SPR_NOACCESS,
4161 &spr_read_generic, &spr_write_pir,
4163 /* XXX : not implemented */
4164 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4165 SPR_NOACCESS, SPR_NOACCESS,
4166 &spr_read_generic, &spr_write_generic,
4168 /* XXX : not implemented */
4169 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4170 SPR_NOACCESS, SPR_NOACCESS,
4171 &spr_read_generic, &spr_write_generic,
4173 /* XXX : not implemented */
4174 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
4175 SPR_NOACCESS, SPR_NOACCESS,
4176 &spr_read_generic, &spr_write_generic,
4178 /* XXX : not implemented */
4179 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
4180 SPR_NOACCESS, SPR_NOACCESS,
4181 &spr_read_generic, &spr_write_generic,
4183 /* Memory management */
4184 #if !defined(CONFIG_USER_ONLY)
4188 env->tlb_type = TLB_EMB;
4190 init_excp_BookE(env);
4191 env->dcache_line_size = 32;
4192 env->icache_line_size = 32;
4193 /* XXX: TODO: allocate internal IRQ controller */
4195 SET_FIT_PERIOD(12, 16, 20, 24);
4196 SET_WDT_PERIOD(20, 24, 28, 32);
4199 POWERPC_FAMILY(440x4)(ObjectClass *oc, void *data)
4201 DeviceClass *dc = DEVICE_CLASS(oc);
4202 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4204 dc->desc = "PowerPC 440x4";
4205 pcc->init_proc = init_proc_440x4;
4206 pcc->check_pow = check_pow_nocheck;
4207 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4208 PPC_DCR | PPC_WRTEE |
4209 PPC_CACHE | PPC_CACHE_ICBI |
4210 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4211 PPC_MEM_TLBSYNC | PPC_MFTB |
4212 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4214 pcc->msr_mask = (1ull << MSR_POW) |
4226 pcc->mmu_model = POWERPC_MMU_BOOKE;
4227 pcc->excp_model = POWERPC_EXCP_BOOKE;
4228 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4229 pcc->bfd_mach = bfd_mach_ppc_403;
4230 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4231 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
4234 static void init_proc_440x5(CPUPPCState *env)
4238 gen_spr_BookE(env, 0x000000000000FFFFULL);
4240 gen_spr_usprgh(env);
4241 /* Processor identification */
4242 spr_register(env, SPR_BOOKE_PIR, "PIR",
4243 SPR_NOACCESS, SPR_NOACCESS,
4244 &spr_read_generic, &spr_write_pir,
4246 /* XXX : not implemented */
4247 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4248 SPR_NOACCESS, SPR_NOACCESS,
4249 &spr_read_generic, &spr_write_generic,
4251 /* XXX : not implemented */
4252 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4253 SPR_NOACCESS, SPR_NOACCESS,
4254 &spr_read_generic, &spr_write_generic,
4256 /* XXX : not implemented */
4257 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
4258 SPR_NOACCESS, SPR_NOACCESS,
4259 &spr_read_generic, &spr_write_generic,
4261 /* XXX : not implemented */
4262 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
4263 SPR_NOACCESS, SPR_NOACCESS,
4264 &spr_read_generic, &spr_write_generic,
4266 /* XXX : not implemented */
4267 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
4268 SPR_NOACCESS, SPR_NOACCESS,
4269 &spr_read_generic, &spr_write_generic,
4271 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
4272 SPR_NOACCESS, SPR_NOACCESS,
4273 &spr_read_generic, &spr_write_generic,
4275 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
4276 SPR_NOACCESS, SPR_NOACCESS,
4277 &spr_read_generic, &spr_write_generic,
4279 /* XXX : not implemented */
4280 spr_register(env, SPR_440_CCR1, "CCR1",
4281 SPR_NOACCESS, SPR_NOACCESS,
4282 &spr_read_generic, &spr_write_generic,
4284 /* Memory management */
4285 #if !defined(CONFIG_USER_ONLY)
4289 env->tlb_type = TLB_EMB;
4291 init_excp_BookE(env);
4292 env->dcache_line_size = 32;
4293 env->icache_line_size = 32;
4294 ppc40x_irq_init(env_archcpu(env));
4296 SET_FIT_PERIOD(12, 16, 20, 24);
4297 SET_WDT_PERIOD(20, 24, 28, 32);
4300 POWERPC_FAMILY(440x5)(ObjectClass *oc, void *data)
4302 DeviceClass *dc = DEVICE_CLASS(oc);
4303 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4305 dc->desc = "PowerPC 440x5";
4306 pcc->init_proc = init_proc_440x5;
4307 pcc->check_pow = check_pow_nocheck;
4308 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4309 PPC_DCR | PPC_WRTEE | PPC_RFMCI |
4310 PPC_CACHE | PPC_CACHE_ICBI |
4311 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4312 PPC_MEM_TLBSYNC | PPC_MFTB |
4313 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4315 pcc->msr_mask = (1ull << MSR_POW) |
4327 pcc->mmu_model = POWERPC_MMU_BOOKE;
4328 pcc->excp_model = POWERPC_EXCP_BOOKE;
4329 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4330 pcc->bfd_mach = bfd_mach_ppc_403;
4331 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4332 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
4335 POWERPC_FAMILY(440x5wDFPU)(ObjectClass *oc, void *data)
4337 DeviceClass *dc = DEVICE_CLASS(oc);
4338 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4340 dc->desc = "PowerPC 440x5 with double precision FPU";
4341 pcc->init_proc = init_proc_440x5;
4342 pcc->check_pow = check_pow_nocheck;
4343 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4344 PPC_FLOAT | PPC_FLOAT_FSQRT |
4346 PPC_DCR | PPC_WRTEE | PPC_RFMCI |
4347 PPC_CACHE | PPC_CACHE_ICBI |
4348 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4349 PPC_MEM_TLBSYNC | PPC_MFTB |
4350 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4352 pcc->insns_flags2 = PPC2_FP_CVT_S64;
4353 pcc->msr_mask = (1ull << MSR_POW) |
4365 pcc->mmu_model = POWERPC_MMU_BOOKE;
4366 pcc->excp_model = POWERPC_EXCP_BOOKE;
4367 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4368 pcc->bfd_mach = bfd_mach_ppc_403;
4369 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4370 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
4373 static void init_proc_MPC5xx(CPUPPCState *env)
4377 gen_spr_5xx_8xx(env);
4379 init_excp_MPC5xx(env);
4380 env->dcache_line_size = 32;
4381 env->icache_line_size = 32;
4382 /* XXX: TODO: allocate internal IRQ controller */
4385 POWERPC_FAMILY(MPC5xx)(ObjectClass *oc, void *data)
4387 DeviceClass *dc = DEVICE_CLASS(oc);
4388 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4390 dc->desc = "Freescale 5xx cores (aka RCPU)";
4391 pcc->init_proc = init_proc_MPC5xx;
4392 pcc->check_pow = check_pow_none;
4393 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4394 PPC_MEM_EIEIO | PPC_MEM_SYNC |
4395 PPC_CACHE_ICBI | PPC_FLOAT | PPC_FLOAT_STFIWX |
4397 pcc->msr_mask = (1ull << MSR_ILE) |
4409 pcc->mmu_model = POWERPC_MMU_REAL;
4410 pcc->excp_model = POWERPC_EXCP_603;
4411 pcc->bus_model = PPC_FLAGS_INPUT_RCPU;
4412 pcc->bfd_mach = bfd_mach_ppc_505;
4413 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
4414 POWERPC_FLAG_BUS_CLK;
4417 static void init_proc_MPC8xx(CPUPPCState *env)
4421 gen_spr_5xx_8xx(env);
4423 init_excp_MPC8xx(env);
4424 env->dcache_line_size = 32;
4425 env->icache_line_size = 32;
4426 /* XXX: TODO: allocate internal IRQ controller */
4429 POWERPC_FAMILY(MPC8xx)(ObjectClass *oc, void *data)
4431 DeviceClass *dc = DEVICE_CLASS(oc);
4432 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4434 dc->desc = "Freescale 8xx cores (aka PowerQUICC)";
4435 pcc->init_proc = init_proc_MPC8xx;
4436 pcc->check_pow = check_pow_none;
4437 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4438 PPC_MEM_EIEIO | PPC_MEM_SYNC |
4439 PPC_CACHE_ICBI | PPC_MFTB;
4440 pcc->msr_mask = (1ull << MSR_ILE) |
4452 pcc->mmu_model = POWERPC_MMU_MPC8xx;
4453 pcc->excp_model = POWERPC_EXCP_603;
4454 pcc->bus_model = PPC_FLAGS_INPUT_RCPU;
4455 pcc->bfd_mach = bfd_mach_ppc_860;
4456 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
4457 POWERPC_FLAG_BUS_CLK;
4460 /* Freescale 82xx cores (aka PowerQUICC-II) */
4462 static void init_proc_G2(CPUPPCState *env)
4464 gen_spr_ne_601(env);
4466 gen_spr_G2_755(env);
4470 /* External access control */
4471 /* XXX : not implemented */
4472 spr_register(env, SPR_EAR, "EAR",
4473 SPR_NOACCESS, SPR_NOACCESS,
4474 &spr_read_generic, &spr_write_generic,
4476 /* Hardware implementation register */
4477 /* XXX : not implemented */
4478 spr_register(env, SPR_HID0, "HID0",
4479 SPR_NOACCESS, SPR_NOACCESS,
4480 &spr_read_generic, &spr_write_generic,
4482 /* XXX : not implemented */
4483 spr_register(env, SPR_HID1, "HID1",
4484 SPR_NOACCESS, SPR_NOACCESS,
4485 &spr_read_generic, &spr_write_generic,
4487 /* XXX : not implemented */
4488 spr_register(env, SPR_HID2, "HID2",
4489 SPR_NOACCESS, SPR_NOACCESS,
4490 &spr_read_generic, &spr_write_generic,
4492 /* Memory management */
4495 gen_6xx_7xx_soft_tlb(env, 64, 2);
4497 env->dcache_line_size = 32;
4498 env->icache_line_size = 32;
4499 /* Allocate hardware IRQ controller */
4500 ppc6xx_irq_init(env_archcpu(env));
4503 POWERPC_FAMILY(G2)(ObjectClass *oc, void *data)
4505 DeviceClass *dc = DEVICE_CLASS(oc);
4506 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4508 dc->desc = "PowerPC G2";
4509 pcc->init_proc = init_proc_G2;
4510 pcc->check_pow = check_pow_hid0;
4511 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4512 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4514 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4515 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4516 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4517 PPC_SEGMENT | PPC_EXTERN;
4518 pcc->msr_mask = (1ull << MSR_POW) |
4519 (1ull << MSR_TGPR) |
4533 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4534 pcc->excp_model = POWERPC_EXCP_G2;
4535 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4536 pcc->bfd_mach = bfd_mach_ppc_ec603e;
4537 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4538 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
4541 static void init_proc_G2LE(CPUPPCState *env)
4543 gen_spr_ne_601(env);
4545 gen_spr_G2_755(env);
4549 /* External access control */
4550 /* XXX : not implemented */
4551 spr_register(env, SPR_EAR, "EAR",
4552 SPR_NOACCESS, SPR_NOACCESS,
4553 &spr_read_generic, &spr_write_generic,
4555 /* Hardware implementation register */
4556 /* XXX : not implemented */
4557 spr_register(env, SPR_HID0, "HID0",
4558 SPR_NOACCESS, SPR_NOACCESS,
4559 &spr_read_generic, &spr_write_generic,
4561 /* XXX : not implemented */
4562 spr_register(env, SPR_HID1, "HID1",
4563 SPR_NOACCESS, SPR_NOACCESS,
4564 &spr_read_generic, &spr_write_generic,
4566 /* XXX : not implemented */
4567 spr_register(env, SPR_HID2, "HID2",
4568 SPR_NOACCESS, SPR_NOACCESS,
4569 &spr_read_generic, &spr_write_generic,
4572 /* Memory management */
4575 gen_6xx_7xx_soft_tlb(env, 64, 2);
4577 env->dcache_line_size = 32;
4578 env->icache_line_size = 32;
4579 /* Allocate hardware IRQ controller */
4580 ppc6xx_irq_init(env_archcpu(env));
4583 POWERPC_FAMILY(G2LE)(ObjectClass *oc, void *data)
4585 DeviceClass *dc = DEVICE_CLASS(oc);
4586 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4588 dc->desc = "PowerPC G2LE";
4589 pcc->init_proc = init_proc_G2LE;
4590 pcc->check_pow = check_pow_hid0;
4591 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4592 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4594 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4595 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4596 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4597 PPC_SEGMENT | PPC_EXTERN;
4598 pcc->msr_mask = (1ull << MSR_POW) |
4599 (1ull << MSR_TGPR) |
4615 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4616 pcc->excp_model = POWERPC_EXCP_G2;
4617 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4618 pcc->bfd_mach = bfd_mach_ppc_ec603e;
4619 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4620 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
4623 static void init_proc_e200(CPUPPCState *env)
4627 gen_spr_BookE(env, 0x000000070000FFFFULL);
4628 /* XXX : not implemented */
4629 spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
4630 &spr_read_spefscr, &spr_write_spefscr,
4631 &spr_read_spefscr, &spr_write_spefscr,
4633 /* Memory management */
4634 gen_spr_BookE206(env, 0x0000005D, NULL, 0);
4635 /* XXX : not implemented */
4636 spr_register(env, SPR_HID0, "HID0",
4637 SPR_NOACCESS, SPR_NOACCESS,
4638 &spr_read_generic, &spr_write_generic,
4640 /* XXX : not implemented */
4641 spr_register(env, SPR_HID1, "HID1",
4642 SPR_NOACCESS, SPR_NOACCESS,
4643 &spr_read_generic, &spr_write_generic,
4645 /* XXX : not implemented */
4646 spr_register(env, SPR_Exxx_ALTCTXCR, "ALTCTXCR",
4647 SPR_NOACCESS, SPR_NOACCESS,
4648 &spr_read_generic, &spr_write_generic,
4650 /* XXX : not implemented */
4651 spr_register(env, SPR_Exxx_BUCSR, "BUCSR",
4652 SPR_NOACCESS, SPR_NOACCESS,
4653 &spr_read_generic, &spr_write_generic,
4655 /* XXX : not implemented */
4656 spr_register(env, SPR_Exxx_CTXCR, "CTXCR",
4657 SPR_NOACCESS, SPR_NOACCESS,
4658 &spr_read_generic, &spr_write_generic,
4660 /* XXX : not implemented */
4661 spr_register(env, SPR_Exxx_DBCNT, "DBCNT",
4662 SPR_NOACCESS, SPR_NOACCESS,
4663 &spr_read_generic, &spr_write_generic,
4665 /* XXX : not implemented */
4666 spr_register(env, SPR_Exxx_DBCR3, "DBCR3",
4667 SPR_NOACCESS, SPR_NOACCESS,
4668 &spr_read_generic, &spr_write_generic,
4670 /* XXX : not implemented */
4671 spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0",
4672 &spr_read_generic, SPR_NOACCESS,
4673 &spr_read_generic, SPR_NOACCESS,
4675 /* XXX : not implemented */
4676 spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0",
4677 SPR_NOACCESS, SPR_NOACCESS,
4678 &spr_read_generic, &spr_write_generic,
4680 /* XXX : not implemented */
4681 spr_register(env, SPR_Exxx_L1FINV0, "L1FINV0",
4682 SPR_NOACCESS, SPR_NOACCESS,
4683 &spr_read_generic, &spr_write_generic,
4685 /* XXX : not implemented */
4686 spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG",
4687 SPR_NOACCESS, SPR_NOACCESS,
4688 &spr_read_generic, &spr_write_generic,
4690 /* XXX : not implemented */
4691 spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG",
4692 SPR_NOACCESS, SPR_NOACCESS,
4693 &spr_read_generic, &spr_write_generic,
4695 /* XXX : not implemented */
4696 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4697 SPR_NOACCESS, SPR_NOACCESS,
4698 &spr_read_generic, &spr_write_generic,
4700 /* XXX : not implemented */
4701 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4702 SPR_NOACCESS, SPR_NOACCESS,
4703 &spr_read_generic, &spr_write_generic,
4705 /* XXX : not implemented */
4706 spr_register(env, SPR_MMUCSR0, "MMUCSR0",
4707 SPR_NOACCESS, SPR_NOACCESS,
4708 &spr_read_generic, &spr_write_generic,
4709 0x00000000); /* TOFIX */
4710 spr_register(env, SPR_BOOKE_DSRR0, "DSRR0",
4711 SPR_NOACCESS, SPR_NOACCESS,
4712 &spr_read_generic, &spr_write_generic,
4714 spr_register(env, SPR_BOOKE_DSRR1, "DSRR1",
4715 SPR_NOACCESS, SPR_NOACCESS,
4716 &spr_read_generic, &spr_write_generic,
4718 #if !defined(CONFIG_USER_ONLY)
4722 env->tlb_type = TLB_EMB;
4724 init_excp_e200(env, 0xFFFF0000UL);
4725 env->dcache_line_size = 32;
4726 env->icache_line_size = 32;
4727 /* XXX: TODO: allocate internal IRQ controller */
4730 POWERPC_FAMILY(e200)(ObjectClass *oc, void *data)
4732 DeviceClass *dc = DEVICE_CLASS(oc);
4733 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4735 dc->desc = "e200 core";
4736 pcc->init_proc = init_proc_e200;
4737 pcc->check_pow = check_pow_hid0;
4739 * XXX: unimplemented instructions:
4746 * all SPE multiply-accumulate instructions
4748 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
4749 PPC_SPE | PPC_SPE_SINGLE |
4750 PPC_WRTEE | PPC_RFDI |
4751 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
4752 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4753 PPC_MEM_TLBSYNC | PPC_TLBIVAX |
4755 pcc->msr_mask = (1ull << MSR_UCLE) |
4769 pcc->mmu_model = POWERPC_MMU_BOOKE206;
4770 pcc->excp_model = POWERPC_EXCP_BOOKE;
4771 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4772 pcc->bfd_mach = bfd_mach_ppc_860;
4773 pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
4774 POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
4775 POWERPC_FLAG_BUS_CLK;
4778 static void init_proc_e300(CPUPPCState *env)
4780 gen_spr_ne_601(env);
4785 /* hardware implementation registers */
4786 /* XXX : not implemented */
4787 spr_register(env, SPR_HID0, "HID0",
4788 SPR_NOACCESS, SPR_NOACCESS,
4789 &spr_read_generic, &spr_write_generic,
4791 /* XXX : not implemented */
4792 spr_register(env, SPR_HID1, "HID1",
4793 SPR_NOACCESS, SPR_NOACCESS,
4794 &spr_read_generic, &spr_write_generic,
4796 /* XXX : not implemented */
4797 spr_register(env, SPR_HID2, "HID2",
4798 SPR_NOACCESS, SPR_NOACCESS,
4799 &spr_read_generic, &spr_write_generic,
4802 /* XXX : not implemented */
4803 spr_register(env, SPR_DABR, "DABR",
4804 SPR_NOACCESS, SPR_NOACCESS,
4805 &spr_read_generic, &spr_write_generic,
4807 /* XXX : not implemented */
4808 spr_register(env, SPR_DABR2, "DABR2",
4809 SPR_NOACCESS, SPR_NOACCESS,
4810 &spr_read_generic, &spr_write_generic,
4812 /* XXX : not implemented */
4813 spr_register(env, SPR_IABR2, "IABR2",
4814 SPR_NOACCESS, SPR_NOACCESS,
4815 &spr_read_generic, &spr_write_generic,
4817 /* XXX : not implemented */
4818 spr_register(env, SPR_IBCR, "IBCR",
4819 SPR_NOACCESS, SPR_NOACCESS,
4820 &spr_read_generic, &spr_write_generic,
4822 /* XXX : not implemented */
4823 spr_register(env, SPR_DBCR, "DBCR",
4824 SPR_NOACCESS, SPR_NOACCESS,
4825 &spr_read_generic, &spr_write_generic,
4827 /* Memory management */
4830 gen_6xx_7xx_soft_tlb(env, 64, 2);
4832 env->dcache_line_size = 32;
4833 env->icache_line_size = 32;
4834 /* Allocate hardware IRQ controller */
4835 ppc6xx_irq_init(env_archcpu(env));
4838 POWERPC_FAMILY(e300)(ObjectClass *oc, void *data)
4840 DeviceClass *dc = DEVICE_CLASS(oc);
4841 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4843 dc->desc = "e300 core";
4844 pcc->init_proc = init_proc_e300;
4845 pcc->check_pow = check_pow_hid0;
4846 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4847 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4849 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4850 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4851 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4852 PPC_SEGMENT | PPC_EXTERN;
4853 pcc->msr_mask = (1ull << MSR_POW) |
4854 (1ull << MSR_TGPR) |
4870 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4871 pcc->excp_model = POWERPC_EXCP_603;
4872 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4873 pcc->bfd_mach = bfd_mach_ppc_603;
4874 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4875 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
4878 #if !defined(CONFIG_USER_ONLY)
4879 static void spr_write_mas73(DisasContext *ctx, int sprn, int gprn)
4881 TCGv val = tcg_temp_new();
4882 tcg_gen_ext32u_tl(val, cpu_gpr[gprn]);
4883 gen_store_spr(SPR_BOOKE_MAS3, val);
4884 tcg_gen_shri_tl(val, cpu_gpr[gprn], 32);
4885 gen_store_spr(SPR_BOOKE_MAS7, val);
4889 static void spr_read_mas73(DisasContext *ctx, int gprn, int sprn)
4891 TCGv mas7 = tcg_temp_new();
4892 TCGv mas3 = tcg_temp_new();
4893 gen_load_spr(mas7, SPR_BOOKE_MAS7);
4894 tcg_gen_shli_tl(mas7, mas7, 32);
4895 gen_load_spr(mas3, SPR_BOOKE_MAS3);
4896 tcg_gen_or_tl(cpu_gpr[gprn], mas3, mas7);
4897 tcg_temp_free(mas3);
4898 tcg_temp_free(mas7);
4903 enum fsl_e500_version {
4911 static void init_proc_e500(CPUPPCState *env, int version)
4913 uint32_t tlbncfg[2];
4915 uint64_t ivpr_mask = 0xFFFF0000ULL;
4916 uint32_t l1cfg0 = 0x3800 /* 8 ways */
4917 | 0x0020; /* 32 kb */
4918 uint32_t l1cfg1 = 0x3800 /* 8 ways */
4919 | 0x0020; /* 32 kb */
4920 uint32_t mmucfg = 0;
4921 #if !defined(CONFIG_USER_ONLY)
4928 * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't
4929 * complain when accessing them.
4930 * gen_spr_BookE(env, 0x0000000F0000FD7FULL);
4936 ivor_mask = 0x0000000F0000FFFFULL;
4940 ivor_mask = 0x000003FE0000FFFFULL;
4943 ivor_mask = 0x000003FF0000FFFFULL;
4946 gen_spr_BookE(env, ivor_mask);
4947 gen_spr_usprg3(env);
4948 /* Processor identification */
4949 spr_register(env, SPR_BOOKE_PIR, "PIR",
4950 SPR_NOACCESS, SPR_NOACCESS,
4951 &spr_read_generic, &spr_write_pir,
4953 /* XXX : not implemented */
4954 spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
4955 &spr_read_spefscr, &spr_write_spefscr,
4956 &spr_read_spefscr, &spr_write_spefscr,
4958 #if !defined(CONFIG_USER_ONLY)
4959 /* Memory management */
4965 tlbncfg[0] = gen_tlbncfg(2, 1, 1, 0, 256);
4966 tlbncfg[1] = gen_tlbncfg(16, 1, 9, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16);
4969 tlbncfg[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4970 tlbncfg[1] = gen_tlbncfg(16, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16);
4974 tlbncfg[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4975 tlbncfg[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 64);
4980 tlbncfg[0] = 0x08052400;
4981 tlbncfg[1] = 0x40028040;
4984 cpu_abort(env_cpu(env), "Unknown CPU: " TARGET_FMT_lx "\n",
4992 env->dcache_line_size = 32;
4993 env->icache_line_size = 32;
4997 env->dcache_line_size = 64;
4998 env->icache_line_size = 64;
4999 l1cfg0 |= 0x1000000; /* 64 byte cache block size */
5000 l1cfg1 |= 0x1000000; /* 64 byte cache block size */
5003 env->dcache_line_size = 32;
5004 env->icache_line_size = 32;
5005 l1cfg0 |= 0x0F83820;
5006 l1cfg1 |= 0x0B83820;
5009 cpu_abort(env_cpu(env), "Unknown CPU: " TARGET_FMT_lx "\n",
5012 gen_spr_BookE206(env, 0x000000DF, tlbncfg, mmucfg);
5013 /* XXX : not implemented */
5014 spr_register(env, SPR_HID0, "HID0",
5015 SPR_NOACCESS, SPR_NOACCESS,
5016 &spr_read_generic, &spr_write_generic,
5018 /* XXX : not implemented */
5019 spr_register(env, SPR_HID1, "HID1",
5020 SPR_NOACCESS, SPR_NOACCESS,
5021 &spr_read_generic, &spr_write_generic,
5023 /* XXX : not implemented */
5024 spr_register(env, SPR_Exxx_BBEAR, "BBEAR",
5025 SPR_NOACCESS, SPR_NOACCESS,
5026 &spr_read_generic, &spr_write_generic,
5028 /* XXX : not implemented */
5029 spr_register(env, SPR_Exxx_BBTAR, "BBTAR",
5030 SPR_NOACCESS, SPR_NOACCESS,
5031 &spr_read_generic, &spr_write_generic,
5033 /* XXX : not implemented */
5034 spr_register(env, SPR_Exxx_MCAR, "MCAR",
5035 SPR_NOACCESS, SPR_NOACCESS,
5036 &spr_read_generic, &spr_write_generic,
5038 /* XXX : not implemented */
5039 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
5040 SPR_NOACCESS, SPR_NOACCESS,
5041 &spr_read_generic, &spr_write_generic,
5043 /* XXX : not implemented */
5044 spr_register(env, SPR_Exxx_NPIDR, "NPIDR",
5045 SPR_NOACCESS, SPR_NOACCESS,
5046 &spr_read_generic, &spr_write_generic,
5048 /* XXX : not implemented */
5049 spr_register(env, SPR_Exxx_BUCSR, "BUCSR",
5050 SPR_NOACCESS, SPR_NOACCESS,
5051 &spr_read_generic, &spr_write_generic,
5053 /* XXX : not implemented */
5054 spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0",
5055 &spr_read_generic, SPR_NOACCESS,
5056 &spr_read_generic, SPR_NOACCESS,
5058 spr_register(env, SPR_Exxx_L1CFG1, "L1CFG1",
5059 &spr_read_generic, SPR_NOACCESS,
5060 &spr_read_generic, SPR_NOACCESS,
5062 spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0",
5063 SPR_NOACCESS, SPR_NOACCESS,
5064 &spr_read_generic, &spr_write_e500_l1csr0,
5066 spr_register(env, SPR_Exxx_L1CSR1, "L1CSR1",
5067 SPR_NOACCESS, SPR_NOACCESS,
5068 &spr_read_generic, &spr_write_e500_l1csr1,
5070 if (version != fsl_e500v1 && version != fsl_e500v2) {
5071 spr_register(env, SPR_Exxx_L2CSR0, "L2CSR0",
5072 SPR_NOACCESS, SPR_NOACCESS,
5073 &spr_read_generic, &spr_write_e500_l2csr0,
5076 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
5077 SPR_NOACCESS, SPR_NOACCESS,
5078 &spr_read_generic, &spr_write_generic,
5080 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
5081 SPR_NOACCESS, SPR_NOACCESS,
5082 &spr_read_generic, &spr_write_generic,
5084 spr_register(env, SPR_MMUCSR0, "MMUCSR0",
5085 SPR_NOACCESS, SPR_NOACCESS,
5086 &spr_read_generic, &spr_write_booke206_mmucsr0,
5088 spr_register(env, SPR_BOOKE_EPR, "EPR",
5089 SPR_NOACCESS, SPR_NOACCESS,
5090 &spr_read_generic, SPR_NOACCESS,
5092 /* XXX better abstract into Emb.xxx features */
5093 if ((version == fsl_e5500) || (version == fsl_e6500)) {
5094 spr_register(env, SPR_BOOKE_EPCR, "EPCR",
5095 SPR_NOACCESS, SPR_NOACCESS,
5096 &spr_read_generic, &spr_write_generic,
5098 spr_register(env, SPR_BOOKE_MAS7_MAS3, "MAS7_MAS3",
5099 SPR_NOACCESS, SPR_NOACCESS,
5100 &spr_read_mas73, &spr_write_mas73,
5102 ivpr_mask = (target_ulong)~0xFFFFULL;
5105 if (version == fsl_e6500) {
5106 /* Thread identification */
5107 spr_register(env, SPR_TIR, "TIR",
5108 SPR_NOACCESS, SPR_NOACCESS,
5109 &spr_read_generic, SPR_NOACCESS,
5111 spr_register(env, SPR_BOOKE_TLB0PS, "TLB0PS",
5112 SPR_NOACCESS, SPR_NOACCESS,
5113 &spr_read_generic, SPR_NOACCESS,
5115 spr_register(env, SPR_BOOKE_TLB1PS, "TLB1PS",
5116 SPR_NOACCESS, SPR_NOACCESS,
5117 &spr_read_generic, SPR_NOACCESS,
5121 #if !defined(CONFIG_USER_ONLY)
5123 env->tlb_type = TLB_MAS;
5124 for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
5125 env->nb_tlb += booke206_tlb_size(env, i);
5129 init_excp_e200(env, ivpr_mask);
5130 /* Allocate hardware IRQ controller */
5131 ppce500_irq_init(env_archcpu(env));
5134 static void init_proc_e500v1(CPUPPCState *env)
5136 init_proc_e500(env, fsl_e500v1);
5139 POWERPC_FAMILY(e500v1)(ObjectClass *oc, void *data)
5141 DeviceClass *dc = DEVICE_CLASS(oc);
5142 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5144 dc->desc = "e500v1 core";
5145 pcc->init_proc = init_proc_e500v1;
5146 pcc->check_pow = check_pow_hid0;
5147 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
5148 PPC_SPE | PPC_SPE_SINGLE |
5149 PPC_WRTEE | PPC_RFDI |
5150 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5151 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5152 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
5153 pcc->insns_flags2 = PPC2_BOOKE206;
5154 pcc->msr_mask = (1ull << MSR_UCLE) |
5168 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5169 pcc->excp_model = POWERPC_EXCP_BOOKE;
5170 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5171 pcc->bfd_mach = bfd_mach_ppc_860;
5172 pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
5173 POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
5174 POWERPC_FLAG_BUS_CLK;
5177 static void init_proc_e500v2(CPUPPCState *env)
5179 init_proc_e500(env, fsl_e500v2);
5182 POWERPC_FAMILY(e500v2)(ObjectClass *oc, void *data)
5184 DeviceClass *dc = DEVICE_CLASS(oc);
5185 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5187 dc->desc = "e500v2 core";
5188 pcc->init_proc = init_proc_e500v2;
5189 pcc->check_pow = check_pow_hid0;
5190 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
5191 PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE |
5192 PPC_WRTEE | PPC_RFDI |
5193 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5194 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5195 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
5196 pcc->insns_flags2 = PPC2_BOOKE206;
5197 pcc->msr_mask = (1ull << MSR_UCLE) |
5211 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5212 pcc->excp_model = POWERPC_EXCP_BOOKE;
5213 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5214 pcc->bfd_mach = bfd_mach_ppc_860;
5215 pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
5216 POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
5217 POWERPC_FLAG_BUS_CLK;
5220 static void init_proc_e500mc(CPUPPCState *env)
5222 init_proc_e500(env, fsl_e500mc);
5225 POWERPC_FAMILY(e500mc)(ObjectClass *oc, void *data)
5227 DeviceClass *dc = DEVICE_CLASS(oc);
5228 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5230 dc->desc = "e500mc core";
5231 pcc->init_proc = init_proc_e500mc;
5232 pcc->check_pow = check_pow_none;
5233 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
5234 PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
5235 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5236 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5237 PPC_FLOAT | PPC_FLOAT_FRES |
5238 PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
5239 PPC_FLOAT_STFIWX | PPC_WAIT |
5240 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
5241 pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL;
5242 pcc->msr_mask = (1ull << MSR_GS) |
5243 (1ull << MSR_UCLE) |
5256 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5257 pcc->excp_model = POWERPC_EXCP_BOOKE;
5258 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5259 /* FIXME: figure out the correct flag for e500mc */
5260 pcc->bfd_mach = bfd_mach_ppc_e500;
5261 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
5262 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
5266 static void init_proc_e5500(CPUPPCState *env)
5268 init_proc_e500(env, fsl_e5500);
5271 POWERPC_FAMILY(e5500)(ObjectClass *oc, void *data)
5273 DeviceClass *dc = DEVICE_CLASS(oc);
5274 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5276 dc->desc = "e5500 core";
5277 pcc->init_proc = init_proc_e5500;
5278 pcc->check_pow = check_pow_none;
5279 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
5280 PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
5281 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5282 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5283 PPC_FLOAT | PPC_FLOAT_FRES |
5284 PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
5285 PPC_FLOAT_STFIWX | PPC_WAIT |
5286 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC |
5287 PPC_64B | PPC_POPCNTB | PPC_POPCNTWD;
5288 pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_PERM_ISA206 |
5290 pcc->msr_mask = (1ull << MSR_CM) |
5292 (1ull << MSR_UCLE) |
5305 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5306 pcc->excp_model = POWERPC_EXCP_BOOKE;
5307 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5308 /* FIXME: figure out the correct flag for e5500 */
5309 pcc->bfd_mach = bfd_mach_ppc_e500;
5310 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
5311 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
5314 static void init_proc_e6500(CPUPPCState *env)
5316 init_proc_e500(env, fsl_e6500);
5319 POWERPC_FAMILY(e6500)(ObjectClass *oc, void *data)
5321 DeviceClass *dc = DEVICE_CLASS(oc);
5322 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5324 dc->desc = "e6500 core";
5325 pcc->init_proc = init_proc_e6500;
5326 pcc->check_pow = check_pow_none;
5327 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
5328 PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
5329 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5330 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5331 PPC_FLOAT | PPC_FLOAT_FRES |
5332 PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
5333 PPC_FLOAT_STFIWX | PPC_WAIT |
5334 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC |
5335 PPC_64B | PPC_POPCNTB | PPC_POPCNTWD | PPC_ALTIVEC;
5336 pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_PERM_ISA206 |
5337 PPC2_FP_CVT_S64 | PPC2_ATOMIC_ISA206;
5338 pcc->msr_mask = (1ull << MSR_CM) |
5340 (1ull << MSR_UCLE) |
5354 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5355 pcc->excp_model = POWERPC_EXCP_BOOKE;
5356 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5357 pcc->bfd_mach = bfd_mach_ppc_e500;
5358 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
5359 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_VRE;
5364 /* Non-embedded PowerPC */
5366 #define POWERPC_MSRR_601 (0x0000000000001040ULL)
5368 static void init_proc_601(CPUPPCState *env)
5370 gen_spr_ne_601(env);
5373 /* Hardware implementation registers */
5374 /* XXX : not implemented */
5375 spr_register(env, SPR_HID0, "HID0",
5376 SPR_NOACCESS, SPR_NOACCESS,
5377 &spr_read_generic, &spr_write_hid0_601,
5379 /* XXX : not implemented */
5380 spr_register(env, SPR_HID1, "HID1",
5381 SPR_NOACCESS, SPR_NOACCESS,
5382 &spr_read_generic, &spr_write_generic,
5384 /* XXX : not implemented */
5385 spr_register(env, SPR_601_HID2, "HID2",
5386 SPR_NOACCESS, SPR_NOACCESS,
5387 &spr_read_generic, &spr_write_generic,
5389 /* XXX : not implemented */
5390 spr_register(env, SPR_601_HID5, "HID5",
5391 SPR_NOACCESS, SPR_NOACCESS,
5392 &spr_read_generic, &spr_write_generic,
5394 /* Memory management */
5397 * XXX: beware that dcache line size is 64
5398 * but dcbz uses 32 bytes "sectors"
5399 * XXX: this breaks clcs instruction !
5401 env->dcache_line_size = 32;
5402 env->icache_line_size = 64;
5403 /* Allocate hardware IRQ controller */
5404 ppc6xx_irq_init(env_archcpu(env));
5407 POWERPC_FAMILY(601)(ObjectClass *oc, void *data)
5409 DeviceClass *dc = DEVICE_CLASS(oc);
5410 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5412 dc->desc = "PowerPC 601";
5413 pcc->init_proc = init_proc_601;
5414 pcc->check_pow = check_pow_none;
5415 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
5417 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5418 PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
5419 PPC_SEGMENT | PPC_EXTERN;
5420 pcc->msr_mask = (1ull << MSR_EE) |
5430 pcc->mmu_model = POWERPC_MMU_601;
5431 #if defined(CONFIG_SOFTMMU)
5432 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5434 pcc->excp_model = POWERPC_EXCP_601;
5435 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5436 pcc->bfd_mach = bfd_mach_ppc_601;
5437 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK | POWERPC_FLAG_HID0_LE;
5440 #define POWERPC_MSRR_601v (0x0000000000001040ULL)
5442 static void init_proc_601v(CPUPPCState *env)
5445 /* XXX : not implemented */
5446 spr_register(env, SPR_601_HID15, "HID15",
5447 SPR_NOACCESS, SPR_NOACCESS,
5448 &spr_read_generic, &spr_write_generic,
5452 POWERPC_FAMILY(601v)(ObjectClass *oc, void *data)
5454 DeviceClass *dc = DEVICE_CLASS(oc);
5455 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5457 dc->desc = "PowerPC 601v";
5458 pcc->init_proc = init_proc_601v;
5459 pcc->check_pow = check_pow_none;
5460 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
5462 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5463 PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
5464 PPC_SEGMENT | PPC_EXTERN;
5465 pcc->msr_mask = (1ull << MSR_EE) |
5475 pcc->mmu_model = POWERPC_MMU_601;
5476 #if defined(CONFIG_SOFTMMU)
5477 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5479 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5480 pcc->bfd_mach = bfd_mach_ppc_601;
5481 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK | POWERPC_FLAG_HID0_LE;
5484 static void init_proc_602(CPUPPCState *env)
5486 gen_spr_ne_601(env);
5491 /* hardware implementation registers */
5492 /* XXX : not implemented */
5493 spr_register(env, SPR_HID0, "HID0",
5494 SPR_NOACCESS, SPR_NOACCESS,
5495 &spr_read_generic, &spr_write_generic,
5497 /* XXX : not implemented */
5498 spr_register(env, SPR_HID1, "HID1",
5499 SPR_NOACCESS, SPR_NOACCESS,
5500 &spr_read_generic, &spr_write_generic,
5502 /* Memory management */
5504 gen_6xx_7xx_soft_tlb(env, 64, 2);
5506 env->dcache_line_size = 32;
5507 env->icache_line_size = 32;
5508 /* Allocate hardware IRQ controller */
5509 ppc6xx_irq_init(env_archcpu(env));
5512 POWERPC_FAMILY(602)(ObjectClass *oc, void *data)
5514 DeviceClass *dc = DEVICE_CLASS(oc);
5515 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5517 dc->desc = "PowerPC 602";
5518 pcc->init_proc = init_proc_602;
5519 pcc->check_pow = check_pow_hid0;
5520 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5521 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5522 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5523 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5524 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5525 PPC_MEM_TLBIE | PPC_6xx_TLB | PPC_MEM_TLBSYNC |
5526 PPC_SEGMENT | PPC_602_SPEC;
5527 pcc->msr_mask = (1ull << MSR_VSX) |
5530 (1ull << MSR_TGPR) |
5545 /* XXX: 602 MMU is quite specific. Should add a special case */
5546 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
5547 pcc->excp_model = POWERPC_EXCP_602;
5548 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5549 pcc->bfd_mach = bfd_mach_ppc_602;
5550 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
5551 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
5554 static void init_proc_603(CPUPPCState *env)
5556 gen_spr_ne_601(env);
5561 /* hardware implementation registers */
5562 /* XXX : not implemented */
5563 spr_register(env, SPR_HID0, "HID0",
5564 SPR_NOACCESS, SPR_NOACCESS,
5565 &spr_read_generic, &spr_write_generic,
5567 /* XXX : not implemented */
5568 spr_register(env, SPR_HID1, "HID1",
5569 SPR_NOACCESS, SPR_NOACCESS,
5570 &spr_read_generic, &spr_write_generic,
5572 /* Memory management */
5574 gen_6xx_7xx_soft_tlb(env, 64, 2);
5576 env->dcache_line_size = 32;
5577 env->icache_line_size = 32;
5578 /* Allocate hardware IRQ controller */
5579 ppc6xx_irq_init(env_archcpu(env));
5582 POWERPC_FAMILY(603)(ObjectClass *oc, void *data)
5584 DeviceClass *dc = DEVICE_CLASS(oc);
5585 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5587 dc->desc = "PowerPC 603";
5588 pcc->init_proc = init_proc_603;
5589 pcc->check_pow = check_pow_hid0;
5590 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5591 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5592 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5593 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5594 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5595 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
5596 PPC_SEGMENT | PPC_EXTERN;
5597 pcc->msr_mask = (1ull << MSR_POW) |
5598 (1ull << MSR_TGPR) |
5613 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
5614 pcc->excp_model = POWERPC_EXCP_603;
5615 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5616 pcc->bfd_mach = bfd_mach_ppc_603;
5617 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
5618 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
5621 static void init_proc_603E(CPUPPCState *env)
5623 gen_spr_ne_601(env);
5628 /* hardware implementation registers */
5629 /* XXX : not implemented */
5630 spr_register(env, SPR_HID0, "HID0",
5631 SPR_NOACCESS, SPR_NOACCESS,
5632 &spr_read_generic, &spr_write_generic,
5634 /* XXX : not implemented */
5635 spr_register(env, SPR_HID1, "HID1",
5636 SPR_NOACCESS, SPR_NOACCESS,
5637 &spr_read_generic, &spr_write_generic,
5639 /* Memory management */
5641 gen_6xx_7xx_soft_tlb(env, 64, 2);
5643 env->dcache_line_size = 32;
5644 env->icache_line_size = 32;
5645 /* Allocate hardware IRQ controller */
5646 ppc6xx_irq_init(env_archcpu(env));
5649 POWERPC_FAMILY(603E)(ObjectClass *oc, void *data)
5651 DeviceClass *dc = DEVICE_CLASS(oc);
5652 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5654 dc->desc = "PowerPC 603e";
5655 pcc->init_proc = init_proc_603E;
5656 pcc->check_pow = check_pow_hid0;
5657 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5658 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5659 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5660 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5661 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5662 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
5663 PPC_SEGMENT | PPC_EXTERN;
5664 pcc->msr_mask = (1ull << MSR_POW) |
5665 (1ull << MSR_TGPR) |
5680 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
5681 pcc->excp_model = POWERPC_EXCP_603E;
5682 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5683 pcc->bfd_mach = bfd_mach_ppc_ec603e;
5684 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
5685 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
5688 static void init_proc_604(CPUPPCState *env)
5690 gen_spr_ne_601(env);
5695 /* Hardware implementation registers */
5696 /* XXX : not implemented */
5697 spr_register(env, SPR_HID0, "HID0",
5698 SPR_NOACCESS, SPR_NOACCESS,
5699 &spr_read_generic, &spr_write_generic,
5701 /* Memory management */
5704 env->dcache_line_size = 32;
5705 env->icache_line_size = 32;
5706 /* Allocate hardware IRQ controller */
5707 ppc6xx_irq_init(env_archcpu(env));
5710 POWERPC_FAMILY(604)(ObjectClass *oc, void *data)
5712 DeviceClass *dc = DEVICE_CLASS(oc);
5713 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5715 dc->desc = "PowerPC 604";
5716 pcc->init_proc = init_proc_604;
5717 pcc->check_pow = check_pow_nocheck;
5718 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5719 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5720 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5721 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5722 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5723 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5724 PPC_SEGMENT | PPC_EXTERN;
5725 pcc->msr_mask = (1ull << MSR_POW) |
5741 pcc->mmu_model = POWERPC_MMU_32B;
5742 #if defined(CONFIG_SOFTMMU)
5743 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5745 pcc->excp_model = POWERPC_EXCP_604;
5746 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5747 pcc->bfd_mach = bfd_mach_ppc_604;
5748 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5749 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
5752 static void init_proc_604E(CPUPPCState *env)
5754 gen_spr_ne_601(env);
5757 /* XXX : not implemented */
5758 spr_register(env, SPR_7XX_MMCR1, "MMCR1",
5759 SPR_NOACCESS, SPR_NOACCESS,
5760 &spr_read_generic, &spr_write_generic,
5762 /* XXX : not implemented */
5763 spr_register(env, SPR_7XX_PMC3, "PMC3",
5764 SPR_NOACCESS, SPR_NOACCESS,
5765 &spr_read_generic, &spr_write_generic,
5767 /* XXX : not implemented */
5768 spr_register(env, SPR_7XX_PMC4, "PMC4",
5769 SPR_NOACCESS, SPR_NOACCESS,
5770 &spr_read_generic, &spr_write_generic,
5774 /* Hardware implementation registers */
5775 /* XXX : not implemented */
5776 spr_register(env, SPR_HID0, "HID0",
5777 SPR_NOACCESS, SPR_NOACCESS,
5778 &spr_read_generic, &spr_write_generic,
5780 /* XXX : not implemented */
5781 spr_register(env, SPR_HID1, "HID1",
5782 SPR_NOACCESS, SPR_NOACCESS,
5783 &spr_read_generic, &spr_write_generic,
5785 /* Memory management */
5788 env->dcache_line_size = 32;
5789 env->icache_line_size = 32;
5790 /* Allocate hardware IRQ controller */
5791 ppc6xx_irq_init(env_archcpu(env));
5794 POWERPC_FAMILY(604E)(ObjectClass *oc, void *data)
5796 DeviceClass *dc = DEVICE_CLASS(oc);
5797 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5799 dc->desc = "PowerPC 604E";
5800 pcc->init_proc = init_proc_604E;
5801 pcc->check_pow = check_pow_nocheck;
5802 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5803 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5804 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5805 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5806 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5807 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5808 PPC_SEGMENT | PPC_EXTERN;
5809 pcc->msr_mask = (1ull << MSR_POW) |
5825 pcc->mmu_model = POWERPC_MMU_32B;
5826 #if defined(CONFIG_SOFTMMU)
5827 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5829 pcc->excp_model = POWERPC_EXCP_604;
5830 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5831 pcc->bfd_mach = bfd_mach_ppc_604;
5832 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5833 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
5836 static void init_proc_740(CPUPPCState *env)
5838 gen_spr_ne_601(env);
5843 /* Thermal management */
5845 /* Hardware implementation registers */
5846 /* XXX : not implemented */
5847 spr_register(env, SPR_HID0, "HID0",
5848 SPR_NOACCESS, SPR_NOACCESS,
5849 &spr_read_generic, &spr_write_generic,
5851 /* XXX : not implemented */
5852 spr_register(env, SPR_HID1, "HID1",
5853 SPR_NOACCESS, SPR_NOACCESS,
5854 &spr_read_generic, &spr_write_generic,
5856 /* Memory management */
5859 env->dcache_line_size = 32;
5860 env->icache_line_size = 32;
5861 /* Allocate hardware IRQ controller */
5862 ppc6xx_irq_init(env_archcpu(env));
5865 POWERPC_FAMILY(740)(ObjectClass *oc, void *data)
5867 DeviceClass *dc = DEVICE_CLASS(oc);
5868 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5870 dc->desc = "PowerPC 740";
5871 pcc->init_proc = init_proc_740;
5872 pcc->check_pow = check_pow_hid0;
5873 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5874 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5875 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5876 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5877 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5878 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5879 PPC_SEGMENT | PPC_EXTERN;
5880 pcc->msr_mask = (1ull << MSR_POW) |
5896 pcc->mmu_model = POWERPC_MMU_32B;
5897 #if defined(CONFIG_SOFTMMU)
5898 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5900 pcc->excp_model = POWERPC_EXCP_7x0;
5901 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5902 pcc->bfd_mach = bfd_mach_ppc_750;
5903 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5904 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
5907 static void init_proc_750(CPUPPCState *env)
5909 gen_spr_ne_601(env);
5912 /* XXX : not implemented */
5913 spr_register(env, SPR_L2CR, "L2CR",
5914 SPR_NOACCESS, SPR_NOACCESS,
5915 &spr_read_generic, spr_access_nop,
5919 /* Thermal management */
5921 /* Hardware implementation registers */
5922 /* XXX : not implemented */
5923 spr_register(env, SPR_HID0, "HID0",
5924 SPR_NOACCESS, SPR_NOACCESS,
5925 &spr_read_generic, &spr_write_generic,
5927 /* XXX : not implemented */
5928 spr_register(env, SPR_HID1, "HID1",
5929 SPR_NOACCESS, SPR_NOACCESS,
5930 &spr_read_generic, &spr_write_generic,
5932 /* Memory management */
5935 * XXX: high BATs are also present but are known to be bugged on
5939 env->dcache_line_size = 32;
5940 env->icache_line_size = 32;
5941 /* Allocate hardware IRQ controller */
5942 ppc6xx_irq_init(env_archcpu(env));
5945 POWERPC_FAMILY(750)(ObjectClass *oc, void *data)
5947 DeviceClass *dc = DEVICE_CLASS(oc);
5948 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5950 dc->desc = "PowerPC 750";
5951 pcc->init_proc = init_proc_750;
5952 pcc->check_pow = check_pow_hid0;
5953 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5954 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5955 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5956 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5957 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5958 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5959 PPC_SEGMENT | PPC_EXTERN;
5960 pcc->msr_mask = (1ull << MSR_POW) |
5976 pcc->mmu_model = POWERPC_MMU_32B;
5977 #if defined(CONFIG_SOFTMMU)
5978 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5980 pcc->excp_model = POWERPC_EXCP_7x0;
5981 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5982 pcc->bfd_mach = bfd_mach_ppc_750;
5983 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5984 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
5987 static void init_proc_750cl(CPUPPCState *env)
5989 gen_spr_ne_601(env);
5992 /* XXX : not implemented */
5993 spr_register(env, SPR_L2CR, "L2CR",
5994 SPR_NOACCESS, SPR_NOACCESS,
5995 &spr_read_generic, spr_access_nop,
5999 /* Thermal management */
6000 /* Those registers are fake on 750CL */
6001 spr_register(env, SPR_THRM1, "THRM1",
6002 SPR_NOACCESS, SPR_NOACCESS,
6003 &spr_read_generic, &spr_write_generic,
6005 spr_register(env, SPR_THRM2, "THRM2",
6006 SPR_NOACCESS, SPR_NOACCESS,
6007 &spr_read_generic, &spr_write_generic,
6009 spr_register(env, SPR_THRM3, "THRM3",
6010 SPR_NOACCESS, SPR_NOACCESS,
6011 &spr_read_generic, &spr_write_generic,
6013 /* XXX: not implemented */
6014 spr_register(env, SPR_750_TDCL, "TDCL",
6015 SPR_NOACCESS, SPR_NOACCESS,
6016 &spr_read_generic, &spr_write_generic,
6018 spr_register(env, SPR_750_TDCH, "TDCH",
6019 SPR_NOACCESS, SPR_NOACCESS,
6020 &spr_read_generic, &spr_write_generic,
6023 /* XXX : not implemented */
6024 spr_register(env, SPR_750_WPAR, "WPAR",
6025 SPR_NOACCESS, SPR_NOACCESS,
6026 &spr_read_generic, &spr_write_generic,
6028 spr_register(env, SPR_750_DMAL, "DMAL",
6029 SPR_NOACCESS, SPR_NOACCESS,
6030 &spr_read_generic, &spr_write_generic,
6032 spr_register(env, SPR_750_DMAU, "DMAU",
6033 SPR_NOACCESS, SPR_NOACCESS,
6034 &spr_read_generic, &spr_write_generic,
6036 /* Hardware implementation registers */
6037 /* XXX : not implemented */
6038 spr_register(env, SPR_HID0, "HID0",
6039 SPR_NOACCESS, SPR_NOACCESS,
6040 &spr_read_generic, &spr_write_generic,
6042 /* XXX : not implemented */
6043 spr_register(env, SPR_HID1, "HID1",
6044 SPR_NOACCESS, SPR_NOACCESS,
6045 &spr_read_generic, &spr_write_generic,
6047 /* XXX : not implemented */
6048 spr_register(env, SPR_750CL_HID2, "HID2",
6049 SPR_NOACCESS, SPR_NOACCESS,
6050 &spr_read_generic, &spr_write_generic,
6052 /* XXX : not implemented */
6053 spr_register(env, SPR_750CL_HID4, "HID4",
6054 SPR_NOACCESS, SPR_NOACCESS,
6055 &spr_read_generic, &spr_write_generic,
6057 /* Quantization registers */
6058 /* XXX : not implemented */
6059 spr_register(env, SPR_750_GQR0, "GQR0",
6060 SPR_NOACCESS, SPR_NOACCESS,
6061 &spr_read_generic, &spr_write_generic,
6063 /* XXX : not implemented */
6064 spr_register(env, SPR_750_GQR1, "GQR1",
6065 SPR_NOACCESS, SPR_NOACCESS,
6066 &spr_read_generic, &spr_write_generic,
6068 /* XXX : not implemented */
6069 spr_register(env, SPR_750_GQR2, "GQR2",
6070 SPR_NOACCESS, SPR_NOACCESS,
6071 &spr_read_generic, &spr_write_generic,
6073 /* XXX : not implemented */
6074 spr_register(env, SPR_750_GQR3, "GQR3",
6075 SPR_NOACCESS, SPR_NOACCESS,
6076 &spr_read_generic, &spr_write_generic,
6078 /* XXX : not implemented */
6079 spr_register(env, SPR_750_GQR4, "GQR4",
6080 SPR_NOACCESS, SPR_NOACCESS,
6081 &spr_read_generic, &spr_write_generic,
6083 /* XXX : not implemented */
6084 spr_register(env, SPR_750_GQR5, "GQR5",
6085 SPR_NOACCESS, SPR_NOACCESS,
6086 &spr_read_generic, &spr_write_generic,
6088 /* XXX : not implemented */
6089 spr_register(env, SPR_750_GQR6, "GQR6",
6090 SPR_NOACCESS, SPR_NOACCESS,
6091 &spr_read_generic, &spr_write_generic,
6093 /* XXX : not implemented */
6094 spr_register(env, SPR_750_GQR7, "GQR7",
6095 SPR_NOACCESS, SPR_NOACCESS,
6096 &spr_read_generic, &spr_write_generic,
6098 /* Memory management */
6100 /* PowerPC 750cl has 8 DBATs and 8 IBATs */
6102 init_excp_750cl(env);
6103 env->dcache_line_size = 32;
6104 env->icache_line_size = 32;
6105 /* Allocate hardware IRQ controller */
6106 ppc6xx_irq_init(env_archcpu(env));
6109 POWERPC_FAMILY(750cl)(ObjectClass *oc, void *data)
6111 DeviceClass *dc = DEVICE_CLASS(oc);
6112 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6114 dc->desc = "PowerPC 750 CL";
6115 pcc->init_proc = init_proc_750cl;
6116 pcc->check_pow = check_pow_hid0;
6118 * XXX: not implemented:
6119 * cache lock instructions:
6121 * floating point paired instructions
6156 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6157 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6158 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6159 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6160 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6161 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6162 PPC_SEGMENT | PPC_EXTERN;
6163 pcc->msr_mask = (1ull << MSR_POW) |
6179 pcc->mmu_model = POWERPC_MMU_32B;
6180 #if defined(CONFIG_SOFTMMU)
6181 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6183 pcc->excp_model = POWERPC_EXCP_7x0;
6184 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6185 pcc->bfd_mach = bfd_mach_ppc_750;
6186 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6187 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
6190 static void init_proc_750cx(CPUPPCState *env)
6192 gen_spr_ne_601(env);
6195 /* XXX : not implemented */
6196 spr_register(env, SPR_L2CR, "L2CR",
6197 SPR_NOACCESS, SPR_NOACCESS,
6198 &spr_read_generic, spr_access_nop,
6202 /* Thermal management */
6204 /* This register is not implemented but is present for compatibility */
6205 spr_register(env, SPR_SDA, "SDA",
6206 SPR_NOACCESS, SPR_NOACCESS,
6207 &spr_read_generic, &spr_write_generic,
6209 /* Hardware implementation registers */
6210 /* XXX : not implemented */
6211 spr_register(env, SPR_HID0, "HID0",
6212 SPR_NOACCESS, SPR_NOACCESS,
6213 &spr_read_generic, &spr_write_generic,
6215 /* XXX : not implemented */
6216 spr_register(env, SPR_HID1, "HID1",
6217 SPR_NOACCESS, SPR_NOACCESS,
6218 &spr_read_generic, &spr_write_generic,
6220 /* Memory management */
6222 /* PowerPC 750cx has 8 DBATs and 8 IBATs */
6224 init_excp_750cx(env);
6225 env->dcache_line_size = 32;
6226 env->icache_line_size = 32;
6227 /* Allocate hardware IRQ controller */
6228 ppc6xx_irq_init(env_archcpu(env));
6231 POWERPC_FAMILY(750cx)(ObjectClass *oc, void *data)
6233 DeviceClass *dc = DEVICE_CLASS(oc);
6234 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6236 dc->desc = "PowerPC 750CX";
6237 pcc->init_proc = init_proc_750cx;
6238 pcc->check_pow = check_pow_hid0;
6239 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6240 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6241 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6242 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6243 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6244 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6245 PPC_SEGMENT | PPC_EXTERN;
6246 pcc->msr_mask = (1ull << MSR_POW) |
6262 pcc->mmu_model = POWERPC_MMU_32B;
6263 #if defined(CONFIG_SOFTMMU)
6264 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6266 pcc->excp_model = POWERPC_EXCP_7x0;
6267 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6268 pcc->bfd_mach = bfd_mach_ppc_750;
6269 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6270 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
6273 static void init_proc_750fx(CPUPPCState *env)
6275 gen_spr_ne_601(env);
6278 /* XXX : not implemented */
6279 spr_register(env, SPR_L2CR, "L2CR",
6280 SPR_NOACCESS, SPR_NOACCESS,
6281 &spr_read_generic, spr_access_nop,
6285 /* Thermal management */
6287 /* XXX : not implemented */
6288 spr_register(env, SPR_750_THRM4, "THRM4",
6289 SPR_NOACCESS, SPR_NOACCESS,
6290 &spr_read_generic, &spr_write_generic,
6292 /* Hardware implementation registers */
6293 /* XXX : not implemented */
6294 spr_register(env, SPR_HID0, "HID0",
6295 SPR_NOACCESS, SPR_NOACCESS,
6296 &spr_read_generic, &spr_write_generic,
6298 /* XXX : not implemented */
6299 spr_register(env, SPR_HID1, "HID1",
6300 SPR_NOACCESS, SPR_NOACCESS,
6301 &spr_read_generic, &spr_write_generic,
6303 /* XXX : not implemented */
6304 spr_register(env, SPR_750FX_HID2, "HID2",
6305 SPR_NOACCESS, SPR_NOACCESS,
6306 &spr_read_generic, &spr_write_generic,
6308 /* Memory management */
6310 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6313 env->dcache_line_size = 32;
6314 env->icache_line_size = 32;
6315 /* Allocate hardware IRQ controller */
6316 ppc6xx_irq_init(env_archcpu(env));
6319 POWERPC_FAMILY(750fx)(ObjectClass *oc, void *data)
6321 DeviceClass *dc = DEVICE_CLASS(oc);
6322 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6324 dc->desc = "PowerPC 750FX";
6325 pcc->init_proc = init_proc_750fx;
6326 pcc->check_pow = check_pow_hid0;
6327 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6328 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6329 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6330 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6331 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6332 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6333 PPC_SEGMENT | PPC_EXTERN;
6334 pcc->msr_mask = (1ull << MSR_POW) |
6350 pcc->mmu_model = POWERPC_MMU_32B;
6351 #if defined(CONFIG_SOFTMMU)
6352 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6354 pcc->excp_model = POWERPC_EXCP_7x0;
6355 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6356 pcc->bfd_mach = bfd_mach_ppc_750;
6357 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6358 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
6361 static void init_proc_750gx(CPUPPCState *env)
6363 gen_spr_ne_601(env);
6366 /* XXX : not implemented (XXX: different from 750fx) */
6367 spr_register(env, SPR_L2CR, "L2CR",
6368 SPR_NOACCESS, SPR_NOACCESS,
6369 &spr_read_generic, spr_access_nop,
6373 /* Thermal management */
6375 /* XXX : not implemented */
6376 spr_register(env, SPR_750_THRM4, "THRM4",
6377 SPR_NOACCESS, SPR_NOACCESS,
6378 &spr_read_generic, &spr_write_generic,
6380 /* Hardware implementation registers */
6381 /* XXX : not implemented (XXX: different from 750fx) */
6382 spr_register(env, SPR_HID0, "HID0",
6383 SPR_NOACCESS, SPR_NOACCESS,
6384 &spr_read_generic, &spr_write_generic,
6386 /* XXX : not implemented */
6387 spr_register(env, SPR_HID1, "HID1",
6388 SPR_NOACCESS, SPR_NOACCESS,
6389 &spr_read_generic, &spr_write_generic,
6391 /* XXX : not implemented (XXX: different from 750fx) */
6392 spr_register(env, SPR_750FX_HID2, "HID2",
6393 SPR_NOACCESS, SPR_NOACCESS,
6394 &spr_read_generic, &spr_write_generic,
6396 /* Memory management */
6398 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6401 env->dcache_line_size = 32;
6402 env->icache_line_size = 32;
6403 /* Allocate hardware IRQ controller */
6404 ppc6xx_irq_init(env_archcpu(env));
6407 POWERPC_FAMILY(750gx)(ObjectClass *oc, void *data)
6409 DeviceClass *dc = DEVICE_CLASS(oc);
6410 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6412 dc->desc = "PowerPC 750GX";
6413 pcc->init_proc = init_proc_750gx;
6414 pcc->check_pow = check_pow_hid0;
6415 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6416 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6417 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6418 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6419 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6420 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6421 PPC_SEGMENT | PPC_EXTERN;
6422 pcc->msr_mask = (1ull << MSR_POW) |
6438 pcc->mmu_model = POWERPC_MMU_32B;
6439 #if defined(CONFIG_SOFTMMU)
6440 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6442 pcc->excp_model = POWERPC_EXCP_7x0;
6443 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6444 pcc->bfd_mach = bfd_mach_ppc_750;
6445 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6446 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
6449 static void init_proc_745(CPUPPCState *env)
6451 gen_spr_ne_601(env);
6454 gen_spr_G2_755(env);
6457 /* Thermal management */
6459 /* Hardware implementation registers */
6460 /* XXX : not implemented */
6461 spr_register(env, SPR_HID0, "HID0",
6462 SPR_NOACCESS, SPR_NOACCESS,
6463 &spr_read_generic, &spr_write_generic,
6465 /* XXX : not implemented */
6466 spr_register(env, SPR_HID1, "HID1",
6467 SPR_NOACCESS, SPR_NOACCESS,
6468 &spr_read_generic, &spr_write_generic,
6470 /* XXX : not implemented */
6471 spr_register(env, SPR_HID2, "HID2",
6472 SPR_NOACCESS, SPR_NOACCESS,
6473 &spr_read_generic, &spr_write_generic,
6475 /* Memory management */
6478 gen_6xx_7xx_soft_tlb(env, 64, 2);
6480 env->dcache_line_size = 32;
6481 env->icache_line_size = 32;
6482 /* Allocate hardware IRQ controller */
6483 ppc6xx_irq_init(env_archcpu(env));
6486 POWERPC_FAMILY(745)(ObjectClass *oc, void *data)
6488 DeviceClass *dc = DEVICE_CLASS(oc);
6489 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6491 dc->desc = "PowerPC 745";
6492 pcc->init_proc = init_proc_745;
6493 pcc->check_pow = check_pow_hid0;
6494 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6495 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6496 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6497 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6498 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6499 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
6500 PPC_SEGMENT | PPC_EXTERN;
6501 pcc->msr_mask = (1ull << MSR_POW) |
6517 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
6518 pcc->excp_model = POWERPC_EXCP_7x5;
6519 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6520 pcc->bfd_mach = bfd_mach_ppc_750;
6521 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6522 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
6525 static void init_proc_755(CPUPPCState *env)
6527 gen_spr_ne_601(env);
6530 gen_spr_G2_755(env);
6533 /* L2 cache control */
6534 /* XXX : not implemented */
6535 spr_register(env, SPR_L2CR, "L2CR",
6536 SPR_NOACCESS, SPR_NOACCESS,
6537 &spr_read_generic, spr_access_nop,
6539 /* XXX : not implemented */
6540 spr_register(env, SPR_L2PMCR, "L2PMCR",
6541 SPR_NOACCESS, SPR_NOACCESS,
6542 &spr_read_generic, &spr_write_generic,
6544 /* Thermal management */
6546 /* Hardware implementation registers */
6547 /* XXX : not implemented */
6548 spr_register(env, SPR_HID0, "HID0",
6549 SPR_NOACCESS, SPR_NOACCESS,
6550 &spr_read_generic, &spr_write_generic,
6552 /* XXX : not implemented */
6553 spr_register(env, SPR_HID1, "HID1",
6554 SPR_NOACCESS, SPR_NOACCESS,
6555 &spr_read_generic, &spr_write_generic,
6557 /* XXX : not implemented */
6558 spr_register(env, SPR_HID2, "HID2",
6559 SPR_NOACCESS, SPR_NOACCESS,
6560 &spr_read_generic, &spr_write_generic,
6562 /* Memory management */
6565 gen_6xx_7xx_soft_tlb(env, 64, 2);
6567 env->dcache_line_size = 32;
6568 env->icache_line_size = 32;
6569 /* Allocate hardware IRQ controller */
6570 ppc6xx_irq_init(env_archcpu(env));
6573 POWERPC_FAMILY(755)(ObjectClass *oc, void *data)
6575 DeviceClass *dc = DEVICE_CLASS(oc);
6576 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6578 dc->desc = "PowerPC 755";
6579 pcc->init_proc = init_proc_755;
6580 pcc->check_pow = check_pow_hid0;
6581 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6582 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6583 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6584 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6585 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6586 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
6587 PPC_SEGMENT | PPC_EXTERN;
6588 pcc->msr_mask = (1ull << MSR_POW) |
6604 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
6605 pcc->excp_model = POWERPC_EXCP_7x5;
6606 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6607 pcc->bfd_mach = bfd_mach_ppc_750;
6608 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6609 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
6612 static void init_proc_7400(CPUPPCState *env)
6614 gen_spr_ne_601(env);
6619 /* 74xx specific SPR */
6621 /* XXX : not implemented */
6622 spr_register(env, SPR_UBAMR, "UBAMR",
6623 &spr_read_ureg, SPR_NOACCESS,
6624 &spr_read_ureg, SPR_NOACCESS,
6626 /* XXX: this seems not implemented on all revisions. */
6627 /* XXX : not implemented */
6628 spr_register(env, SPR_MSSCR1, "MSSCR1",
6629 SPR_NOACCESS, SPR_NOACCESS,
6630 &spr_read_generic, &spr_write_generic,
6632 /* Thermal management */
6634 /* Memory management */
6636 init_excp_7400(env);
6637 env->dcache_line_size = 32;
6638 env->icache_line_size = 32;
6639 /* Allocate hardware IRQ controller */
6640 ppc6xx_irq_init(env_archcpu(env));
6643 POWERPC_FAMILY(7400)(ObjectClass *oc, void *data)
6645 DeviceClass *dc = DEVICE_CLASS(oc);
6646 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6648 dc->desc = "PowerPC 7400 (aka G4)";
6649 pcc->init_proc = init_proc_7400;
6650 pcc->check_pow = check_pow_hid0;
6651 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6652 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6653 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6655 PPC_CACHE | PPC_CACHE_ICBI |
6656 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6657 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6658 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6660 PPC_SEGMENT | PPC_EXTERN |
6662 pcc->msr_mask = (1ull << MSR_VR) |
6679 pcc->mmu_model = POWERPC_MMU_32B;
6680 #if defined(CONFIG_SOFTMMU)
6681 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6683 pcc->excp_model = POWERPC_EXCP_74xx;
6684 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6685 pcc->bfd_mach = bfd_mach_ppc_7400;
6686 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6687 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6688 POWERPC_FLAG_BUS_CLK;
6691 static void init_proc_7410(CPUPPCState *env)
6693 gen_spr_ne_601(env);
6698 /* 74xx specific SPR */
6700 /* XXX : not implemented */
6701 spr_register(env, SPR_UBAMR, "UBAMR",
6702 &spr_read_ureg, SPR_NOACCESS,
6703 &spr_read_ureg, SPR_NOACCESS,
6705 /* Thermal management */
6708 /* XXX : not implemented */
6709 spr_register(env, SPR_L2PMCR, "L2PMCR",
6710 SPR_NOACCESS, SPR_NOACCESS,
6711 &spr_read_generic, &spr_write_generic,
6714 /* XXX : not implemented */
6715 spr_register(env, SPR_LDSTDB, "LDSTDB",
6716 SPR_NOACCESS, SPR_NOACCESS,
6717 &spr_read_generic, &spr_write_generic,
6719 /* Memory management */
6721 init_excp_7400(env);
6722 env->dcache_line_size = 32;
6723 env->icache_line_size = 32;
6724 /* Allocate hardware IRQ controller */
6725 ppc6xx_irq_init(env_archcpu(env));
6728 POWERPC_FAMILY(7410)(ObjectClass *oc, void *data)
6730 DeviceClass *dc = DEVICE_CLASS(oc);
6731 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6733 dc->desc = "PowerPC 7410 (aka G4)";
6734 pcc->init_proc = init_proc_7410;
6735 pcc->check_pow = check_pow_hid0;
6736 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6737 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6738 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6740 PPC_CACHE | PPC_CACHE_ICBI |
6741 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6742 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6743 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6745 PPC_SEGMENT | PPC_EXTERN |
6747 pcc->msr_mask = (1ull << MSR_VR) |
6764 pcc->mmu_model = POWERPC_MMU_32B;
6765 #if defined(CONFIG_SOFTMMU)
6766 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6768 pcc->excp_model = POWERPC_EXCP_74xx;
6769 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6770 pcc->bfd_mach = bfd_mach_ppc_7400;
6771 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6772 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6773 POWERPC_FLAG_BUS_CLK;
6776 static void init_proc_7440(CPUPPCState *env)
6778 gen_spr_ne_601(env);
6783 /* 74xx specific SPR */
6785 /* XXX : not implemented */
6786 spr_register(env, SPR_UBAMR, "UBAMR",
6787 &spr_read_ureg, SPR_NOACCESS,
6788 &spr_read_ureg, SPR_NOACCESS,
6791 /* XXX : not implemented */
6792 spr_register(env, SPR_LDSTCR, "LDSTCR",
6793 SPR_NOACCESS, SPR_NOACCESS,
6794 &spr_read_generic, &spr_write_generic,
6797 /* XXX : not implemented */
6798 spr_register(env, SPR_ICTRL, "ICTRL",
6799 SPR_NOACCESS, SPR_NOACCESS,
6800 &spr_read_generic, &spr_write_generic,
6803 /* XXX : not implemented */
6804 spr_register(env, SPR_MSSSR0, "MSSSR0",
6805 SPR_NOACCESS, SPR_NOACCESS,
6806 &spr_read_generic, &spr_write_generic,
6809 /* XXX : not implemented */
6810 spr_register(env, SPR_7XX_PMC5, "PMC5",
6811 SPR_NOACCESS, SPR_NOACCESS,
6812 &spr_read_generic, &spr_write_generic,
6814 /* XXX : not implemented */
6815 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
6816 &spr_read_ureg, SPR_NOACCESS,
6817 &spr_read_ureg, SPR_NOACCESS,
6819 /* XXX : not implemented */
6820 spr_register(env, SPR_7XX_PMC6, "PMC6",
6821 SPR_NOACCESS, SPR_NOACCESS,
6822 &spr_read_generic, &spr_write_generic,
6824 /* XXX : not implemented */
6825 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
6826 &spr_read_ureg, SPR_NOACCESS,
6827 &spr_read_ureg, SPR_NOACCESS,
6829 /* Memory management */
6831 gen_74xx_soft_tlb(env, 128, 2);
6832 init_excp_7450(env);
6833 env->dcache_line_size = 32;
6834 env->icache_line_size = 32;
6835 /* Allocate hardware IRQ controller */
6836 ppc6xx_irq_init(env_archcpu(env));
6839 POWERPC_FAMILY(7440)(ObjectClass *oc, void *data)
6841 DeviceClass *dc = DEVICE_CLASS(oc);
6842 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6844 dc->desc = "PowerPC 7440 (aka G4)";
6845 pcc->init_proc = init_proc_7440;
6846 pcc->check_pow = check_pow_hid0_74xx;
6847 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6848 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6849 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6851 PPC_CACHE | PPC_CACHE_ICBI |
6852 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6853 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6854 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6855 PPC_MEM_TLBIA | PPC_74xx_TLB |
6856 PPC_SEGMENT | PPC_EXTERN |
6858 pcc->msr_mask = (1ull << MSR_VR) |
6875 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
6876 pcc->excp_model = POWERPC_EXCP_74xx;
6877 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6878 pcc->bfd_mach = bfd_mach_ppc_7400;
6879 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6880 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6881 POWERPC_FLAG_BUS_CLK;
6884 static void init_proc_7450(CPUPPCState *env)
6886 gen_spr_ne_601(env);
6891 /* 74xx specific SPR */
6893 /* Level 3 cache control */
6896 /* XXX : not implemented */
6897 spr_register(env, SPR_L3ITCR1, "L3ITCR1",
6898 SPR_NOACCESS, SPR_NOACCESS,
6899 &spr_read_generic, &spr_write_generic,
6902 /* XXX : not implemented */
6903 spr_register(env, SPR_L3ITCR2, "L3ITCR2",
6904 SPR_NOACCESS, SPR_NOACCESS,
6905 &spr_read_generic, &spr_write_generic,
6908 /* XXX : not implemented */
6909 spr_register(env, SPR_L3ITCR3, "L3ITCR3",
6910 SPR_NOACCESS, SPR_NOACCESS,
6911 &spr_read_generic, &spr_write_generic,
6914 /* XXX : not implemented */
6915 spr_register(env, SPR_L3OHCR, "L3OHCR",
6916 SPR_NOACCESS, SPR_NOACCESS,
6917 &spr_read_generic, &spr_write_generic,
6919 /* XXX : not implemented */
6920 spr_register(env, SPR_UBAMR, "UBAMR",
6921 &spr_read_ureg, SPR_NOACCESS,
6922 &spr_read_ureg, SPR_NOACCESS,
6925 /* XXX : not implemented */
6926 spr_register(env, SPR_LDSTCR, "LDSTCR",
6927 SPR_NOACCESS, SPR_NOACCESS,
6928 &spr_read_generic, &spr_write_generic,
6931 /* XXX : not implemented */
6932 spr_register(env, SPR_ICTRL, "ICTRL",
6933 SPR_NOACCESS, SPR_NOACCESS,
6934 &spr_read_generic, &spr_write_generic,
6937 /* XXX : not implemented */
6938 spr_register(env, SPR_MSSSR0, "MSSSR0",
6939 SPR_NOACCESS, SPR_NOACCESS,
6940 &spr_read_generic, &spr_write_generic,
6943 /* XXX : not implemented */
6944 spr_register(env, SPR_7XX_PMC5, "PMC5",
6945 SPR_NOACCESS, SPR_NOACCESS,
6946 &spr_read_generic, &spr_write_generic,
6948 /* XXX : not implemented */
6949 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
6950 &spr_read_ureg, SPR_NOACCESS,
6951 &spr_read_ureg, SPR_NOACCESS,
6953 /* XXX : not implemented */
6954 spr_register(env, SPR_7XX_PMC6, "PMC6",
6955 SPR_NOACCESS, SPR_NOACCESS,
6956 &spr_read_generic, &spr_write_generic,
6958 /* XXX : not implemented */
6959 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
6960 &spr_read_ureg, SPR_NOACCESS,
6961 &spr_read_ureg, SPR_NOACCESS,
6963 /* Memory management */
6965 gen_74xx_soft_tlb(env, 128, 2);
6966 init_excp_7450(env);
6967 env->dcache_line_size = 32;
6968 env->icache_line_size = 32;
6969 /* Allocate hardware IRQ controller */
6970 ppc6xx_irq_init(env_archcpu(env));
6973 POWERPC_FAMILY(7450)(ObjectClass *oc, void *data)
6975 DeviceClass *dc = DEVICE_CLASS(oc);
6976 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6978 dc->desc = "PowerPC 7450 (aka G4)";
6979 pcc->init_proc = init_proc_7450;
6980 pcc->check_pow = check_pow_hid0_74xx;
6981 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6982 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6983 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6985 PPC_CACHE | PPC_CACHE_ICBI |
6986 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6987 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6988 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6989 PPC_MEM_TLBIA | PPC_74xx_TLB |
6990 PPC_SEGMENT | PPC_EXTERN |
6992 pcc->msr_mask = (1ull << MSR_VR) |
7009 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
7010 pcc->excp_model = POWERPC_EXCP_74xx;
7011 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7012 pcc->bfd_mach = bfd_mach_ppc_7400;
7013 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7014 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7015 POWERPC_FLAG_BUS_CLK;
7018 static void init_proc_7445(CPUPPCState *env)
7020 gen_spr_ne_601(env);
7025 /* 74xx specific SPR */
7028 /* XXX : not implemented */
7029 spr_register(env, SPR_LDSTCR, "LDSTCR",
7030 SPR_NOACCESS, SPR_NOACCESS,
7031 &spr_read_generic, &spr_write_generic,
7034 /* XXX : not implemented */
7035 spr_register(env, SPR_ICTRL, "ICTRL",
7036 SPR_NOACCESS, SPR_NOACCESS,
7037 &spr_read_generic, &spr_write_generic,
7040 /* XXX : not implemented */
7041 spr_register(env, SPR_MSSSR0, "MSSSR0",
7042 SPR_NOACCESS, SPR_NOACCESS,
7043 &spr_read_generic, &spr_write_generic,
7046 /* XXX : not implemented */
7047 spr_register(env, SPR_7XX_PMC5, "PMC5",
7048 SPR_NOACCESS, SPR_NOACCESS,
7049 &spr_read_generic, &spr_write_generic,
7051 /* XXX : not implemented */
7052 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
7053 &spr_read_ureg, SPR_NOACCESS,
7054 &spr_read_ureg, SPR_NOACCESS,
7056 /* XXX : not implemented */
7057 spr_register(env, SPR_7XX_PMC6, "PMC6",
7058 SPR_NOACCESS, SPR_NOACCESS,
7059 &spr_read_generic, &spr_write_generic,
7061 /* XXX : not implemented */
7062 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
7063 &spr_read_ureg, SPR_NOACCESS,
7064 &spr_read_ureg, SPR_NOACCESS,
7067 spr_register(env, SPR_SPRG4, "SPRG4",
7068 SPR_NOACCESS, SPR_NOACCESS,
7069 &spr_read_generic, &spr_write_generic,
7071 spr_register(env, SPR_USPRG4, "USPRG4",
7072 &spr_read_ureg, SPR_NOACCESS,
7073 &spr_read_ureg, SPR_NOACCESS,
7075 spr_register(env, SPR_SPRG5, "SPRG5",
7076 SPR_NOACCESS, SPR_NOACCESS,
7077 &spr_read_generic, &spr_write_generic,
7079 spr_register(env, SPR_USPRG5, "USPRG5",
7080 &spr_read_ureg, SPR_NOACCESS,
7081 &spr_read_ureg, SPR_NOACCESS,
7083 spr_register(env, SPR_SPRG6, "SPRG6",
7084 SPR_NOACCESS, SPR_NOACCESS,
7085 &spr_read_generic, &spr_write_generic,
7087 spr_register(env, SPR_USPRG6, "USPRG6",
7088 &spr_read_ureg, SPR_NOACCESS,
7089 &spr_read_ureg, SPR_NOACCESS,
7091 spr_register(env, SPR_SPRG7, "SPRG7",
7092 SPR_NOACCESS, SPR_NOACCESS,
7093 &spr_read_generic, &spr_write_generic,
7095 spr_register(env, SPR_USPRG7, "USPRG7",
7096 &spr_read_ureg, SPR_NOACCESS,
7097 &spr_read_ureg, SPR_NOACCESS,
7099 /* Memory management */
7102 gen_74xx_soft_tlb(env, 128, 2);
7103 init_excp_7450(env);
7104 env->dcache_line_size = 32;
7105 env->icache_line_size = 32;
7106 /* Allocate hardware IRQ controller */
7107 ppc6xx_irq_init(env_archcpu(env));
7110 POWERPC_FAMILY(7445)(ObjectClass *oc, void *data)
7112 DeviceClass *dc = DEVICE_CLASS(oc);
7113 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7115 dc->desc = "PowerPC 7445 (aka G4)";
7116 pcc->init_proc = init_proc_7445;
7117 pcc->check_pow = check_pow_hid0_74xx;
7118 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7119 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7120 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7122 PPC_CACHE | PPC_CACHE_ICBI |
7123 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7124 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7125 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7126 PPC_MEM_TLBIA | PPC_74xx_TLB |
7127 PPC_SEGMENT | PPC_EXTERN |
7129 pcc->msr_mask = (1ull << MSR_VR) |
7146 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
7147 pcc->excp_model = POWERPC_EXCP_74xx;
7148 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7149 pcc->bfd_mach = bfd_mach_ppc_7400;
7150 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7151 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7152 POWERPC_FLAG_BUS_CLK;
7155 static void init_proc_7455(CPUPPCState *env)
7157 gen_spr_ne_601(env);
7162 /* 74xx specific SPR */
7164 /* Level 3 cache control */
7167 /* XXX : not implemented */
7168 spr_register(env, SPR_LDSTCR, "LDSTCR",
7169 SPR_NOACCESS, SPR_NOACCESS,
7170 &spr_read_generic, &spr_write_generic,
7173 /* XXX : not implemented */
7174 spr_register(env, SPR_ICTRL, "ICTRL",
7175 SPR_NOACCESS, SPR_NOACCESS,
7176 &spr_read_generic, &spr_write_generic,
7179 /* XXX : not implemented */
7180 spr_register(env, SPR_MSSSR0, "MSSSR0",
7181 SPR_NOACCESS, SPR_NOACCESS,
7182 &spr_read_generic, &spr_write_generic,
7185 /* XXX : not implemented */
7186 spr_register(env, SPR_7XX_PMC5, "PMC5",
7187 SPR_NOACCESS, SPR_NOACCESS,
7188 &spr_read_generic, &spr_write_generic,
7190 /* XXX : not implemented */
7191 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
7192 &spr_read_ureg, SPR_NOACCESS,
7193 &spr_read_ureg, SPR_NOACCESS,
7195 /* XXX : not implemented */
7196 spr_register(env, SPR_7XX_PMC6, "PMC6",
7197 SPR_NOACCESS, SPR_NOACCESS,
7198 &spr_read_generic, &spr_write_generic,
7200 /* XXX : not implemented */
7201 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
7202 &spr_read_ureg, SPR_NOACCESS,
7203 &spr_read_ureg, SPR_NOACCESS,
7206 spr_register(env, SPR_SPRG4, "SPRG4",
7207 SPR_NOACCESS, SPR_NOACCESS,
7208 &spr_read_generic, &spr_write_generic,
7210 spr_register(env, SPR_USPRG4, "USPRG4",
7211 &spr_read_ureg, SPR_NOACCESS,
7212 &spr_read_ureg, SPR_NOACCESS,
7214 spr_register(env, SPR_SPRG5, "SPRG5",
7215 SPR_NOACCESS, SPR_NOACCESS,
7216 &spr_read_generic, &spr_write_generic,
7218 spr_register(env, SPR_USPRG5, "USPRG5",
7219 &spr_read_ureg, SPR_NOACCESS,
7220 &spr_read_ureg, SPR_NOACCESS,
7222 spr_register(env, SPR_SPRG6, "SPRG6",
7223 SPR_NOACCESS, SPR_NOACCESS,
7224 &spr_read_generic, &spr_write_generic,
7226 spr_register(env, SPR_USPRG6, "USPRG6",
7227 &spr_read_ureg, SPR_NOACCESS,
7228 &spr_read_ureg, SPR_NOACCESS,
7230 spr_register(env, SPR_SPRG7, "SPRG7",
7231 SPR_NOACCESS, SPR_NOACCESS,
7232 &spr_read_generic, &spr_write_generic,
7234 spr_register(env, SPR_USPRG7, "USPRG7",
7235 &spr_read_ureg, SPR_NOACCESS,
7236 &spr_read_ureg, SPR_NOACCESS,
7238 /* Memory management */
7241 gen_74xx_soft_tlb(env, 128, 2);
7242 init_excp_7450(env);
7243 env->dcache_line_size = 32;
7244 env->icache_line_size = 32;
7245 /* Allocate hardware IRQ controller */
7246 ppc6xx_irq_init(env_archcpu(env));
7249 POWERPC_FAMILY(7455)(ObjectClass *oc, void *data)
7251 DeviceClass *dc = DEVICE_CLASS(oc);
7252 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7254 dc->desc = "PowerPC 7455 (aka G4)";
7255 pcc->init_proc = init_proc_7455;
7256 pcc->check_pow = check_pow_hid0_74xx;
7257 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7258 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7259 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7261 PPC_CACHE | PPC_CACHE_ICBI |
7262 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7263 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7264 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7265 PPC_MEM_TLBIA | PPC_74xx_TLB |
7266 PPC_SEGMENT | PPC_EXTERN |
7268 pcc->msr_mask = (1ull << MSR_VR) |
7285 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
7286 pcc->excp_model = POWERPC_EXCP_74xx;
7287 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7288 pcc->bfd_mach = bfd_mach_ppc_7400;
7289 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7290 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7291 POWERPC_FLAG_BUS_CLK;
7294 static void init_proc_7457(CPUPPCState *env)
7296 gen_spr_ne_601(env);
7301 /* 74xx specific SPR */
7303 /* Level 3 cache control */
7306 /* XXX : not implemented */
7307 spr_register(env, SPR_L3ITCR1, "L3ITCR1",
7308 SPR_NOACCESS, SPR_NOACCESS,
7309 &spr_read_generic, &spr_write_generic,
7312 /* XXX : not implemented */
7313 spr_register(env, SPR_L3ITCR2, "L3ITCR2",
7314 SPR_NOACCESS, SPR_NOACCESS,
7315 &spr_read_generic, &spr_write_generic,
7318 /* XXX : not implemented */
7319 spr_register(env, SPR_L3ITCR3, "L3ITCR3",
7320 SPR_NOACCESS, SPR_NOACCESS,
7321 &spr_read_generic, &spr_write_generic,
7324 /* XXX : not implemented */
7325 spr_register(env, SPR_L3OHCR, "L3OHCR",
7326 SPR_NOACCESS, SPR_NOACCESS,
7327 &spr_read_generic, &spr_write_generic,
7330 /* XXX : not implemented */
7331 spr_register(env, SPR_LDSTCR, "LDSTCR",
7332 SPR_NOACCESS, SPR_NOACCESS,
7333 &spr_read_generic, &spr_write_generic,
7336 /* XXX : not implemented */
7337 spr_register(env, SPR_ICTRL, "ICTRL",
7338 SPR_NOACCESS, SPR_NOACCESS,
7339 &spr_read_generic, &spr_write_generic,
7342 /* XXX : not implemented */
7343 spr_register(env, SPR_MSSSR0, "MSSSR0",
7344 SPR_NOACCESS, SPR_NOACCESS,
7345 &spr_read_generic, &spr_write_generic,
7348 /* XXX : not implemented */
7349 spr_register(env, SPR_7XX_PMC5, "PMC5",
7350 SPR_NOACCESS, SPR_NOACCESS,
7351 &spr_read_generic, &spr_write_generic,
7353 /* XXX : not implemented */
7354 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
7355 &spr_read_ureg, SPR_NOACCESS,
7356 &spr_read_ureg, SPR_NOACCESS,
7358 /* XXX : not implemented */
7359 spr_register(env, SPR_7XX_PMC6, "PMC6",
7360 SPR_NOACCESS, SPR_NOACCESS,
7361 &spr_read_generic, &spr_write_generic,
7363 /* XXX : not implemented */
7364 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
7365 &spr_read_ureg, SPR_NOACCESS,
7366 &spr_read_ureg, SPR_NOACCESS,
7369 spr_register(env, SPR_SPRG4, "SPRG4",
7370 SPR_NOACCESS, SPR_NOACCESS,
7371 &spr_read_generic, &spr_write_generic,
7373 spr_register(env, SPR_USPRG4, "USPRG4",
7374 &spr_read_ureg, SPR_NOACCESS,
7375 &spr_read_ureg, SPR_NOACCESS,
7377 spr_register(env, SPR_SPRG5, "SPRG5",
7378 SPR_NOACCESS, SPR_NOACCESS,
7379 &spr_read_generic, &spr_write_generic,
7381 spr_register(env, SPR_USPRG5, "USPRG5",
7382 &spr_read_ureg, SPR_NOACCESS,
7383 &spr_read_ureg, SPR_NOACCESS,
7385 spr_register(env, SPR_SPRG6, "SPRG6",
7386 SPR_NOACCESS, SPR_NOACCESS,
7387 &spr_read_generic, &spr_write_generic,
7389 spr_register(env, SPR_USPRG6, "USPRG6",
7390 &spr_read_ureg, SPR_NOACCESS,
7391 &spr_read_ureg, SPR_NOACCESS,
7393 spr_register(env, SPR_SPRG7, "SPRG7",
7394 SPR_NOACCESS, SPR_NOACCESS,
7395 &spr_read_generic, &spr_write_generic,
7397 spr_register(env, SPR_USPRG7, "USPRG7",
7398 &spr_read_ureg, SPR_NOACCESS,
7399 &spr_read_ureg, SPR_NOACCESS,
7401 /* Memory management */
7404 gen_74xx_soft_tlb(env, 128, 2);
7405 init_excp_7450(env);
7406 env->dcache_line_size = 32;
7407 env->icache_line_size = 32;
7408 /* Allocate hardware IRQ controller */
7409 ppc6xx_irq_init(env_archcpu(env));
7412 POWERPC_FAMILY(7457)(ObjectClass *oc, void *data)
7414 DeviceClass *dc = DEVICE_CLASS(oc);
7415 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7417 dc->desc = "PowerPC 7457 (aka G4)";
7418 pcc->init_proc = init_proc_7457;
7419 pcc->check_pow = check_pow_hid0_74xx;
7420 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7421 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7422 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7424 PPC_CACHE | PPC_CACHE_ICBI |
7425 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7426 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7427 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7428 PPC_MEM_TLBIA | PPC_74xx_TLB |
7429 PPC_SEGMENT | PPC_EXTERN |
7431 pcc->msr_mask = (1ull << MSR_VR) |
7448 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
7449 pcc->excp_model = POWERPC_EXCP_74xx;
7450 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7451 pcc->bfd_mach = bfd_mach_ppc_7400;
7452 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7453 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7454 POWERPC_FLAG_BUS_CLK;
7457 static void init_proc_e600(CPUPPCState *env)
7459 gen_spr_ne_601(env);
7464 /* 74xx specific SPR */
7466 /* XXX : not implemented */
7467 spr_register(env, SPR_UBAMR, "UBAMR",
7468 &spr_read_ureg, SPR_NOACCESS,
7469 &spr_read_ureg, SPR_NOACCESS,
7471 /* XXX : not implemented */
7472 spr_register(env, SPR_LDSTCR, "LDSTCR",
7473 SPR_NOACCESS, SPR_NOACCESS,
7474 &spr_read_generic, &spr_write_generic,
7476 /* XXX : not implemented */
7477 spr_register(env, SPR_ICTRL, "ICTRL",
7478 SPR_NOACCESS, SPR_NOACCESS,
7479 &spr_read_generic, &spr_write_generic,
7481 /* XXX : not implemented */
7482 spr_register(env, SPR_MSSSR0, "MSSSR0",
7483 SPR_NOACCESS, SPR_NOACCESS,
7484 &spr_read_generic, &spr_write_generic,
7486 /* XXX : not implemented */
7487 spr_register(env, SPR_7XX_PMC5, "PMC5",
7488 SPR_NOACCESS, SPR_NOACCESS,
7489 &spr_read_generic, &spr_write_generic,
7491 /* XXX : not implemented */
7492 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
7493 &spr_read_ureg, SPR_NOACCESS,
7494 &spr_read_ureg, SPR_NOACCESS,
7496 /* XXX : not implemented */
7497 spr_register(env, SPR_7XX_PMC6, "PMC6",
7498 SPR_NOACCESS, SPR_NOACCESS,
7499 &spr_read_generic, &spr_write_generic,
7501 /* XXX : not implemented */
7502 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
7503 &spr_read_ureg, SPR_NOACCESS,
7504 &spr_read_ureg, SPR_NOACCESS,
7507 spr_register(env, SPR_SPRG4, "SPRG4",
7508 SPR_NOACCESS, SPR_NOACCESS,
7509 &spr_read_generic, &spr_write_generic,
7511 spr_register(env, SPR_USPRG4, "USPRG4",
7512 &spr_read_ureg, SPR_NOACCESS,
7513 &spr_read_ureg, SPR_NOACCESS,
7515 spr_register(env, SPR_SPRG5, "SPRG5",
7516 SPR_NOACCESS, SPR_NOACCESS,
7517 &spr_read_generic, &spr_write_generic,
7519 spr_register(env, SPR_USPRG5, "USPRG5",
7520 &spr_read_ureg, SPR_NOACCESS,
7521 &spr_read_ureg, SPR_NOACCESS,
7523 spr_register(env, SPR_SPRG6, "SPRG6",
7524 SPR_NOACCESS, SPR_NOACCESS,
7525 &spr_read_generic, &spr_write_generic,
7527 spr_register(env, SPR_USPRG6, "USPRG6",
7528 &spr_read_ureg, SPR_NOACCESS,
7529 &spr_read_ureg, SPR_NOACCESS,
7531 spr_register(env, SPR_SPRG7, "SPRG7",
7532 SPR_NOACCESS, SPR_NOACCESS,
7533 &spr_read_generic, &spr_write_generic,
7535 spr_register(env, SPR_USPRG7, "USPRG7",
7536 &spr_read_ureg, SPR_NOACCESS,
7537 &spr_read_ureg, SPR_NOACCESS,
7539 /* Memory management */
7542 gen_74xx_soft_tlb(env, 128, 2);
7543 init_excp_7450(env);
7544 env->dcache_line_size = 32;
7545 env->icache_line_size = 32;
7546 /* Allocate hardware IRQ controller */
7547 ppc6xx_irq_init(env_archcpu(env));
7550 POWERPC_FAMILY(e600)(ObjectClass *oc, void *data)
7552 DeviceClass *dc = DEVICE_CLASS(oc);
7553 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7555 dc->desc = "PowerPC e600";
7556 pcc->init_proc = init_proc_e600;
7557 pcc->check_pow = check_pow_hid0_74xx;
7558 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7559 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7560 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7562 PPC_CACHE | PPC_CACHE_ICBI |
7563 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7564 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7565 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7566 PPC_MEM_TLBIA | PPC_74xx_TLB |
7567 PPC_SEGMENT | PPC_EXTERN |
7569 pcc->insns_flags2 = PPC_NONE;
7570 pcc->msr_mask = (1ull << MSR_VR) |
7587 pcc->mmu_model = POWERPC_MMU_32B;
7588 #if defined(CONFIG_SOFTMMU)
7589 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
7591 pcc->excp_model = POWERPC_EXCP_74xx;
7592 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7593 pcc->bfd_mach = bfd_mach_ppc_7400;
7594 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7595 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7596 POWERPC_FLAG_BUS_CLK;
7599 #if defined(TARGET_PPC64)
7600 #if defined(CONFIG_USER_ONLY)
7601 #define POWERPC970_HID5_INIT 0x00000080
7603 #define POWERPC970_HID5_INIT 0x00000000
7606 static void gen_fscr_facility_check(DisasContext *ctx, int facility_sprn,
7607 int bit, int sprn, int cause)
7609 TCGv_i32 t1 = tcg_const_i32(bit);
7610 TCGv_i32 t2 = tcg_const_i32(sprn);
7611 TCGv_i32 t3 = tcg_const_i32(cause);
7613 gen_helper_fscr_facility_check(cpu_env, t1, t2, t3);
7615 tcg_temp_free_i32(t3);
7616 tcg_temp_free_i32(t2);
7617 tcg_temp_free_i32(t1);
7620 static void gen_msr_facility_check(DisasContext *ctx, int facility_sprn,
7621 int bit, int sprn, int cause)
7623 TCGv_i32 t1 = tcg_const_i32(bit);
7624 TCGv_i32 t2 = tcg_const_i32(sprn);
7625 TCGv_i32 t3 = tcg_const_i32(cause);
7627 gen_helper_msr_facility_check(cpu_env, t1, t2, t3);
7629 tcg_temp_free_i32(t3);
7630 tcg_temp_free_i32(t2);
7631 tcg_temp_free_i32(t1);
7634 static void spr_read_prev_upper32(DisasContext *ctx, int gprn, int sprn)
7636 TCGv spr_up = tcg_temp_new();
7637 TCGv spr = tcg_temp_new();
7639 gen_load_spr(spr, sprn - 1);
7640 tcg_gen_shri_tl(spr_up, spr, 32);
7641 tcg_gen_ext32u_tl(cpu_gpr[gprn], spr_up);
7644 tcg_temp_free(spr_up);
7647 static void spr_write_prev_upper32(DisasContext *ctx, int sprn, int gprn)
7649 TCGv spr = tcg_temp_new();
7651 gen_load_spr(spr, sprn - 1);
7652 tcg_gen_deposit_tl(spr, spr, cpu_gpr[gprn], 32, 32);
7653 gen_store_spr(sprn - 1, spr);
7658 static int check_pow_970(CPUPPCState *env)
7660 if (env->spr[SPR_HID0] & (HID0_DEEPNAP | HID0_DOZE | HID0_NAP)) {
7667 static void gen_spr_970_hid(CPUPPCState *env)
7669 /* Hardware implementation registers */
7670 /* XXX : not implemented */
7671 spr_register(env, SPR_HID0, "HID0",
7672 SPR_NOACCESS, SPR_NOACCESS,
7673 &spr_read_generic, &spr_write_clear,
7675 spr_register(env, SPR_HID1, "HID1",
7676 SPR_NOACCESS, SPR_NOACCESS,
7677 &spr_read_generic, &spr_write_generic,
7679 spr_register(env, SPR_970_HID5, "HID5",
7680 SPR_NOACCESS, SPR_NOACCESS,
7681 &spr_read_generic, &spr_write_generic,
7682 POWERPC970_HID5_INIT);
7685 static void gen_spr_970_hior(CPUPPCState *env)
7687 spr_register(env, SPR_HIOR, "SPR_HIOR",
7688 SPR_NOACCESS, SPR_NOACCESS,
7689 &spr_read_hior, &spr_write_hior,
7693 static void gen_spr_book3s_ctrl(CPUPPCState *env)
7695 spr_register(env, SPR_CTRL, "SPR_CTRL",
7696 SPR_NOACCESS, SPR_NOACCESS,
7697 SPR_NOACCESS, &spr_write_generic,
7699 spr_register(env, SPR_UCTRL, "SPR_UCTRL",
7700 &spr_read_ureg, SPR_NOACCESS,
7701 &spr_read_ureg, SPR_NOACCESS,
7705 static void gen_spr_book3s_altivec(CPUPPCState *env)
7707 if (!(env->insns_flags & PPC_ALTIVEC)) {
7711 spr_register_kvm(env, SPR_VRSAVE, "VRSAVE",
7712 &spr_read_generic, &spr_write_generic,
7713 &spr_read_generic, &spr_write_generic,
7714 KVM_REG_PPC_VRSAVE, 0x00000000);
7717 * Can't find information on what this should be on reset. This
7718 * value is the one used by 74xx processors.
7720 vscr_init(env, 0x00010000);
7723 static void gen_spr_book3s_dbg(CPUPPCState *env)
7726 * TODO: different specs define different scopes for these,
7727 * will have to address this:
7728 * 970: super/write and super/read
7729 * powerisa 2.03..2.04: hypv/write and super/read.
7730 * powerisa 2.05 and newer: hypv/write and hypv/read.
7732 spr_register_kvm(env, SPR_DABR, "DABR",
7733 SPR_NOACCESS, SPR_NOACCESS,
7734 &spr_read_generic, &spr_write_generic,
7735 KVM_REG_PPC_DABR, 0x00000000);
7736 spr_register_kvm(env, SPR_DABRX, "DABRX",
7737 SPR_NOACCESS, SPR_NOACCESS,
7738 &spr_read_generic, &spr_write_generic,
7739 KVM_REG_PPC_DABRX, 0x00000000);
7742 static void gen_spr_book3s_207_dbg(CPUPPCState *env)
7744 spr_register_kvm_hv(env, SPR_DAWR0, "DAWR0",
7745 SPR_NOACCESS, SPR_NOACCESS,
7746 SPR_NOACCESS, SPR_NOACCESS,
7747 &spr_read_generic, &spr_write_generic,
7748 KVM_REG_PPC_DAWR, 0x00000000);
7749 spr_register_kvm_hv(env, SPR_DAWRX0, "DAWRX0",
7750 SPR_NOACCESS, SPR_NOACCESS,
7751 SPR_NOACCESS, SPR_NOACCESS,
7752 &spr_read_generic, &spr_write_generic,
7753 KVM_REG_PPC_DAWRX, 0x00000000);
7754 spr_register_kvm_hv(env, SPR_CIABR, "CIABR",
7755 SPR_NOACCESS, SPR_NOACCESS,
7756 SPR_NOACCESS, SPR_NOACCESS,
7757 &spr_read_generic, &spr_write_generic,
7758 KVM_REG_PPC_CIABR, 0x00000000);
7761 static void gen_spr_970_dbg(CPUPPCState *env)
7764 spr_register(env, SPR_IABR, "IABR",
7765 SPR_NOACCESS, SPR_NOACCESS,
7766 &spr_read_generic, &spr_write_generic,
7770 static void gen_spr_book3s_pmu_sup(CPUPPCState *env)
7772 spr_register_kvm(env, SPR_POWER_MMCR0, "MMCR0",
7773 SPR_NOACCESS, SPR_NOACCESS,
7774 &spr_read_generic, &spr_write_generic,
7775 KVM_REG_PPC_MMCR0, 0x00000000);
7776 spr_register_kvm(env, SPR_POWER_MMCR1, "MMCR1",
7777 SPR_NOACCESS, SPR_NOACCESS,
7778 &spr_read_generic, &spr_write_generic,
7779 KVM_REG_PPC_MMCR1, 0x00000000);
7780 spr_register_kvm(env, SPR_POWER_MMCRA, "MMCRA",
7781 SPR_NOACCESS, SPR_NOACCESS,
7782 &spr_read_generic, &spr_write_generic,
7783 KVM_REG_PPC_MMCRA, 0x00000000);
7784 spr_register_kvm(env, SPR_POWER_PMC1, "PMC1",
7785 SPR_NOACCESS, SPR_NOACCESS,
7786 &spr_read_generic, &spr_write_generic,
7787 KVM_REG_PPC_PMC1, 0x00000000);
7788 spr_register_kvm(env, SPR_POWER_PMC2, "PMC2",
7789 SPR_NOACCESS, SPR_NOACCESS,
7790 &spr_read_generic, &spr_write_generic,
7791 KVM_REG_PPC_PMC2, 0x00000000);
7792 spr_register_kvm(env, SPR_POWER_PMC3, "PMC3",
7793 SPR_NOACCESS, SPR_NOACCESS,
7794 &spr_read_generic, &spr_write_generic,
7795 KVM_REG_PPC_PMC3, 0x00000000);
7796 spr_register_kvm(env, SPR_POWER_PMC4, "PMC4",
7797 SPR_NOACCESS, SPR_NOACCESS,
7798 &spr_read_generic, &spr_write_generic,
7799 KVM_REG_PPC_PMC4, 0x00000000);
7800 spr_register_kvm(env, SPR_POWER_PMC5, "PMC5",
7801 SPR_NOACCESS, SPR_NOACCESS,
7802 &spr_read_generic, &spr_write_generic,
7803 KVM_REG_PPC_PMC5, 0x00000000);
7804 spr_register_kvm(env, SPR_POWER_PMC6, "PMC6",
7805 SPR_NOACCESS, SPR_NOACCESS,
7806 &spr_read_generic, &spr_write_generic,
7807 KVM_REG_PPC_PMC6, 0x00000000);
7808 spr_register_kvm(env, SPR_POWER_SIAR, "SIAR",
7809 SPR_NOACCESS, SPR_NOACCESS,
7810 &spr_read_generic, &spr_write_generic,
7811 KVM_REG_PPC_SIAR, 0x00000000);
7812 spr_register_kvm(env, SPR_POWER_SDAR, "SDAR",
7813 SPR_NOACCESS, SPR_NOACCESS,
7814 &spr_read_generic, &spr_write_generic,
7815 KVM_REG_PPC_SDAR, 0x00000000);
7818 static void gen_spr_book3s_pmu_user(CPUPPCState *env)
7820 spr_register(env, SPR_POWER_UMMCR0, "UMMCR0",
7821 &spr_read_ureg, SPR_NOACCESS,
7822 &spr_read_ureg, &spr_write_ureg,
7824 spr_register(env, SPR_POWER_UMMCR1, "UMMCR1",
7825 &spr_read_ureg, SPR_NOACCESS,
7826 &spr_read_ureg, &spr_write_ureg,
7828 spr_register(env, SPR_POWER_UMMCRA, "UMMCRA",
7829 &spr_read_ureg, SPR_NOACCESS,
7830 &spr_read_ureg, &spr_write_ureg,
7832 spr_register(env, SPR_POWER_UPMC1, "UPMC1",
7833 &spr_read_ureg, SPR_NOACCESS,
7834 &spr_read_ureg, &spr_write_ureg,
7836 spr_register(env, SPR_POWER_UPMC2, "UPMC2",
7837 &spr_read_ureg, SPR_NOACCESS,
7838 &spr_read_ureg, &spr_write_ureg,
7840 spr_register(env, SPR_POWER_UPMC3, "UPMC3",
7841 &spr_read_ureg, SPR_NOACCESS,
7842 &spr_read_ureg, &spr_write_ureg,
7844 spr_register(env, SPR_POWER_UPMC4, "UPMC4",
7845 &spr_read_ureg, SPR_NOACCESS,
7846 &spr_read_ureg, &spr_write_ureg,
7848 spr_register(env, SPR_POWER_UPMC5, "UPMC5",
7849 &spr_read_ureg, SPR_NOACCESS,
7850 &spr_read_ureg, &spr_write_ureg,
7852 spr_register(env, SPR_POWER_UPMC6, "UPMC6",
7853 &spr_read_ureg, SPR_NOACCESS,
7854 &spr_read_ureg, &spr_write_ureg,
7856 spr_register(env, SPR_POWER_USIAR, "USIAR",
7857 &spr_read_ureg, SPR_NOACCESS,
7858 &spr_read_ureg, &spr_write_ureg,
7860 spr_register(env, SPR_POWER_USDAR, "USDAR",
7861 &spr_read_ureg, SPR_NOACCESS,
7862 &spr_read_ureg, &spr_write_ureg,
7866 static void gen_spr_970_pmu_sup(CPUPPCState *env)
7868 spr_register_kvm(env, SPR_970_PMC7, "PMC7",
7869 SPR_NOACCESS, SPR_NOACCESS,
7870 &spr_read_generic, &spr_write_generic,
7871 KVM_REG_PPC_PMC7, 0x00000000);
7872 spr_register_kvm(env, SPR_970_PMC8, "PMC8",
7873 SPR_NOACCESS, SPR_NOACCESS,
7874 &spr_read_generic, &spr_write_generic,
7875 KVM_REG_PPC_PMC8, 0x00000000);
7878 static void gen_spr_970_pmu_user(CPUPPCState *env)
7880 spr_register(env, SPR_970_UPMC7, "UPMC7",
7881 &spr_read_ureg, SPR_NOACCESS,
7882 &spr_read_ureg, &spr_write_ureg,
7884 spr_register(env, SPR_970_UPMC8, "UPMC8",
7885 &spr_read_ureg, SPR_NOACCESS,
7886 &spr_read_ureg, &spr_write_ureg,
7890 static void gen_spr_power8_pmu_sup(CPUPPCState *env)
7892 spr_register_kvm(env, SPR_POWER_MMCR2, "MMCR2",
7893 SPR_NOACCESS, SPR_NOACCESS,
7894 &spr_read_generic, &spr_write_generic,
7895 KVM_REG_PPC_MMCR2, 0x00000000);
7896 spr_register_kvm(env, SPR_POWER_MMCRS, "MMCRS",
7897 SPR_NOACCESS, SPR_NOACCESS,
7898 &spr_read_generic, &spr_write_generic,
7899 KVM_REG_PPC_MMCRS, 0x00000000);
7900 spr_register_kvm(env, SPR_POWER_SIER, "SIER",
7901 SPR_NOACCESS, SPR_NOACCESS,
7902 &spr_read_generic, &spr_write_generic,
7903 KVM_REG_PPC_SIER, 0x00000000);
7904 spr_register_kvm(env, SPR_POWER_SPMC1, "SPMC1",
7905 SPR_NOACCESS, SPR_NOACCESS,
7906 &spr_read_generic, &spr_write_generic,
7907 KVM_REG_PPC_SPMC1, 0x00000000);
7908 spr_register_kvm(env, SPR_POWER_SPMC2, "SPMC2",
7909 SPR_NOACCESS, SPR_NOACCESS,
7910 &spr_read_generic, &spr_write_generic,
7911 KVM_REG_PPC_SPMC2, 0x00000000);
7912 spr_register_kvm(env, SPR_TACR, "TACR",
7913 SPR_NOACCESS, SPR_NOACCESS,
7914 &spr_read_generic, &spr_write_generic,
7915 KVM_REG_PPC_TACR, 0x00000000);
7916 spr_register_kvm(env, SPR_TCSCR, "TCSCR",
7917 SPR_NOACCESS, SPR_NOACCESS,
7918 &spr_read_generic, &spr_write_generic,
7919 KVM_REG_PPC_TCSCR, 0x00000000);
7920 spr_register_kvm(env, SPR_CSIGR, "CSIGR",
7921 SPR_NOACCESS, SPR_NOACCESS,
7922 &spr_read_generic, &spr_write_generic,
7923 KVM_REG_PPC_CSIGR, 0x00000000);
7926 static void gen_spr_power8_pmu_user(CPUPPCState *env)
7928 spr_register(env, SPR_POWER_UMMCR2, "UMMCR2",
7929 &spr_read_ureg, SPR_NOACCESS,
7930 &spr_read_ureg, &spr_write_ureg,
7932 spr_register(env, SPR_POWER_USIER, "USIER",
7933 &spr_read_generic, SPR_NOACCESS,
7934 &spr_read_generic, &spr_write_generic,
7938 static void gen_spr_power5p_ear(CPUPPCState *env)
7940 /* External access control */
7941 spr_register(env, SPR_EAR, "EAR",
7942 SPR_NOACCESS, SPR_NOACCESS,
7943 &spr_read_generic, &spr_write_generic,
7947 static void gen_spr_power5p_tb(CPUPPCState *env)
7949 /* TBU40 (High 40 bits of the Timebase register */
7950 spr_register_hv(env, SPR_TBU40, "TBU40",
7951 SPR_NOACCESS, SPR_NOACCESS,
7952 SPR_NOACCESS, SPR_NOACCESS,
7953 SPR_NOACCESS, &spr_write_tbu40,
7957 #if !defined(CONFIG_USER_ONLY)
7958 static void spr_write_hmer(DisasContext *ctx, int sprn, int gprn)
7960 TCGv hmer = tcg_temp_new();
7962 gen_load_spr(hmer, sprn);
7963 tcg_gen_and_tl(hmer, cpu_gpr[gprn], hmer);
7964 gen_store_spr(sprn, hmer);
7965 spr_store_dump_spr(sprn);
7966 tcg_temp_free(hmer);
7969 static void spr_write_lpcr(DisasContext *ctx, int sprn, int gprn)
7971 gen_helper_store_lpcr(cpu_env, cpu_gpr[gprn]);
7973 #endif /* !defined(CONFIG_USER_ONLY) */
7975 static void gen_spr_970_lpar(CPUPPCState *env)
7977 #if !defined(CONFIG_USER_ONLY)
7979 * PPC970: HID4 covers things later controlled by the LPCR and
7980 * RMOR in later CPUs, but with a different encoding. We only
7981 * support the 970 in "Apple mode" which has all hypervisor
7982 * facilities disabled by strapping, so we can basically just
7985 spr_register(env, SPR_970_HID4, "HID4",
7986 SPR_NOACCESS, SPR_NOACCESS,
7987 &spr_read_generic, &spr_write_generic,
7992 static void gen_spr_power5p_lpar(CPUPPCState *env)
7994 #if !defined(CONFIG_USER_ONLY)
7995 /* Logical partitionning */
7996 spr_register_kvm_hv(env, SPR_LPCR, "LPCR",
7997 SPR_NOACCESS, SPR_NOACCESS,
7998 SPR_NOACCESS, SPR_NOACCESS,
7999 &spr_read_generic, &spr_write_lpcr,
8000 KVM_REG_PPC_LPCR, LPCR_LPES0 | LPCR_LPES1);
8001 spr_register_hv(env, SPR_HDEC, "HDEC",
8002 SPR_NOACCESS, SPR_NOACCESS,
8003 SPR_NOACCESS, SPR_NOACCESS,
8004 &spr_read_hdecr, &spr_write_hdecr, 0);
8008 static void gen_spr_book3s_ids(CPUPPCState *env)
8010 /* FIXME: Will need to deal with thread vs core only SPRs */
8012 /* Processor identification */
8013 spr_register_hv(env, SPR_PIR, "PIR",
8014 SPR_NOACCESS, SPR_NOACCESS,
8015 &spr_read_generic, SPR_NOACCESS,
8016 &spr_read_generic, NULL,
8018 spr_register_hv(env, SPR_HID0, "HID0",
8019 SPR_NOACCESS, SPR_NOACCESS,
8020 SPR_NOACCESS, SPR_NOACCESS,
8021 &spr_read_generic, &spr_write_generic,
8023 spr_register_hv(env, SPR_TSCR, "TSCR",
8024 SPR_NOACCESS, SPR_NOACCESS,
8025 SPR_NOACCESS, SPR_NOACCESS,
8026 &spr_read_generic, &spr_write_generic,
8028 spr_register_hv(env, SPR_HMER, "HMER",
8029 SPR_NOACCESS, SPR_NOACCESS,
8030 SPR_NOACCESS, SPR_NOACCESS,
8031 &spr_read_generic, &spr_write_hmer,
8033 spr_register_hv(env, SPR_HMEER, "HMEER",
8034 SPR_NOACCESS, SPR_NOACCESS,
8035 SPR_NOACCESS, SPR_NOACCESS,
8036 &spr_read_generic, &spr_write_generic,
8038 spr_register_hv(env, SPR_TFMR, "TFMR",
8039 SPR_NOACCESS, SPR_NOACCESS,
8040 SPR_NOACCESS, SPR_NOACCESS,
8041 &spr_read_generic, &spr_write_generic,
8043 spr_register_hv(env, SPR_LPIDR, "LPIDR",
8044 SPR_NOACCESS, SPR_NOACCESS,
8045 SPR_NOACCESS, SPR_NOACCESS,
8046 &spr_read_generic, &spr_write_lpidr,
8048 spr_register_hv(env, SPR_HFSCR, "HFSCR",
8049 SPR_NOACCESS, SPR_NOACCESS,
8050 SPR_NOACCESS, SPR_NOACCESS,
8051 &spr_read_generic, &spr_write_generic,
8053 spr_register_hv(env, SPR_MMCRC, "MMCRC",
8054 SPR_NOACCESS, SPR_NOACCESS,
8055 SPR_NOACCESS, SPR_NOACCESS,
8056 &spr_read_generic, &spr_write_generic,
8058 spr_register_hv(env, SPR_MMCRH, "MMCRH",
8059 SPR_NOACCESS, SPR_NOACCESS,
8060 SPR_NOACCESS, SPR_NOACCESS,
8061 &spr_read_generic, &spr_write_generic,
8063 spr_register_hv(env, SPR_HSPRG0, "HSPRG0",
8064 SPR_NOACCESS, SPR_NOACCESS,
8065 SPR_NOACCESS, SPR_NOACCESS,
8066 &spr_read_generic, &spr_write_generic,
8068 spr_register_hv(env, SPR_HSPRG1, "HSPRG1",
8069 SPR_NOACCESS, SPR_NOACCESS,
8070 SPR_NOACCESS, SPR_NOACCESS,
8071 &spr_read_generic, &spr_write_generic,
8073 spr_register_hv(env, SPR_HSRR0, "HSRR0",
8074 SPR_NOACCESS, SPR_NOACCESS,
8075 SPR_NOACCESS, SPR_NOACCESS,
8076 &spr_read_generic, &spr_write_generic,
8078 spr_register_hv(env, SPR_HSRR1, "HSRR1",
8079 SPR_NOACCESS, SPR_NOACCESS,
8080 SPR_NOACCESS, SPR_NOACCESS,
8081 &spr_read_generic, &spr_write_generic,
8083 spr_register_hv(env, SPR_HDAR, "HDAR",
8084 SPR_NOACCESS, SPR_NOACCESS,
8085 SPR_NOACCESS, SPR_NOACCESS,
8086 &spr_read_generic, &spr_write_generic,
8088 spr_register_hv(env, SPR_HDSISR, "HDSISR",
8089 SPR_NOACCESS, SPR_NOACCESS,
8090 SPR_NOACCESS, SPR_NOACCESS,
8091 &spr_read_generic, &spr_write_generic,
8093 spr_register_hv(env, SPR_HRMOR, "HRMOR",
8094 SPR_NOACCESS, SPR_NOACCESS,
8095 SPR_NOACCESS, SPR_NOACCESS,
8096 &spr_read_generic, &spr_write_generic,
8100 static void gen_spr_rmor(CPUPPCState *env)
8102 spr_register_hv(env, SPR_RMOR, "RMOR",
8103 SPR_NOACCESS, SPR_NOACCESS,
8104 SPR_NOACCESS, SPR_NOACCESS,
8105 &spr_read_generic, &spr_write_generic,
8109 static void gen_spr_power8_ids(CPUPPCState *env)
8111 /* Thread identification */
8112 spr_register(env, SPR_TIR, "TIR",
8113 SPR_NOACCESS, SPR_NOACCESS,
8114 &spr_read_generic, SPR_NOACCESS,
8118 static void gen_spr_book3s_purr(CPUPPCState *env)
8120 #if !defined(CONFIG_USER_ONLY)
8121 /* PURR & SPURR: Hack - treat these as aliases for the TB for now */
8122 spr_register_kvm_hv(env, SPR_PURR, "PURR",
8123 &spr_read_purr, SPR_NOACCESS,
8124 &spr_read_purr, SPR_NOACCESS,
8125 &spr_read_purr, &spr_write_purr,
8126 KVM_REG_PPC_PURR, 0x00000000);
8127 spr_register_kvm_hv(env, SPR_SPURR, "SPURR",
8128 &spr_read_purr, SPR_NOACCESS,
8129 &spr_read_purr, SPR_NOACCESS,
8130 &spr_read_purr, &spr_write_purr,
8131 KVM_REG_PPC_SPURR, 0x00000000);
8135 static void gen_spr_power6_dbg(CPUPPCState *env)
8137 #if !defined(CONFIG_USER_ONLY)
8138 spr_register(env, SPR_CFAR, "SPR_CFAR",
8139 SPR_NOACCESS, SPR_NOACCESS,
8140 &spr_read_cfar, &spr_write_cfar,
8145 static void gen_spr_power5p_common(CPUPPCState *env)
8147 spr_register_kvm(env, SPR_PPR, "PPR",
8148 &spr_read_generic, &spr_write_generic,
8149 &spr_read_generic, &spr_write_generic,
8150 KVM_REG_PPC_PPR, 0x00000000);
8153 static void gen_spr_power6_common(CPUPPCState *env)
8155 #if !defined(CONFIG_USER_ONLY)
8156 spr_register_kvm(env, SPR_DSCR, "SPR_DSCR",
8157 SPR_NOACCESS, SPR_NOACCESS,
8158 &spr_read_generic, &spr_write_generic,
8159 KVM_REG_PPC_DSCR, 0x00000000);
8162 * Register PCR to report POWERPC_EXCP_PRIV_REG instead of
8163 * POWERPC_EXCP_INVAL_SPR in userspace. Permit hypervisor access.
8165 spr_register_hv(env, SPR_PCR, "PCR",
8166 SPR_NOACCESS, SPR_NOACCESS,
8167 SPR_NOACCESS, SPR_NOACCESS,
8168 &spr_read_generic, &spr_write_pcr,
8172 static void spr_read_tar(DisasContext *ctx, int gprn, int sprn)
8174 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_TAR, sprn, FSCR_IC_TAR);
8175 spr_read_generic(ctx, gprn, sprn);
8178 static void spr_write_tar(DisasContext *ctx, int sprn, int gprn)
8180 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_TAR, sprn, FSCR_IC_TAR);
8181 spr_write_generic(ctx, sprn, gprn);
8184 static void gen_spr_power8_tce_address_control(CPUPPCState *env)
8186 spr_register_kvm(env, SPR_TAR, "TAR",
8187 &spr_read_tar, &spr_write_tar,
8188 &spr_read_generic, &spr_write_generic,
8189 KVM_REG_PPC_TAR, 0x00000000);
8192 static void spr_read_tm(DisasContext *ctx, int gprn, int sprn)
8194 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8195 spr_read_generic(ctx, gprn, sprn);
8198 static void spr_write_tm(DisasContext *ctx, int sprn, int gprn)
8200 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8201 spr_write_generic(ctx, sprn, gprn);
8204 static void spr_read_tm_upper32(DisasContext *ctx, int gprn, int sprn)
8206 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8207 spr_read_prev_upper32(ctx, gprn, sprn);
8210 static void spr_write_tm_upper32(DisasContext *ctx, int sprn, int gprn)
8212 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8213 spr_write_prev_upper32(ctx, sprn, gprn);
8216 static void gen_spr_power8_tm(CPUPPCState *env)
8218 spr_register_kvm(env, SPR_TFHAR, "TFHAR",
8219 &spr_read_tm, &spr_write_tm,
8220 &spr_read_tm, &spr_write_tm,
8221 KVM_REG_PPC_TFHAR, 0x00000000);
8222 spr_register_kvm(env, SPR_TFIAR, "TFIAR",
8223 &spr_read_tm, &spr_write_tm,
8224 &spr_read_tm, &spr_write_tm,
8225 KVM_REG_PPC_TFIAR, 0x00000000);
8226 spr_register_kvm(env, SPR_TEXASR, "TEXASR",
8227 &spr_read_tm, &spr_write_tm,
8228 &spr_read_tm, &spr_write_tm,
8229 KVM_REG_PPC_TEXASR, 0x00000000);
8230 spr_register(env, SPR_TEXASRU, "TEXASRU",
8231 &spr_read_tm_upper32, &spr_write_tm_upper32,
8232 &spr_read_tm_upper32, &spr_write_tm_upper32,
8236 static void spr_read_ebb(DisasContext *ctx, int gprn, int sprn)
8238 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8239 spr_read_generic(ctx, gprn, sprn);
8242 static void spr_write_ebb(DisasContext *ctx, int sprn, int gprn)
8244 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8245 spr_write_generic(ctx, sprn, gprn);
8248 static void spr_read_ebb_upper32(DisasContext *ctx, int gprn, int sprn)
8250 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8251 spr_read_prev_upper32(ctx, gprn, sprn);
8254 static void spr_write_ebb_upper32(DisasContext *ctx, int sprn, int gprn)
8256 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8257 spr_write_prev_upper32(ctx, sprn, gprn);
8260 static void gen_spr_power8_ebb(CPUPPCState *env)
8262 spr_register(env, SPR_BESCRS, "BESCRS",
8263 &spr_read_ebb, &spr_write_ebb,
8264 &spr_read_generic, &spr_write_generic,
8266 spr_register(env, SPR_BESCRSU, "BESCRSU",
8267 &spr_read_ebb_upper32, &spr_write_ebb_upper32,
8268 &spr_read_prev_upper32, &spr_write_prev_upper32,
8270 spr_register(env, SPR_BESCRR, "BESCRR",
8271 &spr_read_ebb, &spr_write_ebb,
8272 &spr_read_generic, &spr_write_generic,
8274 spr_register(env, SPR_BESCRRU, "BESCRRU",
8275 &spr_read_ebb_upper32, &spr_write_ebb_upper32,
8276 &spr_read_prev_upper32, &spr_write_prev_upper32,
8278 spr_register_kvm(env, SPR_EBBHR, "EBBHR",
8279 &spr_read_ebb, &spr_write_ebb,
8280 &spr_read_generic, &spr_write_generic,
8281 KVM_REG_PPC_EBBHR, 0x00000000);
8282 spr_register_kvm(env, SPR_EBBRR, "EBBRR",
8283 &spr_read_ebb, &spr_write_ebb,
8284 &spr_read_generic, &spr_write_generic,
8285 KVM_REG_PPC_EBBRR, 0x00000000);
8286 spr_register_kvm(env, SPR_BESCR, "BESCR",
8287 &spr_read_ebb, &spr_write_ebb,
8288 &spr_read_generic, &spr_write_generic,
8289 KVM_REG_PPC_BESCR, 0x00000000);
8292 /* Virtual Time Base */
8293 static void gen_spr_vtb(CPUPPCState *env)
8295 spr_register_kvm_hv(env, SPR_VTB, "VTB",
8296 SPR_NOACCESS, SPR_NOACCESS,
8297 &spr_read_vtb, SPR_NOACCESS,
8298 &spr_read_vtb, &spr_write_vtb,
8299 KVM_REG_PPC_VTB, 0x00000000);
8302 static void gen_spr_power8_fscr(CPUPPCState *env)
8304 #if defined(CONFIG_USER_ONLY)
8305 target_ulong initval = 1ULL << FSCR_TAR;
8307 target_ulong initval = 0;
8309 spr_register_kvm(env, SPR_FSCR, "FSCR",
8310 SPR_NOACCESS, SPR_NOACCESS,
8311 &spr_read_generic, &spr_write_generic,
8312 KVM_REG_PPC_FSCR, initval);
8315 static void gen_spr_power8_pspb(CPUPPCState *env)
8317 spr_register_kvm(env, SPR_PSPB, "PSPB",
8318 SPR_NOACCESS, SPR_NOACCESS,
8319 &spr_read_generic, &spr_write_generic32,
8320 KVM_REG_PPC_PSPB, 0);
8323 static void gen_spr_power8_dpdes(CPUPPCState *env)
8325 #if !defined(CONFIG_USER_ONLY)
8326 /* Directed Privileged Door-bell Exception State, used for IPI */
8327 spr_register_kvm_hv(env, SPR_DPDES, "DPDES",
8328 SPR_NOACCESS, SPR_NOACCESS,
8329 &spr_read_dpdes, SPR_NOACCESS,
8330 &spr_read_dpdes, &spr_write_dpdes,
8331 KVM_REG_PPC_DPDES, 0x00000000);
8335 static void gen_spr_power8_ic(CPUPPCState *env)
8337 #if !defined(CONFIG_USER_ONLY)
8338 spr_register_hv(env, SPR_IC, "IC",
8339 SPR_NOACCESS, SPR_NOACCESS,
8340 &spr_read_generic, SPR_NOACCESS,
8341 &spr_read_generic, &spr_write_generic,
8346 static void gen_spr_power8_book4(CPUPPCState *env)
8348 /* Add a number of P8 book4 registers */
8349 #if !defined(CONFIG_USER_ONLY)
8350 spr_register_kvm(env, SPR_ACOP, "ACOP",
8351 SPR_NOACCESS, SPR_NOACCESS,
8352 &spr_read_generic, &spr_write_generic,
8353 KVM_REG_PPC_ACOP, 0);
8354 spr_register_kvm(env, SPR_BOOKS_PID, "PID",
8355 SPR_NOACCESS, SPR_NOACCESS,
8356 &spr_read_generic, &spr_write_pidr,
8357 KVM_REG_PPC_PID, 0);
8358 spr_register_kvm(env, SPR_WORT, "WORT",
8359 SPR_NOACCESS, SPR_NOACCESS,
8360 &spr_read_generic, &spr_write_generic,
8361 KVM_REG_PPC_WORT, 0);
8365 static void gen_spr_power7_book4(CPUPPCState *env)
8367 /* Add a number of P7 book4 registers */
8368 #if !defined(CONFIG_USER_ONLY)
8369 spr_register_kvm(env, SPR_ACOP, "ACOP",
8370 SPR_NOACCESS, SPR_NOACCESS,
8371 &spr_read_generic, &spr_write_generic,
8372 KVM_REG_PPC_ACOP, 0);
8373 spr_register_kvm(env, SPR_BOOKS_PID, "PID",
8374 SPR_NOACCESS, SPR_NOACCESS,
8375 &spr_read_generic, &spr_write_generic,
8376 KVM_REG_PPC_PID, 0);
8380 static void gen_spr_power8_rpr(CPUPPCState *env)
8382 #if !defined(CONFIG_USER_ONLY)
8383 spr_register_hv(env, SPR_RPR, "RPR",
8384 SPR_NOACCESS, SPR_NOACCESS,
8385 SPR_NOACCESS, SPR_NOACCESS,
8386 &spr_read_generic, &spr_write_generic,
8387 0x00000103070F1F3F);
8391 static void gen_spr_power9_mmu(CPUPPCState *env)
8393 #if !defined(CONFIG_USER_ONLY)
8394 /* Partition Table Control */
8395 spr_register_kvm_hv(env, SPR_PTCR, "PTCR",
8396 SPR_NOACCESS, SPR_NOACCESS,
8397 SPR_NOACCESS, SPR_NOACCESS,
8398 &spr_read_generic, &spr_write_ptcr,
8399 KVM_REG_PPC_PTCR, 0x00000000);
8400 /* Address Segment Descriptor Register */
8401 spr_register_hv(env, SPR_ASDR, "ASDR",
8402 SPR_NOACCESS, SPR_NOACCESS,
8403 SPR_NOACCESS, SPR_NOACCESS,
8404 &spr_read_generic, &spr_write_generic,
8405 0x0000000000000000);
8409 static void init_proc_book3s_common(CPUPPCState *env)
8411 gen_spr_ne_601(env);
8413 gen_spr_usprg3(env);
8414 gen_spr_book3s_altivec(env);
8415 gen_spr_book3s_pmu_sup(env);
8416 gen_spr_book3s_pmu_user(env);
8417 gen_spr_book3s_ctrl(env);
8420 static void init_proc_970(CPUPPCState *env)
8422 /* Common Registers */
8423 init_proc_book3s_common(env);
8425 gen_spr_book3s_dbg(env);
8427 /* 970 Specific Registers */
8428 gen_spr_970_hid(env);
8429 gen_spr_970_hior(env);
8431 gen_spr_970_pmu_sup(env);
8432 gen_spr_970_pmu_user(env);
8433 gen_spr_970_lpar(env);
8434 gen_spr_970_dbg(env);
8437 env->dcache_line_size = 128;
8438 env->icache_line_size = 128;
8440 /* Allocate hardware IRQ controller */
8442 ppc970_irq_init(env_archcpu(env));
8445 POWERPC_FAMILY(970)(ObjectClass *oc, void *data)
8447 DeviceClass *dc = DEVICE_CLASS(oc);
8448 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8450 dc->desc = "PowerPC 970";
8451 pcc->init_proc = init_proc_970;
8452 pcc->check_pow = check_pow_970;
8453 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
8454 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8455 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
8457 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8458 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8459 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
8460 PPC_64B | PPC_ALTIVEC |
8461 PPC_SEGMENT_64B | PPC_SLBI;
8462 pcc->insns_flags2 = PPC2_FP_CVT_S64;
8463 pcc->msr_mask = (1ull << MSR_SF) |
8478 pcc->mmu_model = POWERPC_MMU_64B;
8479 #if defined(CONFIG_SOFTMMU)
8480 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
8481 pcc->hash64_opts = &ppc_hash64_opts_basic;
8483 pcc->excp_model = POWERPC_EXCP_970;
8484 pcc->bus_model = PPC_FLAGS_INPUT_970;
8485 pcc->bfd_mach = bfd_mach_ppc64;
8486 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8487 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8488 POWERPC_FLAG_BUS_CLK;
8489 pcc->l1_dcache_size = 0x8000;
8490 pcc->l1_icache_size = 0x10000;
8493 static void init_proc_power5plus(CPUPPCState *env)
8495 /* Common Registers */
8496 init_proc_book3s_common(env);
8498 gen_spr_book3s_dbg(env);
8500 /* POWER5+ Specific Registers */
8501 gen_spr_970_hid(env);
8502 gen_spr_970_hior(env);
8504 gen_spr_970_pmu_sup(env);
8505 gen_spr_970_pmu_user(env);
8506 gen_spr_power5p_common(env);
8507 gen_spr_power5p_lpar(env);
8508 gen_spr_power5p_ear(env);
8509 gen_spr_power5p_tb(env);
8512 env->dcache_line_size = 128;
8513 env->icache_line_size = 128;
8515 /* Allocate hardware IRQ controller */
8517 ppc970_irq_init(env_archcpu(env));
8520 POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data)
8522 DeviceClass *dc = DEVICE_CLASS(oc);
8523 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8525 dc->fw_name = "PowerPC,POWER5";
8526 dc->desc = "POWER5+";
8527 pcc->init_proc = init_proc_power5plus;
8528 pcc->check_pow = check_pow_970;
8529 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
8530 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8531 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
8533 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8534 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8535 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
8537 PPC_SEGMENT_64B | PPC_SLBI;
8538 pcc->insns_flags2 = PPC2_FP_CVT_S64;
8539 pcc->msr_mask = (1ull << MSR_SF) |
8554 pcc->lpcr_mask = LPCR_RMLS | LPCR_ILE | LPCR_LPES0 | LPCR_LPES1 |
8555 LPCR_RMI | LPCR_HDICE;
8556 pcc->mmu_model = POWERPC_MMU_2_03;
8557 #if defined(CONFIG_SOFTMMU)
8558 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
8559 pcc->hash64_opts = &ppc_hash64_opts_basic;
8560 pcc->lrg_decr_bits = 32;
8562 pcc->excp_model = POWERPC_EXCP_970;
8563 pcc->bus_model = PPC_FLAGS_INPUT_970;
8564 pcc->bfd_mach = bfd_mach_ppc64;
8565 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8566 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8567 POWERPC_FLAG_BUS_CLK;
8568 pcc->l1_dcache_size = 0x8000;
8569 pcc->l1_icache_size = 0x10000;
8572 static void init_proc_POWER7(CPUPPCState *env)
8574 /* Common Registers */
8575 init_proc_book3s_common(env);
8577 gen_spr_book3s_dbg(env);
8579 /* POWER7 Specific Registers */
8580 gen_spr_book3s_ids(env);
8583 gen_spr_book3s_purr(env);
8584 gen_spr_power5p_common(env);
8585 gen_spr_power5p_lpar(env);
8586 gen_spr_power5p_ear(env);
8587 gen_spr_power5p_tb(env);
8588 gen_spr_power6_common(env);
8589 gen_spr_power6_dbg(env);
8590 gen_spr_power7_book4(env);
8593 env->dcache_line_size = 128;
8594 env->icache_line_size = 128;
8596 /* Allocate hardware IRQ controller */
8597 init_excp_POWER7(env);
8598 ppcPOWER7_irq_init(env_archcpu(env));
8601 static bool ppc_pvr_match_power7(PowerPCCPUClass *pcc, uint32_t pvr)
8603 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7P_BASE) {
8606 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7_BASE) {
8612 static bool cpu_has_work_POWER7(CPUState *cs)
8614 PowerPCCPU *cpu = POWERPC_CPU(cs);
8615 CPUPPCState *env = &cpu->env;
8618 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
8621 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
8622 (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) {
8625 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
8626 (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) {
8629 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
8630 (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
8633 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
8634 (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
8637 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
8642 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
8646 POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
8648 DeviceClass *dc = DEVICE_CLASS(oc);
8649 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8650 CPUClass *cc = CPU_CLASS(oc);
8652 dc->fw_name = "PowerPC,POWER7";
8653 dc->desc = "POWER7";
8654 pcc->pvr_match = ppc_pvr_match_power7;
8655 pcc->pcr_mask = PCR_VEC_DIS | PCR_VSX_DIS | PCR_COMPAT_2_05;
8656 pcc->pcr_supported = PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
8657 pcc->init_proc = init_proc_POWER7;
8658 pcc->check_pow = check_pow_nocheck;
8659 cc->has_work = cpu_has_work_POWER7;
8660 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
8661 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8662 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
8663 PPC_FLOAT_FRSQRTES |
8666 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8667 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8668 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
8669 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
8670 PPC_SEGMENT_64B | PPC_SLBI |
8671 PPC_POPCNTB | PPC_POPCNTWD |
8673 pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
8674 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
8675 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
8676 PPC2_FP_TST_ISA206 | PPC2_FP_CVT_S64 |
8678 pcc->msr_mask = (1ull << MSR_SF) |
8694 pcc->lpcr_mask = LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_DPFD |
8695 LPCR_VRMASD | LPCR_RMLS | LPCR_ILE |
8696 LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2 |
8697 LPCR_MER | LPCR_TC |
8698 LPCR_LPES0 | LPCR_LPES1 | LPCR_HDICE;
8699 pcc->lpcr_pm = LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2;
8700 pcc->mmu_model = POWERPC_MMU_2_06;
8701 #if defined(CONFIG_SOFTMMU)
8702 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
8703 pcc->hash64_opts = &ppc_hash64_opts_POWER7;
8704 pcc->lrg_decr_bits = 32;
8706 pcc->excp_model = POWERPC_EXCP_POWER7;
8707 pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
8708 pcc->bfd_mach = bfd_mach_ppc64;
8709 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8710 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8711 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
8713 pcc->l1_dcache_size = 0x8000;
8714 pcc->l1_icache_size = 0x8000;
8715 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
8718 static void init_proc_POWER8(CPUPPCState *env)
8720 /* Common Registers */
8721 init_proc_book3s_common(env);
8723 gen_spr_book3s_207_dbg(env);
8725 /* POWER8 Specific Registers */
8726 gen_spr_book3s_ids(env);
8730 gen_spr_book3s_purr(env);
8731 gen_spr_power5p_common(env);
8732 gen_spr_power5p_lpar(env);
8733 gen_spr_power5p_ear(env);
8734 gen_spr_power5p_tb(env);
8735 gen_spr_power6_common(env);
8736 gen_spr_power6_dbg(env);
8737 gen_spr_power8_tce_address_control(env);
8738 gen_spr_power8_ids(env);
8739 gen_spr_power8_ebb(env);
8740 gen_spr_power8_fscr(env);
8741 gen_spr_power8_pmu_sup(env);
8742 gen_spr_power8_pmu_user(env);
8743 gen_spr_power8_tm(env);
8744 gen_spr_power8_pspb(env);
8745 gen_spr_power8_dpdes(env);
8747 gen_spr_power8_ic(env);
8748 gen_spr_power8_book4(env);
8749 gen_spr_power8_rpr(env);
8752 env->dcache_line_size = 128;
8753 env->icache_line_size = 128;
8755 /* Allocate hardware IRQ controller */
8756 init_excp_POWER8(env);
8757 ppcPOWER7_irq_init(env_archcpu(env));
8760 static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, uint32_t pvr)
8762 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8NVL_BASE) {
8765 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8E_BASE) {
8768 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8_BASE) {
8774 static bool cpu_has_work_POWER8(CPUState *cs)
8776 PowerPCCPU *cpu = POWERPC_CPU(cs);
8777 CPUPPCState *env = &cpu->env;
8780 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
8783 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
8784 (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) {
8787 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
8788 (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) {
8791 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
8792 (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
8795 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
8796 (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
8799 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
8800 (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) {
8803 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
8804 (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) {
8807 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
8812 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
8816 POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
8818 DeviceClass *dc = DEVICE_CLASS(oc);
8819 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8820 CPUClass *cc = CPU_CLASS(oc);
8822 dc->fw_name = "PowerPC,POWER8";
8823 dc->desc = "POWER8";
8824 pcc->pvr_match = ppc_pvr_match_power8;
8825 pcc->pcr_mask = PCR_TM_DIS | PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
8826 pcc->pcr_supported = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
8827 pcc->init_proc = init_proc_POWER8;
8828 pcc->check_pow = check_pow_nocheck;
8829 cc->has_work = cpu_has_work_POWER8;
8830 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
8831 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8832 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
8833 PPC_FLOAT_FRSQRTES |
8836 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8837 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8838 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
8839 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
8840 PPC_SEGMENT_64B | PPC_SLBI |
8841 PPC_POPCNTB | PPC_POPCNTWD |
8843 pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
8844 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
8845 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
8846 PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
8847 PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
8848 PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
8849 PPC2_TM | PPC2_PM_ISA206;
8850 pcc->msr_mask = (1ull << MSR_SF) |
8870 pcc->lpcr_mask = LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV |
8871 LPCR_DPFD | LPCR_VRMASD | LPCR_RMLS | LPCR_ILE |
8872 LPCR_AIL | LPCR_ONL | LPCR_P8_PECE0 | LPCR_P8_PECE1 |
8873 LPCR_P8_PECE2 | LPCR_P8_PECE3 | LPCR_P8_PECE4 |
8874 LPCR_MER | LPCR_TC | LPCR_LPES0 | LPCR_HDICE;
8875 pcc->lpcr_pm = LPCR_P8_PECE0 | LPCR_P8_PECE1 | LPCR_P8_PECE2 |
8876 LPCR_P8_PECE3 | LPCR_P8_PECE4;
8877 pcc->mmu_model = POWERPC_MMU_2_07;
8878 #if defined(CONFIG_SOFTMMU)
8879 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
8880 pcc->hash64_opts = &ppc_hash64_opts_POWER7;
8881 pcc->lrg_decr_bits = 32;
8882 pcc->n_host_threads = 8;
8884 pcc->excp_model = POWERPC_EXCP_POWER8;
8885 pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
8886 pcc->bfd_mach = bfd_mach_ppc64;
8887 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8888 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8889 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
8890 POWERPC_FLAG_VSX | POWERPC_FLAG_TM;
8891 pcc->l1_dcache_size = 0x8000;
8892 pcc->l1_icache_size = 0x8000;
8893 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
8896 #ifdef CONFIG_SOFTMMU
8898 * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
8899 * Encoded as array of int_32s in the form:
8900 * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
8902 * y -> radix mode supported page size (encoded as a shift)
8904 static struct ppc_radix_page_info POWER9_radix_page_info = {
8907 0x0000000c, /* 4K - enc: 0x0 */
8908 0xa0000010, /* 64K - enc: 0x5 */
8909 0x20000015, /* 2M - enc: 0x1 */
8910 0x4000001e /* 1G - enc: 0x2 */
8913 #endif /* CONFIG_SOFTMMU */
8915 static void init_proc_POWER9(CPUPPCState *env)
8917 /* Common Registers */
8918 init_proc_book3s_common(env);
8919 gen_spr_book3s_207_dbg(env);
8921 /* POWER8 Specific Registers */
8922 gen_spr_book3s_ids(env);
8925 gen_spr_book3s_purr(env);
8926 gen_spr_power5p_common(env);
8927 gen_spr_power5p_lpar(env);
8928 gen_spr_power5p_ear(env);
8929 gen_spr_power5p_tb(env);
8930 gen_spr_power6_common(env);
8931 gen_spr_power6_dbg(env);
8932 gen_spr_power8_tce_address_control(env);
8933 gen_spr_power8_ids(env);
8934 gen_spr_power8_ebb(env);
8935 gen_spr_power8_fscr(env);
8936 gen_spr_power8_pmu_sup(env);
8937 gen_spr_power8_pmu_user(env);
8938 gen_spr_power8_tm(env);
8939 gen_spr_power8_pspb(env);
8940 gen_spr_power8_dpdes(env);
8942 gen_spr_power8_ic(env);
8943 gen_spr_power8_book4(env);
8944 gen_spr_power8_rpr(env);
8945 gen_spr_power9_mmu(env);
8947 /* POWER9 Specific registers */
8948 spr_register_kvm(env, SPR_TIDR, "TIDR", NULL, NULL,
8949 spr_read_generic, spr_write_generic,
8950 KVM_REG_PPC_TIDR, 0);
8952 /* FIXME: Filter fields properly based on privilege level */
8953 spr_register_kvm_hv(env, SPR_PSSCR, "PSSCR", NULL, NULL, NULL, NULL,
8954 spr_read_generic, spr_write_generic,
8955 KVM_REG_PPC_PSSCR, 0);
8958 env->dcache_line_size = 128;
8959 env->icache_line_size = 128;
8961 /* Allocate hardware IRQ controller */
8962 init_excp_POWER9(env);
8963 ppcPOWER9_irq_init(env_archcpu(env));
8966 static bool ppc_pvr_match_power9(PowerPCCPUClass *pcc, uint32_t pvr)
8968 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER9_BASE) {
8974 static bool cpu_has_work_POWER9(CPUState *cs)
8976 PowerPCCPU *cpu = POWERPC_CPU(cs);
8977 CPUPPCState *env = &cpu->env;
8980 uint64_t psscr = env->spr[SPR_PSSCR];
8982 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
8986 /* If EC is clear, just return true on any pending interrupt */
8987 if (!(psscr & PSSCR_EC)) {
8990 /* External Exception */
8991 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
8992 (env->spr[SPR_LPCR] & LPCR_EEE)) {
8993 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
8994 if (heic == 0 || !msr_hv || msr_pr) {
8998 /* Decrementer Exception */
8999 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
9000 (env->spr[SPR_LPCR] & LPCR_DEE)) {
9003 /* Machine Check or Hypervisor Maintenance Exception */
9004 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK |
9005 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) {
9008 /* Privileged Doorbell Exception */
9009 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
9010 (env->spr[SPR_LPCR] & LPCR_PDEE)) {
9013 /* Hypervisor Doorbell Exception */
9014 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
9015 (env->spr[SPR_LPCR] & LPCR_HDEE)) {
9018 /* Hypervisor virtualization exception */
9019 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) &&
9020 (env->spr[SPR_LPCR] & LPCR_HVEE)) {
9023 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
9028 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
9032 POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
9034 DeviceClass *dc = DEVICE_CLASS(oc);
9035 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
9036 CPUClass *cc = CPU_CLASS(oc);
9038 dc->fw_name = "PowerPC,POWER9";
9039 dc->desc = "POWER9";
9040 pcc->pvr_match = ppc_pvr_match_power9;
9041 pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07;
9042 pcc->pcr_supported = PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 |
9044 pcc->init_proc = init_proc_POWER9;
9045 pcc->check_pow = check_pow_nocheck;
9046 cc->has_work = cpu_has_work_POWER9;
9047 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
9048 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
9049 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
9050 PPC_FLOAT_FRSQRTES |
9053 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
9054 PPC_MEM_SYNC | PPC_MEM_EIEIO |
9056 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
9057 PPC_SEGMENT_64B | PPC_SLBI |
9058 PPC_POPCNTB | PPC_POPCNTWD |
9060 pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
9061 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
9062 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
9063 PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
9064 PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
9065 PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
9066 PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL;
9067 pcc->msr_mask = (1ull << MSR_SF) |
9085 pcc->lpcr_mask = LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD |
9086 (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL |
9087 LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR | LPCR_LD |
9088 (LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE | LPCR_EEE |
9089 LPCR_DEE | LPCR_OEE))
9090 | LPCR_MER | LPCR_GTSE | LPCR_TC |
9091 LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE | LPCR_HDICE;
9092 pcc->lpcr_pm = LPCR_PDEE | LPCR_HDEE | LPCR_EEE | LPCR_DEE | LPCR_OEE;
9093 pcc->mmu_model = POWERPC_MMU_3_00;
9094 #if defined(CONFIG_SOFTMMU)
9095 pcc->handle_mmu_fault = ppc64_v3_handle_mmu_fault;
9096 /* segment page size remain the same */
9097 pcc->hash64_opts = &ppc_hash64_opts_POWER7;
9098 pcc->radix_page_info = &POWER9_radix_page_info;
9099 pcc->lrg_decr_bits = 56;
9100 pcc->n_host_threads = 4;
9102 pcc->excp_model = POWERPC_EXCP_POWER9;
9103 pcc->bus_model = PPC_FLAGS_INPUT_POWER9;
9104 pcc->bfd_mach = bfd_mach_ppc64;
9105 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
9106 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
9107 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
9108 POWERPC_FLAG_VSX | POWERPC_FLAG_TM | POWERPC_FLAG_SCV;
9109 pcc->l1_dcache_size = 0x8000;
9110 pcc->l1_icache_size = 0x8000;
9111 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
9114 #ifdef CONFIG_SOFTMMU
9116 * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
9117 * Encoded as array of int_32s in the form:
9118 * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
9120 * y -> radix mode supported page size (encoded as a shift)
9122 static struct ppc_radix_page_info POWER10_radix_page_info = {
9125 0x0000000c, /* 4K - enc: 0x0 */
9126 0xa0000010, /* 64K - enc: 0x5 */
9127 0x20000015, /* 2M - enc: 0x1 */
9128 0x4000001e /* 1G - enc: 0x2 */
9131 #endif /* CONFIG_SOFTMMU */
9133 static void init_proc_POWER10(CPUPPCState *env)
9135 /* Common Registers */
9136 init_proc_book3s_common(env);
9137 gen_spr_book3s_207_dbg(env);
9139 /* POWER8 Specific Registers */
9140 gen_spr_book3s_ids(env);
9143 gen_spr_book3s_purr(env);
9144 gen_spr_power5p_common(env);
9145 gen_spr_power5p_lpar(env);
9146 gen_spr_power5p_ear(env);
9147 gen_spr_power6_common(env);
9148 gen_spr_power6_dbg(env);
9149 gen_spr_power8_tce_address_control(env);
9150 gen_spr_power8_ids(env);
9151 gen_spr_power8_ebb(env);
9152 gen_spr_power8_fscr(env);
9153 gen_spr_power8_pmu_sup(env);
9154 gen_spr_power8_pmu_user(env);
9155 gen_spr_power8_tm(env);
9156 gen_spr_power8_pspb(env);
9158 gen_spr_power8_ic(env);
9159 gen_spr_power8_book4(env);
9160 gen_spr_power8_rpr(env);
9161 gen_spr_power9_mmu(env);
9163 /* FIXME: Filter fields properly based on privilege level */
9164 spr_register_kvm_hv(env, SPR_PSSCR, "PSSCR", NULL, NULL, NULL, NULL,
9165 spr_read_generic, spr_write_generic,
9166 KVM_REG_PPC_PSSCR, 0);
9169 env->dcache_line_size = 128;
9170 env->icache_line_size = 128;
9172 /* Allocate hardware IRQ controller */
9173 init_excp_POWER10(env);
9174 ppcPOWER9_irq_init(env_archcpu(env));
9177 static bool ppc_pvr_match_power10(PowerPCCPUClass *pcc, uint32_t pvr)
9179 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER10_BASE) {
9185 static bool cpu_has_work_POWER10(CPUState *cs)
9187 PowerPCCPU *cpu = POWERPC_CPU(cs);
9188 CPUPPCState *env = &cpu->env;
9191 uint64_t psscr = env->spr[SPR_PSSCR];
9193 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
9197 /* If EC is clear, just return true on any pending interrupt */
9198 if (!(psscr & PSSCR_EC)) {
9201 /* External Exception */
9202 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
9203 (env->spr[SPR_LPCR] & LPCR_EEE)) {
9204 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
9205 if (heic == 0 || !msr_hv || msr_pr) {
9209 /* Decrementer Exception */
9210 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
9211 (env->spr[SPR_LPCR] & LPCR_DEE)) {
9214 /* Machine Check or Hypervisor Maintenance Exception */
9215 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK |
9216 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) {
9219 /* Privileged Doorbell Exception */
9220 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
9221 (env->spr[SPR_LPCR] & LPCR_PDEE)) {
9224 /* Hypervisor Doorbell Exception */
9225 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
9226 (env->spr[SPR_LPCR] & LPCR_HDEE)) {
9229 /* Hypervisor virtualization exception */
9230 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) &&
9231 (env->spr[SPR_LPCR] & LPCR_HVEE)) {
9234 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
9239 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
9243 POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data)
9245 DeviceClass *dc = DEVICE_CLASS(oc);
9246 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
9247 CPUClass *cc = CPU_CLASS(oc);
9249 dc->fw_name = "PowerPC,POWER10";
9250 dc->desc = "POWER10";
9251 pcc->pvr_match = ppc_pvr_match_power10;
9252 pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07 |
9254 pcc->pcr_supported = PCR_COMPAT_3_10 | PCR_COMPAT_3_00 | PCR_COMPAT_2_07 |
9255 PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
9256 pcc->init_proc = init_proc_POWER10;
9257 pcc->check_pow = check_pow_nocheck;
9258 cc->has_work = cpu_has_work_POWER10;
9259 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
9260 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
9261 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
9262 PPC_FLOAT_FRSQRTES |
9265 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
9266 PPC_MEM_SYNC | PPC_MEM_EIEIO |
9268 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
9269 PPC_SEGMENT_64B | PPC_SLBI |
9270 PPC_POPCNTB | PPC_POPCNTWD |
9272 pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
9273 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
9274 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
9275 PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
9276 PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
9277 PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
9278 PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL | PPC2_ISA310;
9279 pcc->msr_mask = (1ull << MSR_SF) |
9297 pcc->lpcr_mask = LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD |
9298 (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL |
9299 LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR | LPCR_LD |
9300 (LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE | LPCR_EEE |
9301 LPCR_DEE | LPCR_OEE))
9302 | LPCR_MER | LPCR_GTSE | LPCR_TC |
9303 LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE | LPCR_HDICE;
9304 pcc->lpcr_pm = LPCR_PDEE | LPCR_HDEE | LPCR_EEE | LPCR_DEE | LPCR_OEE;
9305 pcc->mmu_model = POWERPC_MMU_3_00;
9306 #if defined(CONFIG_SOFTMMU)
9307 pcc->handle_mmu_fault = ppc64_v3_handle_mmu_fault;
9308 /* segment page size remain the same */
9309 pcc->hash64_opts = &ppc_hash64_opts_POWER7;
9310 pcc->radix_page_info = &POWER10_radix_page_info;
9311 pcc->lrg_decr_bits = 56;
9313 pcc->excp_model = POWERPC_EXCP_POWER10;
9314 pcc->bus_model = PPC_FLAGS_INPUT_POWER9;
9315 pcc->bfd_mach = bfd_mach_ppc64;
9316 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
9317 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
9318 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
9319 POWERPC_FLAG_VSX | POWERPC_FLAG_TM | POWERPC_FLAG_SCV;
9320 pcc->l1_dcache_size = 0x8000;
9321 pcc->l1_icache_size = 0x8000;
9322 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
9325 #if !defined(CONFIG_USER_ONLY)
9326 void cpu_ppc_set_vhyp(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp)
9328 CPUPPCState *env = &cpu->env;
9333 * With a virtual hypervisor mode we never allow the CPU to go
9334 * hypervisor mode itself
9336 env->msr_mask &= ~MSR_HVB;
9339 #endif /* !defined(CONFIG_USER_ONLY) */
9341 #endif /* defined(TARGET_PPC64) */
9343 /*****************************************************************************/
9344 /* Generic CPU instantiation routine */
9345 static void init_ppc_proc(PowerPCCPU *cpu)
9347 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
9348 CPUPPCState *env = &cpu->env;
9349 #if !defined(CONFIG_USER_ONLY)
9352 env->irq_inputs = NULL;
9353 /* Set all exception vectors to an invalid address */
9354 for (i = 0; i < POWERPC_EXCP_NB; i++) {
9355 env->excp_vectors[i] = (target_ulong)(-1ULL);
9357 env->ivor_mask = 0x00000000;
9358 env->ivpr_mask = 0x00000000;
9359 /* Default MMU definitions */
9363 env->tlb_type = TLB_NONE;
9365 /* Register SPR common to all PowerPC implementations */
9366 gen_spr_generic(env);
9367 spr_register(env, SPR_PVR, "PVR",
9368 /* Linux permits userspace to read PVR */
9369 #if defined(CONFIG_LINUX_USER)
9375 &spr_read_generic, SPR_NOACCESS,
9377 /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
9378 if (pcc->svr != POWERPC_SVR_NONE) {
9379 if (pcc->svr & POWERPC_SVR_E500) {
9380 spr_register(env, SPR_E500_SVR, "SVR",
9381 SPR_NOACCESS, SPR_NOACCESS,
9382 &spr_read_generic, SPR_NOACCESS,
9383 pcc->svr & ~POWERPC_SVR_E500);
9385 spr_register(env, SPR_SVR, "SVR",
9386 SPR_NOACCESS, SPR_NOACCESS,
9387 &spr_read_generic, SPR_NOACCESS,
9391 /* PowerPC implementation specific initialisations (SPRs, timers, ...) */
9392 (*pcc->init_proc)(env);
9394 #if !defined(CONFIG_USER_ONLY)
9395 ppc_gdb_gen_spr_xml(cpu);
9398 /* MSR bits & flags consistency checks */
9399 if (env->msr_mask & (1 << 25)) {
9400 switch (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
9401 case POWERPC_FLAG_SPE:
9402 case POWERPC_FLAG_VRE:
9405 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9406 "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n");
9409 } else if (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
9410 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9411 "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n");
9414 if (env->msr_mask & (1 << 17)) {
9415 switch (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
9416 case POWERPC_FLAG_TGPR:
9417 case POWERPC_FLAG_CE:
9420 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9421 "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n");
9424 } else if (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
9425 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9426 "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n");
9429 if (env->msr_mask & (1 << 10)) {
9430 switch (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
9431 POWERPC_FLAG_UBLE)) {
9432 case POWERPC_FLAG_SE:
9433 case POWERPC_FLAG_DWE:
9434 case POWERPC_FLAG_UBLE:
9437 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9438 "Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE or "
9439 "POWERPC_FLAG_UBLE\n");
9442 } else if (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
9443 POWERPC_FLAG_UBLE)) {
9444 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9445 "Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE nor "
9446 "POWERPC_FLAG_UBLE\n");
9449 if (env->msr_mask & (1 << 9)) {
9450 switch (env->flags & (POWERPC_FLAG_BE | POWERPC_FLAG_DE)) {
9451 case POWERPC_FLAG_BE:
9452 case POWERPC_FLAG_DE:
9455 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9456 "Should define POWERPC_FLAG_BE or POWERPC_FLAG_DE\n");
9459 } else if (env->flags & (POWERPC_FLAG_BE | POWERPC_FLAG_DE)) {
9460 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9461 "Should not define POWERPC_FLAG_BE nor POWERPC_FLAG_DE\n");
9464 if (env->msr_mask & (1 << 2)) {
9465 switch (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
9466 case POWERPC_FLAG_PX:
9467 case POWERPC_FLAG_PMM:
9470 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9471 "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n");
9474 } else if (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
9475 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9476 "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
9479 if ((env->flags & (POWERPC_FLAG_RTC_CLK | POWERPC_FLAG_BUS_CLK)) == 0) {
9480 fprintf(stderr, "PowerPC flags inconsistency\n"
9481 "Should define the time-base and decrementer clock source\n");
9484 /* Allocate TLBs buffer when needed */
9485 #if !defined(CONFIG_USER_ONLY)
9486 if (env->nb_tlb != 0) {
9487 int nb_tlb = env->nb_tlb;
9488 if (env->id_tlbs != 0) {
9491 switch (env->tlb_type) {
9493 env->tlb.tlb6 = g_new0(ppc6xx_tlb_t, nb_tlb);
9496 env->tlb.tlbe = g_new0(ppcemb_tlb_t, nb_tlb);
9499 env->tlb.tlbm = g_new0(ppcmas_tlb_t, nb_tlb);
9502 /* Pre-compute some useful values */
9503 env->tlb_per_way = env->nb_tlb / env->nb_ways;
9505 if (env->irq_inputs == NULL) {
9506 warn_report("no internal IRQ controller registered."
9507 " Attempt QEMU to crash very soon !");
9510 if (env->check_pow == NULL) {
9511 warn_report("no power management check handler registered."
9512 " Attempt QEMU to crash very soon !");
9516 #if defined(PPC_DUMP_CPU)
9517 static void dump_ppc_sprs(CPUPPCState *env)
9520 #if !defined(CONFIG_USER_ONLY)
9526 printf("Special purpose registers:\n");
9527 for (i = 0; i < 32; i++) {
9528 for (j = 0; j < 32; j++) {
9530 spr = &env->spr_cb[n];
9531 uw = spr->uea_write != NULL && spr->uea_write != SPR_NOACCESS;
9532 ur = spr->uea_read != NULL && spr->uea_read != SPR_NOACCESS;
9533 #if !defined(CONFIG_USER_ONLY)
9534 sw = spr->oea_write != NULL && spr->oea_write != SPR_NOACCESS;
9535 sr = spr->oea_read != NULL && spr->oea_read != SPR_NOACCESS;
9536 if (sw || sr || uw || ur) {
9537 printf("SPR: %4d (%03x) %-8s s%c%c u%c%c\n",
9538 (i << 5) | j, (i << 5) | j, spr->name,
9539 sw ? 'w' : '-', sr ? 'r' : '-',
9540 uw ? 'w' : '-', ur ? 'r' : '-');
9544 printf("SPR: %4d (%03x) %-8s u%c%c\n",
9545 (i << 5) | j, (i << 5) | j, spr->name,
9546 uw ? 'w' : '-', ur ? 'r' : '-');
9556 static void ppc_cpu_realize(DeviceState *dev, Error **errp)
9558 CPUState *cs = CPU(dev);
9559 PowerPCCPU *cpu = POWERPC_CPU(dev);
9560 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
9561 Error *local_err = NULL;
9563 cpu_exec_realizefn(cs, &local_err);
9564 if (local_err != NULL) {
9565 error_propagate(errp, local_err);
9568 if (cpu->vcpu_id == UNASSIGNED_CPU_INDEX) {
9569 cpu->vcpu_id = cs->cpu_index;
9572 if (tcg_enabled()) {
9573 if (ppc_fixup_cpu(cpu) != 0) {
9574 error_setg(errp, "Unable to emulate selected CPU with TCG");
9579 create_ppc_opcodes(cpu, &local_err);
9580 if (local_err != NULL) {
9581 error_propagate(errp, local_err);
9586 ppc_gdb_init(cs, pcc);
9589 pcc->parent_realize(dev, errp);
9591 #if defined(PPC_DUMP_CPU)
9593 CPUPPCState *env = &cpu->env;
9594 const char *mmu_model, *excp_model, *bus_model;
9595 switch (env->mmu_model) {
9596 case POWERPC_MMU_32B:
9597 mmu_model = "PowerPC 32";
9599 case POWERPC_MMU_SOFT_6xx:
9600 mmu_model = "PowerPC 6xx/7xx with software driven TLBs";
9602 case POWERPC_MMU_SOFT_74xx:
9603 mmu_model = "PowerPC 74xx with software driven TLBs";
9605 case POWERPC_MMU_SOFT_4xx:
9606 mmu_model = "PowerPC 4xx with software driven TLBs";
9608 case POWERPC_MMU_SOFT_4xx_Z:
9609 mmu_model = "PowerPC 4xx with software driven TLBs "
9610 "and zones protections";
9612 case POWERPC_MMU_REAL:
9613 mmu_model = "PowerPC real mode only";
9615 case POWERPC_MMU_MPC8xx:
9616 mmu_model = "PowerPC MPC8xx";
9618 case POWERPC_MMU_BOOKE:
9619 mmu_model = "PowerPC BookE";
9621 case POWERPC_MMU_BOOKE206:
9622 mmu_model = "PowerPC BookE 2.06";
9624 case POWERPC_MMU_601:
9625 mmu_model = "PowerPC 601";
9627 #if defined(TARGET_PPC64)
9628 case POWERPC_MMU_64B:
9629 mmu_model = "PowerPC 64";
9633 mmu_model = "Unknown or invalid";
9636 switch (env->excp_model) {
9637 case POWERPC_EXCP_STD:
9638 excp_model = "PowerPC";
9640 case POWERPC_EXCP_40x:
9641 excp_model = "PowerPC 40x";
9643 case POWERPC_EXCP_601:
9644 excp_model = "PowerPC 601";
9646 case POWERPC_EXCP_602:
9647 excp_model = "PowerPC 602";
9649 case POWERPC_EXCP_603:
9650 excp_model = "PowerPC 603";
9652 case POWERPC_EXCP_603E:
9653 excp_model = "PowerPC 603e";
9655 case POWERPC_EXCP_604:
9656 excp_model = "PowerPC 604";
9658 case POWERPC_EXCP_7x0:
9659 excp_model = "PowerPC 740/750";
9661 case POWERPC_EXCP_7x5:
9662 excp_model = "PowerPC 745/755";
9664 case POWERPC_EXCP_74xx:
9665 excp_model = "PowerPC 74xx";
9667 case POWERPC_EXCP_BOOKE:
9668 excp_model = "PowerPC BookE";
9670 #if defined(TARGET_PPC64)
9671 case POWERPC_EXCP_970:
9672 excp_model = "PowerPC 970";
9676 excp_model = "Unknown or invalid";
9679 switch (env->bus_model) {
9680 case PPC_FLAGS_INPUT_6xx:
9681 bus_model = "PowerPC 6xx";
9683 case PPC_FLAGS_INPUT_BookE:
9684 bus_model = "PowerPC BookE";
9686 case PPC_FLAGS_INPUT_405:
9687 bus_model = "PowerPC 405";
9689 case PPC_FLAGS_INPUT_401:
9690 bus_model = "PowerPC 401/403";
9692 case PPC_FLAGS_INPUT_RCPU:
9693 bus_model = "RCPU / MPC8xx";
9695 #if defined(TARGET_PPC64)
9696 case PPC_FLAGS_INPUT_970:
9697 bus_model = "PowerPC 970";
9701 bus_model = "Unknown or invalid";
9704 printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64 "\n"
9705 " MMU model : %s\n",
9706 object_class_get_name(OBJECT_CLASS(pcc)),
9707 pcc->pvr, pcc->msr_mask, mmu_model);
9708 #if !defined(CONFIG_USER_ONLY)
9709 if (env->tlb.tlb6) {
9710 printf(" %d %s TLB in %d ways\n",
9711 env->nb_tlb, env->id_tlbs ? "splitted" : "merged",
9715 printf(" Exceptions model : %s\n"
9716 " Bus model : %s\n",
9717 excp_model, bus_model);
9718 printf(" MSR features :\n");
9719 if (env->flags & POWERPC_FLAG_SPE) {
9720 printf(" signal processing engine enable"
9722 } else if (env->flags & POWERPC_FLAG_VRE) {
9723 printf(" vector processor enable\n");
9725 if (env->flags & POWERPC_FLAG_TGPR) {
9726 printf(" temporary GPRs\n");
9727 } else if (env->flags & POWERPC_FLAG_CE) {
9728 printf(" critical input enable\n");
9730 if (env->flags & POWERPC_FLAG_SE) {
9731 printf(" single-step trace mode\n");
9732 } else if (env->flags & POWERPC_FLAG_DWE) {
9733 printf(" debug wait enable\n");
9734 } else if (env->flags & POWERPC_FLAG_UBLE) {
9735 printf(" user BTB lock enable\n");
9737 if (env->flags & POWERPC_FLAG_BE) {
9738 printf(" branch-step trace mode\n");
9739 } else if (env->flags & POWERPC_FLAG_DE) {
9740 printf(" debug interrupt enable\n");
9742 if (env->flags & POWERPC_FLAG_PX) {
9743 printf(" inclusive protection\n");
9744 } else if (env->flags & POWERPC_FLAG_PMM) {
9745 printf(" performance monitor mark\n");
9747 if (env->flags == POWERPC_FLAG_NONE) {
9750 printf(" Time-base/decrementer clock source: %s\n",
9751 env->flags & POWERPC_FLAG_RTC_CLK ? "RTC clock" : "bus clock");
9752 dump_ppc_insns(env);
9760 cpu_exec_unrealizefn(cs);
9763 static void ppc_cpu_unrealize(DeviceState *dev)
9765 PowerPCCPU *cpu = POWERPC_CPU(dev);
9766 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
9768 pcc->parent_unrealize(dev);
9770 cpu_remove_sync(CPU(cpu));
9772 destroy_ppc_opcodes(cpu);
9775 static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b)
9777 ObjectClass *oc = (ObjectClass *)a;
9778 uint32_t pvr = *(uint32_t *)b;
9779 PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
9781 /* -cpu host does a PVR lookup during construction */
9782 if (unlikely(strcmp(object_class_get_name(oc),
9783 TYPE_HOST_POWERPC_CPU) == 0)) {
9787 return pcc->pvr == pvr ? 0 : -1;
9790 PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr)
9792 GSList *list, *item;
9793 PowerPCCPUClass *pcc = NULL;
9795 list = object_class_get_list(TYPE_POWERPC_CPU, false);
9796 item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr);
9798 pcc = POWERPC_CPU_CLASS(item->data);
9805 static gint ppc_cpu_compare_class_pvr_mask(gconstpointer a, gconstpointer b)
9807 ObjectClass *oc = (ObjectClass *)a;
9808 uint32_t pvr = *(uint32_t *)b;
9809 PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
9811 /* -cpu host does a PVR lookup during construction */
9812 if (unlikely(strcmp(object_class_get_name(oc),
9813 TYPE_HOST_POWERPC_CPU) == 0)) {
9817 if (pcc->pvr_match(pcc, pvr)) {
9824 PowerPCCPUClass *ppc_cpu_class_by_pvr_mask(uint32_t pvr)
9826 GSList *list, *item;
9827 PowerPCCPUClass *pcc = NULL;
9829 list = object_class_get_list(TYPE_POWERPC_CPU, true);
9830 item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr_mask);
9832 pcc = POWERPC_CPU_CLASS(item->data);
9839 static const char *ppc_cpu_lookup_alias(const char *alias)
9843 for (ai = 0; ppc_cpu_aliases[ai].alias != NULL; ai++) {
9844 if (strcmp(ppc_cpu_aliases[ai].alias, alias) == 0) {
9845 return ppc_cpu_aliases[ai].model;
9852 static ObjectClass *ppc_cpu_class_by_name(const char *name)
9854 char *cpu_model, *typename;
9860 * Lookup by PVR if cpu_model is valid 8 digit hex number (excl:
9861 * 0x prefix if present)
9863 if (!qemu_strtoul(name, &p, 16, &pvr)) {
9865 len = (len == 10) && (name[1] == 'x') ? len - 2 : len;
9866 if ((len == 8) && (*p == '\0')) {
9867 return OBJECT_CLASS(ppc_cpu_class_by_pvr(pvr));
9871 cpu_model = g_ascii_strdown(name, -1);
9872 p = ppc_cpu_lookup_alias(cpu_model);
9875 cpu_model = g_strdup(p);
9878 typename = g_strdup_printf("%s" POWERPC_CPU_TYPE_SUFFIX, cpu_model);
9879 oc = object_class_by_name(typename);
9886 PowerPCCPUClass *ppc_cpu_get_family_class(PowerPCCPUClass *pcc)
9888 ObjectClass *oc = OBJECT_CLASS(pcc);
9890 while (oc && !object_class_is_abstract(oc)) {
9891 oc = object_class_get_parent(oc);
9895 return POWERPC_CPU_CLASS(oc);
9898 /* Sort by PVR, ordering special case "host" last. */
9899 static gint ppc_cpu_list_compare(gconstpointer a, gconstpointer b)
9901 ObjectClass *oc_a = (ObjectClass *)a;
9902 ObjectClass *oc_b = (ObjectClass *)b;
9903 PowerPCCPUClass *pcc_a = POWERPC_CPU_CLASS(oc_a);
9904 PowerPCCPUClass *pcc_b = POWERPC_CPU_CLASS(oc_b);
9905 const char *name_a = object_class_get_name(oc_a);
9906 const char *name_b = object_class_get_name(oc_b);
9908 if (strcmp(name_a, TYPE_HOST_POWERPC_CPU) == 0) {
9910 } else if (strcmp(name_b, TYPE_HOST_POWERPC_CPU) == 0) {
9913 /* Avoid an integer overflow during subtraction */
9914 if (pcc_a->pvr < pcc_b->pvr) {
9916 } else if (pcc_a->pvr > pcc_b->pvr) {
9924 static void ppc_cpu_list_entry(gpointer data, gpointer user_data)
9926 ObjectClass *oc = data;
9927 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
9928 DeviceClass *family = DEVICE_CLASS(ppc_cpu_get_family_class(pcc));
9929 const char *typename = object_class_get_name(oc);
9933 if (unlikely(strcmp(typename, TYPE_HOST_POWERPC_CPU) == 0)) {
9937 name = g_strndup(typename,
9938 strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX));
9939 qemu_printf("PowerPC %-16s PVR %08x\n", name, pcc->pvr);
9940 for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
9941 PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
9942 ObjectClass *alias_oc = ppc_cpu_class_by_name(alias->model);
9944 if (alias_oc != oc) {
9948 * If running with KVM, we might update the family alias later, so
9949 * avoid printing the wrong alias here and use "preferred" instead
9951 if (strcmp(alias->alias, family->desc) == 0) {
9952 qemu_printf("PowerPC %-16s (alias for preferred %s CPU)\n",
9953 alias->alias, family->desc);
9955 qemu_printf("PowerPC %-16s (alias for %s)\n",
9956 alias->alias, name);
9962 void ppc_cpu_list(void)
9966 list = object_class_get_list(TYPE_POWERPC_CPU, false);
9967 list = g_slist_sort(list, ppc_cpu_list_compare);
9968 g_slist_foreach(list, ppc_cpu_list_entry, NULL);
9973 qemu_printf("PowerPC %-16s\n", "host");
9977 static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
9979 ObjectClass *oc = data;
9980 CpuDefinitionInfoList **first = user_data;
9981 const char *typename;
9982 CpuDefinitionInfo *info;
9984 typename = object_class_get_name(oc);
9985 info = g_malloc0(sizeof(*info));
9986 info->name = g_strndup(typename,
9987 strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX));
9989 QAPI_LIST_PREPEND(*first, info);
9992 CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
9994 CpuDefinitionInfoList *cpu_list = NULL;
9998 list = object_class_get_list(TYPE_POWERPC_CPU, false);
9999 g_slist_foreach(list, ppc_cpu_defs_entry, &cpu_list);
10000 g_slist_free(list);
10002 for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
10003 PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
10005 CpuDefinitionInfo *info;
10007 oc = ppc_cpu_class_by_name(alias->model);
10012 info = g_malloc0(sizeof(*info));
10013 info->name = g_strdup(alias->alias);
10014 info->q_typename = g_strdup(object_class_get_name(oc));
10016 QAPI_LIST_PREPEND(cpu_list, info);
10022 static void ppc_cpu_set_pc(CPUState *cs, vaddr value)
10024 PowerPCCPU *cpu = POWERPC_CPU(cs);
10026 cpu->env.nip = value;
10029 static bool ppc_cpu_has_work(CPUState *cs)
10031 PowerPCCPU *cpu = POWERPC_CPU(cs);
10032 CPUPPCState *env = &cpu->env;
10034 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
10037 static void ppc_cpu_reset(DeviceState *dev)
10039 CPUState *s = CPU(dev);
10040 PowerPCCPU *cpu = POWERPC_CPU(s);
10041 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
10042 CPUPPCState *env = &cpu->env;
10046 pcc->parent_reset(dev);
10048 msr = (target_ulong)0;
10049 msr |= (target_ulong)MSR_HVB;
10050 msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
10051 msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
10052 msr |= (target_ulong)1 << MSR_EP;
10053 #if defined(DO_SINGLE_STEP) && 0
10054 /* Single step trace mode */
10055 msr |= (target_ulong)1 << MSR_SE;
10056 msr |= (target_ulong)1 << MSR_BE;
10058 #if defined(CONFIG_USER_ONLY)
10059 msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
10060 msr |= (target_ulong)1 << MSR_FE0; /* Allow floating point exceptions */
10061 msr |= (target_ulong)1 << MSR_FE1;
10062 msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
10063 msr |= (target_ulong)1 << MSR_VSX; /* Allow VSX usage */
10064 msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
10065 msr |= (target_ulong)1 << MSR_PR;
10066 #if defined(TARGET_PPC64)
10067 msr |= (target_ulong)1 << MSR_TM; /* Transactional memory */
10069 #if !defined(TARGET_WORDS_BIGENDIAN)
10070 msr |= (target_ulong)1 << MSR_LE; /* Little-endian user mode */
10071 if (!((env->msr_mask >> MSR_LE) & 1)) {
10072 fprintf(stderr, "Selected CPU does not support little-endian.\n");
10078 #if defined(TARGET_PPC64)
10079 if (mmu_is_64bit(env->mmu_model)) {
10080 msr |= (1ULL << MSR_SF);
10084 hreg_store_msr(env, msr, 1);
10086 #if !defined(CONFIG_USER_ONLY)
10087 env->nip = env->hreset_vector | env->excp_prefix;
10088 if (env->mmu_model != POWERPC_MMU_REAL) {
10089 ppc_tlb_invalidate_all(env);
10093 hreg_compute_hflags(env);
10094 env->reserve_addr = (target_ulong)-1ULL;
10095 /* Be sure no exception or interrupt is pending */
10096 env->pending_interrupts = 0;
10097 s->exception_index = POWERPC_EXCP_NONE;
10098 env->error_code = 0;
10099 ppc_irq_reset(cpu);
10101 /* tininess for underflow is detected before rounding */
10102 set_float_detect_tininess(float_tininess_before_rounding,
10105 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
10106 ppc_spr_t *spr = &env->spr_cb[i];
10111 env->spr[i] = spr->default_value;
10115 #ifndef CONFIG_USER_ONLY
10117 static bool ppc_cpu_is_big_endian(CPUState *cs)
10119 PowerPCCPU *cpu = POWERPC_CPU(cs);
10120 CPUPPCState *env = &cpu->env;
10122 cpu_synchronize_state(cs);
10128 static void ppc_cpu_exec_enter(CPUState *cs)
10130 PowerPCCPU *cpu = POWERPC_CPU(cs);
10133 PPCVirtualHypervisorClass *vhc =
10134 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
10135 vhc->cpu_exec_enter(cpu->vhyp, cpu);
10139 static void ppc_cpu_exec_exit(CPUState *cs)
10141 PowerPCCPU *cpu = POWERPC_CPU(cs);
10144 PPCVirtualHypervisorClass *vhc =
10145 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
10146 vhc->cpu_exec_exit(cpu->vhyp, cpu);
10149 #endif /* CONFIG_TCG */
10151 #endif /* !CONFIG_USER_ONLY */
10153 static void ppc_cpu_instance_init(Object *obj)
10155 PowerPCCPU *cpu = POWERPC_CPU(obj);
10156 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
10157 CPUPPCState *env = &cpu->env;
10159 cpu_set_cpustate_pointers(cpu);
10160 cpu->vcpu_id = UNASSIGNED_CPU_INDEX;
10162 env->msr_mask = pcc->msr_mask;
10163 env->mmu_model = pcc->mmu_model;
10164 env->excp_model = pcc->excp_model;
10165 env->bus_model = pcc->bus_model;
10166 env->insns_flags = pcc->insns_flags;
10167 env->insns_flags2 = pcc->insns_flags2;
10168 env->flags = pcc->flags;
10169 env->bfd_mach = pcc->bfd_mach;
10170 env->check_pow = pcc->check_pow;
10173 * Mark HV mode as supported if the CPU has an MSR_HV bit in the
10174 * msr_mask. The mask can later be cleared by PAPR mode but the hv
10175 * mode support will remain, thus enforcing that we cannot use
10176 * priv. instructions in guest in PAPR mode. For 970 we currently
10177 * simply don't set HV in msr_mask thus simulating an "Apple mode"
10178 * 970. If we ever want to support 970 HV mode, we'll have to add
10179 * a processor attribute of some sort.
10181 #if !defined(CONFIG_USER_ONLY)
10182 env->has_hv_mode = !!(env->msr_mask & MSR_HVB);
10185 ppc_hash64_init(cpu);
10188 static void ppc_cpu_instance_finalize(Object *obj)
10190 PowerPCCPU *cpu = POWERPC_CPU(obj);
10192 ppc_hash64_finalize(cpu);
10195 static bool ppc_pvr_match_default(PowerPCCPUClass *pcc, uint32_t pvr)
10197 return pcc->pvr == pvr;
10200 static void ppc_disas_set_info(CPUState *cs, disassemble_info *info)
10202 PowerPCCPU *cpu = POWERPC_CPU(cs);
10203 CPUPPCState *env = &cpu->env;
10205 if ((env->hflags >> MSR_LE) & 1) {
10206 info->endian = BFD_ENDIAN_LITTLE;
10208 info->mach = env->bfd_mach;
10209 if (!env->bfd_mach) {
10210 #ifdef TARGET_PPC64
10211 info->mach = bfd_mach_ppc64;
10213 info->mach = bfd_mach_ppc;
10216 info->disassembler_options = (char *)"any";
10217 info->print_insn = print_insn_ppc;
10219 info->cap_arch = CS_ARCH_PPC;
10220 #ifdef TARGET_PPC64
10221 info->cap_mode = CS_MODE_64;
10225 static Property ppc_cpu_properties[] = {
10226 DEFINE_PROP_BOOL("pre-2.8-migration", PowerPCCPU, pre_2_8_migration, false),
10227 DEFINE_PROP_BOOL("pre-2.10-migration", PowerPCCPU, pre_2_10_migration,
10229 DEFINE_PROP_BOOL("pre-3.0-migration", PowerPCCPU, pre_3_0_migration,
10231 DEFINE_PROP_END_OF_LIST(),
10235 #include "hw/core/tcg-cpu-ops.h"
10237 static struct TCGCPUOps ppc_tcg_ops = {
10238 .initialize = ppc_translate_init,
10239 .cpu_exec_interrupt = ppc_cpu_exec_interrupt,
10240 .tlb_fill = ppc_cpu_tlb_fill,
10242 #ifndef CONFIG_USER_ONLY
10243 .do_interrupt = ppc_cpu_do_interrupt,
10244 .cpu_exec_enter = ppc_cpu_exec_enter,
10245 .cpu_exec_exit = ppc_cpu_exec_exit,
10246 .do_unaligned_access = ppc_cpu_do_unaligned_access,
10247 #endif /* !CONFIG_USER_ONLY */
10249 #endif /* CONFIG_TCG */
10251 static void ppc_cpu_class_init(ObjectClass *oc, void *data)
10253 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
10254 CPUClass *cc = CPU_CLASS(oc);
10255 DeviceClass *dc = DEVICE_CLASS(oc);
10257 device_class_set_parent_realize(dc, ppc_cpu_realize,
10258 &pcc->parent_realize);
10259 device_class_set_parent_unrealize(dc, ppc_cpu_unrealize,
10260 &pcc->parent_unrealize);
10261 pcc->pvr_match = ppc_pvr_match_default;
10262 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_always;
10263 device_class_set_props(dc, ppc_cpu_properties);
10265 device_class_set_parent_reset(dc, ppc_cpu_reset, &pcc->parent_reset);
10267 cc->class_by_name = ppc_cpu_class_by_name;
10268 cc->has_work = ppc_cpu_has_work;
10269 cc->dump_state = ppc_cpu_dump_state;
10270 cc->dump_statistics = ppc_cpu_dump_statistics;
10271 cc->set_pc = ppc_cpu_set_pc;
10272 cc->gdb_read_register = ppc_cpu_gdb_read_register;
10273 cc->gdb_write_register = ppc_cpu_gdb_write_register;
10274 #ifndef CONFIG_USER_ONLY
10275 cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
10276 cc->vmsd = &vmstate_ppc_cpu;
10278 #if defined(CONFIG_SOFTMMU)
10279 cc->write_elf64_note = ppc64_cpu_write_elf64_note;
10280 cc->write_elf32_note = ppc32_cpu_write_elf32_note;
10283 cc->gdb_num_core_regs = 71;
10284 #ifndef CONFIG_USER_ONLY
10285 cc->gdb_get_dynamic_xml = ppc_gdb_get_dynamic_xml;
10287 #ifdef USE_APPLE_GDB
10288 cc->gdb_read_register = ppc_cpu_gdb_read_register_apple;
10289 cc->gdb_write_register = ppc_cpu_gdb_write_register_apple;
10290 cc->gdb_num_core_regs = 71 + 32;
10293 cc->gdb_arch_name = ppc_gdb_arch_name;
10294 #if defined(TARGET_PPC64)
10295 cc->gdb_core_xml_file = "power64-core.xml";
10297 cc->gdb_core_xml_file = "power-core.xml";
10299 #ifndef CONFIG_USER_ONLY
10300 cc->virtio_is_big_endian = ppc_cpu_is_big_endian;
10302 cc->disas_set_info = ppc_disas_set_info;
10304 dc->fw_name = "PowerPC,UNKNOWN";
10307 cc->tcg_ops = &ppc_tcg_ops;
10308 #endif /* CONFIG_TCG */
10311 static const TypeInfo ppc_cpu_type_info = {
10312 .name = TYPE_POWERPC_CPU,
10313 .parent = TYPE_CPU,
10314 .instance_size = sizeof(PowerPCCPU),
10315 .instance_align = __alignof__(PowerPCCPU),
10316 .instance_init = ppc_cpu_instance_init,
10317 .instance_finalize = ppc_cpu_instance_finalize,
10319 .class_size = sizeof(PowerPCCPUClass),
10320 .class_init = ppc_cpu_class_init,
10323 #ifndef CONFIG_USER_ONLY
10324 static const TypeInfo ppc_vhyp_type_info = {
10325 .name = TYPE_PPC_VIRTUAL_HYPERVISOR,
10326 .parent = TYPE_INTERFACE,
10327 .class_size = sizeof(PPCVirtualHypervisorClass),
10331 static void ppc_cpu_register_types(void)
10333 type_register_static(&ppc_cpu_type_info);
10334 #ifndef CONFIG_USER_ONLY
10335 type_register_static(&ppc_vhyp_type_info);
10339 type_init(ppc_cpu_register_types)