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 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 "qemu/osdep.h"
22 #include "disas/bfd.h"
23 #include "exec/gdbstub.h"
25 #include "sysemu/arch_init.h"
26 #include "sysemu/cpus.h"
27 #include "sysemu/hw_accel.h"
28 #include "cpu-models.h"
29 #include "mmu-hash32.h"
30 #include "mmu-hash64.h"
31 #include "qemu/error-report.h"
32 #include "qapi/visitor.h"
33 #include "hw/qdev-properties.h"
34 #include "hw/ppc/ppc.h"
35 #include "mmu-book3s-v3.h"
36 #include "sysemu/qtest.h"
37 #include "qemu/cutils.h"
38 #include "disas/capstone.h"
40 //#define PPC_DUMP_CPU
41 //#define PPC_DEBUG_SPR
42 //#define PPC_DUMP_SPR_ACCESSES
43 /* #define USE_APPLE_GDB */
46 * do nothing but store/retrieve spr value
48 static void spr_load_dump_spr(int sprn
)
50 #ifdef PPC_DUMP_SPR_ACCESSES
51 TCGv_i32 t0
= tcg_const_i32(sprn
);
52 gen_helper_load_dump_spr(cpu_env
, t0
);
53 tcg_temp_free_i32(t0
);
57 static void spr_read_generic (DisasContext
*ctx
, int gprn
, int sprn
)
59 gen_load_spr(cpu_gpr
[gprn
], sprn
);
60 spr_load_dump_spr(sprn
);
63 static void spr_store_dump_spr(int sprn
)
65 #ifdef PPC_DUMP_SPR_ACCESSES
66 TCGv_i32 t0
= tcg_const_i32(sprn
);
67 gen_helper_store_dump_spr(cpu_env
, t0
);
68 tcg_temp_free_i32(t0
);
72 static void spr_write_generic(DisasContext
*ctx
, int sprn
, int gprn
)
74 gen_store_spr(sprn
, cpu_gpr
[gprn
]);
75 spr_store_dump_spr(sprn
);
78 #if !defined(CONFIG_USER_ONLY)
79 static void spr_write_generic32(DisasContext
*ctx
, int sprn
, int gprn
)
82 TCGv t0
= tcg_temp_new();
83 tcg_gen_ext32u_tl(t0
, cpu_gpr
[gprn
]);
84 gen_store_spr(sprn
, t0
);
86 spr_store_dump_spr(sprn
);
88 spr_write_generic(ctx
, sprn
, gprn
);
92 static void spr_write_clear(DisasContext
*ctx
, int sprn
, int gprn
)
94 TCGv t0
= tcg_temp_new();
95 TCGv t1
= tcg_temp_new();
96 gen_load_spr(t0
, sprn
);
97 tcg_gen_neg_tl(t1
, cpu_gpr
[gprn
]);
98 tcg_gen_and_tl(t0
, t0
, t1
);
99 gen_store_spr(sprn
, t0
);
104 static void spr_access_nop(DisasContext
*ctx
, int sprn
, int gprn
)
110 /* SPR common to all PowerPC */
112 static void spr_read_xer(DisasContext
*ctx
, int gprn
, int sprn
)
114 gen_read_xer(ctx
, cpu_gpr
[gprn
]);
117 static void spr_write_xer(DisasContext
*ctx
, int sprn
, int gprn
)
119 gen_write_xer(cpu_gpr
[gprn
]);
123 static void spr_read_lr(DisasContext
*ctx
, int gprn
, int sprn
)
125 tcg_gen_mov_tl(cpu_gpr
[gprn
], cpu_lr
);
128 static void spr_write_lr(DisasContext
*ctx
, int sprn
, int gprn
)
130 tcg_gen_mov_tl(cpu_lr
, cpu_gpr
[gprn
]);
134 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
135 static void spr_read_cfar(DisasContext
*ctx
, int gprn
, int sprn
)
137 tcg_gen_mov_tl(cpu_gpr
[gprn
], cpu_cfar
);
140 static void spr_write_cfar(DisasContext
*ctx
, int sprn
, int gprn
)
142 tcg_gen_mov_tl(cpu_cfar
, cpu_gpr
[gprn
]);
144 #endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
147 static void spr_read_ctr(DisasContext
*ctx
, int gprn
, int sprn
)
149 tcg_gen_mov_tl(cpu_gpr
[gprn
], cpu_ctr
);
152 static void spr_write_ctr(DisasContext
*ctx
, int sprn
, int gprn
)
154 tcg_gen_mov_tl(cpu_ctr
, cpu_gpr
[gprn
]);
157 /* User read access to SPR */
163 static void spr_read_ureg(DisasContext
*ctx
, int gprn
, int sprn
)
165 gen_load_spr(cpu_gpr
[gprn
], sprn
+ 0x10);
168 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
169 static void spr_write_ureg(DisasContext
*ctx
, int sprn
, int gprn
)
171 gen_store_spr(sprn
+ 0x10, cpu_gpr
[gprn
]);
175 /* SPR common to all non-embedded PowerPC */
177 #if !defined(CONFIG_USER_ONLY)
178 static void spr_read_decr(DisasContext
*ctx
, int gprn
, int sprn
)
180 if (tb_cflags(ctx
->tb
) & CF_USE_ICOUNT
) {
183 gen_helper_load_decr(cpu_gpr
[gprn
], cpu_env
);
184 if (tb_cflags(ctx
->tb
) & CF_USE_ICOUNT
) {
186 gen_stop_exception(ctx
);
190 static void spr_write_decr(DisasContext
*ctx
, int sprn
, int gprn
)
192 if (tb_cflags(ctx
->tb
) & CF_USE_ICOUNT
) {
195 gen_helper_store_decr(cpu_env
, cpu_gpr
[gprn
]);
196 if (tb_cflags(ctx
->tb
) & CF_USE_ICOUNT
) {
198 gen_stop_exception(ctx
);
203 /* SPR common to all non-embedded PowerPC, except 601 */
205 static void spr_read_tbl(DisasContext
*ctx
, int gprn
, int sprn
)
207 if (tb_cflags(ctx
->tb
) & CF_USE_ICOUNT
) {
210 gen_helper_load_tbl(cpu_gpr
[gprn
], cpu_env
);
211 if (tb_cflags(ctx
->tb
) & CF_USE_ICOUNT
) {
213 gen_stop_exception(ctx
);
217 static void spr_read_tbu(DisasContext
*ctx
, int gprn
, int sprn
)
219 if (tb_cflags(ctx
->tb
) & CF_USE_ICOUNT
) {
222 gen_helper_load_tbu(cpu_gpr
[gprn
], cpu_env
);
223 if (tb_cflags(ctx
->tb
) & CF_USE_ICOUNT
) {
225 gen_stop_exception(ctx
);
229 __attribute__ (( unused
))
230 static void spr_read_atbl(DisasContext
*ctx
, int gprn
, int sprn
)
232 gen_helper_load_atbl(cpu_gpr
[gprn
], cpu_env
);
235 __attribute__ (( unused
))
236 static void spr_read_atbu(DisasContext
*ctx
, int gprn
, int sprn
)
238 gen_helper_load_atbu(cpu_gpr
[gprn
], cpu_env
);
241 #if !defined(CONFIG_USER_ONLY)
242 static void spr_write_tbl(DisasContext
*ctx
, int sprn
, int gprn
)
244 if (tb_cflags(ctx
->tb
) & CF_USE_ICOUNT
) {
247 gen_helper_store_tbl(cpu_env
, cpu_gpr
[gprn
]);
248 if (tb_cflags(ctx
->tb
) & CF_USE_ICOUNT
) {
250 gen_stop_exception(ctx
);
254 static void spr_write_tbu(DisasContext
*ctx
, int sprn
, int gprn
)
256 if (tb_cflags(ctx
->tb
) & CF_USE_ICOUNT
) {
259 gen_helper_store_tbu(cpu_env
, cpu_gpr
[gprn
]);
260 if (tb_cflags(ctx
->tb
) & CF_USE_ICOUNT
) {
262 gen_stop_exception(ctx
);
266 __attribute__ (( unused
))
267 static void spr_write_atbl(DisasContext
*ctx
, int sprn
, int gprn
)
269 gen_helper_store_atbl(cpu_env
, cpu_gpr
[gprn
]);
272 __attribute__ (( unused
))
273 static void spr_write_atbu(DisasContext
*ctx
, int sprn
, int gprn
)
275 gen_helper_store_atbu(cpu_env
, cpu_gpr
[gprn
]);
278 #if defined(TARGET_PPC64)
279 __attribute__ (( unused
))
280 static void spr_read_purr(DisasContext
*ctx
, int gprn
, int sprn
)
282 gen_helper_load_purr(cpu_gpr
[gprn
], cpu_env
);
286 static void spr_read_hdecr(DisasContext
*ctx
, int gprn
, int sprn
)
288 if (tb_cflags(ctx
->tb
) & CF_USE_ICOUNT
) {
291 gen_helper_load_hdecr(cpu_gpr
[gprn
], cpu_env
);
292 if (tb_cflags(ctx
->tb
) & CF_USE_ICOUNT
) {
294 gen_stop_exception(ctx
);
298 static void spr_write_hdecr(DisasContext
*ctx
, int sprn
, int gprn
)
300 if (tb_cflags(ctx
->tb
) & CF_USE_ICOUNT
) {
303 gen_helper_store_hdecr(cpu_env
, cpu_gpr
[gprn
]);
304 if (tb_cflags(ctx
->tb
) & CF_USE_ICOUNT
) {
306 gen_stop_exception(ctx
);
313 #if !defined(CONFIG_USER_ONLY)
314 /* IBAT0U...IBAT0U */
315 /* IBAT0L...IBAT7L */
316 static void spr_read_ibat(DisasContext
*ctx
, int gprn
, int sprn
)
318 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, IBAT
[sprn
& 1][(sprn
- SPR_IBAT0U
) / 2]));
321 static void spr_read_ibat_h(DisasContext
*ctx
, int gprn
, int sprn
)
323 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, IBAT
[sprn
& 1][((sprn
- SPR_IBAT4U
) / 2) + 4]));
326 static void spr_write_ibatu(DisasContext
*ctx
, int sprn
, int gprn
)
328 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0U
) / 2);
329 gen_helper_store_ibatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
330 tcg_temp_free_i32(t0
);
333 static void spr_write_ibatu_h(DisasContext
*ctx
, int sprn
, int gprn
)
335 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_IBAT4U
) / 2) + 4);
336 gen_helper_store_ibatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
337 tcg_temp_free_i32(t0
);
340 static void spr_write_ibatl(DisasContext
*ctx
, int sprn
, int gprn
)
342 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0L
) / 2);
343 gen_helper_store_ibatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
344 tcg_temp_free_i32(t0
);
347 static void spr_write_ibatl_h(DisasContext
*ctx
, int sprn
, int gprn
)
349 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_IBAT4L
) / 2) + 4);
350 gen_helper_store_ibatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
351 tcg_temp_free_i32(t0
);
354 /* DBAT0U...DBAT7U */
355 /* DBAT0L...DBAT7L */
356 static void spr_read_dbat(DisasContext
*ctx
, int gprn
, int sprn
)
358 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, DBAT
[sprn
& 1][(sprn
- SPR_DBAT0U
) / 2]));
361 static void spr_read_dbat_h(DisasContext
*ctx
, int gprn
, int sprn
)
363 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, DBAT
[sprn
& 1][((sprn
- SPR_DBAT4U
) / 2) + 4]));
366 static void spr_write_dbatu(DisasContext
*ctx
, int sprn
, int gprn
)
368 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_DBAT0U
) / 2);
369 gen_helper_store_dbatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
370 tcg_temp_free_i32(t0
);
373 static void spr_write_dbatu_h(DisasContext
*ctx
, int sprn
, int gprn
)
375 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_DBAT4U
) / 2) + 4);
376 gen_helper_store_dbatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
377 tcg_temp_free_i32(t0
);
380 static void spr_write_dbatl(DisasContext
*ctx
, int sprn
, int gprn
)
382 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_DBAT0L
) / 2);
383 gen_helper_store_dbatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
384 tcg_temp_free_i32(t0
);
387 static void spr_write_dbatl_h(DisasContext
*ctx
, int sprn
, int gprn
)
389 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_DBAT4L
) / 2) + 4);
390 gen_helper_store_dbatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
391 tcg_temp_free_i32(t0
);
395 static void spr_write_sdr1(DisasContext
*ctx
, int sprn
, int gprn
)
397 gen_helper_store_sdr1(cpu_env
, cpu_gpr
[gprn
]);
400 #if defined(TARGET_PPC64)
401 /* 64 bits PowerPC specific SPRs */
403 static void spr_write_pidr(DisasContext
*ctx
, int sprn
, int gprn
)
405 gen_helper_store_pidr(cpu_env
, cpu_gpr
[gprn
]);
408 static void spr_read_hior(DisasContext
*ctx
, int gprn
, int sprn
)
410 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, excp_prefix
));
413 static void spr_write_hior(DisasContext
*ctx
, int sprn
, int gprn
)
415 TCGv t0
= tcg_temp_new();
416 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], 0x3FFFFF00000ULL
);
417 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_prefix
));
423 /* PowerPC 601 specific registers */
425 static void spr_read_601_rtcl(DisasContext
*ctx
, int gprn
, int sprn
)
427 gen_helper_load_601_rtcl(cpu_gpr
[gprn
], cpu_env
);
430 static void spr_read_601_rtcu(DisasContext
*ctx
, int gprn
, int sprn
)
432 gen_helper_load_601_rtcu(cpu_gpr
[gprn
], cpu_env
);
435 #if !defined(CONFIG_USER_ONLY)
436 static void spr_write_601_rtcu(DisasContext
*ctx
, int sprn
, int gprn
)
438 gen_helper_store_601_rtcu(cpu_env
, cpu_gpr
[gprn
]);
441 static void spr_write_601_rtcl(DisasContext
*ctx
, int sprn
, int gprn
)
443 gen_helper_store_601_rtcl(cpu_env
, cpu_gpr
[gprn
]);
446 static void spr_write_hid0_601(DisasContext
*ctx
, int sprn
, int gprn
)
448 gen_helper_store_hid0_601(cpu_env
, cpu_gpr
[gprn
]);
449 /* Must stop the translation as endianness may have changed */
450 gen_stop_exception(ctx
);
455 #if !defined(CONFIG_USER_ONLY)
456 static void spr_read_601_ubat(DisasContext
*ctx
, int gprn
, int sprn
)
458 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, IBAT
[sprn
& 1][(sprn
- SPR_IBAT0U
) / 2]));
461 static void spr_write_601_ubatu(DisasContext
*ctx
, int sprn
, int gprn
)
463 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0U
) / 2);
464 gen_helper_store_601_batl(cpu_env
, t0
, cpu_gpr
[gprn
]);
465 tcg_temp_free_i32(t0
);
468 static void spr_write_601_ubatl(DisasContext
*ctx
, int sprn
, int gprn
)
470 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0U
) / 2);
471 gen_helper_store_601_batu(cpu_env
, t0
, cpu_gpr
[gprn
]);
472 tcg_temp_free_i32(t0
);
476 /* PowerPC 40x specific registers */
477 #if !defined(CONFIG_USER_ONLY)
478 static void spr_read_40x_pit(DisasContext
*ctx
, int gprn
, int sprn
)
480 gen_helper_load_40x_pit(cpu_gpr
[gprn
], cpu_env
);
483 static void spr_write_40x_pit(DisasContext
*ctx
, int sprn
, int gprn
)
485 gen_helper_store_40x_pit(cpu_env
, cpu_gpr
[gprn
]);
488 static void spr_write_40x_dbcr0(DisasContext
*ctx
, int sprn
, int gprn
)
490 gen_helper_store_40x_dbcr0(cpu_env
, cpu_gpr
[gprn
]);
491 /* We must stop translation as we may have rebooted */
492 gen_stop_exception(ctx
);
495 static void spr_write_40x_sler(DisasContext
*ctx
, int sprn
, int gprn
)
497 gen_helper_store_40x_sler(cpu_env
, cpu_gpr
[gprn
]);
500 static void spr_write_booke_tcr(DisasContext
*ctx
, int sprn
, int gprn
)
502 gen_helper_store_booke_tcr(cpu_env
, cpu_gpr
[gprn
]);
505 static void spr_write_booke_tsr(DisasContext
*ctx
, int sprn
, int gprn
)
507 gen_helper_store_booke_tsr(cpu_env
, cpu_gpr
[gprn
]);
511 /* PowerPC 403 specific registers */
512 /* PBL1 / PBU1 / PBL2 / PBU2 */
513 #if !defined(CONFIG_USER_ONLY)
514 static void spr_read_403_pbr(DisasContext
*ctx
, int gprn
, int sprn
)
516 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, pb
[sprn
- SPR_403_PBL1
]));
519 static void spr_write_403_pbr(DisasContext
*ctx
, int sprn
, int gprn
)
521 TCGv_i32 t0
= tcg_const_i32(sprn
- SPR_403_PBL1
);
522 gen_helper_store_403_pbr(cpu_env
, t0
, cpu_gpr
[gprn
]);
523 tcg_temp_free_i32(t0
);
526 static void spr_write_pir(DisasContext
*ctx
, int sprn
, int gprn
)
528 TCGv t0
= tcg_temp_new();
529 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], 0xF);
530 gen_store_spr(SPR_PIR
, t0
);
535 /* SPE specific registers */
536 static void spr_read_spefscr(DisasContext
*ctx
, int gprn
, int sprn
)
538 TCGv_i32 t0
= tcg_temp_new_i32();
539 tcg_gen_ld_i32(t0
, cpu_env
, offsetof(CPUPPCState
, spe_fscr
));
540 tcg_gen_extu_i32_tl(cpu_gpr
[gprn
], t0
);
541 tcg_temp_free_i32(t0
);
544 static void spr_write_spefscr(DisasContext
*ctx
, int sprn
, int gprn
)
546 TCGv_i32 t0
= tcg_temp_new_i32();
547 tcg_gen_trunc_tl_i32(t0
, cpu_gpr
[gprn
]);
548 tcg_gen_st_i32(t0
, cpu_env
, offsetof(CPUPPCState
, spe_fscr
));
549 tcg_temp_free_i32(t0
);
552 #if !defined(CONFIG_USER_ONLY)
553 /* Callback used to write the exception vector base */
554 static void spr_write_excp_prefix(DisasContext
*ctx
, int sprn
, int gprn
)
556 TCGv t0
= tcg_temp_new();
557 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUPPCState
, ivpr_mask
));
558 tcg_gen_and_tl(t0
, t0
, cpu_gpr
[gprn
]);
559 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_prefix
));
560 gen_store_spr(sprn
, t0
);
564 static void spr_write_excp_vector(DisasContext
*ctx
, int sprn
, int gprn
)
568 if (sprn
>= SPR_BOOKE_IVOR0
&& sprn
<= SPR_BOOKE_IVOR15
) {
569 sprn_offs
= sprn
- SPR_BOOKE_IVOR0
;
570 } else if (sprn
>= SPR_BOOKE_IVOR32
&& sprn
<= SPR_BOOKE_IVOR37
) {
571 sprn_offs
= sprn
- SPR_BOOKE_IVOR32
+ 32;
572 } else if (sprn
>= SPR_BOOKE_IVOR38
&& sprn
<= SPR_BOOKE_IVOR42
) {
573 sprn_offs
= sprn
- SPR_BOOKE_IVOR38
+ 38;
575 printf("Trying to write an unknown exception vector %d %03x\n",
577 gen_inval_exception(ctx
, POWERPC_EXCP_PRIV_REG
);
581 TCGv t0
= tcg_temp_new();
582 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUPPCState
, ivor_mask
));
583 tcg_gen_and_tl(t0
, t0
, cpu_gpr
[gprn
]);
584 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_vectors
[sprn_offs
]));
585 gen_store_spr(sprn
, t0
);
590 static inline void vscr_init(CPUPPCState
*env
, uint32_t val
)
593 /* Altivec always uses round-to-nearest */
594 set_float_rounding_mode(float_round_nearest_even
, &env
->vec_status
);
595 set_flush_to_zero(vscr_nj
, &env
->vec_status
);
598 #ifdef CONFIG_USER_ONLY
599 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
600 oea_read, oea_write, one_reg_id, initial_value) \
601 _spr_register(env, num, name, uea_read, uea_write, initial_value)
602 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
603 oea_read, oea_write, hea_read, hea_write, \
604 one_reg_id, initial_value) \
605 _spr_register(env, num, name, uea_read, uea_write, initial_value)
607 #if !defined(CONFIG_KVM)
608 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
609 oea_read, oea_write, one_reg_id, initial_value) \
610 _spr_register(env, num, name, uea_read, uea_write, \
611 oea_read, oea_write, oea_read, oea_write, initial_value)
612 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
613 oea_read, oea_write, hea_read, hea_write, \
614 one_reg_id, initial_value) \
615 _spr_register(env, num, name, uea_read, uea_write, \
616 oea_read, oea_write, hea_read, hea_write, initial_value)
618 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
619 oea_read, oea_write, one_reg_id, initial_value) \
620 _spr_register(env, num, name, uea_read, uea_write, \
621 oea_read, oea_write, oea_read, oea_write, \
622 one_reg_id, initial_value)
623 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
624 oea_read, oea_write, hea_read, hea_write, \
625 one_reg_id, initial_value) \
626 _spr_register(env, num, name, uea_read, uea_write, \
627 oea_read, oea_write, hea_read, hea_write, \
628 one_reg_id, initial_value)
632 #define spr_register(env, num, name, uea_read, uea_write, \
633 oea_read, oea_write, initial_value) \
634 spr_register_kvm(env, num, name, uea_read, uea_write, \
635 oea_read, oea_write, 0, initial_value)
637 #define spr_register_hv(env, num, name, uea_read, uea_write, \
638 oea_read, oea_write, hea_read, hea_write, \
640 spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
641 oea_read, oea_write, hea_read, hea_write, \
644 static inline void _spr_register(CPUPPCState
*env
, int num
,
646 void (*uea_read
)(DisasContext
*ctx
, int gprn
, int sprn
),
647 void (*uea_write
)(DisasContext
*ctx
, int sprn
, int gprn
),
648 #if !defined(CONFIG_USER_ONLY)
650 void (*oea_read
)(DisasContext
*ctx
, int gprn
, int sprn
),
651 void (*oea_write
)(DisasContext
*ctx
, int sprn
, int gprn
),
652 void (*hea_read
)(DisasContext
*opaque
, int gprn
, int sprn
),
653 void (*hea_write
)(DisasContext
*opaque
, int sprn
, int gprn
),
655 #if defined(CONFIG_KVM)
658 target_ulong initial_value
)
662 spr
= &env
->spr_cb
[num
];
663 if (spr
->name
!= NULL
||env
-> spr
[num
] != 0x00000000 ||
664 #if !defined(CONFIG_USER_ONLY)
665 spr
->oea_read
!= NULL
|| spr
->oea_write
!= NULL
||
667 spr
->uea_read
!= NULL
|| spr
->uea_write
!= NULL
) {
668 printf("Error: Trying to register SPR %d (%03x) twice !\n", num
, num
);
671 #if defined(PPC_DEBUG_SPR)
672 printf("*** register spr %d (%03x) %s val " TARGET_FMT_lx
"\n", num
, num
,
673 name
, initial_value
);
676 spr
->uea_read
= uea_read
;
677 spr
->uea_write
= uea_write
;
678 #if !defined(CONFIG_USER_ONLY)
679 spr
->oea_read
= oea_read
;
680 spr
->oea_write
= oea_write
;
681 spr
->hea_read
= hea_read
;
682 spr
->hea_write
= hea_write
;
684 #if defined(CONFIG_KVM)
685 spr
->one_reg_id
= one_reg_id
,
687 env
->spr
[num
] = spr
->default_value
= initial_value
;
690 /* Generic PowerPC SPRs */
691 static void gen_spr_generic(CPUPPCState
*env
)
693 /* Integer processing */
694 spr_register(env
, SPR_XER
, "XER",
695 &spr_read_xer
, &spr_write_xer
,
696 &spr_read_xer
, &spr_write_xer
,
699 spr_register(env
, SPR_LR
, "LR",
700 &spr_read_lr
, &spr_write_lr
,
701 &spr_read_lr
, &spr_write_lr
,
703 spr_register(env
, SPR_CTR
, "CTR",
704 &spr_read_ctr
, &spr_write_ctr
,
705 &spr_read_ctr
, &spr_write_ctr
,
707 /* Interrupt processing */
708 spr_register(env
, SPR_SRR0
, "SRR0",
709 SPR_NOACCESS
, SPR_NOACCESS
,
710 &spr_read_generic
, &spr_write_generic
,
712 spr_register(env
, SPR_SRR1
, "SRR1",
713 SPR_NOACCESS
, SPR_NOACCESS
,
714 &spr_read_generic
, &spr_write_generic
,
716 /* Processor control */
717 spr_register(env
, SPR_SPRG0
, "SPRG0",
718 SPR_NOACCESS
, SPR_NOACCESS
,
719 &spr_read_generic
, &spr_write_generic
,
721 spr_register(env
, SPR_SPRG1
, "SPRG1",
722 SPR_NOACCESS
, SPR_NOACCESS
,
723 &spr_read_generic
, &spr_write_generic
,
725 spr_register(env
, SPR_SPRG2
, "SPRG2",
726 SPR_NOACCESS
, SPR_NOACCESS
,
727 &spr_read_generic
, &spr_write_generic
,
729 spr_register(env
, SPR_SPRG3
, "SPRG3",
730 SPR_NOACCESS
, SPR_NOACCESS
,
731 &spr_read_generic
, &spr_write_generic
,
735 /* SPR common to all non-embedded PowerPC, including 601 */
736 static void gen_spr_ne_601(CPUPPCState
*env
)
738 /* Exception processing */
739 spr_register_kvm(env
, SPR_DSISR
, "DSISR",
740 SPR_NOACCESS
, SPR_NOACCESS
,
741 &spr_read_generic
, &spr_write_generic
,
742 KVM_REG_PPC_DSISR
, 0x00000000);
743 spr_register_kvm(env
, SPR_DAR
, "DAR",
744 SPR_NOACCESS
, SPR_NOACCESS
,
745 &spr_read_generic
, &spr_write_generic
,
746 KVM_REG_PPC_DAR
, 0x00000000);
748 spr_register(env
, SPR_DECR
, "DECR",
749 SPR_NOACCESS
, SPR_NOACCESS
,
750 &spr_read_decr
, &spr_write_decr
,
754 /* Storage Description Register 1 */
755 static void gen_spr_sdr1(CPUPPCState
*env
)
757 #ifndef CONFIG_USER_ONLY
758 if (env
->has_hv_mode
) {
759 /* SDR1 is a hypervisor resource on CPUs which have a
761 spr_register_hv(env
, SPR_SDR1
, "SDR1",
762 SPR_NOACCESS
, SPR_NOACCESS
,
763 SPR_NOACCESS
, SPR_NOACCESS
,
764 &spr_read_generic
, &spr_write_sdr1
,
767 spr_register(env
, SPR_SDR1
, "SDR1",
768 SPR_NOACCESS
, SPR_NOACCESS
,
769 &spr_read_generic
, &spr_write_sdr1
,
776 static void gen_low_BATs(CPUPPCState
*env
)
778 #if !defined(CONFIG_USER_ONLY)
779 spr_register(env
, SPR_IBAT0U
, "IBAT0U",
780 SPR_NOACCESS
, SPR_NOACCESS
,
781 &spr_read_ibat
, &spr_write_ibatu
,
783 spr_register(env
, SPR_IBAT0L
, "IBAT0L",
784 SPR_NOACCESS
, SPR_NOACCESS
,
785 &spr_read_ibat
, &spr_write_ibatl
,
787 spr_register(env
, SPR_IBAT1U
, "IBAT1U",
788 SPR_NOACCESS
, SPR_NOACCESS
,
789 &spr_read_ibat
, &spr_write_ibatu
,
791 spr_register(env
, SPR_IBAT1L
, "IBAT1L",
792 SPR_NOACCESS
, SPR_NOACCESS
,
793 &spr_read_ibat
, &spr_write_ibatl
,
795 spr_register(env
, SPR_IBAT2U
, "IBAT2U",
796 SPR_NOACCESS
, SPR_NOACCESS
,
797 &spr_read_ibat
, &spr_write_ibatu
,
799 spr_register(env
, SPR_IBAT2L
, "IBAT2L",
800 SPR_NOACCESS
, SPR_NOACCESS
,
801 &spr_read_ibat
, &spr_write_ibatl
,
803 spr_register(env
, SPR_IBAT3U
, "IBAT3U",
804 SPR_NOACCESS
, SPR_NOACCESS
,
805 &spr_read_ibat
, &spr_write_ibatu
,
807 spr_register(env
, SPR_IBAT3L
, "IBAT3L",
808 SPR_NOACCESS
, SPR_NOACCESS
,
809 &spr_read_ibat
, &spr_write_ibatl
,
811 spr_register(env
, SPR_DBAT0U
, "DBAT0U",
812 SPR_NOACCESS
, SPR_NOACCESS
,
813 &spr_read_dbat
, &spr_write_dbatu
,
815 spr_register(env
, SPR_DBAT0L
, "DBAT0L",
816 SPR_NOACCESS
, SPR_NOACCESS
,
817 &spr_read_dbat
, &spr_write_dbatl
,
819 spr_register(env
, SPR_DBAT1U
, "DBAT1U",
820 SPR_NOACCESS
, SPR_NOACCESS
,
821 &spr_read_dbat
, &spr_write_dbatu
,
823 spr_register(env
, SPR_DBAT1L
, "DBAT1L",
824 SPR_NOACCESS
, SPR_NOACCESS
,
825 &spr_read_dbat
, &spr_write_dbatl
,
827 spr_register(env
, SPR_DBAT2U
, "DBAT2U",
828 SPR_NOACCESS
, SPR_NOACCESS
,
829 &spr_read_dbat
, &spr_write_dbatu
,
831 spr_register(env
, SPR_DBAT2L
, "DBAT2L",
832 SPR_NOACCESS
, SPR_NOACCESS
,
833 &spr_read_dbat
, &spr_write_dbatl
,
835 spr_register(env
, SPR_DBAT3U
, "DBAT3U",
836 SPR_NOACCESS
, SPR_NOACCESS
,
837 &spr_read_dbat
, &spr_write_dbatu
,
839 spr_register(env
, SPR_DBAT3L
, "DBAT3L",
840 SPR_NOACCESS
, SPR_NOACCESS
,
841 &spr_read_dbat
, &spr_write_dbatl
,
848 static void gen_high_BATs(CPUPPCState
*env
)
850 #if !defined(CONFIG_USER_ONLY)
851 spr_register(env
, SPR_IBAT4U
, "IBAT4U",
852 SPR_NOACCESS
, SPR_NOACCESS
,
853 &spr_read_ibat_h
, &spr_write_ibatu_h
,
855 spr_register(env
, SPR_IBAT4L
, "IBAT4L",
856 SPR_NOACCESS
, SPR_NOACCESS
,
857 &spr_read_ibat_h
, &spr_write_ibatl_h
,
859 spr_register(env
, SPR_IBAT5U
, "IBAT5U",
860 SPR_NOACCESS
, SPR_NOACCESS
,
861 &spr_read_ibat_h
, &spr_write_ibatu_h
,
863 spr_register(env
, SPR_IBAT5L
, "IBAT5L",
864 SPR_NOACCESS
, SPR_NOACCESS
,
865 &spr_read_ibat_h
, &spr_write_ibatl_h
,
867 spr_register(env
, SPR_IBAT6U
, "IBAT6U",
868 SPR_NOACCESS
, SPR_NOACCESS
,
869 &spr_read_ibat_h
, &spr_write_ibatu_h
,
871 spr_register(env
, SPR_IBAT6L
, "IBAT6L",
872 SPR_NOACCESS
, SPR_NOACCESS
,
873 &spr_read_ibat_h
, &spr_write_ibatl_h
,
875 spr_register(env
, SPR_IBAT7U
, "IBAT7U",
876 SPR_NOACCESS
, SPR_NOACCESS
,
877 &spr_read_ibat_h
, &spr_write_ibatu_h
,
879 spr_register(env
, SPR_IBAT7L
, "IBAT7L",
880 SPR_NOACCESS
, SPR_NOACCESS
,
881 &spr_read_ibat_h
, &spr_write_ibatl_h
,
883 spr_register(env
, SPR_DBAT4U
, "DBAT4U",
884 SPR_NOACCESS
, SPR_NOACCESS
,
885 &spr_read_dbat_h
, &spr_write_dbatu_h
,
887 spr_register(env
, SPR_DBAT4L
, "DBAT4L",
888 SPR_NOACCESS
, SPR_NOACCESS
,
889 &spr_read_dbat_h
, &spr_write_dbatl_h
,
891 spr_register(env
, SPR_DBAT5U
, "DBAT5U",
892 SPR_NOACCESS
, SPR_NOACCESS
,
893 &spr_read_dbat_h
, &spr_write_dbatu_h
,
895 spr_register(env
, SPR_DBAT5L
, "DBAT5L",
896 SPR_NOACCESS
, SPR_NOACCESS
,
897 &spr_read_dbat_h
, &spr_write_dbatl_h
,
899 spr_register(env
, SPR_DBAT6U
, "DBAT6U",
900 SPR_NOACCESS
, SPR_NOACCESS
,
901 &spr_read_dbat_h
, &spr_write_dbatu_h
,
903 spr_register(env
, SPR_DBAT6L
, "DBAT6L",
904 SPR_NOACCESS
, SPR_NOACCESS
,
905 &spr_read_dbat_h
, &spr_write_dbatl_h
,
907 spr_register(env
, SPR_DBAT7U
, "DBAT7U",
908 SPR_NOACCESS
, SPR_NOACCESS
,
909 &spr_read_dbat_h
, &spr_write_dbatu_h
,
911 spr_register(env
, SPR_DBAT7L
, "DBAT7L",
912 SPR_NOACCESS
, SPR_NOACCESS
,
913 &spr_read_dbat_h
, &spr_write_dbatl_h
,
919 /* Generic PowerPC time base */
920 static void gen_tbl(CPUPPCState
*env
)
922 spr_register(env
, SPR_VTBL
, "TBL",
923 &spr_read_tbl
, SPR_NOACCESS
,
924 &spr_read_tbl
, SPR_NOACCESS
,
926 spr_register(env
, SPR_TBL
, "TBL",
927 &spr_read_tbl
, SPR_NOACCESS
,
928 &spr_read_tbl
, &spr_write_tbl
,
930 spr_register(env
, SPR_VTBU
, "TBU",
931 &spr_read_tbu
, SPR_NOACCESS
,
932 &spr_read_tbu
, SPR_NOACCESS
,
934 spr_register(env
, SPR_TBU
, "TBU",
935 &spr_read_tbu
, SPR_NOACCESS
,
936 &spr_read_tbu
, &spr_write_tbu
,
940 /* Softare table search registers */
941 static void gen_6xx_7xx_soft_tlb(CPUPPCState
*env
, int nb_tlbs
, int nb_ways
)
943 #if !defined(CONFIG_USER_ONLY)
944 env
->nb_tlb
= nb_tlbs
;
945 env
->nb_ways
= nb_ways
;
947 env
->tlb_type
= TLB_6XX
;
948 spr_register(env
, SPR_DMISS
, "DMISS",
949 SPR_NOACCESS
, SPR_NOACCESS
,
950 &spr_read_generic
, SPR_NOACCESS
,
952 spr_register(env
, SPR_DCMP
, "DCMP",
953 SPR_NOACCESS
, SPR_NOACCESS
,
954 &spr_read_generic
, SPR_NOACCESS
,
956 spr_register(env
, SPR_HASH1
, "HASH1",
957 SPR_NOACCESS
, SPR_NOACCESS
,
958 &spr_read_generic
, SPR_NOACCESS
,
960 spr_register(env
, SPR_HASH2
, "HASH2",
961 SPR_NOACCESS
, SPR_NOACCESS
,
962 &spr_read_generic
, SPR_NOACCESS
,
964 spr_register(env
, SPR_IMISS
, "IMISS",
965 SPR_NOACCESS
, SPR_NOACCESS
,
966 &spr_read_generic
, SPR_NOACCESS
,
968 spr_register(env
, SPR_ICMP
, "ICMP",
969 SPR_NOACCESS
, SPR_NOACCESS
,
970 &spr_read_generic
, SPR_NOACCESS
,
972 spr_register(env
, SPR_RPA
, "RPA",
973 SPR_NOACCESS
, SPR_NOACCESS
,
974 &spr_read_generic
, &spr_write_generic
,
979 /* SPR common to MPC755 and G2 */
980 static void gen_spr_G2_755(CPUPPCState
*env
)
983 spr_register(env
, SPR_SPRG4
, "SPRG4",
984 SPR_NOACCESS
, SPR_NOACCESS
,
985 &spr_read_generic
, &spr_write_generic
,
987 spr_register(env
, SPR_SPRG5
, "SPRG5",
988 SPR_NOACCESS
, SPR_NOACCESS
,
989 &spr_read_generic
, &spr_write_generic
,
991 spr_register(env
, SPR_SPRG6
, "SPRG6",
992 SPR_NOACCESS
, SPR_NOACCESS
,
993 &spr_read_generic
, &spr_write_generic
,
995 spr_register(env
, SPR_SPRG7
, "SPRG7",
996 SPR_NOACCESS
, SPR_NOACCESS
,
997 &spr_read_generic
, &spr_write_generic
,
1001 /* SPR common to all 7xx PowerPC implementations */
1002 static void gen_spr_7xx(CPUPPCState
*env
)
1005 /* XXX : not implemented */
1006 spr_register_kvm(env
, SPR_DABR
, "DABR",
1007 SPR_NOACCESS
, SPR_NOACCESS
,
1008 &spr_read_generic
, &spr_write_generic
,
1009 KVM_REG_PPC_DABR
, 0x00000000);
1010 /* XXX : not implemented */
1011 spr_register(env
, SPR_IABR
, "IABR",
1012 SPR_NOACCESS
, SPR_NOACCESS
,
1013 &spr_read_generic
, &spr_write_generic
,
1015 /* Cache management */
1016 /* XXX : not implemented */
1017 spr_register(env
, SPR_ICTC
, "ICTC",
1018 SPR_NOACCESS
, SPR_NOACCESS
,
1019 &spr_read_generic
, &spr_write_generic
,
1021 /* Performance monitors */
1022 /* XXX : not implemented */
1023 spr_register(env
, SPR_7XX_MMCR0
, "MMCR0",
1024 SPR_NOACCESS
, SPR_NOACCESS
,
1025 &spr_read_generic
, &spr_write_generic
,
1027 /* XXX : not implemented */
1028 spr_register(env
, SPR_7XX_MMCR1
, "MMCR1",
1029 SPR_NOACCESS
, SPR_NOACCESS
,
1030 &spr_read_generic
, &spr_write_generic
,
1032 /* XXX : not implemented */
1033 spr_register(env
, SPR_7XX_PMC1
, "PMC1",
1034 SPR_NOACCESS
, SPR_NOACCESS
,
1035 &spr_read_generic
, &spr_write_generic
,
1037 /* XXX : not implemented */
1038 spr_register(env
, SPR_7XX_PMC2
, "PMC2",
1039 SPR_NOACCESS
, SPR_NOACCESS
,
1040 &spr_read_generic
, &spr_write_generic
,
1042 /* XXX : not implemented */
1043 spr_register(env
, SPR_7XX_PMC3
, "PMC3",
1044 SPR_NOACCESS
, SPR_NOACCESS
,
1045 &spr_read_generic
, &spr_write_generic
,
1047 /* XXX : not implemented */
1048 spr_register(env
, SPR_7XX_PMC4
, "PMC4",
1049 SPR_NOACCESS
, SPR_NOACCESS
,
1050 &spr_read_generic
, &spr_write_generic
,
1052 /* XXX : not implemented */
1053 spr_register(env
, SPR_7XX_SIAR
, "SIAR",
1054 SPR_NOACCESS
, SPR_NOACCESS
,
1055 &spr_read_generic
, SPR_NOACCESS
,
1057 /* XXX : not implemented */
1058 spr_register(env
, SPR_7XX_UMMCR0
, "UMMCR0",
1059 &spr_read_ureg
, SPR_NOACCESS
,
1060 &spr_read_ureg
, SPR_NOACCESS
,
1062 /* XXX : not implemented */
1063 spr_register(env
, SPR_7XX_UMMCR1
, "UMMCR1",
1064 &spr_read_ureg
, SPR_NOACCESS
,
1065 &spr_read_ureg
, SPR_NOACCESS
,
1067 /* XXX : not implemented */
1068 spr_register(env
, SPR_7XX_UPMC1
, "UPMC1",
1069 &spr_read_ureg
, SPR_NOACCESS
,
1070 &spr_read_ureg
, SPR_NOACCESS
,
1072 /* XXX : not implemented */
1073 spr_register(env
, SPR_7XX_UPMC2
, "UPMC2",
1074 &spr_read_ureg
, SPR_NOACCESS
,
1075 &spr_read_ureg
, SPR_NOACCESS
,
1077 /* XXX : not implemented */
1078 spr_register(env
, SPR_7XX_UPMC3
, "UPMC3",
1079 &spr_read_ureg
, SPR_NOACCESS
,
1080 &spr_read_ureg
, SPR_NOACCESS
,
1082 /* XXX : not implemented */
1083 spr_register(env
, SPR_7XX_UPMC4
, "UPMC4",
1084 &spr_read_ureg
, SPR_NOACCESS
,
1085 &spr_read_ureg
, SPR_NOACCESS
,
1087 /* XXX : not implemented */
1088 spr_register(env
, SPR_7XX_USIAR
, "USIAR",
1089 &spr_read_ureg
, SPR_NOACCESS
,
1090 &spr_read_ureg
, SPR_NOACCESS
,
1092 /* External access control */
1093 /* XXX : not implemented */
1094 spr_register(env
, SPR_EAR
, "EAR",
1095 SPR_NOACCESS
, SPR_NOACCESS
,
1096 &spr_read_generic
, &spr_write_generic
,
1101 #ifndef CONFIG_USER_ONLY
1102 static void spr_write_amr(DisasContext
*ctx
, int sprn
, int gprn
)
1104 TCGv t0
= tcg_temp_new();
1105 TCGv t1
= tcg_temp_new();
1106 TCGv t2
= tcg_temp_new();
1108 /* Note, the HV=1 PR=0 case is handled earlier by simply using
1109 * spr_write_generic for HV mode in the SPR table
1112 /* Build insertion mask into t1 based on context */
1114 gen_load_spr(t1
, SPR_UAMOR
);
1116 gen_load_spr(t1
, SPR_AMOR
);
1119 /* Mask new bits into t2 */
1120 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1122 /* Load AMR and clear new bits in t0 */
1123 gen_load_spr(t0
, SPR_AMR
);
1124 tcg_gen_andc_tl(t0
, t0
, t1
);
1126 /* Or'in new bits and write it out */
1127 tcg_gen_or_tl(t0
, t0
, t2
);
1128 gen_store_spr(SPR_AMR
, t0
);
1129 spr_store_dump_spr(SPR_AMR
);
1136 static void spr_write_uamor(DisasContext
*ctx
, int sprn
, int gprn
)
1138 TCGv t0
= tcg_temp_new();
1139 TCGv t1
= tcg_temp_new();
1140 TCGv t2
= tcg_temp_new();
1142 /* Note, the HV=1 case is handled earlier by simply using
1143 * spr_write_generic for HV mode in the SPR table
1146 /* Build insertion mask into t1 based on context */
1147 gen_load_spr(t1
, SPR_AMOR
);
1149 /* Mask new bits into t2 */
1150 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1152 /* Load AMR and clear new bits in t0 */
1153 gen_load_spr(t0
, SPR_UAMOR
);
1154 tcg_gen_andc_tl(t0
, t0
, t1
);
1156 /* Or'in new bits and write it out */
1157 tcg_gen_or_tl(t0
, t0
, t2
);
1158 gen_store_spr(SPR_UAMOR
, t0
);
1159 spr_store_dump_spr(SPR_UAMOR
);
1166 static void spr_write_iamr(DisasContext
*ctx
, int sprn
, int gprn
)
1168 TCGv t0
= tcg_temp_new();
1169 TCGv t1
= tcg_temp_new();
1170 TCGv t2
= tcg_temp_new();
1172 /* Note, the HV=1 case is handled earlier by simply using
1173 * spr_write_generic for HV mode in the SPR table
1176 /* Build insertion mask into t1 based on context */
1177 gen_load_spr(t1
, SPR_AMOR
);
1179 /* Mask new bits into t2 */
1180 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1182 /* Load AMR and clear new bits in t0 */
1183 gen_load_spr(t0
, SPR_IAMR
);
1184 tcg_gen_andc_tl(t0
, t0
, t1
);
1186 /* Or'in new bits and write it out */
1187 tcg_gen_or_tl(t0
, t0
, t2
);
1188 gen_store_spr(SPR_IAMR
, t0
);
1189 spr_store_dump_spr(SPR_IAMR
);
1195 #endif /* CONFIG_USER_ONLY */
1197 static void gen_spr_amr(CPUPPCState
*env
)
1199 #ifndef CONFIG_USER_ONLY
1200 /* Virtual Page Class Key protection */
1201 /* The AMR is accessible either via SPR 13 or SPR 29. 13 is
1202 * userspace accessible, 29 is privileged. So we only need to set
1203 * the kvm ONE_REG id on one of them, we use 29 */
1204 spr_register(env
, SPR_UAMR
, "UAMR",
1205 &spr_read_generic
, &spr_write_amr
,
1206 &spr_read_generic
, &spr_write_amr
,
1208 spr_register_kvm_hv(env
, SPR_AMR
, "AMR",
1209 SPR_NOACCESS
, SPR_NOACCESS
,
1210 &spr_read_generic
, &spr_write_amr
,
1211 &spr_read_generic
, &spr_write_generic
,
1212 KVM_REG_PPC_AMR
, 0);
1213 spr_register_kvm_hv(env
, SPR_UAMOR
, "UAMOR",
1214 SPR_NOACCESS
, SPR_NOACCESS
,
1215 &spr_read_generic
, &spr_write_uamor
,
1216 &spr_read_generic
, &spr_write_generic
,
1217 KVM_REG_PPC_UAMOR
, 0);
1218 spr_register_hv(env
, SPR_AMOR
, "AMOR",
1219 SPR_NOACCESS
, SPR_NOACCESS
,
1220 SPR_NOACCESS
, SPR_NOACCESS
,
1221 &spr_read_generic
, &spr_write_generic
,
1223 #endif /* !CONFIG_USER_ONLY */
1226 static void gen_spr_iamr(CPUPPCState
*env
)
1228 #ifndef CONFIG_USER_ONLY
1229 spr_register_kvm_hv(env
, SPR_IAMR
, "IAMR",
1230 SPR_NOACCESS
, SPR_NOACCESS
,
1231 &spr_read_generic
, &spr_write_iamr
,
1232 &spr_read_generic
, &spr_write_generic
,
1233 KVM_REG_PPC_IAMR
, 0);
1234 #endif /* !CONFIG_USER_ONLY */
1236 #endif /* TARGET_PPC64 */
1238 #ifndef CONFIG_USER_ONLY
1239 static void spr_read_thrm(DisasContext
*ctx
, int gprn
, int sprn
)
1241 gen_helper_fixup_thrm(cpu_env
);
1242 gen_load_spr(cpu_gpr
[gprn
], sprn
);
1243 spr_load_dump_spr(sprn
);
1245 #endif /* !CONFIG_USER_ONLY */
1247 static void gen_spr_thrm(CPUPPCState
*env
)
1249 /* Thermal management */
1250 /* XXX : not implemented */
1251 spr_register(env
, SPR_THRM1
, "THRM1",
1252 SPR_NOACCESS
, SPR_NOACCESS
,
1253 &spr_read_thrm
, &spr_write_generic
,
1255 /* XXX : not implemented */
1256 spr_register(env
, SPR_THRM2
, "THRM2",
1257 SPR_NOACCESS
, SPR_NOACCESS
,
1258 &spr_read_thrm
, &spr_write_generic
,
1260 /* XXX : not implemented */
1261 spr_register(env
, SPR_THRM3
, "THRM3",
1262 SPR_NOACCESS
, SPR_NOACCESS
,
1263 &spr_read_thrm
, &spr_write_generic
,
1267 /* SPR specific to PowerPC 604 implementation */
1268 static void gen_spr_604(CPUPPCState
*env
)
1270 /* Processor identification */
1271 spr_register(env
, SPR_PIR
, "PIR",
1272 SPR_NOACCESS
, SPR_NOACCESS
,
1273 &spr_read_generic
, &spr_write_pir
,
1276 /* XXX : not implemented */
1277 spr_register(env
, SPR_IABR
, "IABR",
1278 SPR_NOACCESS
, SPR_NOACCESS
,
1279 &spr_read_generic
, &spr_write_generic
,
1281 /* XXX : not implemented */
1282 spr_register_kvm(env
, SPR_DABR
, "DABR",
1283 SPR_NOACCESS
, SPR_NOACCESS
,
1284 &spr_read_generic
, &spr_write_generic
,
1285 KVM_REG_PPC_DABR
, 0x00000000);
1286 /* Performance counters */
1287 /* XXX : not implemented */
1288 spr_register(env
, SPR_7XX_MMCR0
, "MMCR0",
1289 SPR_NOACCESS
, SPR_NOACCESS
,
1290 &spr_read_generic
, &spr_write_generic
,
1292 /* XXX : not implemented */
1293 spr_register(env
, SPR_7XX_PMC1
, "PMC1",
1294 SPR_NOACCESS
, SPR_NOACCESS
,
1295 &spr_read_generic
, &spr_write_generic
,
1297 /* XXX : not implemented */
1298 spr_register(env
, SPR_7XX_PMC2
, "PMC2",
1299 SPR_NOACCESS
, SPR_NOACCESS
,
1300 &spr_read_generic
, &spr_write_generic
,
1302 /* XXX : not implemented */
1303 spr_register(env
, SPR_7XX_SIAR
, "SIAR",
1304 SPR_NOACCESS
, SPR_NOACCESS
,
1305 &spr_read_generic
, SPR_NOACCESS
,
1307 /* XXX : not implemented */
1308 spr_register(env
, SPR_SDA
, "SDA",
1309 SPR_NOACCESS
, SPR_NOACCESS
,
1310 &spr_read_generic
, SPR_NOACCESS
,
1312 /* External access control */
1313 /* XXX : not implemented */
1314 spr_register(env
, SPR_EAR
, "EAR",
1315 SPR_NOACCESS
, SPR_NOACCESS
,
1316 &spr_read_generic
, &spr_write_generic
,
1320 /* SPR specific to PowerPC 603 implementation */
1321 static void gen_spr_603(CPUPPCState
*env
)
1323 /* External access control */
1324 /* XXX : not implemented */
1325 spr_register(env
, SPR_EAR
, "EAR",
1326 SPR_NOACCESS
, SPR_NOACCESS
,
1327 &spr_read_generic
, &spr_write_generic
,
1330 /* XXX : not implemented */
1331 spr_register(env
, SPR_IABR
, "IABR",
1332 SPR_NOACCESS
, SPR_NOACCESS
,
1333 &spr_read_generic
, &spr_write_generic
,
1338 /* SPR specific to PowerPC G2 implementation */
1339 static void gen_spr_G2(CPUPPCState
*env
)
1341 /* Memory base address */
1343 /* XXX : not implemented */
1344 spr_register(env
, SPR_MBAR
, "MBAR",
1345 SPR_NOACCESS
, SPR_NOACCESS
,
1346 &spr_read_generic
, &spr_write_generic
,
1348 /* Exception processing */
1349 spr_register(env
, SPR_BOOKE_CSRR0
, "CSRR0",
1350 SPR_NOACCESS
, SPR_NOACCESS
,
1351 &spr_read_generic
, &spr_write_generic
,
1353 spr_register(env
, SPR_BOOKE_CSRR1
, "CSRR1",
1354 SPR_NOACCESS
, SPR_NOACCESS
,
1355 &spr_read_generic
, &spr_write_generic
,
1358 /* XXX : not implemented */
1359 spr_register(env
, SPR_DABR
, "DABR",
1360 SPR_NOACCESS
, SPR_NOACCESS
,
1361 &spr_read_generic
, &spr_write_generic
,
1363 /* XXX : not implemented */
1364 spr_register(env
, SPR_DABR2
, "DABR2",
1365 SPR_NOACCESS
, SPR_NOACCESS
,
1366 &spr_read_generic
, &spr_write_generic
,
1368 /* XXX : not implemented */
1369 spr_register(env
, SPR_IABR
, "IABR",
1370 SPR_NOACCESS
, SPR_NOACCESS
,
1371 &spr_read_generic
, &spr_write_generic
,
1373 /* XXX : not implemented */
1374 spr_register(env
, SPR_IABR2
, "IABR2",
1375 SPR_NOACCESS
, SPR_NOACCESS
,
1376 &spr_read_generic
, &spr_write_generic
,
1378 /* XXX : not implemented */
1379 spr_register(env
, SPR_IBCR
, "IBCR",
1380 SPR_NOACCESS
, SPR_NOACCESS
,
1381 &spr_read_generic
, &spr_write_generic
,
1383 /* XXX : not implemented */
1384 spr_register(env
, SPR_DBCR
, "DBCR",
1385 SPR_NOACCESS
, SPR_NOACCESS
,
1386 &spr_read_generic
, &spr_write_generic
,
1390 /* SPR specific to PowerPC 602 implementation */
1391 static void gen_spr_602(CPUPPCState
*env
)
1394 /* XXX : not implemented */
1395 spr_register(env
, SPR_SER
, "SER",
1396 SPR_NOACCESS
, SPR_NOACCESS
,
1397 &spr_read_generic
, &spr_write_generic
,
1399 /* XXX : not implemented */
1400 spr_register(env
, SPR_SEBR
, "SEBR",
1401 SPR_NOACCESS
, SPR_NOACCESS
,
1402 &spr_read_generic
, &spr_write_generic
,
1404 /* XXX : not implemented */
1405 spr_register(env
, SPR_ESASRR
, "ESASRR",
1406 SPR_NOACCESS
, SPR_NOACCESS
,
1407 &spr_read_generic
, &spr_write_generic
,
1409 /* Floating point status */
1410 /* XXX : not implemented */
1411 spr_register(env
, SPR_SP
, "SP",
1412 SPR_NOACCESS
, SPR_NOACCESS
,
1413 &spr_read_generic
, &spr_write_generic
,
1415 /* XXX : not implemented */
1416 spr_register(env
, SPR_LT
, "LT",
1417 SPR_NOACCESS
, SPR_NOACCESS
,
1418 &spr_read_generic
, &spr_write_generic
,
1420 /* Watchdog timer */
1421 /* XXX : not implemented */
1422 spr_register(env
, SPR_TCR
, "TCR",
1423 SPR_NOACCESS
, SPR_NOACCESS
,
1424 &spr_read_generic
, &spr_write_generic
,
1426 /* Interrupt base */
1427 spr_register(env
, SPR_IBR
, "IBR",
1428 SPR_NOACCESS
, SPR_NOACCESS
,
1429 &spr_read_generic
, &spr_write_generic
,
1431 /* XXX : not implemented */
1432 spr_register(env
, SPR_IABR
, "IABR",
1433 SPR_NOACCESS
, SPR_NOACCESS
,
1434 &spr_read_generic
, &spr_write_generic
,
1438 /* SPR specific to PowerPC 601 implementation */
1439 static void gen_spr_601(CPUPPCState
*env
)
1441 /* Multiplication/division register */
1443 spr_register(env
, SPR_MQ
, "MQ",
1444 &spr_read_generic
, &spr_write_generic
,
1445 &spr_read_generic
, &spr_write_generic
,
1448 spr_register(env
, SPR_601_RTCU
, "RTCU",
1449 SPR_NOACCESS
, SPR_NOACCESS
,
1450 SPR_NOACCESS
, &spr_write_601_rtcu
,
1452 spr_register(env
, SPR_601_VRTCU
, "RTCU",
1453 &spr_read_601_rtcu
, SPR_NOACCESS
,
1454 &spr_read_601_rtcu
, SPR_NOACCESS
,
1456 spr_register(env
, SPR_601_RTCL
, "RTCL",
1457 SPR_NOACCESS
, SPR_NOACCESS
,
1458 SPR_NOACCESS
, &spr_write_601_rtcl
,
1460 spr_register(env
, SPR_601_VRTCL
, "RTCL",
1461 &spr_read_601_rtcl
, SPR_NOACCESS
,
1462 &spr_read_601_rtcl
, SPR_NOACCESS
,
1466 spr_register(env
, SPR_601_UDECR
, "UDECR",
1467 &spr_read_decr
, SPR_NOACCESS
,
1468 &spr_read_decr
, SPR_NOACCESS
,
1471 /* External access control */
1472 /* XXX : not implemented */
1473 spr_register(env
, SPR_EAR
, "EAR",
1474 SPR_NOACCESS
, SPR_NOACCESS
,
1475 &spr_read_generic
, &spr_write_generic
,
1477 /* Memory management */
1478 #if !defined(CONFIG_USER_ONLY)
1479 spr_register(env
, SPR_IBAT0U
, "IBAT0U",
1480 SPR_NOACCESS
, SPR_NOACCESS
,
1481 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1483 spr_register(env
, SPR_IBAT0L
, "IBAT0L",
1484 SPR_NOACCESS
, SPR_NOACCESS
,
1485 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1487 spr_register(env
, SPR_IBAT1U
, "IBAT1U",
1488 SPR_NOACCESS
, SPR_NOACCESS
,
1489 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1491 spr_register(env
, SPR_IBAT1L
, "IBAT1L",
1492 SPR_NOACCESS
, SPR_NOACCESS
,
1493 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1495 spr_register(env
, SPR_IBAT2U
, "IBAT2U",
1496 SPR_NOACCESS
, SPR_NOACCESS
,
1497 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1499 spr_register(env
, SPR_IBAT2L
, "IBAT2L",
1500 SPR_NOACCESS
, SPR_NOACCESS
,
1501 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1503 spr_register(env
, SPR_IBAT3U
, "IBAT3U",
1504 SPR_NOACCESS
, SPR_NOACCESS
,
1505 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1507 spr_register(env
, SPR_IBAT3L
, "IBAT3L",
1508 SPR_NOACCESS
, SPR_NOACCESS
,
1509 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1515 static void gen_spr_74xx(CPUPPCState
*env
)
1517 /* Processor identification */
1518 spr_register(env
, SPR_PIR
, "PIR",
1519 SPR_NOACCESS
, SPR_NOACCESS
,
1520 &spr_read_generic
, &spr_write_pir
,
1522 /* XXX : not implemented */
1523 spr_register(env
, SPR_74XX_MMCR2
, "MMCR2",
1524 SPR_NOACCESS
, SPR_NOACCESS
,
1525 &spr_read_generic
, &spr_write_generic
,
1527 /* XXX : not implemented */
1528 spr_register(env
, SPR_74XX_UMMCR2
, "UMMCR2",
1529 &spr_read_ureg
, SPR_NOACCESS
,
1530 &spr_read_ureg
, SPR_NOACCESS
,
1532 /* XXX: not implemented */
1533 spr_register(env
, SPR_BAMR
, "BAMR",
1534 SPR_NOACCESS
, SPR_NOACCESS
,
1535 &spr_read_generic
, &spr_write_generic
,
1537 /* XXX : not implemented */
1538 spr_register(env
, SPR_MSSCR0
, "MSSCR0",
1539 SPR_NOACCESS
, SPR_NOACCESS
,
1540 &spr_read_generic
, &spr_write_generic
,
1542 /* Hardware implementation registers */
1543 /* XXX : not implemented */
1544 spr_register(env
, SPR_HID0
, "HID0",
1545 SPR_NOACCESS
, SPR_NOACCESS
,
1546 &spr_read_generic
, &spr_write_generic
,
1548 /* XXX : not implemented */
1549 spr_register(env
, SPR_HID1
, "HID1",
1550 SPR_NOACCESS
, SPR_NOACCESS
,
1551 &spr_read_generic
, &spr_write_generic
,
1554 spr_register(env
, SPR_VRSAVE
, "VRSAVE",
1555 &spr_read_generic
, &spr_write_generic
,
1556 &spr_read_generic
, &spr_write_generic
,
1558 /* XXX : not implemented */
1559 spr_register(env
, SPR_L2CR
, "L2CR",
1560 SPR_NOACCESS
, SPR_NOACCESS
,
1561 &spr_read_generic
, spr_access_nop
,
1563 /* Not strictly an SPR */
1564 vscr_init(env
, 0x00010000);
1567 static void gen_l3_ctrl(CPUPPCState
*env
)
1570 /* XXX : not implemented */
1571 spr_register(env
, SPR_L3CR
, "L3CR",
1572 SPR_NOACCESS
, SPR_NOACCESS
,
1573 &spr_read_generic
, &spr_write_generic
,
1576 /* XXX : not implemented */
1577 spr_register(env
, SPR_L3ITCR0
, "L3ITCR0",
1578 SPR_NOACCESS
, SPR_NOACCESS
,
1579 &spr_read_generic
, &spr_write_generic
,
1582 /* XXX : not implemented */
1583 spr_register(env
, SPR_L3PM
, "L3PM",
1584 SPR_NOACCESS
, SPR_NOACCESS
,
1585 &spr_read_generic
, &spr_write_generic
,
1589 static void gen_74xx_soft_tlb(CPUPPCState
*env
, int nb_tlbs
, int nb_ways
)
1591 #if !defined(CONFIG_USER_ONLY)
1592 env
->nb_tlb
= nb_tlbs
;
1593 env
->nb_ways
= nb_ways
;
1595 env
->tlb_type
= TLB_6XX
;
1596 /* XXX : not implemented */
1597 spr_register(env
, SPR_PTEHI
, "PTEHI",
1598 SPR_NOACCESS
, SPR_NOACCESS
,
1599 &spr_read_generic
, &spr_write_generic
,
1601 /* XXX : not implemented */
1602 spr_register(env
, SPR_PTELO
, "PTELO",
1603 SPR_NOACCESS
, SPR_NOACCESS
,
1604 &spr_read_generic
, &spr_write_generic
,
1606 /* XXX : not implemented */
1607 spr_register(env
, SPR_TLBMISS
, "TLBMISS",
1608 SPR_NOACCESS
, SPR_NOACCESS
,
1609 &spr_read_generic
, &spr_write_generic
,
1614 #if !defined(CONFIG_USER_ONLY)
1615 static void spr_write_e500_l1csr0(DisasContext
*ctx
, int sprn
, int gprn
)
1617 TCGv t0
= tcg_temp_new();
1619 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], L1CSR0_DCE
| L1CSR0_CPE
);
1620 gen_store_spr(sprn
, t0
);
1624 static void spr_write_e500_l1csr1(DisasContext
*ctx
, int sprn
, int gprn
)
1626 TCGv t0
= tcg_temp_new();
1628 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], L1CSR1_ICE
| L1CSR1_CPE
);
1629 gen_store_spr(sprn
, t0
);
1633 static void spr_write_booke206_mmucsr0(DisasContext
*ctx
, int sprn
, int gprn
)
1635 gen_helper_booke206_tlbflush(cpu_env
, cpu_gpr
[gprn
]);
1638 static void spr_write_booke_pid(DisasContext
*ctx
, int sprn
, int gprn
)
1640 TCGv_i32 t0
= tcg_const_i32(sprn
);
1641 gen_helper_booke_setpid(cpu_env
, t0
, cpu_gpr
[gprn
]);
1642 tcg_temp_free_i32(t0
);
1646 static void gen_spr_usprg3(CPUPPCState
*env
)
1648 spr_register(env
, SPR_USPRG3
, "USPRG3",
1649 &spr_read_ureg
, SPR_NOACCESS
,
1650 &spr_read_ureg
, SPR_NOACCESS
,
1654 static void gen_spr_usprgh(CPUPPCState
*env
)
1656 spr_register(env
, SPR_USPRG4
, "USPRG4",
1657 &spr_read_ureg
, SPR_NOACCESS
,
1658 &spr_read_ureg
, SPR_NOACCESS
,
1660 spr_register(env
, SPR_USPRG5
, "USPRG5",
1661 &spr_read_ureg
, SPR_NOACCESS
,
1662 &spr_read_ureg
, SPR_NOACCESS
,
1664 spr_register(env
, SPR_USPRG6
, "USPRG6",
1665 &spr_read_ureg
, SPR_NOACCESS
,
1666 &spr_read_ureg
, SPR_NOACCESS
,
1668 spr_register(env
, SPR_USPRG7
, "USPRG7",
1669 &spr_read_ureg
, SPR_NOACCESS
,
1670 &spr_read_ureg
, SPR_NOACCESS
,
1674 /* PowerPC BookE SPR */
1675 static void gen_spr_BookE(CPUPPCState
*env
, uint64_t ivor_mask
)
1677 const char *ivor_names
[64] = {
1678 "IVOR0", "IVOR1", "IVOR2", "IVOR3",
1679 "IVOR4", "IVOR5", "IVOR6", "IVOR7",
1680 "IVOR8", "IVOR9", "IVOR10", "IVOR11",
1681 "IVOR12", "IVOR13", "IVOR14", "IVOR15",
1682 "IVOR16", "IVOR17", "IVOR18", "IVOR19",
1683 "IVOR20", "IVOR21", "IVOR22", "IVOR23",
1684 "IVOR24", "IVOR25", "IVOR26", "IVOR27",
1685 "IVOR28", "IVOR29", "IVOR30", "IVOR31",
1686 "IVOR32", "IVOR33", "IVOR34", "IVOR35",
1687 "IVOR36", "IVOR37", "IVOR38", "IVOR39",
1688 "IVOR40", "IVOR41", "IVOR42", "IVOR43",
1689 "IVOR44", "IVOR45", "IVOR46", "IVOR47",
1690 "IVOR48", "IVOR49", "IVOR50", "IVOR51",
1691 "IVOR52", "IVOR53", "IVOR54", "IVOR55",
1692 "IVOR56", "IVOR57", "IVOR58", "IVOR59",
1693 "IVOR60", "IVOR61", "IVOR62", "IVOR63",
1695 #define SPR_BOOKE_IVORxx (-1)
1696 int ivor_sprn
[64] = {
1697 SPR_BOOKE_IVOR0
, SPR_BOOKE_IVOR1
, SPR_BOOKE_IVOR2
, SPR_BOOKE_IVOR3
,
1698 SPR_BOOKE_IVOR4
, SPR_BOOKE_IVOR5
, SPR_BOOKE_IVOR6
, SPR_BOOKE_IVOR7
,
1699 SPR_BOOKE_IVOR8
, SPR_BOOKE_IVOR9
, SPR_BOOKE_IVOR10
, SPR_BOOKE_IVOR11
,
1700 SPR_BOOKE_IVOR12
, SPR_BOOKE_IVOR13
, SPR_BOOKE_IVOR14
, SPR_BOOKE_IVOR15
,
1701 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1702 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1703 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1704 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1705 SPR_BOOKE_IVOR32
, SPR_BOOKE_IVOR33
, SPR_BOOKE_IVOR34
, SPR_BOOKE_IVOR35
,
1706 SPR_BOOKE_IVOR36
, SPR_BOOKE_IVOR37
, SPR_BOOKE_IVOR38
, SPR_BOOKE_IVOR39
,
1707 SPR_BOOKE_IVOR40
, SPR_BOOKE_IVOR41
, SPR_BOOKE_IVOR42
, SPR_BOOKE_IVORxx
,
1708 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1709 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1710 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1711 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1712 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1716 /* Interrupt processing */
1717 spr_register(env
, SPR_BOOKE_CSRR0
, "CSRR0",
1718 SPR_NOACCESS
, SPR_NOACCESS
,
1719 &spr_read_generic
, &spr_write_generic
,
1721 spr_register(env
, SPR_BOOKE_CSRR1
, "CSRR1",
1722 SPR_NOACCESS
, SPR_NOACCESS
,
1723 &spr_read_generic
, &spr_write_generic
,
1726 /* XXX : not implemented */
1727 spr_register(env
, SPR_BOOKE_IAC1
, "IAC1",
1728 SPR_NOACCESS
, SPR_NOACCESS
,
1729 &spr_read_generic
, &spr_write_generic
,
1731 /* XXX : not implemented */
1732 spr_register(env
, SPR_BOOKE_IAC2
, "IAC2",
1733 SPR_NOACCESS
, SPR_NOACCESS
,
1734 &spr_read_generic
, &spr_write_generic
,
1736 /* XXX : not implemented */
1737 spr_register(env
, SPR_BOOKE_DAC1
, "DAC1",
1738 SPR_NOACCESS
, SPR_NOACCESS
,
1739 &spr_read_generic
, &spr_write_generic
,
1741 /* XXX : not implemented */
1742 spr_register(env
, SPR_BOOKE_DAC2
, "DAC2",
1743 SPR_NOACCESS
, SPR_NOACCESS
,
1744 &spr_read_generic
, &spr_write_generic
,
1746 /* XXX : not implemented */
1747 spr_register(env
, SPR_BOOKE_DBCR0
, "DBCR0",
1748 SPR_NOACCESS
, SPR_NOACCESS
,
1749 &spr_read_generic
, &spr_write_40x_dbcr0
,
1751 /* XXX : not implemented */
1752 spr_register(env
, SPR_BOOKE_DBCR1
, "DBCR1",
1753 SPR_NOACCESS
, SPR_NOACCESS
,
1754 &spr_read_generic
, &spr_write_generic
,
1756 /* XXX : not implemented */
1757 spr_register(env
, SPR_BOOKE_DBCR2
, "DBCR2",
1758 SPR_NOACCESS
, SPR_NOACCESS
,
1759 &spr_read_generic
, &spr_write_generic
,
1761 /* XXX : not implemented */
1762 spr_register(env
, SPR_BOOKE_DBSR
, "DBSR",
1763 SPR_NOACCESS
, SPR_NOACCESS
,
1764 &spr_read_generic
, &spr_write_clear
,
1766 spr_register(env
, SPR_BOOKE_DEAR
, "DEAR",
1767 SPR_NOACCESS
, SPR_NOACCESS
,
1768 &spr_read_generic
, &spr_write_generic
,
1770 spr_register(env
, SPR_BOOKE_ESR
, "ESR",
1771 SPR_NOACCESS
, SPR_NOACCESS
,
1772 &spr_read_generic
, &spr_write_generic
,
1774 spr_register(env
, SPR_BOOKE_IVPR
, "IVPR",
1775 SPR_NOACCESS
, SPR_NOACCESS
,
1776 &spr_read_generic
, &spr_write_excp_prefix
,
1778 /* Exception vectors */
1779 for (i
= 0; i
< 64; i
++) {
1780 if (ivor_mask
& (1ULL << i
)) {
1781 if (ivor_sprn
[i
] == SPR_BOOKE_IVORxx
) {
1782 fprintf(stderr
, "ERROR: IVOR %d SPR is not defined\n", i
);
1785 spr_register(env
, ivor_sprn
[i
], ivor_names
[i
],
1786 SPR_NOACCESS
, SPR_NOACCESS
,
1787 &spr_read_generic
, &spr_write_excp_vector
,
1791 spr_register(env
, SPR_BOOKE_PID
, "PID",
1792 SPR_NOACCESS
, SPR_NOACCESS
,
1793 &spr_read_generic
, &spr_write_booke_pid
,
1795 spr_register(env
, SPR_BOOKE_TCR
, "TCR",
1796 SPR_NOACCESS
, SPR_NOACCESS
,
1797 &spr_read_generic
, &spr_write_booke_tcr
,
1799 spr_register(env
, SPR_BOOKE_TSR
, "TSR",
1800 SPR_NOACCESS
, SPR_NOACCESS
,
1801 &spr_read_generic
, &spr_write_booke_tsr
,
1804 spr_register(env
, SPR_DECR
, "DECR",
1805 SPR_NOACCESS
, SPR_NOACCESS
,
1806 &spr_read_decr
, &spr_write_decr
,
1808 spr_register(env
, SPR_BOOKE_DECAR
, "DECAR",
1809 SPR_NOACCESS
, SPR_NOACCESS
,
1810 SPR_NOACCESS
, &spr_write_generic
,
1813 spr_register(env
, SPR_USPRG0
, "USPRG0",
1814 &spr_read_generic
, &spr_write_generic
,
1815 &spr_read_generic
, &spr_write_generic
,
1817 spr_register(env
, SPR_SPRG4
, "SPRG4",
1818 SPR_NOACCESS
, SPR_NOACCESS
,
1819 &spr_read_generic
, &spr_write_generic
,
1821 spr_register(env
, SPR_SPRG5
, "SPRG5",
1822 SPR_NOACCESS
, SPR_NOACCESS
,
1823 &spr_read_generic
, &spr_write_generic
,
1825 spr_register(env
, SPR_SPRG6
, "SPRG6",
1826 SPR_NOACCESS
, SPR_NOACCESS
,
1827 &spr_read_generic
, &spr_write_generic
,
1829 spr_register(env
, SPR_SPRG7
, "SPRG7",
1830 SPR_NOACCESS
, SPR_NOACCESS
,
1831 &spr_read_generic
, &spr_write_generic
,
1835 static inline uint32_t gen_tlbncfg(uint32_t assoc
, uint32_t minsize
,
1836 uint32_t maxsize
, uint32_t flags
,
1839 return (assoc
<< TLBnCFG_ASSOC_SHIFT
) |
1840 (minsize
<< TLBnCFG_MINSIZE_SHIFT
) |
1841 (maxsize
<< TLBnCFG_MAXSIZE_SHIFT
) |
1845 /* BookE 2.06 storage control registers */
1846 static void gen_spr_BookE206(CPUPPCState
*env
, uint32_t mas_mask
,
1847 uint32_t *tlbncfg
, uint32_t mmucfg
)
1849 #if !defined(CONFIG_USER_ONLY)
1850 const char *mas_names
[8] = {
1851 "MAS0", "MAS1", "MAS2", "MAS3", "MAS4", "MAS5", "MAS6", "MAS7",
1854 SPR_BOOKE_MAS0
, SPR_BOOKE_MAS1
, SPR_BOOKE_MAS2
, SPR_BOOKE_MAS3
,
1855 SPR_BOOKE_MAS4
, SPR_BOOKE_MAS5
, SPR_BOOKE_MAS6
, SPR_BOOKE_MAS7
,
1859 /* TLB assist registers */
1860 /* XXX : not implemented */
1861 for (i
= 0; i
< 8; i
++) {
1862 void (*uea_write
)(DisasContext
*ctx
, int sprn
, int gprn
) = &spr_write_generic32
;
1863 if (i
== 2 && (mas_mask
& (1 << i
)) && (env
->insns_flags
& PPC_64B
)) {
1864 uea_write
= &spr_write_generic
;
1866 if (mas_mask
& (1 << i
)) {
1867 spr_register(env
, mas_sprn
[i
], mas_names
[i
],
1868 SPR_NOACCESS
, SPR_NOACCESS
,
1869 &spr_read_generic
, uea_write
,
1873 if (env
->nb_pids
> 1) {
1874 /* XXX : not implemented */
1875 spr_register(env
, SPR_BOOKE_PID1
, "PID1",
1876 SPR_NOACCESS
, SPR_NOACCESS
,
1877 &spr_read_generic
, &spr_write_booke_pid
,
1880 if (env
->nb_pids
> 2) {
1881 /* XXX : not implemented */
1882 spr_register(env
, SPR_BOOKE_PID2
, "PID2",
1883 SPR_NOACCESS
, SPR_NOACCESS
,
1884 &spr_read_generic
, &spr_write_booke_pid
,
1887 /* XXX : not implemented */
1888 spr_register(env
, SPR_MMUCFG
, "MMUCFG",
1889 SPR_NOACCESS
, SPR_NOACCESS
,
1890 &spr_read_generic
, SPR_NOACCESS
,
1892 switch (env
->nb_ways
) {
1894 spr_register(env
, SPR_BOOKE_TLB3CFG
, "TLB3CFG",
1895 SPR_NOACCESS
, SPR_NOACCESS
,
1896 &spr_read_generic
, SPR_NOACCESS
,
1900 spr_register(env
, SPR_BOOKE_TLB2CFG
, "TLB2CFG",
1901 SPR_NOACCESS
, SPR_NOACCESS
,
1902 &spr_read_generic
, SPR_NOACCESS
,
1906 spr_register(env
, SPR_BOOKE_TLB1CFG
, "TLB1CFG",
1907 SPR_NOACCESS
, SPR_NOACCESS
,
1908 &spr_read_generic
, SPR_NOACCESS
,
1912 spr_register(env
, SPR_BOOKE_TLB0CFG
, "TLB0CFG",
1913 SPR_NOACCESS
, SPR_NOACCESS
,
1914 &spr_read_generic
, SPR_NOACCESS
,
1923 gen_spr_usprgh(env
);
1926 /* SPR specific to PowerPC 440 implementation */
1927 static void gen_spr_440(CPUPPCState
*env
)
1930 /* XXX : not implemented */
1931 spr_register(env
, SPR_440_DNV0
, "DNV0",
1932 SPR_NOACCESS
, SPR_NOACCESS
,
1933 &spr_read_generic
, &spr_write_generic
,
1935 /* XXX : not implemented */
1936 spr_register(env
, SPR_440_DNV1
, "DNV1",
1937 SPR_NOACCESS
, SPR_NOACCESS
,
1938 &spr_read_generic
, &spr_write_generic
,
1940 /* XXX : not implemented */
1941 spr_register(env
, SPR_440_DNV2
, "DNV2",
1942 SPR_NOACCESS
, SPR_NOACCESS
,
1943 &spr_read_generic
, &spr_write_generic
,
1945 /* XXX : not implemented */
1946 spr_register(env
, SPR_440_DNV3
, "DNV3",
1947 SPR_NOACCESS
, SPR_NOACCESS
,
1948 &spr_read_generic
, &spr_write_generic
,
1950 /* XXX : not implemented */
1951 spr_register(env
, SPR_440_DTV0
, "DTV0",
1952 SPR_NOACCESS
, SPR_NOACCESS
,
1953 &spr_read_generic
, &spr_write_generic
,
1955 /* XXX : not implemented */
1956 spr_register(env
, SPR_440_DTV1
, "DTV1",
1957 SPR_NOACCESS
, SPR_NOACCESS
,
1958 &spr_read_generic
, &spr_write_generic
,
1960 /* XXX : not implemented */
1961 spr_register(env
, SPR_440_DTV2
, "DTV2",
1962 SPR_NOACCESS
, SPR_NOACCESS
,
1963 &spr_read_generic
, &spr_write_generic
,
1965 /* XXX : not implemented */
1966 spr_register(env
, SPR_440_DTV3
, "DTV3",
1967 SPR_NOACCESS
, SPR_NOACCESS
,
1968 &spr_read_generic
, &spr_write_generic
,
1970 /* XXX : not implemented */
1971 spr_register(env
, SPR_440_DVLIM
, "DVLIM",
1972 SPR_NOACCESS
, SPR_NOACCESS
,
1973 &spr_read_generic
, &spr_write_generic
,
1975 /* XXX : not implemented */
1976 spr_register(env
, SPR_440_INV0
, "INV0",
1977 SPR_NOACCESS
, SPR_NOACCESS
,
1978 &spr_read_generic
, &spr_write_generic
,
1980 /* XXX : not implemented */
1981 spr_register(env
, SPR_440_INV1
, "INV1",
1982 SPR_NOACCESS
, SPR_NOACCESS
,
1983 &spr_read_generic
, &spr_write_generic
,
1985 /* XXX : not implemented */
1986 spr_register(env
, SPR_440_INV2
, "INV2",
1987 SPR_NOACCESS
, SPR_NOACCESS
,
1988 &spr_read_generic
, &spr_write_generic
,
1990 /* XXX : not implemented */
1991 spr_register(env
, SPR_440_INV3
, "INV3",
1992 SPR_NOACCESS
, SPR_NOACCESS
,
1993 &spr_read_generic
, &spr_write_generic
,
1995 /* XXX : not implemented */
1996 spr_register(env
, SPR_440_ITV0
, "ITV0",
1997 SPR_NOACCESS
, SPR_NOACCESS
,
1998 &spr_read_generic
, &spr_write_generic
,
2000 /* XXX : not implemented */
2001 spr_register(env
, SPR_440_ITV1
, "ITV1",
2002 SPR_NOACCESS
, SPR_NOACCESS
,
2003 &spr_read_generic
, &spr_write_generic
,
2005 /* XXX : not implemented */
2006 spr_register(env
, SPR_440_ITV2
, "ITV2",
2007 SPR_NOACCESS
, SPR_NOACCESS
,
2008 &spr_read_generic
, &spr_write_generic
,
2010 /* XXX : not implemented */
2011 spr_register(env
, SPR_440_ITV3
, "ITV3",
2012 SPR_NOACCESS
, SPR_NOACCESS
,
2013 &spr_read_generic
, &spr_write_generic
,
2015 /* XXX : not implemented */
2016 spr_register(env
, SPR_440_IVLIM
, "IVLIM",
2017 SPR_NOACCESS
, SPR_NOACCESS
,
2018 &spr_read_generic
, &spr_write_generic
,
2021 /* XXX : not implemented */
2022 spr_register(env
, SPR_BOOKE_DCDBTRH
, "DCDBTRH",
2023 SPR_NOACCESS
, SPR_NOACCESS
,
2024 &spr_read_generic
, SPR_NOACCESS
,
2026 /* XXX : not implemented */
2027 spr_register(env
, SPR_BOOKE_DCDBTRL
, "DCDBTRL",
2028 SPR_NOACCESS
, SPR_NOACCESS
,
2029 &spr_read_generic
, SPR_NOACCESS
,
2031 /* XXX : not implemented */
2032 spr_register(env
, SPR_BOOKE_ICDBDR
, "ICDBDR",
2033 SPR_NOACCESS
, SPR_NOACCESS
,
2034 &spr_read_generic
, SPR_NOACCESS
,
2036 /* XXX : not implemented */
2037 spr_register(env
, SPR_BOOKE_ICDBTRH
, "ICDBTRH",
2038 SPR_NOACCESS
, SPR_NOACCESS
,
2039 &spr_read_generic
, SPR_NOACCESS
,
2041 /* XXX : not implemented */
2042 spr_register(env
, SPR_BOOKE_ICDBTRL
, "ICDBTRL",
2043 SPR_NOACCESS
, SPR_NOACCESS
,
2044 &spr_read_generic
, SPR_NOACCESS
,
2046 /* XXX : not implemented */
2047 spr_register(env
, SPR_440_DBDR
, "DBDR",
2048 SPR_NOACCESS
, SPR_NOACCESS
,
2049 &spr_read_generic
, &spr_write_generic
,
2051 /* Processor control */
2052 spr_register(env
, SPR_4xx_CCR0
, "CCR0",
2053 SPR_NOACCESS
, SPR_NOACCESS
,
2054 &spr_read_generic
, &spr_write_generic
,
2056 spr_register(env
, SPR_440_RSTCFG
, "RSTCFG",
2057 SPR_NOACCESS
, SPR_NOACCESS
,
2058 &spr_read_generic
, SPR_NOACCESS
,
2060 /* Storage control */
2061 spr_register(env
, SPR_440_MMUCR
, "MMUCR",
2062 SPR_NOACCESS
, SPR_NOACCESS
,
2063 &spr_read_generic
, &spr_write_generic
,
2067 /* SPR shared between PowerPC 40x implementations */
2068 static void gen_spr_40x(CPUPPCState
*env
)
2071 /* not emulated, as QEMU do not emulate caches */
2072 spr_register(env
, SPR_40x_DCCR
, "DCCR",
2073 SPR_NOACCESS
, SPR_NOACCESS
,
2074 &spr_read_generic
, &spr_write_generic
,
2076 /* not emulated, as QEMU do not emulate caches */
2077 spr_register(env
, SPR_40x_ICCR
, "ICCR",
2078 SPR_NOACCESS
, SPR_NOACCESS
,
2079 &spr_read_generic
, &spr_write_generic
,
2081 /* not emulated, as QEMU do not emulate caches */
2082 spr_register(env
, SPR_BOOKE_ICDBDR
, "ICDBDR",
2083 SPR_NOACCESS
, SPR_NOACCESS
,
2084 &spr_read_generic
, SPR_NOACCESS
,
2087 spr_register(env
, SPR_40x_DEAR
, "DEAR",
2088 SPR_NOACCESS
, SPR_NOACCESS
,
2089 &spr_read_generic
, &spr_write_generic
,
2091 spr_register(env
, SPR_40x_ESR
, "ESR",
2092 SPR_NOACCESS
, SPR_NOACCESS
,
2093 &spr_read_generic
, &spr_write_generic
,
2095 spr_register(env
, SPR_40x_EVPR
, "EVPR",
2096 SPR_NOACCESS
, SPR_NOACCESS
,
2097 &spr_read_generic
, &spr_write_excp_prefix
,
2099 spr_register(env
, SPR_40x_SRR2
, "SRR2",
2100 &spr_read_generic
, &spr_write_generic
,
2101 &spr_read_generic
, &spr_write_generic
,
2103 spr_register(env
, SPR_40x_SRR3
, "SRR3",
2104 &spr_read_generic
, &spr_write_generic
,
2105 &spr_read_generic
, &spr_write_generic
,
2108 spr_register(env
, SPR_40x_PIT
, "PIT",
2109 SPR_NOACCESS
, SPR_NOACCESS
,
2110 &spr_read_40x_pit
, &spr_write_40x_pit
,
2112 spr_register(env
, SPR_40x_TCR
, "TCR",
2113 SPR_NOACCESS
, SPR_NOACCESS
,
2114 &spr_read_generic
, &spr_write_booke_tcr
,
2116 spr_register(env
, SPR_40x_TSR
, "TSR",
2117 SPR_NOACCESS
, SPR_NOACCESS
,
2118 &spr_read_generic
, &spr_write_booke_tsr
,
2122 /* SPR specific to PowerPC 405 implementation */
2123 static void gen_spr_405(CPUPPCState
*env
)
2126 spr_register(env
, SPR_40x_PID
, "PID",
2127 SPR_NOACCESS
, SPR_NOACCESS
,
2128 &spr_read_generic
, &spr_write_generic
,
2130 spr_register(env
, SPR_4xx_CCR0
, "CCR0",
2131 SPR_NOACCESS
, SPR_NOACCESS
,
2132 &spr_read_generic
, &spr_write_generic
,
2134 /* Debug interface */
2135 /* XXX : not implemented */
2136 spr_register(env
, SPR_40x_DBCR0
, "DBCR0",
2137 SPR_NOACCESS
, SPR_NOACCESS
,
2138 &spr_read_generic
, &spr_write_40x_dbcr0
,
2140 /* XXX : not implemented */
2141 spr_register(env
, SPR_405_DBCR1
, "DBCR1",
2142 SPR_NOACCESS
, SPR_NOACCESS
,
2143 &spr_read_generic
, &spr_write_generic
,
2145 /* XXX : not implemented */
2146 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2147 SPR_NOACCESS
, SPR_NOACCESS
,
2148 &spr_read_generic
, &spr_write_clear
,
2149 /* Last reset was system reset */
2151 /* XXX : not implemented */
2152 spr_register(env
, SPR_40x_DAC1
, "DAC1",
2153 SPR_NOACCESS
, SPR_NOACCESS
,
2154 &spr_read_generic
, &spr_write_generic
,
2156 spr_register(env
, SPR_40x_DAC2
, "DAC2",
2157 SPR_NOACCESS
, SPR_NOACCESS
,
2158 &spr_read_generic
, &spr_write_generic
,
2160 /* XXX : not implemented */
2161 spr_register(env
, SPR_405_DVC1
, "DVC1",
2162 SPR_NOACCESS
, SPR_NOACCESS
,
2163 &spr_read_generic
, &spr_write_generic
,
2165 /* XXX : not implemented */
2166 spr_register(env
, SPR_405_DVC2
, "DVC2",
2167 SPR_NOACCESS
, SPR_NOACCESS
,
2168 &spr_read_generic
, &spr_write_generic
,
2170 /* XXX : not implemented */
2171 spr_register(env
, SPR_40x_IAC1
, "IAC1",
2172 SPR_NOACCESS
, SPR_NOACCESS
,
2173 &spr_read_generic
, &spr_write_generic
,
2175 spr_register(env
, SPR_40x_IAC2
, "IAC2",
2176 SPR_NOACCESS
, SPR_NOACCESS
,
2177 &spr_read_generic
, &spr_write_generic
,
2179 /* XXX : not implemented */
2180 spr_register(env
, SPR_405_IAC3
, "IAC3",
2181 SPR_NOACCESS
, SPR_NOACCESS
,
2182 &spr_read_generic
, &spr_write_generic
,
2184 /* XXX : not implemented */
2185 spr_register(env
, SPR_405_IAC4
, "IAC4",
2186 SPR_NOACCESS
, SPR_NOACCESS
,
2187 &spr_read_generic
, &spr_write_generic
,
2189 /* Storage control */
2190 /* XXX: TODO: not implemented */
2191 spr_register(env
, SPR_405_SLER
, "SLER",
2192 SPR_NOACCESS
, SPR_NOACCESS
,
2193 &spr_read_generic
, &spr_write_40x_sler
,
2195 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2196 SPR_NOACCESS
, SPR_NOACCESS
,
2197 &spr_read_generic
, &spr_write_generic
,
2199 /* XXX : not implemented */
2200 spr_register(env
, SPR_405_SU0R
, "SU0R",
2201 SPR_NOACCESS
, SPR_NOACCESS
,
2202 &spr_read_generic
, &spr_write_generic
,
2205 spr_register(env
, SPR_USPRG0
, "USPRG0",
2206 &spr_read_ureg
, SPR_NOACCESS
,
2207 &spr_read_ureg
, SPR_NOACCESS
,
2209 spr_register(env
, SPR_SPRG4
, "SPRG4",
2210 SPR_NOACCESS
, SPR_NOACCESS
,
2211 &spr_read_generic
, &spr_write_generic
,
2213 spr_register(env
, SPR_SPRG5
, "SPRG5",
2214 SPR_NOACCESS
, SPR_NOACCESS
,
2215 spr_read_generic
, &spr_write_generic
,
2217 spr_register(env
, SPR_SPRG6
, "SPRG6",
2218 SPR_NOACCESS
, SPR_NOACCESS
,
2219 spr_read_generic
, &spr_write_generic
,
2221 spr_register(env
, SPR_SPRG7
, "SPRG7",
2222 SPR_NOACCESS
, SPR_NOACCESS
,
2223 spr_read_generic
, &spr_write_generic
,
2225 gen_spr_usprgh(env
);
2228 /* SPR shared between PowerPC 401 & 403 implementations */
2229 static void gen_spr_401_403(CPUPPCState
*env
)
2232 spr_register(env
, SPR_403_VTBL
, "TBL",
2233 &spr_read_tbl
, SPR_NOACCESS
,
2234 &spr_read_tbl
, SPR_NOACCESS
,
2236 spr_register(env
, SPR_403_TBL
, "TBL",
2237 SPR_NOACCESS
, SPR_NOACCESS
,
2238 SPR_NOACCESS
, &spr_write_tbl
,
2240 spr_register(env
, SPR_403_VTBU
, "TBU",
2241 &spr_read_tbu
, SPR_NOACCESS
,
2242 &spr_read_tbu
, SPR_NOACCESS
,
2244 spr_register(env
, SPR_403_TBU
, "TBU",
2245 SPR_NOACCESS
, SPR_NOACCESS
,
2246 SPR_NOACCESS
, &spr_write_tbu
,
2249 /* not emulated, as QEMU do not emulate caches */
2250 spr_register(env
, SPR_403_CDBCR
, "CDBCR",
2251 SPR_NOACCESS
, SPR_NOACCESS
,
2252 &spr_read_generic
, &spr_write_generic
,
2256 /* SPR specific to PowerPC 401 implementation */
2257 static void gen_spr_401(CPUPPCState
*env
)
2259 /* Debug interface */
2260 /* XXX : not implemented */
2261 spr_register(env
, SPR_40x_DBCR0
, "DBCR",
2262 SPR_NOACCESS
, SPR_NOACCESS
,
2263 &spr_read_generic
, &spr_write_40x_dbcr0
,
2265 /* XXX : not implemented */
2266 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2267 SPR_NOACCESS
, SPR_NOACCESS
,
2268 &spr_read_generic
, &spr_write_clear
,
2269 /* Last reset was system reset */
2271 /* XXX : not implemented */
2272 spr_register(env
, SPR_40x_DAC1
, "DAC",
2273 SPR_NOACCESS
, SPR_NOACCESS
,
2274 &spr_read_generic
, &spr_write_generic
,
2276 /* XXX : not implemented */
2277 spr_register(env
, SPR_40x_IAC1
, "IAC",
2278 SPR_NOACCESS
, SPR_NOACCESS
,
2279 &spr_read_generic
, &spr_write_generic
,
2281 /* Storage control */
2282 /* XXX: TODO: not implemented */
2283 spr_register(env
, SPR_405_SLER
, "SLER",
2284 SPR_NOACCESS
, SPR_NOACCESS
,
2285 &spr_read_generic
, &spr_write_40x_sler
,
2287 /* not emulated, as QEMU never does speculative access */
2288 spr_register(env
, SPR_40x_SGR
, "SGR",
2289 SPR_NOACCESS
, SPR_NOACCESS
,
2290 &spr_read_generic
, &spr_write_generic
,
2292 /* not emulated, as QEMU do not emulate caches */
2293 spr_register(env
, SPR_40x_DCWR
, "DCWR",
2294 SPR_NOACCESS
, SPR_NOACCESS
,
2295 &spr_read_generic
, &spr_write_generic
,
2299 static void gen_spr_401x2(CPUPPCState
*env
)
2302 spr_register(env
, SPR_40x_PID
, "PID",
2303 SPR_NOACCESS
, SPR_NOACCESS
,
2304 &spr_read_generic
, &spr_write_generic
,
2306 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2307 SPR_NOACCESS
, SPR_NOACCESS
,
2308 &spr_read_generic
, &spr_write_generic
,
2312 /* SPR specific to PowerPC 403 implementation */
2313 static void gen_spr_403(CPUPPCState
*env
)
2315 /* Debug interface */
2316 /* XXX : not implemented */
2317 spr_register(env
, SPR_40x_DBCR0
, "DBCR0",
2318 SPR_NOACCESS
, SPR_NOACCESS
,
2319 &spr_read_generic
, &spr_write_40x_dbcr0
,
2321 /* XXX : not implemented */
2322 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2323 SPR_NOACCESS
, SPR_NOACCESS
,
2324 &spr_read_generic
, &spr_write_clear
,
2325 /* Last reset was system reset */
2327 /* XXX : not implemented */
2328 spr_register(env
, SPR_40x_DAC1
, "DAC1",
2329 SPR_NOACCESS
, SPR_NOACCESS
,
2330 &spr_read_generic
, &spr_write_generic
,
2332 /* XXX : not implemented */
2333 spr_register(env
, SPR_40x_DAC2
, "DAC2",
2334 SPR_NOACCESS
, SPR_NOACCESS
,
2335 &spr_read_generic
, &spr_write_generic
,
2337 /* XXX : not implemented */
2338 spr_register(env
, SPR_40x_IAC1
, "IAC1",
2339 SPR_NOACCESS
, SPR_NOACCESS
,
2340 &spr_read_generic
, &spr_write_generic
,
2342 /* XXX : not implemented */
2343 spr_register(env
, SPR_40x_IAC2
, "IAC2",
2344 SPR_NOACCESS
, SPR_NOACCESS
,
2345 &spr_read_generic
, &spr_write_generic
,
2349 static void gen_spr_403_real(CPUPPCState
*env
)
2351 spr_register(env
, SPR_403_PBL1
, "PBL1",
2352 SPR_NOACCESS
, SPR_NOACCESS
,
2353 &spr_read_403_pbr
, &spr_write_403_pbr
,
2355 spr_register(env
, SPR_403_PBU1
, "PBU1",
2356 SPR_NOACCESS
, SPR_NOACCESS
,
2357 &spr_read_403_pbr
, &spr_write_403_pbr
,
2359 spr_register(env
, SPR_403_PBL2
, "PBL2",
2360 SPR_NOACCESS
, SPR_NOACCESS
,
2361 &spr_read_403_pbr
, &spr_write_403_pbr
,
2363 spr_register(env
, SPR_403_PBU2
, "PBU2",
2364 SPR_NOACCESS
, SPR_NOACCESS
,
2365 &spr_read_403_pbr
, &spr_write_403_pbr
,
2369 static void gen_spr_403_mmu(CPUPPCState
*env
)
2372 spr_register(env
, SPR_40x_PID
, "PID",
2373 SPR_NOACCESS
, SPR_NOACCESS
,
2374 &spr_read_generic
, &spr_write_generic
,
2376 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2377 SPR_NOACCESS
, SPR_NOACCESS
,
2378 &spr_read_generic
, &spr_write_generic
,
2382 /* SPR specific to PowerPC compression coprocessor extension */
2383 static void gen_spr_compress(CPUPPCState
*env
)
2385 /* XXX : not implemented */
2386 spr_register(env
, SPR_401_SKR
, "SKR",
2387 SPR_NOACCESS
, SPR_NOACCESS
,
2388 &spr_read_generic
, &spr_write_generic
,
2392 static void gen_spr_5xx_8xx(CPUPPCState
*env
)
2394 /* Exception processing */
2395 spr_register_kvm(env
, SPR_DSISR
, "DSISR",
2396 SPR_NOACCESS
, SPR_NOACCESS
,
2397 &spr_read_generic
, &spr_write_generic
,
2398 KVM_REG_PPC_DSISR
, 0x00000000);
2399 spr_register_kvm(env
, SPR_DAR
, "DAR",
2400 SPR_NOACCESS
, SPR_NOACCESS
,
2401 &spr_read_generic
, &spr_write_generic
,
2402 KVM_REG_PPC_DAR
, 0x00000000);
2404 spr_register(env
, SPR_DECR
, "DECR",
2405 SPR_NOACCESS
, SPR_NOACCESS
,
2406 &spr_read_decr
, &spr_write_decr
,
2408 /* XXX : not implemented */
2409 spr_register(env
, SPR_MPC_EIE
, "EIE",
2410 SPR_NOACCESS
, SPR_NOACCESS
,
2411 &spr_read_generic
, &spr_write_generic
,
2413 /* XXX : not implemented */
2414 spr_register(env
, SPR_MPC_EID
, "EID",
2415 SPR_NOACCESS
, SPR_NOACCESS
,
2416 &spr_read_generic
, &spr_write_generic
,
2418 /* XXX : not implemented */
2419 spr_register(env
, SPR_MPC_NRI
, "NRI",
2420 SPR_NOACCESS
, SPR_NOACCESS
,
2421 &spr_read_generic
, &spr_write_generic
,
2423 /* XXX : not implemented */
2424 spr_register(env
, SPR_MPC_CMPA
, "CMPA",
2425 SPR_NOACCESS
, SPR_NOACCESS
,
2426 &spr_read_generic
, &spr_write_generic
,
2428 /* XXX : not implemented */
2429 spr_register(env
, SPR_MPC_CMPB
, "CMPB",
2430 SPR_NOACCESS
, SPR_NOACCESS
,
2431 &spr_read_generic
, &spr_write_generic
,
2433 /* XXX : not implemented */
2434 spr_register(env
, SPR_MPC_CMPC
, "CMPC",
2435 SPR_NOACCESS
, SPR_NOACCESS
,
2436 &spr_read_generic
, &spr_write_generic
,
2438 /* XXX : not implemented */
2439 spr_register(env
, SPR_MPC_CMPD
, "CMPD",
2440 SPR_NOACCESS
, SPR_NOACCESS
,
2441 &spr_read_generic
, &spr_write_generic
,
2443 /* XXX : not implemented */
2444 spr_register(env
, SPR_MPC_ECR
, "ECR",
2445 SPR_NOACCESS
, SPR_NOACCESS
,
2446 &spr_read_generic
, &spr_write_generic
,
2448 /* XXX : not implemented */
2449 spr_register(env
, SPR_MPC_DER
, "DER",
2450 SPR_NOACCESS
, SPR_NOACCESS
,
2451 &spr_read_generic
, &spr_write_generic
,
2453 /* XXX : not implemented */
2454 spr_register(env
, SPR_MPC_COUNTA
, "COUNTA",
2455 SPR_NOACCESS
, SPR_NOACCESS
,
2456 &spr_read_generic
, &spr_write_generic
,
2458 /* XXX : not implemented */
2459 spr_register(env
, SPR_MPC_COUNTB
, "COUNTB",
2460 SPR_NOACCESS
, SPR_NOACCESS
,
2461 &spr_read_generic
, &spr_write_generic
,
2463 /* XXX : not implemented */
2464 spr_register(env
, SPR_MPC_CMPE
, "CMPE",
2465 SPR_NOACCESS
, SPR_NOACCESS
,
2466 &spr_read_generic
, &spr_write_generic
,
2468 /* XXX : not implemented */
2469 spr_register(env
, SPR_MPC_CMPF
, "CMPF",
2470 SPR_NOACCESS
, SPR_NOACCESS
,
2471 &spr_read_generic
, &spr_write_generic
,
2473 /* XXX : not implemented */
2474 spr_register(env
, SPR_MPC_CMPG
, "CMPG",
2475 SPR_NOACCESS
, SPR_NOACCESS
,
2476 &spr_read_generic
, &spr_write_generic
,
2478 /* XXX : not implemented */
2479 spr_register(env
, SPR_MPC_CMPH
, "CMPH",
2480 SPR_NOACCESS
, SPR_NOACCESS
,
2481 &spr_read_generic
, &spr_write_generic
,
2483 /* XXX : not implemented */
2484 spr_register(env
, SPR_MPC_LCTRL1
, "LCTRL1",
2485 SPR_NOACCESS
, SPR_NOACCESS
,
2486 &spr_read_generic
, &spr_write_generic
,
2488 /* XXX : not implemented */
2489 spr_register(env
, SPR_MPC_LCTRL2
, "LCTRL2",
2490 SPR_NOACCESS
, SPR_NOACCESS
,
2491 &spr_read_generic
, &spr_write_generic
,
2493 /* XXX : not implemented */
2494 spr_register(env
, SPR_MPC_BAR
, "BAR",
2495 SPR_NOACCESS
, SPR_NOACCESS
,
2496 &spr_read_generic
, &spr_write_generic
,
2498 /* XXX : not implemented */
2499 spr_register(env
, SPR_MPC_DPDR
, "DPDR",
2500 SPR_NOACCESS
, SPR_NOACCESS
,
2501 &spr_read_generic
, &spr_write_generic
,
2503 /* XXX : not implemented */
2504 spr_register(env
, SPR_MPC_IMMR
, "IMMR",
2505 SPR_NOACCESS
, SPR_NOACCESS
,
2506 &spr_read_generic
, &spr_write_generic
,
2510 static void gen_spr_5xx(CPUPPCState
*env
)
2512 /* XXX : not implemented */
2513 spr_register(env
, SPR_RCPU_MI_GRA
, "MI_GRA",
2514 SPR_NOACCESS
, SPR_NOACCESS
,
2515 &spr_read_generic
, &spr_write_generic
,
2517 /* XXX : not implemented */
2518 spr_register(env
, SPR_RCPU_L2U_GRA
, "L2U_GRA",
2519 SPR_NOACCESS
, SPR_NOACCESS
,
2520 &spr_read_generic
, &spr_write_generic
,
2522 /* XXX : not implemented */
2523 spr_register(env
, SPR_RPCU_BBCMCR
, "L2U_BBCMCR",
2524 SPR_NOACCESS
, SPR_NOACCESS
,
2525 &spr_read_generic
, &spr_write_generic
,
2527 /* XXX : not implemented */
2528 spr_register(env
, SPR_RCPU_L2U_MCR
, "L2U_MCR",
2529 SPR_NOACCESS
, SPR_NOACCESS
,
2530 &spr_read_generic
, &spr_write_generic
,
2532 /* XXX : not implemented */
2533 spr_register(env
, SPR_RCPU_MI_RBA0
, "MI_RBA0",
2534 SPR_NOACCESS
, SPR_NOACCESS
,
2535 &spr_read_generic
, &spr_write_generic
,
2537 /* XXX : not implemented */
2538 spr_register(env
, SPR_RCPU_MI_RBA1
, "MI_RBA1",
2539 SPR_NOACCESS
, SPR_NOACCESS
,
2540 &spr_read_generic
, &spr_write_generic
,
2542 /* XXX : not implemented */
2543 spr_register(env
, SPR_RCPU_MI_RBA2
, "MI_RBA2",
2544 SPR_NOACCESS
, SPR_NOACCESS
,
2545 &spr_read_generic
, &spr_write_generic
,
2547 /* XXX : not implemented */
2548 spr_register(env
, SPR_RCPU_MI_RBA3
, "MI_RBA3",
2549 SPR_NOACCESS
, SPR_NOACCESS
,
2550 &spr_read_generic
, &spr_write_generic
,
2552 /* XXX : not implemented */
2553 spr_register(env
, SPR_RCPU_L2U_RBA0
, "L2U_RBA0",
2554 SPR_NOACCESS
, SPR_NOACCESS
,
2555 &spr_read_generic
, &spr_write_generic
,
2557 /* XXX : not implemented */
2558 spr_register(env
, SPR_RCPU_L2U_RBA1
, "L2U_RBA1",
2559 SPR_NOACCESS
, SPR_NOACCESS
,
2560 &spr_read_generic
, &spr_write_generic
,
2562 /* XXX : not implemented */
2563 spr_register(env
, SPR_RCPU_L2U_RBA2
, "L2U_RBA2",
2564 SPR_NOACCESS
, SPR_NOACCESS
,
2565 &spr_read_generic
, &spr_write_generic
,
2567 /* XXX : not implemented */
2568 spr_register(env
, SPR_RCPU_L2U_RBA3
, "L2U_RBA3",
2569 SPR_NOACCESS
, SPR_NOACCESS
,
2570 &spr_read_generic
, &spr_write_generic
,
2572 /* XXX : not implemented */
2573 spr_register(env
, SPR_RCPU_MI_RA0
, "MI_RA0",
2574 SPR_NOACCESS
, SPR_NOACCESS
,
2575 &spr_read_generic
, &spr_write_generic
,
2577 /* XXX : not implemented */
2578 spr_register(env
, SPR_RCPU_MI_RA1
, "MI_RA1",
2579 SPR_NOACCESS
, SPR_NOACCESS
,
2580 &spr_read_generic
, &spr_write_generic
,
2582 /* XXX : not implemented */
2583 spr_register(env
, SPR_RCPU_MI_RA2
, "MI_RA2",
2584 SPR_NOACCESS
, SPR_NOACCESS
,
2585 &spr_read_generic
, &spr_write_generic
,
2587 /* XXX : not implemented */
2588 spr_register(env
, SPR_RCPU_MI_RA3
, "MI_RA3",
2589 SPR_NOACCESS
, SPR_NOACCESS
,
2590 &spr_read_generic
, &spr_write_generic
,
2592 /* XXX : not implemented */
2593 spr_register(env
, SPR_RCPU_L2U_RA0
, "L2U_RA0",
2594 SPR_NOACCESS
, SPR_NOACCESS
,
2595 &spr_read_generic
, &spr_write_generic
,
2597 /* XXX : not implemented */
2598 spr_register(env
, SPR_RCPU_L2U_RA1
, "L2U_RA1",
2599 SPR_NOACCESS
, SPR_NOACCESS
,
2600 &spr_read_generic
, &spr_write_generic
,
2602 /* XXX : not implemented */
2603 spr_register(env
, SPR_RCPU_L2U_RA2
, "L2U_RA2",
2604 SPR_NOACCESS
, SPR_NOACCESS
,
2605 &spr_read_generic
, &spr_write_generic
,
2607 /* XXX : not implemented */
2608 spr_register(env
, SPR_RCPU_L2U_RA3
, "L2U_RA3",
2609 SPR_NOACCESS
, SPR_NOACCESS
,
2610 &spr_read_generic
, &spr_write_generic
,
2612 /* XXX : not implemented */
2613 spr_register(env
, SPR_RCPU_FPECR
, "FPECR",
2614 SPR_NOACCESS
, SPR_NOACCESS
,
2615 &spr_read_generic
, &spr_write_generic
,
2619 static void gen_spr_8xx(CPUPPCState
*env
)
2621 /* XXX : not implemented */
2622 spr_register(env
, SPR_MPC_IC_CST
, "IC_CST",
2623 SPR_NOACCESS
, SPR_NOACCESS
,
2624 &spr_read_generic
, &spr_write_generic
,
2626 /* XXX : not implemented */
2627 spr_register(env
, SPR_MPC_IC_ADR
, "IC_ADR",
2628 SPR_NOACCESS
, SPR_NOACCESS
,
2629 &spr_read_generic
, &spr_write_generic
,
2631 /* XXX : not implemented */
2632 spr_register(env
, SPR_MPC_IC_DAT
, "IC_DAT",
2633 SPR_NOACCESS
, SPR_NOACCESS
,
2634 &spr_read_generic
, &spr_write_generic
,
2636 /* XXX : not implemented */
2637 spr_register(env
, SPR_MPC_DC_CST
, "DC_CST",
2638 SPR_NOACCESS
, SPR_NOACCESS
,
2639 &spr_read_generic
, &spr_write_generic
,
2641 /* XXX : not implemented */
2642 spr_register(env
, SPR_MPC_DC_ADR
, "DC_ADR",
2643 SPR_NOACCESS
, SPR_NOACCESS
,
2644 &spr_read_generic
, &spr_write_generic
,
2646 /* XXX : not implemented */
2647 spr_register(env
, SPR_MPC_DC_DAT
, "DC_DAT",
2648 SPR_NOACCESS
, SPR_NOACCESS
,
2649 &spr_read_generic
, &spr_write_generic
,
2651 /* XXX : not implemented */
2652 spr_register(env
, SPR_MPC_MI_CTR
, "MI_CTR",
2653 SPR_NOACCESS
, SPR_NOACCESS
,
2654 &spr_read_generic
, &spr_write_generic
,
2656 /* XXX : not implemented */
2657 spr_register(env
, SPR_MPC_MI_AP
, "MI_AP",
2658 SPR_NOACCESS
, SPR_NOACCESS
,
2659 &spr_read_generic
, &spr_write_generic
,
2661 /* XXX : not implemented */
2662 spr_register(env
, SPR_MPC_MI_EPN
, "MI_EPN",
2663 SPR_NOACCESS
, SPR_NOACCESS
,
2664 &spr_read_generic
, &spr_write_generic
,
2666 /* XXX : not implemented */
2667 spr_register(env
, SPR_MPC_MI_TWC
, "MI_TWC",
2668 SPR_NOACCESS
, SPR_NOACCESS
,
2669 &spr_read_generic
, &spr_write_generic
,
2671 /* XXX : not implemented */
2672 spr_register(env
, SPR_MPC_MI_RPN
, "MI_RPN",
2673 SPR_NOACCESS
, SPR_NOACCESS
,
2674 &spr_read_generic
, &spr_write_generic
,
2676 /* XXX : not implemented */
2677 spr_register(env
, SPR_MPC_MI_DBCAM
, "MI_DBCAM",
2678 SPR_NOACCESS
, SPR_NOACCESS
,
2679 &spr_read_generic
, &spr_write_generic
,
2681 /* XXX : not implemented */
2682 spr_register(env
, SPR_MPC_MI_DBRAM0
, "MI_DBRAM0",
2683 SPR_NOACCESS
, SPR_NOACCESS
,
2684 &spr_read_generic
, &spr_write_generic
,
2686 /* XXX : not implemented */
2687 spr_register(env
, SPR_MPC_MI_DBRAM1
, "MI_DBRAM1",
2688 SPR_NOACCESS
, SPR_NOACCESS
,
2689 &spr_read_generic
, &spr_write_generic
,
2691 /* XXX : not implemented */
2692 spr_register(env
, SPR_MPC_MD_CTR
, "MD_CTR",
2693 SPR_NOACCESS
, SPR_NOACCESS
,
2694 &spr_read_generic
, &spr_write_generic
,
2696 /* XXX : not implemented */
2697 spr_register(env
, SPR_MPC_MD_CASID
, "MD_CASID",
2698 SPR_NOACCESS
, SPR_NOACCESS
,
2699 &spr_read_generic
, &spr_write_generic
,
2701 /* XXX : not implemented */
2702 spr_register(env
, SPR_MPC_MD_AP
, "MD_AP",
2703 SPR_NOACCESS
, SPR_NOACCESS
,
2704 &spr_read_generic
, &spr_write_generic
,
2706 /* XXX : not implemented */
2707 spr_register(env
, SPR_MPC_MD_EPN
, "MD_EPN",
2708 SPR_NOACCESS
, SPR_NOACCESS
,
2709 &spr_read_generic
, &spr_write_generic
,
2711 /* XXX : not implemented */
2712 spr_register(env
, SPR_MPC_MD_TWB
, "MD_TWB",
2713 SPR_NOACCESS
, SPR_NOACCESS
,
2714 &spr_read_generic
, &spr_write_generic
,
2716 /* XXX : not implemented */
2717 spr_register(env
, SPR_MPC_MD_TWC
, "MD_TWC",
2718 SPR_NOACCESS
, SPR_NOACCESS
,
2719 &spr_read_generic
, &spr_write_generic
,
2721 /* XXX : not implemented */
2722 spr_register(env
, SPR_MPC_MD_RPN
, "MD_RPN",
2723 SPR_NOACCESS
, SPR_NOACCESS
,
2724 &spr_read_generic
, &spr_write_generic
,
2726 /* XXX : not implemented */
2727 spr_register(env
, SPR_MPC_MD_TW
, "MD_TW",
2728 SPR_NOACCESS
, SPR_NOACCESS
,
2729 &spr_read_generic
, &spr_write_generic
,
2731 /* XXX : not implemented */
2732 spr_register(env
, SPR_MPC_MD_DBCAM
, "MD_DBCAM",
2733 SPR_NOACCESS
, SPR_NOACCESS
,
2734 &spr_read_generic
, &spr_write_generic
,
2736 /* XXX : not implemented */
2737 spr_register(env
, SPR_MPC_MD_DBRAM0
, "MD_DBRAM0",
2738 SPR_NOACCESS
, SPR_NOACCESS
,
2739 &spr_read_generic
, &spr_write_generic
,
2741 /* XXX : not implemented */
2742 spr_register(env
, SPR_MPC_MD_DBRAM1
, "MD_DBRAM1",
2743 SPR_NOACCESS
, SPR_NOACCESS
,
2744 &spr_read_generic
, &spr_write_generic
,
2750 * AMR => SPR 29 (Power 2.04)
2751 * CTRL => SPR 136 (Power 2.04)
2752 * CTRL => SPR 152 (Power 2.04)
2753 * SCOMC => SPR 276 (64 bits ?)
2754 * SCOMD => SPR 277 (64 bits ?)
2755 * TBU40 => SPR 286 (Power 2.04 hypv)
2756 * HSPRG0 => SPR 304 (Power 2.04 hypv)
2757 * HSPRG1 => SPR 305 (Power 2.04 hypv)
2758 * HDSISR => SPR 306 (Power 2.04 hypv)
2759 * HDAR => SPR 307 (Power 2.04 hypv)
2760 * PURR => SPR 309 (Power 2.04 hypv)
2761 * HDEC => SPR 310 (Power 2.04 hypv)
2762 * HIOR => SPR 311 (hypv)
2763 * RMOR => SPR 312 (970)
2764 * HRMOR => SPR 313 (Power 2.04 hypv)
2765 * HSRR0 => SPR 314 (Power 2.04 hypv)
2766 * HSRR1 => SPR 315 (Power 2.04 hypv)
2767 * LPIDR => SPR 317 (970)
2768 * EPR => SPR 702 (Power 2.04 emb)
2769 * perf => 768-783 (Power 2.04)
2770 * perf => 784-799 (Power 2.04)
2771 * PPR => SPR 896 (Power 2.04)
2772 * EPLC => SPR 947 (Power 2.04 emb)
2773 * EPSC => SPR 948 (Power 2.04 emb)
2774 * DABRX => 1015 (Power 2.04 hypv)
2775 * FPECR => SPR 1022 (?)
2776 * ... and more (thermal management, performance counters, ...)
2779 /*****************************************************************************/
2780 /* Exception vectors models */
2781 static void init_excp_4xx_real(CPUPPCState
*env
)
2783 #if !defined(CONFIG_USER_ONLY)
2784 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000100;
2785 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2786 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2787 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2788 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2789 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2790 env
->excp_vectors
[POWERPC_EXCP_PIT
] = 0x00001000;
2791 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00001010;
2792 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001020;
2793 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00002000;
2794 env
->ivor_mask
= 0x0000FFF0UL
;
2795 env
->ivpr_mask
= 0xFFFF0000UL
;
2796 /* Hardware reset vector */
2797 env
->hreset_vector
= 0xFFFFFFFCUL
;
2801 static void init_excp_4xx_softmmu(CPUPPCState
*env
)
2803 #if !defined(CONFIG_USER_ONLY)
2804 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000100;
2805 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2806 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2807 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2808 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2809 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2810 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2811 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2812 env
->excp_vectors
[POWERPC_EXCP_PIT
] = 0x00001000;
2813 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00001010;
2814 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001020;
2815 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00001100;
2816 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00001200;
2817 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00002000;
2818 env
->ivor_mask
= 0x0000FFF0UL
;
2819 env
->ivpr_mask
= 0xFFFF0000UL
;
2820 /* Hardware reset vector */
2821 env
->hreset_vector
= 0xFFFFFFFCUL
;
2825 static void init_excp_MPC5xx(CPUPPCState
*env
)
2827 #if !defined(CONFIG_USER_ONLY)
2828 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2829 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2830 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2831 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2832 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2833 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000900;
2834 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2835 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2836 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2837 env
->excp_vectors
[POWERPC_EXCP_FPA
] = 0x00000E00;
2838 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001000;
2839 env
->excp_vectors
[POWERPC_EXCP_DABR
] = 0x00001C00;
2840 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001C00;
2841 env
->excp_vectors
[POWERPC_EXCP_MEXTBR
] = 0x00001E00;
2842 env
->excp_vectors
[POWERPC_EXCP_NMEXTBR
] = 0x00001F00;
2843 env
->ivor_mask
= 0x0000FFF0UL
;
2844 env
->ivpr_mask
= 0xFFFF0000UL
;
2845 /* Hardware reset vector */
2846 env
->hreset_vector
= 0x00000100UL
;
2850 static void init_excp_MPC8xx(CPUPPCState
*env
)
2852 #if !defined(CONFIG_USER_ONLY)
2853 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2854 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2855 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2856 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2857 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2858 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2859 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2860 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000900;
2861 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2862 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2863 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2864 env
->excp_vectors
[POWERPC_EXCP_FPA
] = 0x00000E00;
2865 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001000;
2866 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00001100;
2867 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00001200;
2868 env
->excp_vectors
[POWERPC_EXCP_ITLBE
] = 0x00001300;
2869 env
->excp_vectors
[POWERPC_EXCP_DTLBE
] = 0x00001400;
2870 env
->excp_vectors
[POWERPC_EXCP_DABR
] = 0x00001C00;
2871 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001C00;
2872 env
->excp_vectors
[POWERPC_EXCP_MEXTBR
] = 0x00001E00;
2873 env
->excp_vectors
[POWERPC_EXCP_NMEXTBR
] = 0x00001F00;
2874 env
->ivor_mask
= 0x0000FFF0UL
;
2875 env
->ivpr_mask
= 0xFFFF0000UL
;
2876 /* Hardware reset vector */
2877 env
->hreset_vector
= 0x00000100UL
;
2881 static void init_excp_G2(CPUPPCState
*env
)
2883 #if !defined(CONFIG_USER_ONLY)
2884 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2885 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2886 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2887 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2888 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2889 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2890 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2891 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
2892 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2893 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000A00;
2894 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2895 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2896 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
2897 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
2898 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
2899 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
2900 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
2901 /* Hardware reset vector */
2902 env
->hreset_vector
= 0x00000100UL
;
2906 static void init_excp_e200(CPUPPCState
*env
, target_ulong ivpr_mask
)
2908 #if !defined(CONFIG_USER_ONLY)
2909 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000FFC;
2910 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000000;
2911 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000000;
2912 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000000;
2913 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000000;
2914 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000000;
2915 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000000;
2916 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000000;
2917 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000000;
2918 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000000;
2919 env
->excp_vectors
[POWERPC_EXCP_APU
] = 0x00000000;
2920 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000000;
2921 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00000000;
2922 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00000000;
2923 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00000000;
2924 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00000000;
2925 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00000000;
2926 env
->excp_vectors
[POWERPC_EXCP_SPEU
] = 0x00000000;
2927 env
->excp_vectors
[POWERPC_EXCP_EFPDI
] = 0x00000000;
2928 env
->excp_vectors
[POWERPC_EXCP_EFPRI
] = 0x00000000;
2929 env
->ivor_mask
= 0x0000FFF7UL
;
2930 env
->ivpr_mask
= ivpr_mask
;
2931 /* Hardware reset vector */
2932 env
->hreset_vector
= 0xFFFFFFFCUL
;
2936 static void init_excp_BookE(CPUPPCState
*env
)
2938 #if !defined(CONFIG_USER_ONLY)
2939 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000000;
2940 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000000;
2941 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000000;
2942 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000000;
2943 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000000;
2944 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000000;
2945 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000000;
2946 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000000;
2947 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000000;
2948 env
->excp_vectors
[POWERPC_EXCP_APU
] = 0x00000000;
2949 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000000;
2950 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00000000;
2951 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00000000;
2952 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00000000;
2953 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00000000;
2954 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00000000;
2955 env
->ivor_mask
= 0x0000FFF0UL
;
2956 env
->ivpr_mask
= 0xFFFF0000UL
;
2957 /* Hardware reset vector */
2958 env
->hreset_vector
= 0xFFFFFFFCUL
;
2962 static void init_excp_601(CPUPPCState
*env
)
2964 #if !defined(CONFIG_USER_ONLY)
2965 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2966 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2967 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2968 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2969 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2970 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2971 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2972 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
2973 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2974 env
->excp_vectors
[POWERPC_EXCP_IO
] = 0x00000A00;
2975 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2976 env
->excp_vectors
[POWERPC_EXCP_RUNM
] = 0x00002000;
2977 /* Hardware reset vector */
2978 env
->hreset_vector
= 0x00000100UL
;
2982 static void init_excp_602(CPUPPCState
*env
)
2984 #if !defined(CONFIG_USER_ONLY)
2985 /* XXX: exception prefix has a special behavior on 602 */
2986 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2987 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2988 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2989 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2990 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2991 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2992 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2993 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
2994 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2995 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2996 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2997 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
2998 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
2999 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3000 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3001 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3002 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001500;
3003 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001600;
3004 /* Hardware reset vector */
3005 env
->hreset_vector
= 0x00000100UL
;
3009 static void init_excp_603(CPUPPCState
*env
)
3011 #if !defined(CONFIG_USER_ONLY)
3012 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3013 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3014 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3015 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3016 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3017 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3018 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3019 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3020 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3021 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3022 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3023 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3024 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3025 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3026 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3027 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3028 /* Hardware reset vector */
3029 env
->hreset_vector
= 0x00000100UL
;
3033 static void init_excp_604(CPUPPCState
*env
)
3035 #if !defined(CONFIG_USER_ONLY)
3036 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3037 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3038 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3039 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3040 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3041 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3042 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3043 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3044 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3045 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3046 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3047 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3048 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3049 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3050 /* Hardware reset vector */
3051 env
->hreset_vector
= 0x00000100UL
;
3055 static void init_excp_7x0(CPUPPCState
*env
)
3057 #if !defined(CONFIG_USER_ONLY)
3058 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3059 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3060 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3061 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3062 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3063 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3064 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3065 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3066 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3067 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3068 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3069 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3070 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3071 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3072 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3073 /* Hardware reset vector */
3074 env
->hreset_vector
= 0x00000100UL
;
3078 static void init_excp_750cl(CPUPPCState
*env
)
3080 #if !defined(CONFIG_USER_ONLY)
3081 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3082 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3083 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3084 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3085 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3086 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3087 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3088 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3089 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3090 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3091 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3092 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3093 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3094 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3095 /* Hardware reset vector */
3096 env
->hreset_vector
= 0x00000100UL
;
3100 static void init_excp_750cx(CPUPPCState
*env
)
3102 #if !defined(CONFIG_USER_ONLY)
3103 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3104 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3105 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3106 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3107 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3108 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3109 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3110 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3111 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3112 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3113 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3114 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3115 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3116 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3117 /* Hardware reset vector */
3118 env
->hreset_vector
= 0x00000100UL
;
3122 /* XXX: Check if this is correct */
3123 static void init_excp_7x5(CPUPPCState
*env
)
3125 #if !defined(CONFIG_USER_ONLY)
3126 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3127 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3128 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3129 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3130 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3131 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3132 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3133 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3134 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3135 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3136 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3137 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3138 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3139 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3140 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3141 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3142 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3143 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3144 /* Hardware reset vector */
3145 env
->hreset_vector
= 0x00000100UL
;
3149 static void init_excp_7400(CPUPPCState
*env
)
3151 #if !defined(CONFIG_USER_ONLY)
3152 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3153 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3154 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3155 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3156 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3157 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3158 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3159 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3160 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3161 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3162 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3163 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3164 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3165 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3166 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3167 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001600;
3168 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3169 /* Hardware reset vector */
3170 env
->hreset_vector
= 0x00000100UL
;
3174 static void init_excp_7450(CPUPPCState
*env
)
3176 #if !defined(CONFIG_USER_ONLY)
3177 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3178 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3179 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3180 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3181 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3182 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3183 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3184 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3185 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3186 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3187 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3188 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3189 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3190 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3191 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3192 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3193 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3194 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3195 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001600;
3196 /* Hardware reset vector */
3197 env
->hreset_vector
= 0x00000100UL
;
3201 #if defined(TARGET_PPC64)
3202 static void init_excp_970(CPUPPCState
*env
)
3204 #if !defined(CONFIG_USER_ONLY)
3205 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3206 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3207 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3208 env
->excp_vectors
[POWERPC_EXCP_DSEG
] = 0x00000380;
3209 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3210 env
->excp_vectors
[POWERPC_EXCP_ISEG
] = 0x00000480;
3211 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3212 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3213 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3214 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3215 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3216 env
->excp_vectors
[POWERPC_EXCP_HDECR
] = 0x00000980;
3217 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3218 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3219 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3220 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3221 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3222 env
->excp_vectors
[POWERPC_EXCP_MAINT
] = 0x00001600;
3223 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001700;
3224 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001800;
3225 /* Hardware reset vector */
3226 env
->hreset_vector
= 0x0000000000000100ULL
;
3230 static void init_excp_POWER7(CPUPPCState
*env
)
3232 #if !defined(CONFIG_USER_ONLY)
3233 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3234 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3235 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3236 env
->excp_vectors
[POWERPC_EXCP_DSEG
] = 0x00000380;
3237 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3238 env
->excp_vectors
[POWERPC_EXCP_ISEG
] = 0x00000480;
3239 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3240 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3241 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3242 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3243 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3244 env
->excp_vectors
[POWERPC_EXCP_HDECR
] = 0x00000980;
3245 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3246 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3247 env
->excp_vectors
[POWERPC_EXCP_HDSI
] = 0x00000E00;
3248 env
->excp_vectors
[POWERPC_EXCP_HISI
] = 0x00000E20;
3249 env
->excp_vectors
[POWERPC_EXCP_HV_EMU
] = 0x00000E40;
3250 env
->excp_vectors
[POWERPC_EXCP_HV_MAINT
] = 0x00000E60;
3251 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3252 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3253 env
->excp_vectors
[POWERPC_EXCP_VSXU
] = 0x00000F40;
3254 /* Hardware reset vector */
3255 env
->hreset_vector
= 0x0000000000000100ULL
;
3259 static void init_excp_POWER8(CPUPPCState
*env
)
3261 init_excp_POWER7(env
);
3263 #if !defined(CONFIG_USER_ONLY)
3264 env
->excp_vectors
[POWERPC_EXCP_SDOOR
] = 0x00000A00;
3265 env
->excp_vectors
[POWERPC_EXCP_FU
] = 0x00000F60;
3266 env
->excp_vectors
[POWERPC_EXCP_HV_FU
] = 0x00000F80;
3267 env
->excp_vectors
[POWERPC_EXCP_SDOOR_HV
] = 0x00000E80;
3273 /*****************************************************************************/
3274 /* Power management enable checks */
3275 static int check_pow_none(CPUPPCState
*env
)
3280 static int check_pow_nocheck(CPUPPCState
*env
)
3285 static int check_pow_hid0(CPUPPCState
*env
)
3287 if (env
->spr
[SPR_HID0
] & 0x00E00000)
3293 static int check_pow_hid0_74xx(CPUPPCState
*env
)
3295 if (env
->spr
[SPR_HID0
] & 0x00600000)
3301 static bool ppc_cpu_interrupts_big_endian_always(PowerPCCPU
*cpu
)
3307 static bool ppc_cpu_interrupts_big_endian_lpcr(PowerPCCPU
*cpu
)
3309 return !(cpu
->env
.spr
[SPR_LPCR
] & LPCR_ILE
);
3313 /*****************************************************************************/
3314 /* PowerPC implementations definitions */
3316 #define POWERPC_FAMILY(_name) \
3318 glue(glue(ppc_, _name), _cpu_family_class_init)(ObjectClass *, void *); \
3320 static const TypeInfo \
3321 glue(glue(ppc_, _name), _cpu_family_type_info) = { \
3322 .name = stringify(_name) "-family-" TYPE_POWERPC_CPU, \
3323 .parent = TYPE_POWERPC_CPU, \
3325 .class_init = glue(glue(ppc_, _name), _cpu_family_class_init), \
3328 static void glue(glue(ppc_, _name), _cpu_family_register_types)(void) \
3330 type_register_static( \
3331 &glue(glue(ppc_, _name), _cpu_family_type_info)); \
3334 type_init(glue(glue(ppc_, _name), _cpu_family_register_types)) \
3336 static void glue(glue(ppc_, _name), _cpu_family_class_init)
3338 static void init_proc_401(CPUPPCState
*env
)
3341 gen_spr_401_403(env
);
3343 init_excp_4xx_real(env
);
3344 env
->dcache_line_size
= 32;
3345 env
->icache_line_size
= 32;
3346 /* Allocate hardware IRQ controller */
3347 ppc40x_irq_init(ppc_env_get_cpu(env
));
3349 SET_FIT_PERIOD(12, 16, 20, 24);
3350 SET_WDT_PERIOD(16, 20, 24, 28);
3353 POWERPC_FAMILY(401)(ObjectClass
*oc
, void *data
)
3355 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3356 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3358 dc
->desc
= "PowerPC 401";
3359 pcc
->init_proc
= init_proc_401
;
3360 pcc
->check_pow
= check_pow_nocheck
;
3361 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3362 PPC_WRTEE
| PPC_DCR
|
3363 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3365 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3366 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3367 pcc
->msr_mask
= (1ull << MSR_KEY
) |
3376 pcc
->mmu_model
= POWERPC_MMU_REAL
;
3377 pcc
->excp_model
= POWERPC_EXCP_40x
;
3378 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3379 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3380 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3381 POWERPC_FLAG_BUS_CLK
;
3384 static void init_proc_401x2(CPUPPCState
*env
)
3387 gen_spr_401_403(env
);
3389 gen_spr_compress(env
);
3390 /* Memory management */
3391 #if !defined(CONFIG_USER_ONLY)
3395 env
->tlb_type
= TLB_EMB
;
3397 init_excp_4xx_softmmu(env
);
3398 env
->dcache_line_size
= 32;
3399 env
->icache_line_size
= 32;
3400 /* Allocate hardware IRQ controller */
3401 ppc40x_irq_init(ppc_env_get_cpu(env
));
3403 SET_FIT_PERIOD(12, 16, 20, 24);
3404 SET_WDT_PERIOD(16, 20, 24, 28);
3407 POWERPC_FAMILY(401x2
)(ObjectClass
*oc
, void *data
)
3409 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3410 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3412 dc
->desc
= "PowerPC 401x2";
3413 pcc
->init_proc
= init_proc_401x2
;
3414 pcc
->check_pow
= check_pow_nocheck
;
3415 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3416 PPC_DCR
| PPC_WRTEE
|
3417 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3418 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3419 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3420 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3421 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3422 pcc
->msr_mask
= (1ull << 20) |
3434 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3435 pcc
->excp_model
= POWERPC_EXCP_40x
;
3436 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3437 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3438 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3439 POWERPC_FLAG_BUS_CLK
;
3442 static void init_proc_401x3(CPUPPCState
*env
)
3445 gen_spr_401_403(env
);
3448 gen_spr_compress(env
);
3449 init_excp_4xx_softmmu(env
);
3450 env
->dcache_line_size
= 32;
3451 env
->icache_line_size
= 32;
3452 /* Allocate hardware IRQ controller */
3453 ppc40x_irq_init(ppc_env_get_cpu(env
));
3455 SET_FIT_PERIOD(12, 16, 20, 24);
3456 SET_WDT_PERIOD(16, 20, 24, 28);
3459 POWERPC_FAMILY(401x3
)(ObjectClass
*oc
, void *data
)
3461 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3462 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3464 dc
->desc
= "PowerPC 401x3";
3465 pcc
->init_proc
= init_proc_401x3
;
3466 pcc
->check_pow
= check_pow_nocheck
;
3467 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3468 PPC_DCR
| PPC_WRTEE
|
3469 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3470 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3471 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3472 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3473 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3474 pcc
->msr_mask
= (1ull << 20) |
3487 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3488 pcc
->excp_model
= POWERPC_EXCP_40x
;
3489 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3490 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3491 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3492 POWERPC_FLAG_BUS_CLK
;
3495 static void init_proc_IOP480(CPUPPCState
*env
)
3498 gen_spr_401_403(env
);
3500 gen_spr_compress(env
);
3501 /* Memory management */
3502 #if !defined(CONFIG_USER_ONLY)
3506 env
->tlb_type
= TLB_EMB
;
3508 init_excp_4xx_softmmu(env
);
3509 env
->dcache_line_size
= 32;
3510 env
->icache_line_size
= 32;
3511 /* Allocate hardware IRQ controller */
3512 ppc40x_irq_init(ppc_env_get_cpu(env
));
3514 SET_FIT_PERIOD(8, 12, 16, 20);
3515 SET_WDT_PERIOD(16, 20, 24, 28);
3518 POWERPC_FAMILY(IOP480
)(ObjectClass
*oc
, void *data
)
3520 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3521 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3523 dc
->desc
= "IOP480";
3524 pcc
->init_proc
= init_proc_IOP480
;
3525 pcc
->check_pow
= check_pow_nocheck
;
3526 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3527 PPC_DCR
| PPC_WRTEE
|
3528 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3529 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3530 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3531 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3532 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3533 pcc
->msr_mask
= (1ull << 20) |
3545 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3546 pcc
->excp_model
= POWERPC_EXCP_40x
;
3547 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3548 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3549 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3550 POWERPC_FLAG_BUS_CLK
;
3553 static void init_proc_403(CPUPPCState
*env
)
3556 gen_spr_401_403(env
);
3558 gen_spr_403_real(env
);
3559 init_excp_4xx_real(env
);
3560 env
->dcache_line_size
= 32;
3561 env
->icache_line_size
= 32;
3562 /* Allocate hardware IRQ controller */
3563 ppc40x_irq_init(ppc_env_get_cpu(env
));
3565 SET_FIT_PERIOD(8, 12, 16, 20);
3566 SET_WDT_PERIOD(16, 20, 24, 28);
3569 POWERPC_FAMILY(403)(ObjectClass
*oc
, void *data
)
3571 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3572 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3574 dc
->desc
= "PowerPC 403";
3575 pcc
->init_proc
= init_proc_403
;
3576 pcc
->check_pow
= check_pow_nocheck
;
3577 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3578 PPC_DCR
| PPC_WRTEE
|
3579 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3581 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3582 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3583 pcc
->msr_mask
= (1ull << MSR_POW
) |
3592 pcc
->mmu_model
= POWERPC_MMU_REAL
;
3593 pcc
->excp_model
= POWERPC_EXCP_40x
;
3594 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3595 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3596 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_PX
|
3597 POWERPC_FLAG_BUS_CLK
;
3600 static void init_proc_403GCX(CPUPPCState
*env
)
3603 gen_spr_401_403(env
);
3605 gen_spr_403_real(env
);
3606 gen_spr_403_mmu(env
);
3607 /* Bus access control */
3608 /* not emulated, as QEMU never does speculative access */
3609 spr_register(env
, SPR_40x_SGR
, "SGR",
3610 SPR_NOACCESS
, SPR_NOACCESS
,
3611 &spr_read_generic
, &spr_write_generic
,
3613 /* not emulated, as QEMU do not emulate caches */
3614 spr_register(env
, SPR_40x_DCWR
, "DCWR",
3615 SPR_NOACCESS
, SPR_NOACCESS
,
3616 &spr_read_generic
, &spr_write_generic
,
3618 /* Memory management */
3619 #if !defined(CONFIG_USER_ONLY)
3623 env
->tlb_type
= TLB_EMB
;
3625 init_excp_4xx_softmmu(env
);
3626 env
->dcache_line_size
= 32;
3627 env
->icache_line_size
= 32;
3628 /* Allocate hardware IRQ controller */
3629 ppc40x_irq_init(ppc_env_get_cpu(env
));
3631 SET_FIT_PERIOD(8, 12, 16, 20);
3632 SET_WDT_PERIOD(16, 20, 24, 28);
3635 POWERPC_FAMILY(403GCX
)(ObjectClass
*oc
, void *data
)
3637 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3638 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3640 dc
->desc
= "PowerPC 403 GCX";
3641 pcc
->init_proc
= init_proc_403GCX
;
3642 pcc
->check_pow
= check_pow_nocheck
;
3643 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3644 PPC_DCR
| PPC_WRTEE
|
3645 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3647 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3648 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3649 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3650 pcc
->msr_mask
= (1ull << MSR_POW
) |
3659 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3660 pcc
->excp_model
= POWERPC_EXCP_40x
;
3661 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3662 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3663 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_PX
|
3664 POWERPC_FLAG_BUS_CLK
;
3667 static void init_proc_405(CPUPPCState
*env
)
3673 /* Bus access control */
3674 /* not emulated, as QEMU never does speculative access */
3675 spr_register(env
, SPR_40x_SGR
, "SGR",
3676 SPR_NOACCESS
, SPR_NOACCESS
,
3677 &spr_read_generic
, &spr_write_generic
,
3679 /* not emulated, as QEMU do not emulate caches */
3680 spr_register(env
, SPR_40x_DCWR
, "DCWR",
3681 SPR_NOACCESS
, SPR_NOACCESS
,
3682 &spr_read_generic
, &spr_write_generic
,
3684 /* Memory management */
3685 #if !defined(CONFIG_USER_ONLY)
3689 env
->tlb_type
= TLB_EMB
;
3691 init_excp_4xx_softmmu(env
);
3692 env
->dcache_line_size
= 32;
3693 env
->icache_line_size
= 32;
3694 /* Allocate hardware IRQ controller */
3695 ppc40x_irq_init(ppc_env_get_cpu(env
));
3697 SET_FIT_PERIOD(8, 12, 16, 20);
3698 SET_WDT_PERIOD(16, 20, 24, 28);
3701 POWERPC_FAMILY(405)(ObjectClass
*oc
, void *data
)
3703 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3704 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3706 dc
->desc
= "PowerPC 405";
3707 pcc
->init_proc
= init_proc_405
;
3708 pcc
->check_pow
= check_pow_nocheck
;
3709 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3710 PPC_DCR
| PPC_WRTEE
|
3711 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3712 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3713 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3714 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3715 PPC_4xx_COMMON
| PPC_405_MAC
| PPC_40x_EXCP
;
3716 pcc
->msr_mask
= (1ull << MSR_POW
) |
3725 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx
;
3726 pcc
->excp_model
= POWERPC_EXCP_40x
;
3727 pcc
->bus_model
= PPC_FLAGS_INPUT_405
;
3728 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3729 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3730 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3733 static void init_proc_440EP(CPUPPCState
*env
)
3737 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3739 gen_spr_usprgh(env
);
3740 /* Processor identification */
3741 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3742 SPR_NOACCESS
, SPR_NOACCESS
,
3743 &spr_read_generic
, &spr_write_pir
,
3745 /* XXX : not implemented */
3746 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
3747 SPR_NOACCESS
, SPR_NOACCESS
,
3748 &spr_read_generic
, &spr_write_generic
,
3750 /* XXX : not implemented */
3751 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
3752 SPR_NOACCESS
, SPR_NOACCESS
,
3753 &spr_read_generic
, &spr_write_generic
,
3755 /* XXX : not implemented */
3756 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
3757 SPR_NOACCESS
, SPR_NOACCESS
,
3758 &spr_read_generic
, &spr_write_generic
,
3760 /* XXX : not implemented */
3761 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
3762 SPR_NOACCESS
, SPR_NOACCESS
,
3763 &spr_read_generic
, &spr_write_generic
,
3765 /* XXX : not implemented */
3766 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
3767 SPR_NOACCESS
, SPR_NOACCESS
,
3768 &spr_read_generic
, &spr_write_generic
,
3770 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
3771 SPR_NOACCESS
, SPR_NOACCESS
,
3772 &spr_read_generic
, &spr_write_generic
,
3774 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
3775 SPR_NOACCESS
, SPR_NOACCESS
,
3776 &spr_read_generic
, &spr_write_generic
,
3778 /* XXX : not implemented */
3779 spr_register(env
, SPR_440_CCR1
, "CCR1",
3780 SPR_NOACCESS
, SPR_NOACCESS
,
3781 &spr_read_generic
, &spr_write_generic
,
3783 /* Memory management */
3784 #if !defined(CONFIG_USER_ONLY)
3788 env
->tlb_type
= TLB_EMB
;
3790 init_excp_BookE(env
);
3791 env
->dcache_line_size
= 32;
3792 env
->icache_line_size
= 32;
3793 ppc40x_irq_init(ppc_env_get_cpu(env
));
3795 SET_FIT_PERIOD(12, 16, 20, 24);
3796 SET_WDT_PERIOD(20, 24, 28, 32);
3799 POWERPC_FAMILY(440EP
)(ObjectClass
*oc
, void *data
)
3801 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3802 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3804 dc
->desc
= "PowerPC 440 EP";
3805 pcc
->init_proc
= init_proc_440EP
;
3806 pcc
->check_pow
= check_pow_nocheck
;
3807 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3808 PPC_FLOAT
| PPC_FLOAT_FRES
| PPC_FLOAT_FSEL
|
3809 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
3811 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
3812 PPC_CACHE
| PPC_CACHE_ICBI
|
3813 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3814 PPC_MEM_TLBSYNC
| PPC_MFTB
|
3815 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3817 pcc
->msr_mask
= (1ull << MSR_POW
) |
3829 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3830 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3831 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3832 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3833 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3834 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3837 POWERPC_FAMILY(460EX
)(ObjectClass
*oc
, void *data
)
3839 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3840 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3842 dc
->desc
= "PowerPC 460 EX";
3843 pcc
->init_proc
= init_proc_440EP
;
3844 pcc
->check_pow
= check_pow_nocheck
;
3845 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3846 PPC_FLOAT
| PPC_FLOAT_FRES
| PPC_FLOAT_FSEL
|
3847 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
3849 PPC_DCR
| PPC_DCRX
| PPC_WRTEE
| PPC_RFMCI
|
3850 PPC_CACHE
| PPC_CACHE_ICBI
|
3851 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3852 PPC_MEM_TLBSYNC
| PPC_MFTB
|
3853 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3855 pcc
->msr_mask
= (1ull << MSR_POW
) |
3867 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3868 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3869 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3870 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3871 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3872 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3875 static void init_proc_440GP(CPUPPCState
*env
)
3879 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3881 gen_spr_usprgh(env
);
3882 /* Processor identification */
3883 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3884 SPR_NOACCESS
, SPR_NOACCESS
,
3885 &spr_read_generic
, &spr_write_pir
,
3887 /* XXX : not implemented */
3888 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
3889 SPR_NOACCESS
, SPR_NOACCESS
,
3890 &spr_read_generic
, &spr_write_generic
,
3892 /* XXX : not implemented */
3893 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
3894 SPR_NOACCESS
, SPR_NOACCESS
,
3895 &spr_read_generic
, &spr_write_generic
,
3897 /* XXX : not implemented */
3898 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
3899 SPR_NOACCESS
, SPR_NOACCESS
,
3900 &spr_read_generic
, &spr_write_generic
,
3902 /* XXX : not implemented */
3903 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
3904 SPR_NOACCESS
, SPR_NOACCESS
,
3905 &spr_read_generic
, &spr_write_generic
,
3907 /* Memory management */
3908 #if !defined(CONFIG_USER_ONLY)
3912 env
->tlb_type
= TLB_EMB
;
3914 init_excp_BookE(env
);
3915 env
->dcache_line_size
= 32;
3916 env
->icache_line_size
= 32;
3917 /* XXX: TODO: allocate internal IRQ controller */
3919 SET_FIT_PERIOD(12, 16, 20, 24);
3920 SET_WDT_PERIOD(20, 24, 28, 32);
3923 POWERPC_FAMILY(440GP
)(ObjectClass
*oc
, void *data
)
3925 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3926 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3928 dc
->desc
= "PowerPC 440 GP";
3929 pcc
->init_proc
= init_proc_440GP
;
3930 pcc
->check_pow
= check_pow_nocheck
;
3931 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3932 PPC_DCR
| PPC_DCRX
| PPC_WRTEE
| PPC_MFAPIDI
|
3933 PPC_CACHE
| PPC_CACHE_ICBI
|
3934 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3935 PPC_MEM_TLBSYNC
| PPC_TLBIVA
| PPC_MFTB
|
3936 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3938 pcc
->msr_mask
= (1ull << MSR_POW
) |
3950 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3951 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3952 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3953 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3954 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3955 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3958 static void init_proc_440x4(CPUPPCState
*env
)
3962 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3964 gen_spr_usprgh(env
);
3965 /* Processor identification */
3966 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3967 SPR_NOACCESS
, SPR_NOACCESS
,
3968 &spr_read_generic
, &spr_write_pir
,
3970 /* XXX : not implemented */
3971 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
3972 SPR_NOACCESS
, SPR_NOACCESS
,
3973 &spr_read_generic
, &spr_write_generic
,
3975 /* XXX : not implemented */
3976 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
3977 SPR_NOACCESS
, SPR_NOACCESS
,
3978 &spr_read_generic
, &spr_write_generic
,
3980 /* XXX : not implemented */
3981 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
3982 SPR_NOACCESS
, SPR_NOACCESS
,
3983 &spr_read_generic
, &spr_write_generic
,
3985 /* XXX : not implemented */
3986 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
3987 SPR_NOACCESS
, SPR_NOACCESS
,
3988 &spr_read_generic
, &spr_write_generic
,
3990 /* Memory management */
3991 #if !defined(CONFIG_USER_ONLY)
3995 env
->tlb_type
= TLB_EMB
;
3997 init_excp_BookE(env
);
3998 env
->dcache_line_size
= 32;
3999 env
->icache_line_size
= 32;
4000 /* XXX: TODO: allocate internal IRQ controller */
4002 SET_FIT_PERIOD(12, 16, 20, 24);
4003 SET_WDT_PERIOD(20, 24, 28, 32);
4006 POWERPC_FAMILY(440x4
)(ObjectClass
*oc
, void *data
)
4008 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4009 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4011 dc
->desc
= "PowerPC 440x4";
4012 pcc
->init_proc
= init_proc_440x4
;
4013 pcc
->check_pow
= check_pow_nocheck
;
4014 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4015 PPC_DCR
| PPC_WRTEE
|
4016 PPC_CACHE
| PPC_CACHE_ICBI
|
4017 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4018 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4019 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4021 pcc
->msr_mask
= (1ull << MSR_POW
) |
4033 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4034 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4035 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4036 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4037 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4038 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4041 static void init_proc_440x5(CPUPPCState
*env
)
4045 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
4047 gen_spr_usprgh(env
);
4048 /* Processor identification */
4049 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4050 SPR_NOACCESS
, SPR_NOACCESS
,
4051 &spr_read_generic
, &spr_write_pir
,
4053 /* XXX : not implemented */
4054 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4055 SPR_NOACCESS
, SPR_NOACCESS
,
4056 &spr_read_generic
, &spr_write_generic
,
4058 /* XXX : not implemented */
4059 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4060 SPR_NOACCESS
, SPR_NOACCESS
,
4061 &spr_read_generic
, &spr_write_generic
,
4063 /* XXX : not implemented */
4064 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
4065 SPR_NOACCESS
, SPR_NOACCESS
,
4066 &spr_read_generic
, &spr_write_generic
,
4068 /* XXX : not implemented */
4069 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
4070 SPR_NOACCESS
, SPR_NOACCESS
,
4071 &spr_read_generic
, &spr_write_generic
,
4073 /* XXX : not implemented */
4074 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
4075 SPR_NOACCESS
, SPR_NOACCESS
,
4076 &spr_read_generic
, &spr_write_generic
,
4078 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
4079 SPR_NOACCESS
, SPR_NOACCESS
,
4080 &spr_read_generic
, &spr_write_generic
,
4082 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
4083 SPR_NOACCESS
, SPR_NOACCESS
,
4084 &spr_read_generic
, &spr_write_generic
,
4086 /* XXX : not implemented */
4087 spr_register(env
, SPR_440_CCR1
, "CCR1",
4088 SPR_NOACCESS
, SPR_NOACCESS
,
4089 &spr_read_generic
, &spr_write_generic
,
4091 /* Memory management */
4092 #if !defined(CONFIG_USER_ONLY)
4096 env
->tlb_type
= TLB_EMB
;
4098 init_excp_BookE(env
);
4099 env
->dcache_line_size
= 32;
4100 env
->icache_line_size
= 32;
4101 ppc40x_irq_init(ppc_env_get_cpu(env
));
4103 SET_FIT_PERIOD(12, 16, 20, 24);
4104 SET_WDT_PERIOD(20, 24, 28, 32);
4107 POWERPC_FAMILY(440x5
)(ObjectClass
*oc
, void *data
)
4109 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4110 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4112 dc
->desc
= "PowerPC 440x5";
4113 pcc
->init_proc
= init_proc_440x5
;
4114 pcc
->check_pow
= check_pow_nocheck
;
4115 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4116 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
4117 PPC_CACHE
| PPC_CACHE_ICBI
|
4118 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4119 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4120 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4122 pcc
->msr_mask
= (1ull << MSR_POW
) |
4134 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4135 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4136 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4137 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4138 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4139 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4142 POWERPC_FAMILY(440x5wDFPU
)(ObjectClass
*oc
, void *data
)
4144 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4145 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4147 dc
->desc
= "PowerPC 440x5 with double precision FPU";
4148 pcc
->init_proc
= init_proc_440x5
;
4149 pcc
->check_pow
= check_pow_nocheck
;
4150 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4151 PPC_FLOAT
| PPC_FLOAT_FSQRT
|
4153 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
4154 PPC_CACHE
| PPC_CACHE_ICBI
|
4155 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4156 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4157 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4159 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
4160 pcc
->msr_mask
= (1ull << MSR_POW
) |
4172 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4173 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4174 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4175 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4176 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4177 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4180 static void init_proc_MPC5xx(CPUPPCState
*env
)
4184 gen_spr_5xx_8xx(env
);
4186 init_excp_MPC5xx(env
);
4187 env
->dcache_line_size
= 32;
4188 env
->icache_line_size
= 32;
4189 /* XXX: TODO: allocate internal IRQ controller */
4192 POWERPC_FAMILY(MPC5xx
)(ObjectClass
*oc
, void *data
)
4194 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4195 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4197 dc
->desc
= "Freescale 5xx cores (aka RCPU)";
4198 pcc
->init_proc
= init_proc_MPC5xx
;
4199 pcc
->check_pow
= check_pow_none
;
4200 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4201 PPC_MEM_EIEIO
| PPC_MEM_SYNC
|
4202 PPC_CACHE_ICBI
| PPC_FLOAT
| PPC_FLOAT_STFIWX
|
4204 pcc
->msr_mask
= (1ull << MSR_ILE
) |
4216 pcc
->mmu_model
= POWERPC_MMU_REAL
;
4217 pcc
->excp_model
= POWERPC_EXCP_603
;
4218 pcc
->bus_model
= PPC_FLAGS_INPUT_RCPU
;
4219 pcc
->bfd_mach
= bfd_mach_ppc_505
;
4220 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
4221 POWERPC_FLAG_BUS_CLK
;
4224 static void init_proc_MPC8xx(CPUPPCState
*env
)
4228 gen_spr_5xx_8xx(env
);
4230 init_excp_MPC8xx(env
);
4231 env
->dcache_line_size
= 32;
4232 env
->icache_line_size
= 32;
4233 /* XXX: TODO: allocate internal IRQ controller */
4236 POWERPC_FAMILY(MPC8xx
)(ObjectClass
*oc
, void *data
)
4238 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4239 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4241 dc
->desc
= "Freescale 8xx cores (aka PowerQUICC)";
4242 pcc
->init_proc
= init_proc_MPC8xx
;
4243 pcc
->check_pow
= check_pow_none
;
4244 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4245 PPC_MEM_EIEIO
| PPC_MEM_SYNC
|
4246 PPC_CACHE_ICBI
| PPC_MFTB
;
4247 pcc
->msr_mask
= (1ull << MSR_ILE
) |
4259 pcc
->mmu_model
= POWERPC_MMU_MPC8xx
;
4260 pcc
->excp_model
= POWERPC_EXCP_603
;
4261 pcc
->bus_model
= PPC_FLAGS_INPUT_RCPU
;
4262 pcc
->bfd_mach
= bfd_mach_ppc_860
;
4263 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
4264 POWERPC_FLAG_BUS_CLK
;
4267 /* Freescale 82xx cores (aka PowerQUICC-II) */
4269 static void init_proc_G2(CPUPPCState
*env
)
4271 gen_spr_ne_601(env
);
4273 gen_spr_G2_755(env
);
4277 /* External access control */
4278 /* XXX : not implemented */
4279 spr_register(env
, SPR_EAR
, "EAR",
4280 SPR_NOACCESS
, SPR_NOACCESS
,
4281 &spr_read_generic
, &spr_write_generic
,
4283 /* Hardware implementation register */
4284 /* XXX : not implemented */
4285 spr_register(env
, SPR_HID0
, "HID0",
4286 SPR_NOACCESS
, SPR_NOACCESS
,
4287 &spr_read_generic
, &spr_write_generic
,
4289 /* XXX : not implemented */
4290 spr_register(env
, SPR_HID1
, "HID1",
4291 SPR_NOACCESS
, SPR_NOACCESS
,
4292 &spr_read_generic
, &spr_write_generic
,
4294 /* XXX : not implemented */
4295 spr_register(env
, SPR_HID2
, "HID2",
4296 SPR_NOACCESS
, SPR_NOACCESS
,
4297 &spr_read_generic
, &spr_write_generic
,
4299 /* Memory management */
4302 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4304 env
->dcache_line_size
= 32;
4305 env
->icache_line_size
= 32;
4306 /* Allocate hardware IRQ controller */
4307 ppc6xx_irq_init(ppc_env_get_cpu(env
));
4310 POWERPC_FAMILY(G2
)(ObjectClass
*oc
, void *data
)
4312 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4313 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4315 dc
->desc
= "PowerPC G2";
4316 pcc
->init_proc
= init_proc_G2
;
4317 pcc
->check_pow
= check_pow_hid0
;
4318 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4319 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4321 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4322 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4323 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4324 PPC_SEGMENT
| PPC_EXTERN
;
4325 pcc
->msr_mask
= (1ull << MSR_POW
) |
4326 (1ull << MSR_TGPR
) |
4340 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4341 pcc
->excp_model
= POWERPC_EXCP_G2
;
4342 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4343 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
4344 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4345 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4348 static void init_proc_G2LE(CPUPPCState
*env
)
4350 gen_spr_ne_601(env
);
4352 gen_spr_G2_755(env
);
4356 /* External access control */
4357 /* XXX : not implemented */
4358 spr_register(env
, SPR_EAR
, "EAR",
4359 SPR_NOACCESS
, SPR_NOACCESS
,
4360 &spr_read_generic
, &spr_write_generic
,
4362 /* Hardware implementation register */
4363 /* XXX : not implemented */
4364 spr_register(env
, SPR_HID0
, "HID0",
4365 SPR_NOACCESS
, SPR_NOACCESS
,
4366 &spr_read_generic
, &spr_write_generic
,
4368 /* XXX : not implemented */
4369 spr_register(env
, SPR_HID1
, "HID1",
4370 SPR_NOACCESS
, SPR_NOACCESS
,
4371 &spr_read_generic
, &spr_write_generic
,
4373 /* XXX : not implemented */
4374 spr_register(env
, SPR_HID2
, "HID2",
4375 SPR_NOACCESS
, SPR_NOACCESS
,
4376 &spr_read_generic
, &spr_write_generic
,
4379 /* Memory management */
4382 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4384 env
->dcache_line_size
= 32;
4385 env
->icache_line_size
= 32;
4386 /* Allocate hardware IRQ controller */
4387 ppc6xx_irq_init(ppc_env_get_cpu(env
));
4390 POWERPC_FAMILY(G2LE
)(ObjectClass
*oc
, void *data
)
4392 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4393 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4395 dc
->desc
= "PowerPC G2LE";
4396 pcc
->init_proc
= init_proc_G2LE
;
4397 pcc
->check_pow
= check_pow_hid0
;
4398 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4399 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4401 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4402 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4403 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4404 PPC_SEGMENT
| PPC_EXTERN
;
4405 pcc
->msr_mask
= (1ull << MSR_POW
) |
4406 (1ull << MSR_TGPR
) |
4422 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4423 pcc
->excp_model
= POWERPC_EXCP_G2
;
4424 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4425 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
4426 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4427 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4430 static void init_proc_e200(CPUPPCState
*env
)
4434 gen_spr_BookE(env
, 0x000000070000FFFFULL
);
4435 /* XXX : not implemented */
4436 spr_register(env
, SPR_BOOKE_SPEFSCR
, "SPEFSCR",
4437 &spr_read_spefscr
, &spr_write_spefscr
,
4438 &spr_read_spefscr
, &spr_write_spefscr
,
4440 /* Memory management */
4441 gen_spr_BookE206(env
, 0x0000005D, NULL
, 0);
4442 /* XXX : not implemented */
4443 spr_register(env
, SPR_HID0
, "HID0",
4444 SPR_NOACCESS
, SPR_NOACCESS
,
4445 &spr_read_generic
, &spr_write_generic
,
4447 /* XXX : not implemented */
4448 spr_register(env
, SPR_HID1
, "HID1",
4449 SPR_NOACCESS
, SPR_NOACCESS
,
4450 &spr_read_generic
, &spr_write_generic
,
4452 /* XXX : not implemented */
4453 spr_register(env
, SPR_Exxx_ALTCTXCR
, "ALTCTXCR",
4454 SPR_NOACCESS
, SPR_NOACCESS
,
4455 &spr_read_generic
, &spr_write_generic
,
4457 /* XXX : not implemented */
4458 spr_register(env
, SPR_Exxx_BUCSR
, "BUCSR",
4459 SPR_NOACCESS
, SPR_NOACCESS
,
4460 &spr_read_generic
, &spr_write_generic
,
4462 /* XXX : not implemented */
4463 spr_register(env
, SPR_Exxx_CTXCR
, "CTXCR",
4464 SPR_NOACCESS
, SPR_NOACCESS
,
4465 &spr_read_generic
, &spr_write_generic
,
4467 /* XXX : not implemented */
4468 spr_register(env
, SPR_Exxx_DBCNT
, "DBCNT",
4469 SPR_NOACCESS
, SPR_NOACCESS
,
4470 &spr_read_generic
, &spr_write_generic
,
4472 /* XXX : not implemented */
4473 spr_register(env
, SPR_Exxx_DBCR3
, "DBCR3",
4474 SPR_NOACCESS
, SPR_NOACCESS
,
4475 &spr_read_generic
, &spr_write_generic
,
4477 /* XXX : not implemented */
4478 spr_register(env
, SPR_Exxx_L1CFG0
, "L1CFG0",
4479 &spr_read_generic
, SPR_NOACCESS
,
4480 &spr_read_generic
, SPR_NOACCESS
,
4482 /* XXX : not implemented */
4483 spr_register(env
, SPR_Exxx_L1CSR0
, "L1CSR0",
4484 SPR_NOACCESS
, SPR_NOACCESS
,
4485 &spr_read_generic
, &spr_write_generic
,
4487 /* XXX : not implemented */
4488 spr_register(env
, SPR_Exxx_L1FINV0
, "L1FINV0",
4489 SPR_NOACCESS
, SPR_NOACCESS
,
4490 &spr_read_generic
, &spr_write_generic
,
4492 /* XXX : not implemented */
4493 spr_register(env
, SPR_BOOKE_TLB0CFG
, "TLB0CFG",
4494 SPR_NOACCESS
, SPR_NOACCESS
,
4495 &spr_read_generic
, &spr_write_generic
,
4497 /* XXX : not implemented */
4498 spr_register(env
, SPR_BOOKE_TLB1CFG
, "TLB1CFG",
4499 SPR_NOACCESS
, SPR_NOACCESS
,
4500 &spr_read_generic
, &spr_write_generic
,
4502 /* XXX : not implemented */
4503 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4504 SPR_NOACCESS
, SPR_NOACCESS
,
4505 &spr_read_generic
, &spr_write_generic
,
4507 /* XXX : not implemented */
4508 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4509 SPR_NOACCESS
, SPR_NOACCESS
,
4510 &spr_read_generic
, &spr_write_generic
,
4512 /* XXX : not implemented */
4513 spr_register(env
, SPR_MMUCSR0
, "MMUCSR0",
4514 SPR_NOACCESS
, SPR_NOACCESS
,
4515 &spr_read_generic
, &spr_write_generic
,
4516 0x00000000); /* TOFIX */
4517 spr_register(env
, SPR_BOOKE_DSRR0
, "DSRR0",
4518 SPR_NOACCESS
, SPR_NOACCESS
,
4519 &spr_read_generic
, &spr_write_generic
,
4521 spr_register(env
, SPR_BOOKE_DSRR1
, "DSRR1",
4522 SPR_NOACCESS
, SPR_NOACCESS
,
4523 &spr_read_generic
, &spr_write_generic
,
4525 #if !defined(CONFIG_USER_ONLY)
4529 env
->tlb_type
= TLB_EMB
;
4531 init_excp_e200(env
, 0xFFFF0000UL
);
4532 env
->dcache_line_size
= 32;
4533 env
->icache_line_size
= 32;
4534 /* XXX: TODO: allocate internal IRQ controller */
4537 POWERPC_FAMILY(e200
)(ObjectClass
*oc
, void *data
)
4539 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4540 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4542 dc
->desc
= "e200 core";
4543 pcc
->init_proc
= init_proc_e200
;
4544 pcc
->check_pow
= check_pow_hid0
;
4545 /* XXX: unimplemented instructions:
4552 * all SPE multiply-accumulate instructions
4554 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
4555 PPC_SPE
| PPC_SPE_SINGLE
|
4556 PPC_WRTEE
| PPC_RFDI
|
4557 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
4558 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4559 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
|
4561 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
4575 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
4576 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4577 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4578 pcc
->bfd_mach
= bfd_mach_ppc_860
;
4579 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
4580 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
4581 POWERPC_FLAG_BUS_CLK
;
4584 static void init_proc_e300(CPUPPCState
*env
)
4586 gen_spr_ne_601(env
);
4591 /* hardware implementation registers */
4592 /* XXX : not implemented */
4593 spr_register(env
, SPR_HID0
, "HID0",
4594 SPR_NOACCESS
, SPR_NOACCESS
,
4595 &spr_read_generic
, &spr_write_generic
,
4597 /* XXX : not implemented */
4598 spr_register(env
, SPR_HID1
, "HID1",
4599 SPR_NOACCESS
, SPR_NOACCESS
,
4600 &spr_read_generic
, &spr_write_generic
,
4602 /* XXX : not implemented */
4603 spr_register(env
, SPR_HID2
, "HID2",
4604 SPR_NOACCESS
, SPR_NOACCESS
,
4605 &spr_read_generic
, &spr_write_generic
,
4608 /* XXX : not implemented */
4609 spr_register(env
, SPR_DABR
, "DABR",
4610 SPR_NOACCESS
, SPR_NOACCESS
,
4611 &spr_read_generic
, &spr_write_generic
,
4613 /* XXX : not implemented */
4614 spr_register(env
, SPR_DABR2
, "DABR2",
4615 SPR_NOACCESS
, SPR_NOACCESS
,
4616 &spr_read_generic
, &spr_write_generic
,
4618 /* XXX : not implemented */
4619 spr_register(env
, SPR_IABR2
, "IABR2",
4620 SPR_NOACCESS
, SPR_NOACCESS
,
4621 &spr_read_generic
, &spr_write_generic
,
4623 /* XXX : not implemented */
4624 spr_register(env
, SPR_IBCR
, "IBCR",
4625 SPR_NOACCESS
, SPR_NOACCESS
,
4626 &spr_read_generic
, &spr_write_generic
,
4628 /* XXX : not implemented */
4629 spr_register(env
, SPR_DBCR
, "DBCR",
4630 SPR_NOACCESS
, SPR_NOACCESS
,
4631 &spr_read_generic
, &spr_write_generic
,
4633 /* Memory management */
4636 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4638 env
->dcache_line_size
= 32;
4639 env
->icache_line_size
= 32;
4640 /* Allocate hardware IRQ controller */
4641 ppc6xx_irq_init(ppc_env_get_cpu(env
));
4644 POWERPC_FAMILY(e300
)(ObjectClass
*oc
, void *data
)
4646 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4647 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4649 dc
->desc
= "e300 core";
4650 pcc
->init_proc
= init_proc_e300
;
4651 pcc
->check_pow
= check_pow_hid0
;
4652 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4653 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4655 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4656 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4657 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4658 PPC_SEGMENT
| PPC_EXTERN
;
4659 pcc
->msr_mask
= (1ull << MSR_POW
) |
4660 (1ull << MSR_TGPR
) |
4676 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4677 pcc
->excp_model
= POWERPC_EXCP_603
;
4678 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4679 pcc
->bfd_mach
= bfd_mach_ppc_603
;
4680 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4681 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4684 #if !defined(CONFIG_USER_ONLY)
4685 static void spr_write_mas73(DisasContext
*ctx
, int sprn
, int gprn
)
4687 TCGv val
= tcg_temp_new();
4688 tcg_gen_ext32u_tl(val
, cpu_gpr
[gprn
]);
4689 gen_store_spr(SPR_BOOKE_MAS3
, val
);
4690 tcg_gen_shri_tl(val
, cpu_gpr
[gprn
], 32);
4691 gen_store_spr(SPR_BOOKE_MAS7
, val
);
4695 static void spr_read_mas73(DisasContext
*ctx
, int gprn
, int sprn
)
4697 TCGv mas7
= tcg_temp_new();
4698 TCGv mas3
= tcg_temp_new();
4699 gen_load_spr(mas7
, SPR_BOOKE_MAS7
);
4700 tcg_gen_shli_tl(mas7
, mas7
, 32);
4701 gen_load_spr(mas3
, SPR_BOOKE_MAS3
);
4702 tcg_gen_or_tl(cpu_gpr
[gprn
], mas3
, mas7
);
4703 tcg_temp_free(mas3
);
4704 tcg_temp_free(mas7
);
4709 enum fsl_e500_version
{
4717 static void init_proc_e500(CPUPPCState
*env
, int version
)
4719 PowerPCCPU
*cpu
= ppc_env_get_cpu(env
);
4720 uint32_t tlbncfg
[2];
4722 uint64_t ivpr_mask
= 0xFFFF0000ULL
;
4723 uint32_t l1cfg0
= 0x3800 /* 8 ways */
4724 | 0x0020; /* 32 kb */
4725 uint32_t l1cfg1
= 0x3800 /* 8 ways */
4726 | 0x0020; /* 32 kb */
4727 uint32_t mmucfg
= 0;
4728 #if !defined(CONFIG_USER_ONLY)
4735 * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't
4736 * complain when accessing them.
4737 * gen_spr_BookE(env, 0x0000000F0000FD7FULL);
4743 ivor_mask
= 0x0000000F0000FFFFULL
;
4747 ivor_mask
= 0x000003FE0000FFFFULL
;
4750 ivor_mask
= 0x000003FF0000FFFFULL
;
4753 gen_spr_BookE(env
, ivor_mask
);
4754 gen_spr_usprg3(env
);
4755 /* Processor identification */
4756 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4757 SPR_NOACCESS
, SPR_NOACCESS
,
4758 &spr_read_generic
, &spr_write_pir
,
4760 /* XXX : not implemented */
4761 spr_register(env
, SPR_BOOKE_SPEFSCR
, "SPEFSCR",
4762 &spr_read_spefscr
, &spr_write_spefscr
,
4763 &spr_read_spefscr
, &spr_write_spefscr
,
4765 #if !defined(CONFIG_USER_ONLY)
4766 /* Memory management */
4772 tlbncfg
[0] = gen_tlbncfg(2, 1, 1, 0, 256);
4773 tlbncfg
[1] = gen_tlbncfg(16, 1, 9, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 16);
4776 tlbncfg
[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4777 tlbncfg
[1] = gen_tlbncfg(16, 1, 12, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 16);
4781 tlbncfg
[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4782 tlbncfg
[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 64);
4787 tlbncfg
[0] = 0x08052400;
4788 tlbncfg
[1] = 0x40028040;
4791 cpu_abort(CPU(cpu
), "Unknown CPU: " TARGET_FMT_lx
"\n", env
->spr
[SPR_PVR
]);
4798 env
->dcache_line_size
= 32;
4799 env
->icache_line_size
= 32;
4803 env
->dcache_line_size
= 64;
4804 env
->icache_line_size
= 64;
4805 l1cfg0
|= 0x1000000; /* 64 byte cache block size */
4806 l1cfg1
|= 0x1000000; /* 64 byte cache block size */
4809 env
->dcache_line_size
= 32;
4810 env
->icache_line_size
= 32;
4811 l1cfg0
|= 0x0F83820;
4812 l1cfg1
|= 0x0B83820;
4815 cpu_abort(CPU(cpu
), "Unknown CPU: " TARGET_FMT_lx
"\n", env
->spr
[SPR_PVR
]);
4817 gen_spr_BookE206(env
, 0x000000DF, tlbncfg
, mmucfg
);
4818 /* XXX : not implemented */
4819 spr_register(env
, SPR_HID0
, "HID0",
4820 SPR_NOACCESS
, SPR_NOACCESS
,
4821 &spr_read_generic
, &spr_write_generic
,
4823 /* XXX : not implemented */
4824 spr_register(env
, SPR_HID1
, "HID1",
4825 SPR_NOACCESS
, SPR_NOACCESS
,
4826 &spr_read_generic
, &spr_write_generic
,
4828 /* XXX : not implemented */
4829 spr_register(env
, SPR_Exxx_BBEAR
, "BBEAR",
4830 SPR_NOACCESS
, SPR_NOACCESS
,
4831 &spr_read_generic
, &spr_write_generic
,
4833 /* XXX : not implemented */
4834 spr_register(env
, SPR_Exxx_BBTAR
, "BBTAR",
4835 SPR_NOACCESS
, SPR_NOACCESS
,
4836 &spr_read_generic
, &spr_write_generic
,
4838 /* XXX : not implemented */
4839 spr_register(env
, SPR_Exxx_MCAR
, "MCAR",
4840 SPR_NOACCESS
, SPR_NOACCESS
,
4841 &spr_read_generic
, &spr_write_generic
,
4843 /* XXX : not implemented */
4844 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
4845 SPR_NOACCESS
, SPR_NOACCESS
,
4846 &spr_read_generic
, &spr_write_generic
,
4848 /* XXX : not implemented */
4849 spr_register(env
, SPR_Exxx_NPIDR
, "NPIDR",
4850 SPR_NOACCESS
, SPR_NOACCESS
,
4851 &spr_read_generic
, &spr_write_generic
,
4853 /* XXX : not implemented */
4854 spr_register(env
, SPR_Exxx_BUCSR
, "BUCSR",
4855 SPR_NOACCESS
, SPR_NOACCESS
,
4856 &spr_read_generic
, &spr_write_generic
,
4858 /* XXX : not implemented */
4859 spr_register(env
, SPR_Exxx_L1CFG0
, "L1CFG0",
4860 &spr_read_generic
, SPR_NOACCESS
,
4861 &spr_read_generic
, SPR_NOACCESS
,
4863 spr_register(env
, SPR_Exxx_L1CFG1
, "L1CFG1",
4864 &spr_read_generic
, SPR_NOACCESS
,
4865 &spr_read_generic
, SPR_NOACCESS
,
4867 spr_register(env
, SPR_Exxx_L1CSR0
, "L1CSR0",
4868 SPR_NOACCESS
, SPR_NOACCESS
,
4869 &spr_read_generic
, &spr_write_e500_l1csr0
,
4871 spr_register(env
, SPR_Exxx_L1CSR1
, "L1CSR1",
4872 SPR_NOACCESS
, SPR_NOACCESS
,
4873 &spr_read_generic
, &spr_write_e500_l1csr1
,
4875 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
4876 SPR_NOACCESS
, SPR_NOACCESS
,
4877 &spr_read_generic
, &spr_write_generic
,
4879 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
4880 SPR_NOACCESS
, SPR_NOACCESS
,
4881 &spr_read_generic
, &spr_write_generic
,
4883 spr_register(env
, SPR_MMUCSR0
, "MMUCSR0",
4884 SPR_NOACCESS
, SPR_NOACCESS
,
4885 &spr_read_generic
, &spr_write_booke206_mmucsr0
,
4887 spr_register(env
, SPR_BOOKE_EPR
, "EPR",
4888 SPR_NOACCESS
, SPR_NOACCESS
,
4889 &spr_read_generic
, SPR_NOACCESS
,
4891 /* XXX better abstract into Emb.xxx features */
4892 if ((version
== fsl_e5500
) || (version
== fsl_e6500
)) {
4893 spr_register(env
, SPR_BOOKE_EPCR
, "EPCR",
4894 SPR_NOACCESS
, SPR_NOACCESS
,
4895 &spr_read_generic
, &spr_write_generic
,
4897 spr_register(env
, SPR_BOOKE_MAS7_MAS3
, "MAS7_MAS3",
4898 SPR_NOACCESS
, SPR_NOACCESS
,
4899 &spr_read_mas73
, &spr_write_mas73
,
4901 ivpr_mask
= (target_ulong
)~0xFFFFULL
;
4904 if (version
== fsl_e6500
) {
4905 spr_register(env
, SPR_BOOKE_SPRG8
, "SPRG8",
4906 SPR_NOACCESS
, SPR_NOACCESS
,
4907 &spr_read_generic
, &spr_write_generic
,
4909 spr_register(env
, SPR_BOOKE_SPRG9
, "SPRG9",
4910 SPR_NOACCESS
, SPR_NOACCESS
,
4911 &spr_read_generic
, &spr_write_generic
,
4913 /* Thread identification */
4914 spr_register(env
, SPR_TIR
, "TIR",
4915 SPR_NOACCESS
, SPR_NOACCESS
,
4916 &spr_read_generic
, SPR_NOACCESS
,
4918 spr_register(env
, SPR_BOOKE_TLB0PS
, "TLB0PS",
4919 SPR_NOACCESS
, SPR_NOACCESS
,
4920 &spr_read_generic
, SPR_NOACCESS
,
4922 spr_register(env
, SPR_BOOKE_TLB1PS
, "TLB1PS",
4923 SPR_NOACCESS
, SPR_NOACCESS
,
4924 &spr_read_generic
, SPR_NOACCESS
,
4928 #if !defined(CONFIG_USER_ONLY)
4930 env
->tlb_type
= TLB_MAS
;
4931 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
4932 env
->nb_tlb
+= booke206_tlb_size(env
, i
);
4936 init_excp_e200(env
, ivpr_mask
);
4937 /* Allocate hardware IRQ controller */
4938 ppce500_irq_init(ppc_env_get_cpu(env
));
4941 static void init_proc_e500v1(CPUPPCState
*env
)
4943 init_proc_e500(env
, fsl_e500v1
);
4946 POWERPC_FAMILY(e500v1
)(ObjectClass
*oc
, void *data
)
4948 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4949 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4951 dc
->desc
= "e500v1 core";
4952 pcc
->init_proc
= init_proc_e500v1
;
4953 pcc
->check_pow
= check_pow_hid0
;
4954 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
4955 PPC_SPE
| PPC_SPE_SINGLE
|
4956 PPC_WRTEE
| PPC_RFDI
|
4957 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
4958 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4959 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
4960 pcc
->insns_flags2
= PPC2_BOOKE206
;
4961 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
4975 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
4976 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4977 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4978 pcc
->bfd_mach
= bfd_mach_ppc_860
;
4979 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
4980 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
4981 POWERPC_FLAG_BUS_CLK
;
4984 static void init_proc_e500v2(CPUPPCState
*env
)
4986 init_proc_e500(env
, fsl_e500v2
);
4989 POWERPC_FAMILY(e500v2
)(ObjectClass
*oc
, void *data
)
4991 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4992 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4994 dc
->desc
= "e500v2 core";
4995 pcc
->init_proc
= init_proc_e500v2
;
4996 pcc
->check_pow
= check_pow_hid0
;
4997 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
4998 PPC_SPE
| PPC_SPE_SINGLE
| PPC_SPE_DOUBLE
|
4999 PPC_WRTEE
| PPC_RFDI
|
5000 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5001 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5002 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5003 pcc
->insns_flags2
= PPC2_BOOKE206
;
5004 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
5018 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5019 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5020 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5021 pcc
->bfd_mach
= bfd_mach_ppc_860
;
5022 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
5023 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
5024 POWERPC_FLAG_BUS_CLK
;
5027 static void init_proc_e500mc(CPUPPCState
*env
)
5029 init_proc_e500(env
, fsl_e500mc
);
5032 POWERPC_FAMILY(e500mc
)(ObjectClass
*oc
, void *data
)
5034 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5035 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5037 dc
->desc
= "e500mc core";
5038 pcc
->init_proc
= init_proc_e500mc
;
5039 pcc
->check_pow
= check_pow_none
;
5040 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5041 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5042 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5043 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5044 PPC_FLOAT
| PPC_FLOAT_FRES
|
5045 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5046 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5047 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5048 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
;
5049 pcc
->msr_mask
= (1ull << MSR_GS
) |
5050 (1ull << MSR_UCLE
) |
5063 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5064 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5065 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5066 /* FIXME: figure out the correct flag for e500mc */
5067 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5068 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5069 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5073 static void init_proc_e5500(CPUPPCState
*env
)
5075 init_proc_e500(env
, fsl_e5500
);
5078 POWERPC_FAMILY(e5500
)(ObjectClass
*oc
, void *data
)
5080 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5081 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5083 dc
->desc
= "e5500 core";
5084 pcc
->init_proc
= init_proc_e5500
;
5085 pcc
->check_pow
= check_pow_none
;
5086 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5087 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5088 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5089 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5090 PPC_FLOAT
| PPC_FLOAT_FRES
|
5091 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5092 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5093 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
|
5094 PPC_64B
| PPC_POPCNTB
| PPC_POPCNTWD
;
5095 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
| PPC2_PERM_ISA206
| \
5097 pcc
->msr_mask
= (1ull << MSR_CM
) |
5099 (1ull << MSR_UCLE
) |
5112 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5113 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5114 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5115 /* FIXME: figure out the correct flag for e5500 */
5116 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5117 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5118 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5121 static void init_proc_e6500(CPUPPCState
*env
)
5123 init_proc_e500(env
, fsl_e6500
);
5126 POWERPC_FAMILY(e6500
)(ObjectClass
*oc
, void *data
)
5128 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5129 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5131 dc
->desc
= "e6500 core";
5132 pcc
->init_proc
= init_proc_e6500
;
5133 pcc
->check_pow
= check_pow_none
;
5134 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5135 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5136 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5137 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5138 PPC_FLOAT
| PPC_FLOAT_FRES
|
5139 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5140 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5141 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
|
5142 PPC_64B
| PPC_POPCNTB
| PPC_POPCNTWD
| PPC_ALTIVEC
;
5143 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
| PPC2_PERM_ISA206
| \
5144 PPC2_FP_CVT_S64
| PPC2_ATOMIC_ISA206
;
5145 pcc
->msr_mask
= (1ull << MSR_CM
) |
5147 (1ull << MSR_UCLE
) |
5161 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5162 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5163 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5164 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5165 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5166 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_VRE
;
5171 /* Non-embedded PowerPC */
5173 #define POWERPC_MSRR_601 (0x0000000000001040ULL)
5175 static void init_proc_601(CPUPPCState
*env
)
5177 gen_spr_ne_601(env
);
5180 /* Hardware implementation registers */
5181 /* XXX : not implemented */
5182 spr_register(env
, SPR_HID0
, "HID0",
5183 SPR_NOACCESS
, SPR_NOACCESS
,
5184 &spr_read_generic
, &spr_write_hid0_601
,
5186 /* XXX : not implemented */
5187 spr_register(env
, SPR_HID1
, "HID1",
5188 SPR_NOACCESS
, SPR_NOACCESS
,
5189 &spr_read_generic
, &spr_write_generic
,
5191 /* XXX : not implemented */
5192 spr_register(env
, SPR_601_HID2
, "HID2",
5193 SPR_NOACCESS
, SPR_NOACCESS
,
5194 &spr_read_generic
, &spr_write_generic
,
5196 /* XXX : not implemented */
5197 spr_register(env
, SPR_601_HID5
, "HID5",
5198 SPR_NOACCESS
, SPR_NOACCESS
,
5199 &spr_read_generic
, &spr_write_generic
,
5201 /* Memory management */
5203 /* XXX: beware that dcache line size is 64
5204 * but dcbz uses 32 bytes "sectors"
5205 * XXX: this breaks clcs instruction !
5207 env
->dcache_line_size
= 32;
5208 env
->icache_line_size
= 64;
5209 /* Allocate hardware IRQ controller */
5210 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5213 POWERPC_FAMILY(601)(ObjectClass
*oc
, void *data
)
5215 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5216 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5218 dc
->desc
= "PowerPC 601";
5219 pcc
->init_proc
= init_proc_601
;
5220 pcc
->check_pow
= check_pow_none
;
5221 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_POWER_BR
|
5223 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5224 PPC_MEM_SYNC
| PPC_MEM_EIEIO
| PPC_MEM_TLBIE
|
5225 PPC_SEGMENT
| PPC_EXTERN
;
5226 pcc
->msr_mask
= (1ull << MSR_EE
) |
5236 pcc
->mmu_model
= POWERPC_MMU_601
;
5237 #if defined(CONFIG_SOFTMMU)
5238 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5240 pcc
->excp_model
= POWERPC_EXCP_601
;
5241 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5242 pcc
->bfd_mach
= bfd_mach_ppc_601
;
5243 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_RTC_CLK
;
5246 #define POWERPC_MSRR_601v (0x0000000000001040ULL)
5248 static void init_proc_601v(CPUPPCState
*env
)
5251 /* XXX : not implemented */
5252 spr_register(env
, SPR_601_HID15
, "HID15",
5253 SPR_NOACCESS
, SPR_NOACCESS
,
5254 &spr_read_generic
, &spr_write_generic
,
5258 POWERPC_FAMILY(601v
)(ObjectClass
*oc
, void *data
)
5260 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5261 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5263 dc
->desc
= "PowerPC 601v";
5264 pcc
->init_proc
= init_proc_601v
;
5265 pcc
->check_pow
= check_pow_none
;
5266 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_POWER_BR
|
5268 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5269 PPC_MEM_SYNC
| PPC_MEM_EIEIO
| PPC_MEM_TLBIE
|
5270 PPC_SEGMENT
| PPC_EXTERN
;
5271 pcc
->msr_mask
= (1ull << MSR_EE
) |
5281 pcc
->mmu_model
= POWERPC_MMU_601
;
5282 #if defined(CONFIG_SOFTMMU)
5283 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5285 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5286 pcc
->bfd_mach
= bfd_mach_ppc_601
;
5287 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_RTC_CLK
;
5290 static void init_proc_602(CPUPPCState
*env
)
5292 gen_spr_ne_601(env
);
5297 /* hardware implementation registers */
5298 /* XXX : not implemented */
5299 spr_register(env
, SPR_HID0
, "HID0",
5300 SPR_NOACCESS
, SPR_NOACCESS
,
5301 &spr_read_generic
, &spr_write_generic
,
5303 /* XXX : not implemented */
5304 spr_register(env
, SPR_HID1
, "HID1",
5305 SPR_NOACCESS
, SPR_NOACCESS
,
5306 &spr_read_generic
, &spr_write_generic
,
5308 /* Memory management */
5310 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5312 env
->dcache_line_size
= 32;
5313 env
->icache_line_size
= 32;
5314 /* Allocate hardware IRQ controller */
5315 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5318 POWERPC_FAMILY(602)(ObjectClass
*oc
, void *data
)
5320 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5321 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5323 dc
->desc
= "PowerPC 602";
5324 pcc
->init_proc
= init_proc_602
;
5325 pcc
->check_pow
= check_pow_hid0
;
5326 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5327 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5328 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5329 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5330 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5331 PPC_MEM_TLBIE
| PPC_6xx_TLB
| PPC_MEM_TLBSYNC
|
5332 PPC_SEGMENT
| PPC_602_SPEC
;
5333 pcc
->msr_mask
= (1ull << MSR_VSX
) |
5336 (1ull << MSR_TGPR
) |
5351 /* XXX: 602 MMU is quite specific. Should add a special case */
5352 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5353 pcc
->excp_model
= POWERPC_EXCP_602
;
5354 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5355 pcc
->bfd_mach
= bfd_mach_ppc_602
;
5356 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5357 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5360 static void init_proc_603(CPUPPCState
*env
)
5362 gen_spr_ne_601(env
);
5367 /* hardware implementation registers */
5368 /* XXX : not implemented */
5369 spr_register(env
, SPR_HID0
, "HID0",
5370 SPR_NOACCESS
, SPR_NOACCESS
,
5371 &spr_read_generic
, &spr_write_generic
,
5373 /* XXX : not implemented */
5374 spr_register(env
, SPR_HID1
, "HID1",
5375 SPR_NOACCESS
, SPR_NOACCESS
,
5376 &spr_read_generic
, &spr_write_generic
,
5378 /* Memory management */
5380 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5382 env
->dcache_line_size
= 32;
5383 env
->icache_line_size
= 32;
5384 /* Allocate hardware IRQ controller */
5385 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5388 POWERPC_FAMILY(603)(ObjectClass
*oc
, void *data
)
5390 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5391 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5393 dc
->desc
= "PowerPC 603";
5394 pcc
->init_proc
= init_proc_603
;
5395 pcc
->check_pow
= check_pow_hid0
;
5396 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5397 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5398 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5399 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5400 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5401 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
5402 PPC_SEGMENT
| PPC_EXTERN
;
5403 pcc
->msr_mask
= (1ull << MSR_POW
) |
5404 (1ull << MSR_TGPR
) |
5419 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5420 pcc
->excp_model
= POWERPC_EXCP_603
;
5421 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5422 pcc
->bfd_mach
= bfd_mach_ppc_603
;
5423 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5424 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5427 static void init_proc_603E(CPUPPCState
*env
)
5429 gen_spr_ne_601(env
);
5434 /* hardware implementation registers */
5435 /* XXX : not implemented */
5436 spr_register(env
, SPR_HID0
, "HID0",
5437 SPR_NOACCESS
, SPR_NOACCESS
,
5438 &spr_read_generic
, &spr_write_generic
,
5440 /* XXX : not implemented */
5441 spr_register(env
, SPR_HID1
, "HID1",
5442 SPR_NOACCESS
, SPR_NOACCESS
,
5443 &spr_read_generic
, &spr_write_generic
,
5445 /* Memory management */
5447 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5449 env
->dcache_line_size
= 32;
5450 env
->icache_line_size
= 32;
5451 /* Allocate hardware IRQ controller */
5452 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5455 POWERPC_FAMILY(603E
)(ObjectClass
*oc
, void *data
)
5457 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5458 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5460 dc
->desc
= "PowerPC 603e";
5461 pcc
->init_proc
= init_proc_603E
;
5462 pcc
->check_pow
= check_pow_hid0
;
5463 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5464 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5465 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5466 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5467 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5468 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
5469 PPC_SEGMENT
| PPC_EXTERN
;
5470 pcc
->msr_mask
= (1ull << MSR_POW
) |
5471 (1ull << MSR_TGPR
) |
5486 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5487 pcc
->excp_model
= POWERPC_EXCP_603E
;
5488 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5489 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
5490 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5491 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5494 static void init_proc_604(CPUPPCState
*env
)
5496 gen_spr_ne_601(env
);
5501 /* Hardware implementation registers */
5502 /* XXX : not implemented */
5503 spr_register(env
, SPR_HID0
, "HID0",
5504 SPR_NOACCESS
, SPR_NOACCESS
,
5505 &spr_read_generic
, &spr_write_generic
,
5507 /* Memory management */
5510 env
->dcache_line_size
= 32;
5511 env
->icache_line_size
= 32;
5512 /* Allocate hardware IRQ controller */
5513 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5516 POWERPC_FAMILY(604)(ObjectClass
*oc
, void *data
)
5518 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5519 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5521 dc
->desc
= "PowerPC 604";
5522 pcc
->init_proc
= init_proc_604
;
5523 pcc
->check_pow
= check_pow_nocheck
;
5524 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5525 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5526 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5527 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5528 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5529 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5530 PPC_SEGMENT
| PPC_EXTERN
;
5531 pcc
->msr_mask
= (1ull << MSR_POW
) |
5547 pcc
->mmu_model
= POWERPC_MMU_32B
;
5548 #if defined(CONFIG_SOFTMMU)
5549 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5551 pcc
->excp_model
= POWERPC_EXCP_604
;
5552 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5553 pcc
->bfd_mach
= bfd_mach_ppc_604
;
5554 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5555 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5558 static void init_proc_604E(CPUPPCState
*env
)
5560 gen_spr_ne_601(env
);
5563 /* XXX : not implemented */
5564 spr_register(env
, SPR_7XX_MMCR1
, "MMCR1",
5565 SPR_NOACCESS
, SPR_NOACCESS
,
5566 &spr_read_generic
, &spr_write_generic
,
5568 /* XXX : not implemented */
5569 spr_register(env
, SPR_7XX_PMC3
, "PMC3",
5570 SPR_NOACCESS
, SPR_NOACCESS
,
5571 &spr_read_generic
, &spr_write_generic
,
5573 /* XXX : not implemented */
5574 spr_register(env
, SPR_7XX_PMC4
, "PMC4",
5575 SPR_NOACCESS
, SPR_NOACCESS
,
5576 &spr_read_generic
, &spr_write_generic
,
5580 /* Hardware implementation registers */
5581 /* XXX : not implemented */
5582 spr_register(env
, SPR_HID0
, "HID0",
5583 SPR_NOACCESS
, SPR_NOACCESS
,
5584 &spr_read_generic
, &spr_write_generic
,
5586 /* XXX : not implemented */
5587 spr_register(env
, SPR_HID1
, "HID1",
5588 SPR_NOACCESS
, SPR_NOACCESS
,
5589 &spr_read_generic
, &spr_write_generic
,
5591 /* Memory management */
5594 env
->dcache_line_size
= 32;
5595 env
->icache_line_size
= 32;
5596 /* Allocate hardware IRQ controller */
5597 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5600 POWERPC_FAMILY(604E
)(ObjectClass
*oc
, void *data
)
5602 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5603 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5605 dc
->desc
= "PowerPC 604E";
5606 pcc
->init_proc
= init_proc_604E
;
5607 pcc
->check_pow
= check_pow_nocheck
;
5608 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5609 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5610 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5611 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5612 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5613 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5614 PPC_SEGMENT
| PPC_EXTERN
;
5615 pcc
->msr_mask
= (1ull << MSR_POW
) |
5631 pcc
->mmu_model
= POWERPC_MMU_32B
;
5632 #if defined(CONFIG_SOFTMMU)
5633 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5635 pcc
->excp_model
= POWERPC_EXCP_604
;
5636 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5637 pcc
->bfd_mach
= bfd_mach_ppc_604
;
5638 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5639 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5642 static void init_proc_740(CPUPPCState
*env
)
5644 gen_spr_ne_601(env
);
5649 /* Thermal management */
5651 /* Hardware implementation registers */
5652 /* XXX : not implemented */
5653 spr_register(env
, SPR_HID0
, "HID0",
5654 SPR_NOACCESS
, SPR_NOACCESS
,
5655 &spr_read_generic
, &spr_write_generic
,
5657 /* XXX : not implemented */
5658 spr_register(env
, SPR_HID1
, "HID1",
5659 SPR_NOACCESS
, SPR_NOACCESS
,
5660 &spr_read_generic
, &spr_write_generic
,
5662 /* Memory management */
5665 env
->dcache_line_size
= 32;
5666 env
->icache_line_size
= 32;
5667 /* Allocate hardware IRQ controller */
5668 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5671 POWERPC_FAMILY(740)(ObjectClass
*oc
, void *data
)
5673 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5674 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5676 dc
->desc
= "PowerPC 740";
5677 pcc
->init_proc
= init_proc_740
;
5678 pcc
->check_pow
= check_pow_hid0
;
5679 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5680 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5681 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5682 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5683 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5684 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5685 PPC_SEGMENT
| PPC_EXTERN
;
5686 pcc
->msr_mask
= (1ull << MSR_POW
) |
5702 pcc
->mmu_model
= POWERPC_MMU_32B
;
5703 #if defined(CONFIG_SOFTMMU)
5704 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5706 pcc
->excp_model
= POWERPC_EXCP_7x0
;
5707 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5708 pcc
->bfd_mach
= bfd_mach_ppc_750
;
5709 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5710 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5713 static void init_proc_750(CPUPPCState
*env
)
5715 gen_spr_ne_601(env
);
5718 /* XXX : not implemented */
5719 spr_register(env
, SPR_L2CR
, "L2CR",
5720 SPR_NOACCESS
, SPR_NOACCESS
,
5721 &spr_read_generic
, spr_access_nop
,
5725 /* Thermal management */
5727 /* Hardware implementation registers */
5728 /* XXX : not implemented */
5729 spr_register(env
, SPR_HID0
, "HID0",
5730 SPR_NOACCESS
, SPR_NOACCESS
,
5731 &spr_read_generic
, &spr_write_generic
,
5733 /* XXX : not implemented */
5734 spr_register(env
, SPR_HID1
, "HID1",
5735 SPR_NOACCESS
, SPR_NOACCESS
,
5736 &spr_read_generic
, &spr_write_generic
,
5738 /* Memory management */
5740 /* XXX: high BATs are also present but are known to be bugged on
5744 env
->dcache_line_size
= 32;
5745 env
->icache_line_size
= 32;
5746 /* Allocate hardware IRQ controller */
5747 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5750 POWERPC_FAMILY(750)(ObjectClass
*oc
, void *data
)
5752 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5753 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5755 dc
->desc
= "PowerPC 750";
5756 pcc
->init_proc
= init_proc_750
;
5757 pcc
->check_pow
= check_pow_hid0
;
5758 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5759 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5760 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5761 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5762 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5763 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5764 PPC_SEGMENT
| PPC_EXTERN
;
5765 pcc
->msr_mask
= (1ull << MSR_POW
) |
5781 pcc
->mmu_model
= POWERPC_MMU_32B
;
5782 #if defined(CONFIG_SOFTMMU)
5783 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5785 pcc
->excp_model
= POWERPC_EXCP_7x0
;
5786 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5787 pcc
->bfd_mach
= bfd_mach_ppc_750
;
5788 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5789 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5792 static void init_proc_750cl(CPUPPCState
*env
)
5794 gen_spr_ne_601(env
);
5797 /* XXX : not implemented */
5798 spr_register(env
, SPR_L2CR
, "L2CR",
5799 SPR_NOACCESS
, SPR_NOACCESS
,
5800 &spr_read_generic
, spr_access_nop
,
5804 /* Thermal management */
5805 /* Those registers are fake on 750CL */
5806 spr_register(env
, SPR_THRM1
, "THRM1",
5807 SPR_NOACCESS
, SPR_NOACCESS
,
5808 &spr_read_generic
, &spr_write_generic
,
5810 spr_register(env
, SPR_THRM2
, "THRM2",
5811 SPR_NOACCESS
, SPR_NOACCESS
,
5812 &spr_read_generic
, &spr_write_generic
,
5814 spr_register(env
, SPR_THRM3
, "THRM3",
5815 SPR_NOACCESS
, SPR_NOACCESS
,
5816 &spr_read_generic
, &spr_write_generic
,
5818 /* XXX: not implemented */
5819 spr_register(env
, SPR_750_TDCL
, "TDCL",
5820 SPR_NOACCESS
, SPR_NOACCESS
,
5821 &spr_read_generic
, &spr_write_generic
,
5823 spr_register(env
, SPR_750_TDCH
, "TDCH",
5824 SPR_NOACCESS
, SPR_NOACCESS
,
5825 &spr_read_generic
, &spr_write_generic
,
5828 /* XXX : not implemented */
5829 spr_register(env
, SPR_750_WPAR
, "WPAR",
5830 SPR_NOACCESS
, SPR_NOACCESS
,
5831 &spr_read_generic
, &spr_write_generic
,
5833 spr_register(env
, SPR_750_DMAL
, "DMAL",
5834 SPR_NOACCESS
, SPR_NOACCESS
,
5835 &spr_read_generic
, &spr_write_generic
,
5837 spr_register(env
, SPR_750_DMAU
, "DMAU",
5838 SPR_NOACCESS
, SPR_NOACCESS
,
5839 &spr_read_generic
, &spr_write_generic
,
5841 /* Hardware implementation registers */
5842 /* XXX : not implemented */
5843 spr_register(env
, SPR_HID0
, "HID0",
5844 SPR_NOACCESS
, SPR_NOACCESS
,
5845 &spr_read_generic
, &spr_write_generic
,
5847 /* XXX : not implemented */
5848 spr_register(env
, SPR_HID1
, "HID1",
5849 SPR_NOACCESS
, SPR_NOACCESS
,
5850 &spr_read_generic
, &spr_write_generic
,
5852 /* XXX : not implemented */
5853 spr_register(env
, SPR_750CL_HID2
, "HID2",
5854 SPR_NOACCESS
, SPR_NOACCESS
,
5855 &spr_read_generic
, &spr_write_generic
,
5857 /* XXX : not implemented */
5858 spr_register(env
, SPR_750CL_HID4
, "HID4",
5859 SPR_NOACCESS
, SPR_NOACCESS
,
5860 &spr_read_generic
, &spr_write_generic
,
5862 /* Quantization registers */
5863 /* XXX : not implemented */
5864 spr_register(env
, SPR_750_GQR0
, "GQR0",
5865 SPR_NOACCESS
, SPR_NOACCESS
,
5866 &spr_read_generic
, &spr_write_generic
,
5868 /* XXX : not implemented */
5869 spr_register(env
, SPR_750_GQR1
, "GQR1",
5870 SPR_NOACCESS
, SPR_NOACCESS
,
5871 &spr_read_generic
, &spr_write_generic
,
5873 /* XXX : not implemented */
5874 spr_register(env
, SPR_750_GQR2
, "GQR2",
5875 SPR_NOACCESS
, SPR_NOACCESS
,
5876 &spr_read_generic
, &spr_write_generic
,
5878 /* XXX : not implemented */
5879 spr_register(env
, SPR_750_GQR3
, "GQR3",
5880 SPR_NOACCESS
, SPR_NOACCESS
,
5881 &spr_read_generic
, &spr_write_generic
,
5883 /* XXX : not implemented */
5884 spr_register(env
, SPR_750_GQR4
, "GQR4",
5885 SPR_NOACCESS
, SPR_NOACCESS
,
5886 &spr_read_generic
, &spr_write_generic
,
5888 /* XXX : not implemented */
5889 spr_register(env
, SPR_750_GQR5
, "GQR5",
5890 SPR_NOACCESS
, SPR_NOACCESS
,
5891 &spr_read_generic
, &spr_write_generic
,
5893 /* XXX : not implemented */
5894 spr_register(env
, SPR_750_GQR6
, "GQR6",
5895 SPR_NOACCESS
, SPR_NOACCESS
,
5896 &spr_read_generic
, &spr_write_generic
,
5898 /* XXX : not implemented */
5899 spr_register(env
, SPR_750_GQR7
, "GQR7",
5900 SPR_NOACCESS
, SPR_NOACCESS
,
5901 &spr_read_generic
, &spr_write_generic
,
5903 /* Memory management */
5905 /* PowerPC 750cl has 8 DBATs and 8 IBATs */
5907 init_excp_750cl(env
);
5908 env
->dcache_line_size
= 32;
5909 env
->icache_line_size
= 32;
5910 /* Allocate hardware IRQ controller */
5911 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5914 POWERPC_FAMILY(750cl
)(ObjectClass
*oc
, void *data
)
5916 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5917 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5919 dc
->desc
= "PowerPC 750 CL";
5920 pcc
->init_proc
= init_proc_750cl
;
5921 pcc
->check_pow
= check_pow_hid0
;
5922 /* XXX: not implemented:
5923 * cache lock instructions:
5925 * floating point paired instructions
5960 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5961 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5962 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5963 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5964 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5965 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5966 PPC_SEGMENT
| PPC_EXTERN
;
5967 pcc
->msr_mask
= (1ull << MSR_POW
) |
5983 pcc
->mmu_model
= POWERPC_MMU_32B
;
5984 #if defined(CONFIG_SOFTMMU)
5985 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5987 pcc
->excp_model
= POWERPC_EXCP_7x0
;
5988 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5989 pcc
->bfd_mach
= bfd_mach_ppc_750
;
5990 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5991 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5994 static void init_proc_750cx(CPUPPCState
*env
)
5996 gen_spr_ne_601(env
);
5999 /* XXX : not implemented */
6000 spr_register(env
, SPR_L2CR
, "L2CR",
6001 SPR_NOACCESS
, SPR_NOACCESS
,
6002 &spr_read_generic
, spr_access_nop
,
6006 /* Thermal management */
6008 /* This register is not implemented but is present for compatibility */
6009 spr_register(env
, SPR_SDA
, "SDA",
6010 SPR_NOACCESS
, SPR_NOACCESS
,
6011 &spr_read_generic
, &spr_write_generic
,
6013 /* Hardware implementation registers */
6014 /* XXX : not implemented */
6015 spr_register(env
, SPR_HID0
, "HID0",
6016 SPR_NOACCESS
, SPR_NOACCESS
,
6017 &spr_read_generic
, &spr_write_generic
,
6019 /* XXX : not implemented */
6020 spr_register(env
, SPR_HID1
, "HID1",
6021 SPR_NOACCESS
, SPR_NOACCESS
,
6022 &spr_read_generic
, &spr_write_generic
,
6024 /* Memory management */
6026 /* PowerPC 750cx has 8 DBATs and 8 IBATs */
6028 init_excp_750cx(env
);
6029 env
->dcache_line_size
= 32;
6030 env
->icache_line_size
= 32;
6031 /* Allocate hardware IRQ controller */
6032 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6035 POWERPC_FAMILY(750cx
)(ObjectClass
*oc
, void *data
)
6037 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6038 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6040 dc
->desc
= "PowerPC 750CX";
6041 pcc
->init_proc
= init_proc_750cx
;
6042 pcc
->check_pow
= check_pow_hid0
;
6043 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6044 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6045 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6046 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6047 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6048 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6049 PPC_SEGMENT
| PPC_EXTERN
;
6050 pcc
->msr_mask
= (1ull << MSR_POW
) |
6066 pcc
->mmu_model
= POWERPC_MMU_32B
;
6067 #if defined(CONFIG_SOFTMMU)
6068 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6070 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6071 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6072 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6073 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6074 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6077 static void init_proc_750fx(CPUPPCState
*env
)
6079 gen_spr_ne_601(env
);
6082 /* XXX : not implemented */
6083 spr_register(env
, SPR_L2CR
, "L2CR",
6084 SPR_NOACCESS
, SPR_NOACCESS
,
6085 &spr_read_generic
, spr_access_nop
,
6089 /* Thermal management */
6091 /* XXX : not implemented */
6092 spr_register(env
, SPR_750_THRM4
, "THRM4",
6093 SPR_NOACCESS
, SPR_NOACCESS
,
6094 &spr_read_generic
, &spr_write_generic
,
6096 /* Hardware implementation registers */
6097 /* XXX : not implemented */
6098 spr_register(env
, SPR_HID0
, "HID0",
6099 SPR_NOACCESS
, SPR_NOACCESS
,
6100 &spr_read_generic
, &spr_write_generic
,
6102 /* XXX : not implemented */
6103 spr_register(env
, SPR_HID1
, "HID1",
6104 SPR_NOACCESS
, SPR_NOACCESS
,
6105 &spr_read_generic
, &spr_write_generic
,
6107 /* XXX : not implemented */
6108 spr_register(env
, SPR_750FX_HID2
, "HID2",
6109 SPR_NOACCESS
, SPR_NOACCESS
,
6110 &spr_read_generic
, &spr_write_generic
,
6112 /* Memory management */
6114 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6117 env
->dcache_line_size
= 32;
6118 env
->icache_line_size
= 32;
6119 /* Allocate hardware IRQ controller */
6120 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6123 POWERPC_FAMILY(750fx
)(ObjectClass
*oc
, void *data
)
6125 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6126 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6128 dc
->desc
= "PowerPC 750FX";
6129 pcc
->init_proc
= init_proc_750fx
;
6130 pcc
->check_pow
= check_pow_hid0
;
6131 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6132 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6133 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6134 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6135 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6136 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6137 PPC_SEGMENT
| PPC_EXTERN
;
6138 pcc
->msr_mask
= (1ull << MSR_POW
) |
6154 pcc
->mmu_model
= POWERPC_MMU_32B
;
6155 #if defined(CONFIG_SOFTMMU)
6156 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6158 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6159 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6160 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6161 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6162 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6165 static void init_proc_750gx(CPUPPCState
*env
)
6167 gen_spr_ne_601(env
);
6170 /* XXX : not implemented (XXX: different from 750fx) */
6171 spr_register(env
, SPR_L2CR
, "L2CR",
6172 SPR_NOACCESS
, SPR_NOACCESS
,
6173 &spr_read_generic
, spr_access_nop
,
6177 /* Thermal management */
6179 /* XXX : not implemented */
6180 spr_register(env
, SPR_750_THRM4
, "THRM4",
6181 SPR_NOACCESS
, SPR_NOACCESS
,
6182 &spr_read_generic
, &spr_write_generic
,
6184 /* Hardware implementation registers */
6185 /* XXX : not implemented (XXX: different from 750fx) */
6186 spr_register(env
, SPR_HID0
, "HID0",
6187 SPR_NOACCESS
, SPR_NOACCESS
,
6188 &spr_read_generic
, &spr_write_generic
,
6190 /* XXX : not implemented */
6191 spr_register(env
, SPR_HID1
, "HID1",
6192 SPR_NOACCESS
, SPR_NOACCESS
,
6193 &spr_read_generic
, &spr_write_generic
,
6195 /* XXX : not implemented (XXX: different from 750fx) */
6196 spr_register(env
, SPR_750FX_HID2
, "HID2",
6197 SPR_NOACCESS
, SPR_NOACCESS
,
6198 &spr_read_generic
, &spr_write_generic
,
6200 /* Memory management */
6202 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6205 env
->dcache_line_size
= 32;
6206 env
->icache_line_size
= 32;
6207 /* Allocate hardware IRQ controller */
6208 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6211 POWERPC_FAMILY(750gx
)(ObjectClass
*oc
, void *data
)
6213 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6214 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6216 dc
->desc
= "PowerPC 750GX";
6217 pcc
->init_proc
= init_proc_750gx
;
6218 pcc
->check_pow
= check_pow_hid0
;
6219 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6220 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6221 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6222 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6223 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6224 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6225 PPC_SEGMENT
| PPC_EXTERN
;
6226 pcc
->msr_mask
= (1ull << MSR_POW
) |
6242 pcc
->mmu_model
= POWERPC_MMU_32B
;
6243 #if defined(CONFIG_SOFTMMU)
6244 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6246 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6247 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6248 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6249 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6250 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6253 static void init_proc_745(CPUPPCState
*env
)
6255 gen_spr_ne_601(env
);
6258 gen_spr_G2_755(env
);
6261 /* Thermal management */
6263 /* Hardware implementation registers */
6264 /* XXX : not implemented */
6265 spr_register(env
, SPR_HID0
, "HID0",
6266 SPR_NOACCESS
, SPR_NOACCESS
,
6267 &spr_read_generic
, &spr_write_generic
,
6269 /* XXX : not implemented */
6270 spr_register(env
, SPR_HID1
, "HID1",
6271 SPR_NOACCESS
, SPR_NOACCESS
,
6272 &spr_read_generic
, &spr_write_generic
,
6274 /* XXX : not implemented */
6275 spr_register(env
, SPR_HID2
, "HID2",
6276 SPR_NOACCESS
, SPR_NOACCESS
,
6277 &spr_read_generic
, &spr_write_generic
,
6279 /* Memory management */
6282 gen_6xx_7xx_soft_tlb(env
, 64, 2);
6284 env
->dcache_line_size
= 32;
6285 env
->icache_line_size
= 32;
6286 /* Allocate hardware IRQ controller */
6287 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6290 POWERPC_FAMILY(745)(ObjectClass
*oc
, void *data
)
6292 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6293 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6295 dc
->desc
= "PowerPC 745";
6296 pcc
->init_proc
= init_proc_745
;
6297 pcc
->check_pow
= check_pow_hid0
;
6298 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6299 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6300 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6301 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6302 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6303 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
6304 PPC_SEGMENT
| PPC_EXTERN
;
6305 pcc
->msr_mask
= (1ull << MSR_POW
) |
6321 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
6322 pcc
->excp_model
= POWERPC_EXCP_7x5
;
6323 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6324 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6325 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6326 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6329 static void init_proc_755(CPUPPCState
*env
)
6331 gen_spr_ne_601(env
);
6334 gen_spr_G2_755(env
);
6337 /* L2 cache control */
6338 /* XXX : not implemented */
6339 spr_register(env
, SPR_L2CR
, "L2CR",
6340 SPR_NOACCESS
, SPR_NOACCESS
,
6341 &spr_read_generic
, spr_access_nop
,
6343 /* XXX : not implemented */
6344 spr_register(env
, SPR_L2PMCR
, "L2PMCR",
6345 SPR_NOACCESS
, SPR_NOACCESS
,
6346 &spr_read_generic
, &spr_write_generic
,
6348 /* Thermal management */
6350 /* Hardware implementation registers */
6351 /* XXX : not implemented */
6352 spr_register(env
, SPR_HID0
, "HID0",
6353 SPR_NOACCESS
, SPR_NOACCESS
,
6354 &spr_read_generic
, &spr_write_generic
,
6356 /* XXX : not implemented */
6357 spr_register(env
, SPR_HID1
, "HID1",
6358 SPR_NOACCESS
, SPR_NOACCESS
,
6359 &spr_read_generic
, &spr_write_generic
,
6361 /* XXX : not implemented */
6362 spr_register(env
, SPR_HID2
, "HID2",
6363 SPR_NOACCESS
, SPR_NOACCESS
,
6364 &spr_read_generic
, &spr_write_generic
,
6366 /* Memory management */
6369 gen_6xx_7xx_soft_tlb(env
, 64, 2);
6371 env
->dcache_line_size
= 32;
6372 env
->icache_line_size
= 32;
6373 /* Allocate hardware IRQ controller */
6374 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6377 POWERPC_FAMILY(755)(ObjectClass
*oc
, void *data
)
6379 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6380 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6382 dc
->desc
= "PowerPC 755";
6383 pcc
->init_proc
= init_proc_755
;
6384 pcc
->check_pow
= check_pow_hid0
;
6385 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6386 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6387 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6388 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6389 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6390 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
6391 PPC_SEGMENT
| PPC_EXTERN
;
6392 pcc
->msr_mask
= (1ull << MSR_POW
) |
6408 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
6409 pcc
->excp_model
= POWERPC_EXCP_7x5
;
6410 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6411 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6412 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6413 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6416 static void init_proc_7400(CPUPPCState
*env
)
6418 gen_spr_ne_601(env
);
6423 /* 74xx specific SPR */
6425 /* XXX : not implemented */
6426 spr_register(env
, SPR_UBAMR
, "UBAMR",
6427 &spr_read_ureg
, SPR_NOACCESS
,
6428 &spr_read_ureg
, SPR_NOACCESS
,
6430 /* XXX: this seems not implemented on all revisions. */
6431 /* XXX : not implemented */
6432 spr_register(env
, SPR_MSSCR1
, "MSSCR1",
6433 SPR_NOACCESS
, SPR_NOACCESS
,
6434 &spr_read_generic
, &spr_write_generic
,
6436 /* Thermal management */
6438 /* Memory management */
6440 init_excp_7400(env
);
6441 env
->dcache_line_size
= 32;
6442 env
->icache_line_size
= 32;
6443 /* Allocate hardware IRQ controller */
6444 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6447 POWERPC_FAMILY(7400)(ObjectClass
*oc
, void *data
)
6449 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6450 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6452 dc
->desc
= "PowerPC 7400 (aka G4)";
6453 pcc
->init_proc
= init_proc_7400
;
6454 pcc
->check_pow
= check_pow_hid0
;
6455 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6456 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6457 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6459 PPC_CACHE
| PPC_CACHE_ICBI
|
6460 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6461 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6462 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6464 PPC_SEGMENT
| PPC_EXTERN
|
6466 pcc
->msr_mask
= (1ull << MSR_VR
) |
6483 pcc
->mmu_model
= POWERPC_MMU_32B
;
6484 #if defined(CONFIG_SOFTMMU)
6485 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6487 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6488 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6489 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6490 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6491 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6492 POWERPC_FLAG_BUS_CLK
;
6495 static void init_proc_7410(CPUPPCState
*env
)
6497 gen_spr_ne_601(env
);
6502 /* 74xx specific SPR */
6504 /* XXX : not implemented */
6505 spr_register(env
, SPR_UBAMR
, "UBAMR",
6506 &spr_read_ureg
, SPR_NOACCESS
,
6507 &spr_read_ureg
, SPR_NOACCESS
,
6509 /* Thermal management */
6512 /* XXX : not implemented */
6513 spr_register(env
, SPR_L2PMCR
, "L2PMCR",
6514 SPR_NOACCESS
, SPR_NOACCESS
,
6515 &spr_read_generic
, &spr_write_generic
,
6518 /* XXX : not implemented */
6519 spr_register(env
, SPR_LDSTDB
, "LDSTDB",
6520 SPR_NOACCESS
, SPR_NOACCESS
,
6521 &spr_read_generic
, &spr_write_generic
,
6523 /* Memory management */
6525 init_excp_7400(env
);
6526 env
->dcache_line_size
= 32;
6527 env
->icache_line_size
= 32;
6528 /* Allocate hardware IRQ controller */
6529 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6532 POWERPC_FAMILY(7410)(ObjectClass
*oc
, void *data
)
6534 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6535 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6537 dc
->desc
= "PowerPC 7410 (aka G4)";
6538 pcc
->init_proc
= init_proc_7410
;
6539 pcc
->check_pow
= check_pow_hid0
;
6540 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6541 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6542 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6544 PPC_CACHE
| PPC_CACHE_ICBI
|
6545 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6546 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6547 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6549 PPC_SEGMENT
| PPC_EXTERN
|
6551 pcc
->msr_mask
= (1ull << MSR_VR
) |
6568 pcc
->mmu_model
= POWERPC_MMU_32B
;
6569 #if defined(CONFIG_SOFTMMU)
6570 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6572 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6573 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6574 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6575 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6576 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6577 POWERPC_FLAG_BUS_CLK
;
6580 static void init_proc_7440(CPUPPCState
*env
)
6582 gen_spr_ne_601(env
);
6587 /* 74xx specific SPR */
6589 /* XXX : not implemented */
6590 spr_register(env
, SPR_UBAMR
, "UBAMR",
6591 &spr_read_ureg
, SPR_NOACCESS
,
6592 &spr_read_ureg
, SPR_NOACCESS
,
6595 /* XXX : not implemented */
6596 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6597 SPR_NOACCESS
, SPR_NOACCESS
,
6598 &spr_read_generic
, &spr_write_generic
,
6601 /* XXX : not implemented */
6602 spr_register(env
, SPR_ICTRL
, "ICTRL",
6603 SPR_NOACCESS
, SPR_NOACCESS
,
6604 &spr_read_generic
, &spr_write_generic
,
6607 /* XXX : not implemented */
6608 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6609 SPR_NOACCESS
, SPR_NOACCESS
,
6610 &spr_read_generic
, &spr_write_generic
,
6613 /* XXX : not implemented */
6614 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6615 SPR_NOACCESS
, SPR_NOACCESS
,
6616 &spr_read_generic
, &spr_write_generic
,
6618 /* XXX : not implemented */
6619 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6620 &spr_read_ureg
, SPR_NOACCESS
,
6621 &spr_read_ureg
, SPR_NOACCESS
,
6623 /* XXX : not implemented */
6624 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6625 SPR_NOACCESS
, SPR_NOACCESS
,
6626 &spr_read_generic
, &spr_write_generic
,
6628 /* XXX : not implemented */
6629 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6630 &spr_read_ureg
, SPR_NOACCESS
,
6631 &spr_read_ureg
, SPR_NOACCESS
,
6633 /* Memory management */
6635 gen_74xx_soft_tlb(env
, 128, 2);
6636 init_excp_7450(env
);
6637 env
->dcache_line_size
= 32;
6638 env
->icache_line_size
= 32;
6639 /* Allocate hardware IRQ controller */
6640 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6643 POWERPC_FAMILY(7440)(ObjectClass
*oc
, void *data
)
6645 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6646 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6648 dc
->desc
= "PowerPC 7440 (aka G4)";
6649 pcc
->init_proc
= init_proc_7440
;
6650 pcc
->check_pow
= check_pow_hid0_74xx
;
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
|
6659 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6660 PPC_SEGMENT
| PPC_EXTERN
|
6662 pcc
->msr_mask
= (1ull << MSR_VR
) |
6679 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6680 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6681 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6682 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6683 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6684 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6685 POWERPC_FLAG_BUS_CLK
;
6688 static void init_proc_7450(CPUPPCState
*env
)
6690 gen_spr_ne_601(env
);
6695 /* 74xx specific SPR */
6697 /* Level 3 cache control */
6700 /* XXX : not implemented */
6701 spr_register(env
, SPR_L3ITCR1
, "L3ITCR1",
6702 SPR_NOACCESS
, SPR_NOACCESS
,
6703 &spr_read_generic
, &spr_write_generic
,
6706 /* XXX : not implemented */
6707 spr_register(env
, SPR_L3ITCR2
, "L3ITCR2",
6708 SPR_NOACCESS
, SPR_NOACCESS
,
6709 &spr_read_generic
, &spr_write_generic
,
6712 /* XXX : not implemented */
6713 spr_register(env
, SPR_L3ITCR3
, "L3ITCR3",
6714 SPR_NOACCESS
, SPR_NOACCESS
,
6715 &spr_read_generic
, &spr_write_generic
,
6718 /* XXX : not implemented */
6719 spr_register(env
, SPR_L3OHCR
, "L3OHCR",
6720 SPR_NOACCESS
, SPR_NOACCESS
,
6721 &spr_read_generic
, &spr_write_generic
,
6723 /* XXX : not implemented */
6724 spr_register(env
, SPR_UBAMR
, "UBAMR",
6725 &spr_read_ureg
, SPR_NOACCESS
,
6726 &spr_read_ureg
, SPR_NOACCESS
,
6729 /* XXX : not implemented */
6730 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6731 SPR_NOACCESS
, SPR_NOACCESS
,
6732 &spr_read_generic
, &spr_write_generic
,
6735 /* XXX : not implemented */
6736 spr_register(env
, SPR_ICTRL
, "ICTRL",
6737 SPR_NOACCESS
, SPR_NOACCESS
,
6738 &spr_read_generic
, &spr_write_generic
,
6741 /* XXX : not implemented */
6742 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6743 SPR_NOACCESS
, SPR_NOACCESS
,
6744 &spr_read_generic
, &spr_write_generic
,
6747 /* XXX : not implemented */
6748 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6749 SPR_NOACCESS
, SPR_NOACCESS
,
6750 &spr_read_generic
, &spr_write_generic
,
6752 /* XXX : not implemented */
6753 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6754 &spr_read_ureg
, SPR_NOACCESS
,
6755 &spr_read_ureg
, SPR_NOACCESS
,
6757 /* XXX : not implemented */
6758 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6759 SPR_NOACCESS
, SPR_NOACCESS
,
6760 &spr_read_generic
, &spr_write_generic
,
6762 /* XXX : not implemented */
6763 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6764 &spr_read_ureg
, SPR_NOACCESS
,
6765 &spr_read_ureg
, SPR_NOACCESS
,
6767 /* Memory management */
6769 gen_74xx_soft_tlb(env
, 128, 2);
6770 init_excp_7450(env
);
6771 env
->dcache_line_size
= 32;
6772 env
->icache_line_size
= 32;
6773 /* Allocate hardware IRQ controller */
6774 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6777 POWERPC_FAMILY(7450)(ObjectClass
*oc
, void *data
)
6779 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6780 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6782 dc
->desc
= "PowerPC 7450 (aka G4)";
6783 pcc
->init_proc
= init_proc_7450
;
6784 pcc
->check_pow
= check_pow_hid0_74xx
;
6785 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6786 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6787 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6789 PPC_CACHE
| PPC_CACHE_ICBI
|
6790 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6791 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6792 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6793 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6794 PPC_SEGMENT
| PPC_EXTERN
|
6796 pcc
->msr_mask
= (1ull << MSR_VR
) |
6813 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6814 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6815 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6816 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6817 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6818 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6819 POWERPC_FLAG_BUS_CLK
;
6822 static void init_proc_7445(CPUPPCState
*env
)
6824 gen_spr_ne_601(env
);
6829 /* 74xx specific SPR */
6832 /* XXX : not implemented */
6833 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6834 SPR_NOACCESS
, SPR_NOACCESS
,
6835 &spr_read_generic
, &spr_write_generic
,
6838 /* XXX : not implemented */
6839 spr_register(env
, SPR_ICTRL
, "ICTRL",
6840 SPR_NOACCESS
, SPR_NOACCESS
,
6841 &spr_read_generic
, &spr_write_generic
,
6844 /* XXX : not implemented */
6845 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6846 SPR_NOACCESS
, SPR_NOACCESS
,
6847 &spr_read_generic
, &spr_write_generic
,
6850 /* XXX : not implemented */
6851 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6852 SPR_NOACCESS
, SPR_NOACCESS
,
6853 &spr_read_generic
, &spr_write_generic
,
6855 /* XXX : not implemented */
6856 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6857 &spr_read_ureg
, SPR_NOACCESS
,
6858 &spr_read_ureg
, SPR_NOACCESS
,
6860 /* XXX : not implemented */
6861 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6862 SPR_NOACCESS
, SPR_NOACCESS
,
6863 &spr_read_generic
, &spr_write_generic
,
6865 /* XXX : not implemented */
6866 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6867 &spr_read_ureg
, SPR_NOACCESS
,
6868 &spr_read_ureg
, SPR_NOACCESS
,
6871 spr_register(env
, SPR_SPRG4
, "SPRG4",
6872 SPR_NOACCESS
, SPR_NOACCESS
,
6873 &spr_read_generic
, &spr_write_generic
,
6875 spr_register(env
, SPR_USPRG4
, "USPRG4",
6876 &spr_read_ureg
, SPR_NOACCESS
,
6877 &spr_read_ureg
, SPR_NOACCESS
,
6879 spr_register(env
, SPR_SPRG5
, "SPRG5",
6880 SPR_NOACCESS
, SPR_NOACCESS
,
6881 &spr_read_generic
, &spr_write_generic
,
6883 spr_register(env
, SPR_USPRG5
, "USPRG5",
6884 &spr_read_ureg
, SPR_NOACCESS
,
6885 &spr_read_ureg
, SPR_NOACCESS
,
6887 spr_register(env
, SPR_SPRG6
, "SPRG6",
6888 SPR_NOACCESS
, SPR_NOACCESS
,
6889 &spr_read_generic
, &spr_write_generic
,
6891 spr_register(env
, SPR_USPRG6
, "USPRG6",
6892 &spr_read_ureg
, SPR_NOACCESS
,
6893 &spr_read_ureg
, SPR_NOACCESS
,
6895 spr_register(env
, SPR_SPRG7
, "SPRG7",
6896 SPR_NOACCESS
, SPR_NOACCESS
,
6897 &spr_read_generic
, &spr_write_generic
,
6899 spr_register(env
, SPR_USPRG7
, "USPRG7",
6900 &spr_read_ureg
, SPR_NOACCESS
,
6901 &spr_read_ureg
, SPR_NOACCESS
,
6903 /* Memory management */
6906 gen_74xx_soft_tlb(env
, 128, 2);
6907 init_excp_7450(env
);
6908 env
->dcache_line_size
= 32;
6909 env
->icache_line_size
= 32;
6910 /* Allocate hardware IRQ controller */
6911 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6914 POWERPC_FAMILY(7445)(ObjectClass
*oc
, void *data
)
6916 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6917 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6919 dc
->desc
= "PowerPC 7445 (aka G4)";
6920 pcc
->init_proc
= init_proc_7445
;
6921 pcc
->check_pow
= check_pow_hid0_74xx
;
6922 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6923 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6924 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6926 PPC_CACHE
| PPC_CACHE_ICBI
|
6927 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6928 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6929 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6930 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6931 PPC_SEGMENT
| PPC_EXTERN
|
6933 pcc
->msr_mask
= (1ull << MSR_VR
) |
6950 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6951 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6952 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6953 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6954 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6955 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6956 POWERPC_FLAG_BUS_CLK
;
6959 static void init_proc_7455(CPUPPCState
*env
)
6961 gen_spr_ne_601(env
);
6966 /* 74xx specific SPR */
6968 /* Level 3 cache control */
6971 /* XXX : not implemented */
6972 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6973 SPR_NOACCESS
, SPR_NOACCESS
,
6974 &spr_read_generic
, &spr_write_generic
,
6977 /* XXX : not implemented */
6978 spr_register(env
, SPR_ICTRL
, "ICTRL",
6979 SPR_NOACCESS
, SPR_NOACCESS
,
6980 &spr_read_generic
, &spr_write_generic
,
6983 /* XXX : not implemented */
6984 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6985 SPR_NOACCESS
, SPR_NOACCESS
,
6986 &spr_read_generic
, &spr_write_generic
,
6989 /* XXX : not implemented */
6990 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6991 SPR_NOACCESS
, SPR_NOACCESS
,
6992 &spr_read_generic
, &spr_write_generic
,
6994 /* XXX : not implemented */
6995 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6996 &spr_read_ureg
, SPR_NOACCESS
,
6997 &spr_read_ureg
, SPR_NOACCESS
,
6999 /* XXX : not implemented */
7000 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7001 SPR_NOACCESS
, SPR_NOACCESS
,
7002 &spr_read_generic
, &spr_write_generic
,
7004 /* XXX : not implemented */
7005 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7006 &spr_read_ureg
, SPR_NOACCESS
,
7007 &spr_read_ureg
, SPR_NOACCESS
,
7010 spr_register(env
, SPR_SPRG4
, "SPRG4",
7011 SPR_NOACCESS
, SPR_NOACCESS
,
7012 &spr_read_generic
, &spr_write_generic
,
7014 spr_register(env
, SPR_USPRG4
, "USPRG4",
7015 &spr_read_ureg
, SPR_NOACCESS
,
7016 &spr_read_ureg
, SPR_NOACCESS
,
7018 spr_register(env
, SPR_SPRG5
, "SPRG5",
7019 SPR_NOACCESS
, SPR_NOACCESS
,
7020 &spr_read_generic
, &spr_write_generic
,
7022 spr_register(env
, SPR_USPRG5
, "USPRG5",
7023 &spr_read_ureg
, SPR_NOACCESS
,
7024 &spr_read_ureg
, SPR_NOACCESS
,
7026 spr_register(env
, SPR_SPRG6
, "SPRG6",
7027 SPR_NOACCESS
, SPR_NOACCESS
,
7028 &spr_read_generic
, &spr_write_generic
,
7030 spr_register(env
, SPR_USPRG6
, "USPRG6",
7031 &spr_read_ureg
, SPR_NOACCESS
,
7032 &spr_read_ureg
, SPR_NOACCESS
,
7034 spr_register(env
, SPR_SPRG7
, "SPRG7",
7035 SPR_NOACCESS
, SPR_NOACCESS
,
7036 &spr_read_generic
, &spr_write_generic
,
7038 spr_register(env
, SPR_USPRG7
, "USPRG7",
7039 &spr_read_ureg
, SPR_NOACCESS
,
7040 &spr_read_ureg
, SPR_NOACCESS
,
7042 /* Memory management */
7045 gen_74xx_soft_tlb(env
, 128, 2);
7046 init_excp_7450(env
);
7047 env
->dcache_line_size
= 32;
7048 env
->icache_line_size
= 32;
7049 /* Allocate hardware IRQ controller */
7050 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7053 POWERPC_FAMILY(7455)(ObjectClass
*oc
, void *data
)
7055 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7056 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7058 dc
->desc
= "PowerPC 7455 (aka G4)";
7059 pcc
->init_proc
= init_proc_7455
;
7060 pcc
->check_pow
= check_pow_hid0_74xx
;
7061 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7062 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7063 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7065 PPC_CACHE
| PPC_CACHE_ICBI
|
7066 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7067 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7068 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7069 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7070 PPC_SEGMENT
| PPC_EXTERN
|
7072 pcc
->msr_mask
= (1ull << MSR_VR
) |
7089 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7090 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7091 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7092 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7093 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7094 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7095 POWERPC_FLAG_BUS_CLK
;
7098 static void init_proc_7457(CPUPPCState
*env
)
7100 gen_spr_ne_601(env
);
7105 /* 74xx specific SPR */
7107 /* Level 3 cache control */
7110 /* XXX : not implemented */
7111 spr_register(env
, SPR_L3ITCR1
, "L3ITCR1",
7112 SPR_NOACCESS
, SPR_NOACCESS
,
7113 &spr_read_generic
, &spr_write_generic
,
7116 /* XXX : not implemented */
7117 spr_register(env
, SPR_L3ITCR2
, "L3ITCR2",
7118 SPR_NOACCESS
, SPR_NOACCESS
,
7119 &spr_read_generic
, &spr_write_generic
,
7122 /* XXX : not implemented */
7123 spr_register(env
, SPR_L3ITCR3
, "L3ITCR3",
7124 SPR_NOACCESS
, SPR_NOACCESS
,
7125 &spr_read_generic
, &spr_write_generic
,
7128 /* XXX : not implemented */
7129 spr_register(env
, SPR_L3OHCR
, "L3OHCR",
7130 SPR_NOACCESS
, SPR_NOACCESS
,
7131 &spr_read_generic
, &spr_write_generic
,
7134 /* XXX : not implemented */
7135 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7136 SPR_NOACCESS
, SPR_NOACCESS
,
7137 &spr_read_generic
, &spr_write_generic
,
7140 /* XXX : not implemented */
7141 spr_register(env
, SPR_ICTRL
, "ICTRL",
7142 SPR_NOACCESS
, SPR_NOACCESS
,
7143 &spr_read_generic
, &spr_write_generic
,
7146 /* XXX : not implemented */
7147 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7148 SPR_NOACCESS
, SPR_NOACCESS
,
7149 &spr_read_generic
, &spr_write_generic
,
7152 /* XXX : not implemented */
7153 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7154 SPR_NOACCESS
, SPR_NOACCESS
,
7155 &spr_read_generic
, &spr_write_generic
,
7157 /* XXX : not implemented */
7158 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7159 &spr_read_ureg
, SPR_NOACCESS
,
7160 &spr_read_ureg
, SPR_NOACCESS
,
7162 /* XXX : not implemented */
7163 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7164 SPR_NOACCESS
, SPR_NOACCESS
,
7165 &spr_read_generic
, &spr_write_generic
,
7167 /* XXX : not implemented */
7168 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7169 &spr_read_ureg
, SPR_NOACCESS
,
7170 &spr_read_ureg
, SPR_NOACCESS
,
7173 spr_register(env
, SPR_SPRG4
, "SPRG4",
7174 SPR_NOACCESS
, SPR_NOACCESS
,
7175 &spr_read_generic
, &spr_write_generic
,
7177 spr_register(env
, SPR_USPRG4
, "USPRG4",
7178 &spr_read_ureg
, SPR_NOACCESS
,
7179 &spr_read_ureg
, SPR_NOACCESS
,
7181 spr_register(env
, SPR_SPRG5
, "SPRG5",
7182 SPR_NOACCESS
, SPR_NOACCESS
,
7183 &spr_read_generic
, &spr_write_generic
,
7185 spr_register(env
, SPR_USPRG5
, "USPRG5",
7186 &spr_read_ureg
, SPR_NOACCESS
,
7187 &spr_read_ureg
, SPR_NOACCESS
,
7189 spr_register(env
, SPR_SPRG6
, "SPRG6",
7190 SPR_NOACCESS
, SPR_NOACCESS
,
7191 &spr_read_generic
, &spr_write_generic
,
7193 spr_register(env
, SPR_USPRG6
, "USPRG6",
7194 &spr_read_ureg
, SPR_NOACCESS
,
7195 &spr_read_ureg
, SPR_NOACCESS
,
7197 spr_register(env
, SPR_SPRG7
, "SPRG7",
7198 SPR_NOACCESS
, SPR_NOACCESS
,
7199 &spr_read_generic
, &spr_write_generic
,
7201 spr_register(env
, SPR_USPRG7
, "USPRG7",
7202 &spr_read_ureg
, SPR_NOACCESS
,
7203 &spr_read_ureg
, SPR_NOACCESS
,
7205 /* Memory management */
7208 gen_74xx_soft_tlb(env
, 128, 2);
7209 init_excp_7450(env
);
7210 env
->dcache_line_size
= 32;
7211 env
->icache_line_size
= 32;
7212 /* Allocate hardware IRQ controller */
7213 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7216 POWERPC_FAMILY(7457)(ObjectClass
*oc
, void *data
)
7218 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7219 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7221 dc
->desc
= "PowerPC 7457 (aka G4)";
7222 pcc
->init_proc
= init_proc_7457
;
7223 pcc
->check_pow
= check_pow_hid0_74xx
;
7224 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7225 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7226 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7228 PPC_CACHE
| PPC_CACHE_ICBI
|
7229 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7230 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7231 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7232 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7233 PPC_SEGMENT
| PPC_EXTERN
|
7235 pcc
->msr_mask
= (1ull << MSR_VR
) |
7252 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7253 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7254 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7255 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7256 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7257 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7258 POWERPC_FLAG_BUS_CLK
;
7261 static void init_proc_e600(CPUPPCState
*env
)
7263 gen_spr_ne_601(env
);
7268 /* 74xx specific SPR */
7270 /* XXX : not implemented */
7271 spr_register(env
, SPR_UBAMR
, "UBAMR",
7272 &spr_read_ureg
, SPR_NOACCESS
,
7273 &spr_read_ureg
, SPR_NOACCESS
,
7275 /* XXX : not implemented */
7276 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7277 SPR_NOACCESS
, SPR_NOACCESS
,
7278 &spr_read_generic
, &spr_write_generic
,
7280 /* XXX : not implemented */
7281 spr_register(env
, SPR_ICTRL
, "ICTRL",
7282 SPR_NOACCESS
, SPR_NOACCESS
,
7283 &spr_read_generic
, &spr_write_generic
,
7285 /* XXX : not implemented */
7286 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7287 SPR_NOACCESS
, SPR_NOACCESS
,
7288 &spr_read_generic
, &spr_write_generic
,
7290 /* XXX : not implemented */
7291 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7292 SPR_NOACCESS
, SPR_NOACCESS
,
7293 &spr_read_generic
, &spr_write_generic
,
7295 /* XXX : not implemented */
7296 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7297 &spr_read_ureg
, SPR_NOACCESS
,
7298 &spr_read_ureg
, SPR_NOACCESS
,
7300 /* XXX : not implemented */
7301 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7302 SPR_NOACCESS
, SPR_NOACCESS
,
7303 &spr_read_generic
, &spr_write_generic
,
7305 /* XXX : not implemented */
7306 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7307 &spr_read_ureg
, SPR_NOACCESS
,
7308 &spr_read_ureg
, SPR_NOACCESS
,
7311 spr_register(env
, SPR_SPRG4
, "SPRG4",
7312 SPR_NOACCESS
, SPR_NOACCESS
,
7313 &spr_read_generic
, &spr_write_generic
,
7315 spr_register(env
, SPR_USPRG4
, "USPRG4",
7316 &spr_read_ureg
, SPR_NOACCESS
,
7317 &spr_read_ureg
, SPR_NOACCESS
,
7319 spr_register(env
, SPR_SPRG5
, "SPRG5",
7320 SPR_NOACCESS
, SPR_NOACCESS
,
7321 &spr_read_generic
, &spr_write_generic
,
7323 spr_register(env
, SPR_USPRG5
, "USPRG5",
7324 &spr_read_ureg
, SPR_NOACCESS
,
7325 &spr_read_ureg
, SPR_NOACCESS
,
7327 spr_register(env
, SPR_SPRG6
, "SPRG6",
7328 SPR_NOACCESS
, SPR_NOACCESS
,
7329 &spr_read_generic
, &spr_write_generic
,
7331 spr_register(env
, SPR_USPRG6
, "USPRG6",
7332 &spr_read_ureg
, SPR_NOACCESS
,
7333 &spr_read_ureg
, SPR_NOACCESS
,
7335 spr_register(env
, SPR_SPRG7
, "SPRG7",
7336 SPR_NOACCESS
, SPR_NOACCESS
,
7337 &spr_read_generic
, &spr_write_generic
,
7339 spr_register(env
, SPR_USPRG7
, "USPRG7",
7340 &spr_read_ureg
, SPR_NOACCESS
,
7341 &spr_read_ureg
, SPR_NOACCESS
,
7343 /* Memory management */
7346 gen_74xx_soft_tlb(env
, 128, 2);
7347 init_excp_7450(env
);
7348 env
->dcache_line_size
= 32;
7349 env
->icache_line_size
= 32;
7350 /* Allocate hardware IRQ controller */
7351 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7354 POWERPC_FAMILY(e600
)(ObjectClass
*oc
, void *data
)
7356 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7357 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7359 dc
->desc
= "PowerPC e600";
7360 pcc
->init_proc
= init_proc_e600
;
7361 pcc
->check_pow
= check_pow_hid0_74xx
;
7362 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7363 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7364 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7366 PPC_CACHE
| PPC_CACHE_ICBI
|
7367 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7368 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7369 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7370 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7371 PPC_SEGMENT
| PPC_EXTERN
|
7373 pcc
->insns_flags2
= PPC_NONE
;
7374 pcc
->msr_mask
= (1ull << MSR_VR
) |
7391 pcc
->mmu_model
= POWERPC_MMU_32B
;
7392 #if defined(CONFIG_SOFTMMU)
7393 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
7395 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7396 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7397 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7398 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7399 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7400 POWERPC_FLAG_BUS_CLK
;
7403 #if defined(TARGET_PPC64)
7404 #if defined(CONFIG_USER_ONLY)
7405 #define POWERPC970_HID5_INIT 0x00000080
7407 #define POWERPC970_HID5_INIT 0x00000000
7410 static void gen_fscr_facility_check(DisasContext
*ctx
, int facility_sprn
,
7411 int bit
, int sprn
, int cause
)
7413 TCGv_i32 t1
= tcg_const_i32(bit
);
7414 TCGv_i32 t2
= tcg_const_i32(sprn
);
7415 TCGv_i32 t3
= tcg_const_i32(cause
);
7417 gen_helper_fscr_facility_check(cpu_env
, t1
, t2
, t3
);
7419 tcg_temp_free_i32(t3
);
7420 tcg_temp_free_i32(t2
);
7421 tcg_temp_free_i32(t1
);
7424 static void gen_msr_facility_check(DisasContext
*ctx
, int facility_sprn
,
7425 int bit
, int sprn
, int cause
)
7427 TCGv_i32 t1
= tcg_const_i32(bit
);
7428 TCGv_i32 t2
= tcg_const_i32(sprn
);
7429 TCGv_i32 t3
= tcg_const_i32(cause
);
7431 gen_helper_msr_facility_check(cpu_env
, t1
, t2
, t3
);
7433 tcg_temp_free_i32(t3
);
7434 tcg_temp_free_i32(t2
);
7435 tcg_temp_free_i32(t1
);
7438 static void spr_read_prev_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
7440 TCGv spr_up
= tcg_temp_new();
7441 TCGv spr
= tcg_temp_new();
7443 gen_load_spr(spr
, sprn
- 1);
7444 tcg_gen_shri_tl(spr_up
, spr
, 32);
7445 tcg_gen_ext32u_tl(cpu_gpr
[gprn
], spr_up
);
7448 tcg_temp_free(spr_up
);
7451 static void spr_write_prev_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
7453 TCGv spr
= tcg_temp_new();
7455 gen_load_spr(spr
, sprn
- 1);
7456 tcg_gen_deposit_tl(spr
, spr
, cpu_gpr
[gprn
], 32, 32);
7457 gen_store_spr(sprn
- 1, spr
);
7462 static int check_pow_970(CPUPPCState
*env
)
7464 if (env
->spr
[SPR_HID0
] & (HID0_DEEPNAP
| HID0_DOZE
| HID0_NAP
)) {
7471 static void gen_spr_970_hid(CPUPPCState
*env
)
7473 /* Hardware implementation registers */
7474 /* XXX : not implemented */
7475 spr_register(env
, SPR_HID0
, "HID0",
7476 SPR_NOACCESS
, SPR_NOACCESS
,
7477 &spr_read_generic
, &spr_write_clear
,
7479 spr_register(env
, SPR_HID1
, "HID1",
7480 SPR_NOACCESS
, SPR_NOACCESS
,
7481 &spr_read_generic
, &spr_write_generic
,
7483 spr_register(env
, SPR_970_HID5
, "HID5",
7484 SPR_NOACCESS
, SPR_NOACCESS
,
7485 &spr_read_generic
, &spr_write_generic
,
7486 POWERPC970_HID5_INIT
);
7489 static void gen_spr_970_hior(CPUPPCState
*env
)
7491 spr_register(env
, SPR_HIOR
, "SPR_HIOR",
7492 SPR_NOACCESS
, SPR_NOACCESS
,
7493 &spr_read_hior
, &spr_write_hior
,
7497 static void gen_spr_book3s_ctrl(CPUPPCState
*env
)
7499 spr_register(env
, SPR_CTRL
, "SPR_CTRL",
7500 SPR_NOACCESS
, SPR_NOACCESS
,
7501 SPR_NOACCESS
, &spr_write_generic
,
7503 spr_register(env
, SPR_UCTRL
, "SPR_UCTRL",
7504 &spr_read_ureg
, SPR_NOACCESS
,
7505 &spr_read_ureg
, SPR_NOACCESS
,
7509 static void gen_spr_book3s_altivec(CPUPPCState
*env
)
7511 if (!(env
->insns_flags
& PPC_ALTIVEC
)) {
7515 spr_register_kvm(env
, SPR_VRSAVE
, "VRSAVE",
7516 &spr_read_generic
, &spr_write_generic
,
7517 &spr_read_generic
, &spr_write_generic
,
7518 KVM_REG_PPC_VRSAVE
, 0x00000000);
7520 /* Can't find information on what this should be on reset. This
7521 * value is the one used by 74xx processors. */
7522 vscr_init(env
, 0x00010000);
7525 static void gen_spr_book3s_dbg(CPUPPCState
*env
)
7528 * TODO: different specs define different scopes for these,
7529 * will have to address this:
7530 * 970: super/write and super/read
7531 * powerisa 2.03..2.04: hypv/write and super/read.
7532 * powerisa 2.05 and newer: hypv/write and hypv/read.
7534 spr_register_kvm(env
, SPR_DABR
, "DABR",
7535 SPR_NOACCESS
, SPR_NOACCESS
,
7536 &spr_read_generic
, &spr_write_generic
,
7537 KVM_REG_PPC_DABR
, 0x00000000);
7538 spr_register_kvm(env
, SPR_DABRX
, "DABRX",
7539 SPR_NOACCESS
, SPR_NOACCESS
,
7540 &spr_read_generic
, &spr_write_generic
,
7541 KVM_REG_PPC_DABRX
, 0x00000000);
7544 static void gen_spr_book3s_207_dbg(CPUPPCState
*env
)
7546 spr_register_kvm_hv(env
, SPR_DAWR
, "DAWR",
7547 SPR_NOACCESS
, SPR_NOACCESS
,
7548 SPR_NOACCESS
, SPR_NOACCESS
,
7549 &spr_read_generic
, &spr_write_generic
,
7550 KVM_REG_PPC_DAWR
, 0x00000000);
7551 spr_register_kvm_hv(env
, SPR_DAWRX
, "DAWRX",
7552 SPR_NOACCESS
, SPR_NOACCESS
,
7553 SPR_NOACCESS
, SPR_NOACCESS
,
7554 &spr_read_generic
, &spr_write_generic
,
7555 KVM_REG_PPC_DAWRX
, 0x00000000);
7556 spr_register_kvm_hv(env
, SPR_CIABR
, "CIABR",
7557 SPR_NOACCESS
, SPR_NOACCESS
,
7558 SPR_NOACCESS
, SPR_NOACCESS
,
7559 &spr_read_generic
, &spr_write_generic
,
7560 KVM_REG_PPC_CIABR
, 0x00000000);
7563 static void gen_spr_970_dbg(CPUPPCState
*env
)
7566 spr_register(env
, SPR_IABR
, "IABR",
7567 SPR_NOACCESS
, SPR_NOACCESS
,
7568 &spr_read_generic
, &spr_write_generic
,
7572 static void gen_spr_book3s_pmu_sup(CPUPPCState
*env
)
7574 spr_register_kvm(env
, SPR_POWER_MMCR0
, "MMCR0",
7575 SPR_NOACCESS
, SPR_NOACCESS
,
7576 &spr_read_generic
, &spr_write_generic
,
7577 KVM_REG_PPC_MMCR0
, 0x00000000);
7578 spr_register_kvm(env
, SPR_POWER_MMCR1
, "MMCR1",
7579 SPR_NOACCESS
, SPR_NOACCESS
,
7580 &spr_read_generic
, &spr_write_generic
,
7581 KVM_REG_PPC_MMCR1
, 0x00000000);
7582 spr_register_kvm(env
, SPR_POWER_MMCRA
, "MMCRA",
7583 SPR_NOACCESS
, SPR_NOACCESS
,
7584 &spr_read_generic
, &spr_write_generic
,
7585 KVM_REG_PPC_MMCRA
, 0x00000000);
7586 spr_register_kvm(env
, SPR_POWER_PMC1
, "PMC1",
7587 SPR_NOACCESS
, SPR_NOACCESS
,
7588 &spr_read_generic
, &spr_write_generic
,
7589 KVM_REG_PPC_PMC1
, 0x00000000);
7590 spr_register_kvm(env
, SPR_POWER_PMC2
, "PMC2",
7591 SPR_NOACCESS
, SPR_NOACCESS
,
7592 &spr_read_generic
, &spr_write_generic
,
7593 KVM_REG_PPC_PMC2
, 0x00000000);
7594 spr_register_kvm(env
, SPR_POWER_PMC3
, "PMC3",
7595 SPR_NOACCESS
, SPR_NOACCESS
,
7596 &spr_read_generic
, &spr_write_generic
,
7597 KVM_REG_PPC_PMC3
, 0x00000000);
7598 spr_register_kvm(env
, SPR_POWER_PMC4
, "PMC4",
7599 SPR_NOACCESS
, SPR_NOACCESS
,
7600 &spr_read_generic
, &spr_write_generic
,
7601 KVM_REG_PPC_PMC4
, 0x00000000);
7602 spr_register_kvm(env
, SPR_POWER_PMC5
, "PMC5",
7603 SPR_NOACCESS
, SPR_NOACCESS
,
7604 &spr_read_generic
, &spr_write_generic
,
7605 KVM_REG_PPC_PMC5
, 0x00000000);
7606 spr_register_kvm(env
, SPR_POWER_PMC6
, "PMC6",
7607 SPR_NOACCESS
, SPR_NOACCESS
,
7608 &spr_read_generic
, &spr_write_generic
,
7609 KVM_REG_PPC_PMC6
, 0x00000000);
7610 spr_register_kvm(env
, SPR_POWER_SIAR
, "SIAR",
7611 SPR_NOACCESS
, SPR_NOACCESS
,
7612 &spr_read_generic
, &spr_write_generic
,
7613 KVM_REG_PPC_SIAR
, 0x00000000);
7614 spr_register_kvm(env
, SPR_POWER_SDAR
, "SDAR",
7615 SPR_NOACCESS
, SPR_NOACCESS
,
7616 &spr_read_generic
, &spr_write_generic
,
7617 KVM_REG_PPC_SDAR
, 0x00000000);
7620 static void gen_spr_book3s_pmu_user(CPUPPCState
*env
)
7622 spr_register(env
, SPR_POWER_UMMCR0
, "UMMCR0",
7623 &spr_read_ureg
, SPR_NOACCESS
,
7624 &spr_read_ureg
, &spr_write_ureg
,
7626 spr_register(env
, SPR_POWER_UMMCR1
, "UMMCR1",
7627 &spr_read_ureg
, SPR_NOACCESS
,
7628 &spr_read_ureg
, &spr_write_ureg
,
7630 spr_register(env
, SPR_POWER_UMMCRA
, "UMMCRA",
7631 &spr_read_ureg
, SPR_NOACCESS
,
7632 &spr_read_ureg
, &spr_write_ureg
,
7634 spr_register(env
, SPR_POWER_UPMC1
, "UPMC1",
7635 &spr_read_ureg
, SPR_NOACCESS
,
7636 &spr_read_ureg
, &spr_write_ureg
,
7638 spr_register(env
, SPR_POWER_UPMC2
, "UPMC2",
7639 &spr_read_ureg
, SPR_NOACCESS
,
7640 &spr_read_ureg
, &spr_write_ureg
,
7642 spr_register(env
, SPR_POWER_UPMC3
, "UPMC3",
7643 &spr_read_ureg
, SPR_NOACCESS
,
7644 &spr_read_ureg
, &spr_write_ureg
,
7646 spr_register(env
, SPR_POWER_UPMC4
, "UPMC4",
7647 &spr_read_ureg
, SPR_NOACCESS
,
7648 &spr_read_ureg
, &spr_write_ureg
,
7650 spr_register(env
, SPR_POWER_UPMC5
, "UPMC5",
7651 &spr_read_ureg
, SPR_NOACCESS
,
7652 &spr_read_ureg
, &spr_write_ureg
,
7654 spr_register(env
, SPR_POWER_UPMC6
, "UPMC6",
7655 &spr_read_ureg
, SPR_NOACCESS
,
7656 &spr_read_ureg
, &spr_write_ureg
,
7658 spr_register(env
, SPR_POWER_USIAR
, "USIAR",
7659 &spr_read_ureg
, SPR_NOACCESS
,
7660 &spr_read_ureg
, &spr_write_ureg
,
7662 spr_register(env
, SPR_POWER_USDAR
, "USDAR",
7663 &spr_read_ureg
, SPR_NOACCESS
,
7664 &spr_read_ureg
, &spr_write_ureg
,
7668 static void gen_spr_970_pmu_sup(CPUPPCState
*env
)
7670 spr_register_kvm(env
, SPR_970_PMC7
, "PMC7",
7671 SPR_NOACCESS
, SPR_NOACCESS
,
7672 &spr_read_generic
, &spr_write_generic
,
7673 KVM_REG_PPC_PMC7
, 0x00000000);
7674 spr_register_kvm(env
, SPR_970_PMC8
, "PMC8",
7675 SPR_NOACCESS
, SPR_NOACCESS
,
7676 &spr_read_generic
, &spr_write_generic
,
7677 KVM_REG_PPC_PMC8
, 0x00000000);
7680 static void gen_spr_970_pmu_user(CPUPPCState
*env
)
7682 spr_register(env
, SPR_970_UPMC7
, "UPMC7",
7683 &spr_read_ureg
, SPR_NOACCESS
,
7684 &spr_read_ureg
, &spr_write_ureg
,
7686 spr_register(env
, SPR_970_UPMC8
, "UPMC8",
7687 &spr_read_ureg
, SPR_NOACCESS
,
7688 &spr_read_ureg
, &spr_write_ureg
,
7692 static void gen_spr_power8_pmu_sup(CPUPPCState
*env
)
7694 spr_register_kvm(env
, SPR_POWER_MMCR2
, "MMCR2",
7695 SPR_NOACCESS
, SPR_NOACCESS
,
7696 &spr_read_generic
, &spr_write_generic
,
7697 KVM_REG_PPC_MMCR2
, 0x00000000);
7698 spr_register_kvm(env
, SPR_POWER_MMCRS
, "MMCRS",
7699 SPR_NOACCESS
, SPR_NOACCESS
,
7700 &spr_read_generic
, &spr_write_generic
,
7701 KVM_REG_PPC_MMCRS
, 0x00000000);
7702 spr_register_kvm(env
, SPR_POWER_SIER
, "SIER",
7703 SPR_NOACCESS
, SPR_NOACCESS
,
7704 &spr_read_generic
, &spr_write_generic
,
7705 KVM_REG_PPC_SIER
, 0x00000000);
7706 spr_register_kvm(env
, SPR_POWER_SPMC1
, "SPMC1",
7707 SPR_NOACCESS
, SPR_NOACCESS
,
7708 &spr_read_generic
, &spr_write_generic
,
7709 KVM_REG_PPC_SPMC1
, 0x00000000);
7710 spr_register_kvm(env
, SPR_POWER_SPMC2
, "SPMC2",
7711 SPR_NOACCESS
, SPR_NOACCESS
,
7712 &spr_read_generic
, &spr_write_generic
,
7713 KVM_REG_PPC_SPMC2
, 0x00000000);
7714 spr_register_kvm(env
, SPR_TACR
, "TACR",
7715 SPR_NOACCESS
, SPR_NOACCESS
,
7716 &spr_read_generic
, &spr_write_generic
,
7717 KVM_REG_PPC_TACR
, 0x00000000);
7718 spr_register_kvm(env
, SPR_TCSCR
, "TCSCR",
7719 SPR_NOACCESS
, SPR_NOACCESS
,
7720 &spr_read_generic
, &spr_write_generic
,
7721 KVM_REG_PPC_TCSCR
, 0x00000000);
7722 spr_register_kvm(env
, SPR_CSIGR
, "CSIGR",
7723 SPR_NOACCESS
, SPR_NOACCESS
,
7724 &spr_read_generic
, &spr_write_generic
,
7725 KVM_REG_PPC_CSIGR
, 0x00000000);
7728 static void gen_spr_power8_pmu_user(CPUPPCState
*env
)
7730 spr_register(env
, SPR_POWER_UMMCR2
, "UMMCR2",
7731 &spr_read_ureg
, SPR_NOACCESS
,
7732 &spr_read_ureg
, &spr_write_ureg
,
7734 spr_register(env
, SPR_POWER_USIER
, "USIER",
7735 &spr_read_generic
, SPR_NOACCESS
,
7736 &spr_read_generic
, &spr_write_generic
,
7740 static void gen_spr_power5p_ear(CPUPPCState
*env
)
7742 /* External access control */
7743 spr_register(env
, SPR_EAR
, "EAR",
7744 SPR_NOACCESS
, SPR_NOACCESS
,
7745 &spr_read_generic
, &spr_write_generic
,
7749 #if !defined(CONFIG_USER_ONLY)
7750 static void spr_write_hmer(DisasContext
*ctx
, int sprn
, int gprn
)
7752 TCGv hmer
= tcg_temp_new();
7754 gen_load_spr(hmer
, sprn
);
7755 tcg_gen_and_tl(hmer
, cpu_gpr
[gprn
], hmer
);
7756 gen_store_spr(sprn
, hmer
);
7757 spr_store_dump_spr(sprn
);
7758 tcg_temp_free(hmer
);
7761 static void spr_write_lpcr(DisasContext
*ctx
, int sprn
, int gprn
)
7763 gen_helper_store_lpcr(cpu_env
, cpu_gpr
[gprn
]);
7766 static void spr_write_970_hid4(DisasContext
*ctx
, int sprn
, int gprn
)
7768 #if defined(TARGET_PPC64)
7769 spr_write_generic(ctx
, sprn
, gprn
);
7770 gen_helper_store_lpcr(cpu_env
, cpu_gpr
[gprn
]);
7774 #endif /* !defined(CONFIG_USER_ONLY) */
7776 static void gen_spr_970_lpar(CPUPPCState
*env
)
7778 #if !defined(CONFIG_USER_ONLY)
7779 /* Logical partitionning */
7780 /* PPC970: HID4 is effectively the LPCR */
7781 spr_register(env
, SPR_970_HID4
, "HID4",
7782 SPR_NOACCESS
, SPR_NOACCESS
,
7783 &spr_read_generic
, &spr_write_970_hid4
,
7788 static void gen_spr_power5p_lpar(CPUPPCState
*env
)
7790 #if !defined(CONFIG_USER_ONLY)
7791 /* Logical partitionning */
7792 spr_register_kvm_hv(env
, SPR_LPCR
, "LPCR",
7793 SPR_NOACCESS
, SPR_NOACCESS
,
7794 SPR_NOACCESS
, SPR_NOACCESS
,
7795 &spr_read_generic
, &spr_write_lpcr
,
7796 KVM_REG_PPC_LPCR
, LPCR_LPES0
| LPCR_LPES1
);
7797 spr_register_hv(env
, SPR_HDEC
, "HDEC",
7798 SPR_NOACCESS
, SPR_NOACCESS
,
7799 SPR_NOACCESS
, SPR_NOACCESS
,
7800 &spr_read_hdecr
, &spr_write_hdecr
, 0);
7804 static void gen_spr_book3s_ids(CPUPPCState
*env
)
7806 /* FIXME: Will need to deal with thread vs core only SPRs */
7808 /* Processor identification */
7809 spr_register_hv(env
, SPR_PIR
, "PIR",
7810 SPR_NOACCESS
, SPR_NOACCESS
,
7811 SPR_NOACCESS
, SPR_NOACCESS
,
7812 &spr_read_generic
, NULL
,
7814 spr_register_hv(env
, SPR_HID0
, "HID0",
7815 SPR_NOACCESS
, SPR_NOACCESS
,
7816 SPR_NOACCESS
, SPR_NOACCESS
,
7817 &spr_read_generic
, &spr_write_generic
,
7819 spr_register_hv(env
, SPR_TSCR
, "TSCR",
7820 SPR_NOACCESS
, SPR_NOACCESS
,
7821 SPR_NOACCESS
, SPR_NOACCESS
,
7822 &spr_read_generic
, &spr_write_generic
,
7824 spr_register_hv(env
, SPR_HMER
, "HMER",
7825 SPR_NOACCESS
, SPR_NOACCESS
,
7826 SPR_NOACCESS
, SPR_NOACCESS
,
7827 &spr_read_generic
, &spr_write_hmer
,
7829 spr_register_hv(env
, SPR_HMEER
, "HMEER",
7830 SPR_NOACCESS
, SPR_NOACCESS
,
7831 SPR_NOACCESS
, SPR_NOACCESS
,
7832 &spr_read_generic
, &spr_write_generic
,
7834 spr_register_hv(env
, SPR_TFMR
, "TFMR",
7835 SPR_NOACCESS
, SPR_NOACCESS
,
7836 SPR_NOACCESS
, SPR_NOACCESS
,
7837 &spr_read_generic
, &spr_write_generic
,
7839 spr_register_hv(env
, SPR_LPIDR
, "LPIDR",
7840 SPR_NOACCESS
, SPR_NOACCESS
,
7841 SPR_NOACCESS
, SPR_NOACCESS
,
7842 &spr_read_generic
, &spr_write_generic
,
7844 spr_register_hv(env
, SPR_HFSCR
, "HFSCR",
7845 SPR_NOACCESS
, SPR_NOACCESS
,
7846 SPR_NOACCESS
, SPR_NOACCESS
,
7847 &spr_read_generic
, &spr_write_generic
,
7849 spr_register_hv(env
, SPR_MMCRC
, "MMCRC",
7850 SPR_NOACCESS
, SPR_NOACCESS
,
7851 SPR_NOACCESS
, SPR_NOACCESS
,
7852 &spr_read_generic
, &spr_write_generic
,
7854 spr_register_hv(env
, SPR_MMCRH
, "MMCRH",
7855 SPR_NOACCESS
, SPR_NOACCESS
,
7856 SPR_NOACCESS
, SPR_NOACCESS
,
7857 &spr_read_generic
, &spr_write_generic
,
7859 spr_register_hv(env
, SPR_HSPRG0
, "HSPRG0",
7860 SPR_NOACCESS
, SPR_NOACCESS
,
7861 SPR_NOACCESS
, SPR_NOACCESS
,
7862 &spr_read_generic
, &spr_write_generic
,
7864 spr_register_hv(env
, SPR_HSPRG1
, "HSPRG1",
7865 SPR_NOACCESS
, SPR_NOACCESS
,
7866 SPR_NOACCESS
, SPR_NOACCESS
,
7867 &spr_read_generic
, &spr_write_generic
,
7869 spr_register_hv(env
, SPR_HSRR0
, "HSRR0",
7870 SPR_NOACCESS
, SPR_NOACCESS
,
7871 SPR_NOACCESS
, SPR_NOACCESS
,
7872 &spr_read_generic
, &spr_write_generic
,
7874 spr_register_hv(env
, SPR_HSRR1
, "HSRR1",
7875 SPR_NOACCESS
, SPR_NOACCESS
,
7876 SPR_NOACCESS
, SPR_NOACCESS
,
7877 &spr_read_generic
, &spr_write_generic
,
7879 spr_register_hv(env
, SPR_HDAR
, "HDAR",
7880 SPR_NOACCESS
, SPR_NOACCESS
,
7881 SPR_NOACCESS
, SPR_NOACCESS
,
7882 &spr_read_generic
, &spr_write_generic
,
7884 spr_register_hv(env
, SPR_HDSISR
, "HDSISR",
7885 SPR_NOACCESS
, SPR_NOACCESS
,
7886 SPR_NOACCESS
, SPR_NOACCESS
,
7887 &spr_read_generic
, &spr_write_generic
,
7889 spr_register_hv(env
, SPR_RMOR
, "RMOR",
7890 SPR_NOACCESS
, SPR_NOACCESS
,
7891 SPR_NOACCESS
, SPR_NOACCESS
,
7892 &spr_read_generic
, &spr_write_generic
,
7894 spr_register_hv(env
, SPR_HRMOR
, "HRMOR",
7895 SPR_NOACCESS
, SPR_NOACCESS
,
7896 SPR_NOACCESS
, SPR_NOACCESS
,
7897 &spr_read_generic
, &spr_write_generic
,
7901 static void gen_spr_power8_ids(CPUPPCState
*env
)
7903 /* Thread identification */
7904 spr_register(env
, SPR_TIR
, "TIR",
7905 SPR_NOACCESS
, SPR_NOACCESS
,
7906 &spr_read_generic
, SPR_NOACCESS
,
7910 static void gen_spr_book3s_purr(CPUPPCState
*env
)
7912 #if !defined(CONFIG_USER_ONLY)
7913 /* PURR & SPURR: Hack - treat these as aliases for the TB for now */
7914 spr_register_kvm(env
, SPR_PURR
, "PURR",
7915 &spr_read_purr
, SPR_NOACCESS
,
7916 &spr_read_purr
, SPR_NOACCESS
,
7917 KVM_REG_PPC_PURR
, 0x00000000);
7918 spr_register_kvm(env
, SPR_SPURR
, "SPURR",
7919 &spr_read_purr
, SPR_NOACCESS
,
7920 &spr_read_purr
, SPR_NOACCESS
,
7921 KVM_REG_PPC_SPURR
, 0x00000000);
7925 static void gen_spr_power6_dbg(CPUPPCState
*env
)
7927 #if !defined(CONFIG_USER_ONLY)
7928 spr_register(env
, SPR_CFAR
, "SPR_CFAR",
7929 SPR_NOACCESS
, SPR_NOACCESS
,
7930 &spr_read_cfar
, &spr_write_cfar
,
7935 static void gen_spr_power5p_common(CPUPPCState
*env
)
7937 spr_register_kvm(env
, SPR_PPR
, "PPR",
7938 &spr_read_generic
, &spr_write_generic
,
7939 &spr_read_generic
, &spr_write_generic
,
7940 KVM_REG_PPC_PPR
, 0x00000000);
7943 static void gen_spr_power6_common(CPUPPCState
*env
)
7945 #if !defined(CONFIG_USER_ONLY)
7946 spr_register_kvm(env
, SPR_DSCR
, "SPR_DSCR",
7947 SPR_NOACCESS
, SPR_NOACCESS
,
7948 &spr_read_generic
, &spr_write_generic
,
7949 KVM_REG_PPC_DSCR
, 0x00000000);
7952 * Register PCR to report POWERPC_EXCP_PRIV_REG instead of
7953 * POWERPC_EXCP_INVAL_SPR.
7955 spr_register(env
, SPR_PCR
, "PCR",
7956 SPR_NOACCESS
, SPR_NOACCESS
,
7957 SPR_NOACCESS
, SPR_NOACCESS
,
7961 static void spr_read_tar(DisasContext
*ctx
, int gprn
, int sprn
)
7963 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_TAR
, sprn
, FSCR_IC_TAR
);
7964 spr_read_generic(ctx
, gprn
, sprn
);
7967 static void spr_write_tar(DisasContext
*ctx
, int sprn
, int gprn
)
7969 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_TAR
, sprn
, FSCR_IC_TAR
);
7970 spr_write_generic(ctx
, sprn
, gprn
);
7973 static void gen_spr_power8_tce_address_control(CPUPPCState
*env
)
7975 spr_register_kvm(env
, SPR_TAR
, "TAR",
7976 &spr_read_tar
, &spr_write_tar
,
7977 &spr_read_generic
, &spr_write_generic
,
7978 KVM_REG_PPC_TAR
, 0x00000000);
7981 static void spr_read_tm(DisasContext
*ctx
, int gprn
, int sprn
)
7983 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
7984 spr_read_generic(ctx
, gprn
, sprn
);
7987 static void spr_write_tm(DisasContext
*ctx
, int sprn
, int gprn
)
7989 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
7990 spr_write_generic(ctx
, sprn
, gprn
);
7993 static void spr_read_tm_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
7995 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
7996 spr_read_prev_upper32(ctx
, gprn
, sprn
);
7999 static void spr_write_tm_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
8001 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8002 spr_write_prev_upper32(ctx
, sprn
, gprn
);
8005 static void gen_spr_power8_tm(CPUPPCState
*env
)
8007 spr_register_kvm(env
, SPR_TFHAR
, "TFHAR",
8008 &spr_read_tm
, &spr_write_tm
,
8009 &spr_read_tm
, &spr_write_tm
,
8010 KVM_REG_PPC_TFHAR
, 0x00000000);
8011 spr_register_kvm(env
, SPR_TFIAR
, "TFIAR",
8012 &spr_read_tm
, &spr_write_tm
,
8013 &spr_read_tm
, &spr_write_tm
,
8014 KVM_REG_PPC_TFIAR
, 0x00000000);
8015 spr_register_kvm(env
, SPR_TEXASR
, "TEXASR",
8016 &spr_read_tm
, &spr_write_tm
,
8017 &spr_read_tm
, &spr_write_tm
,
8018 KVM_REG_PPC_TEXASR
, 0x00000000);
8019 spr_register(env
, SPR_TEXASRU
, "TEXASRU",
8020 &spr_read_tm_upper32
, &spr_write_tm_upper32
,
8021 &spr_read_tm_upper32
, &spr_write_tm_upper32
,
8025 static void spr_read_ebb(DisasContext
*ctx
, int gprn
, int sprn
)
8027 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8028 spr_read_generic(ctx
, gprn
, sprn
);
8031 static void spr_write_ebb(DisasContext
*ctx
, int sprn
, int gprn
)
8033 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8034 spr_write_generic(ctx
, sprn
, gprn
);
8037 static void spr_read_ebb_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
8039 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8040 spr_read_prev_upper32(ctx
, gprn
, sprn
);
8043 static void spr_write_ebb_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
8045 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8046 spr_write_prev_upper32(ctx
, sprn
, gprn
);
8049 static void gen_spr_power8_ebb(CPUPPCState
*env
)
8051 spr_register(env
, SPR_BESCRS
, "BESCRS",
8052 &spr_read_ebb
, &spr_write_ebb
,
8053 &spr_read_generic
, &spr_write_generic
,
8055 spr_register(env
, SPR_BESCRSU
, "BESCRSU",
8056 &spr_read_ebb_upper32
, &spr_write_ebb_upper32
,
8057 &spr_read_prev_upper32
, &spr_write_prev_upper32
,
8059 spr_register(env
, SPR_BESCRR
, "BESCRR",
8060 &spr_read_ebb
, &spr_write_ebb
,
8061 &spr_read_generic
, &spr_write_generic
,
8063 spr_register(env
, SPR_BESCRRU
, "BESCRRU",
8064 &spr_read_ebb_upper32
, &spr_write_ebb_upper32
,
8065 &spr_read_prev_upper32
, &spr_write_prev_upper32
,
8067 spr_register_kvm(env
, SPR_EBBHR
, "EBBHR",
8068 &spr_read_ebb
, &spr_write_ebb
,
8069 &spr_read_generic
, &spr_write_generic
,
8070 KVM_REG_PPC_EBBHR
, 0x00000000);
8071 spr_register_kvm(env
, SPR_EBBRR
, "EBBRR",
8072 &spr_read_ebb
, &spr_write_ebb
,
8073 &spr_read_generic
, &spr_write_generic
,
8074 KVM_REG_PPC_EBBRR
, 0x00000000);
8075 spr_register_kvm(env
, SPR_BESCR
, "BESCR",
8076 &spr_read_ebb
, &spr_write_ebb
,
8077 &spr_read_generic
, &spr_write_generic
,
8078 KVM_REG_PPC_BESCR
, 0x00000000);
8081 /* Virtual Time Base */
8082 static void gen_spr_vtb(CPUPPCState
*env
)
8084 spr_register_kvm(env
, SPR_VTB
, "VTB",
8085 SPR_NOACCESS
, SPR_NOACCESS
,
8086 &spr_read_tbl
, SPR_NOACCESS
,
8087 KVM_REG_PPC_VTB
, 0x00000000);
8090 static void gen_spr_power8_fscr(CPUPPCState
*env
)
8092 #if defined(CONFIG_USER_ONLY)
8093 target_ulong initval
= 1ULL << FSCR_TAR
;
8095 target_ulong initval
= 0;
8097 spr_register_kvm(env
, SPR_FSCR
, "FSCR",
8098 SPR_NOACCESS
, SPR_NOACCESS
,
8099 &spr_read_generic
, &spr_write_generic
,
8100 KVM_REG_PPC_FSCR
, initval
);
8103 static void gen_spr_power8_pspb(CPUPPCState
*env
)
8105 spr_register_kvm(env
, SPR_PSPB
, "PSPB",
8106 SPR_NOACCESS
, SPR_NOACCESS
,
8107 &spr_read_generic
, &spr_write_generic32
,
8108 KVM_REG_PPC_PSPB
, 0);
8111 static void gen_spr_power8_ic(CPUPPCState
*env
)
8113 #if !defined(CONFIG_USER_ONLY)
8114 spr_register_hv(env
, SPR_IC
, "IC",
8115 SPR_NOACCESS
, SPR_NOACCESS
,
8116 &spr_read_generic
, SPR_NOACCESS
,
8117 &spr_read_generic
, &spr_write_generic
,
8122 static void gen_spr_power8_book4(CPUPPCState
*env
)
8124 /* Add a number of P8 book4 registers */
8125 #if !defined(CONFIG_USER_ONLY)
8126 spr_register_kvm(env
, SPR_ACOP
, "ACOP",
8127 SPR_NOACCESS
, SPR_NOACCESS
,
8128 &spr_read_generic
, &spr_write_generic
,
8129 KVM_REG_PPC_ACOP
, 0);
8130 spr_register_kvm(env
, SPR_BOOKS_PID
, "PID",
8131 SPR_NOACCESS
, SPR_NOACCESS
,
8132 &spr_read_generic
, &spr_write_pidr
,
8133 KVM_REG_PPC_PID
, 0);
8134 spr_register_kvm(env
, SPR_WORT
, "WORT",
8135 SPR_NOACCESS
, SPR_NOACCESS
,
8136 &spr_read_generic
, &spr_write_generic
,
8137 KVM_REG_PPC_WORT
, 0);
8141 static void gen_spr_power7_book4(CPUPPCState
*env
)
8143 /* Add a number of P7 book4 registers */
8144 #if !defined(CONFIG_USER_ONLY)
8145 spr_register_kvm(env
, SPR_ACOP
, "ACOP",
8146 SPR_NOACCESS
, SPR_NOACCESS
,
8147 &spr_read_generic
, &spr_write_generic
,
8148 KVM_REG_PPC_ACOP
, 0);
8149 spr_register_kvm(env
, SPR_BOOKS_PID
, "PID",
8150 SPR_NOACCESS
, SPR_NOACCESS
,
8151 &spr_read_generic
, &spr_write_generic
,
8152 KVM_REG_PPC_PID
, 0);
8156 static void gen_spr_power8_rpr(CPUPPCState
*env
)
8158 #if !defined(CONFIG_USER_ONLY)
8159 spr_register_hv(env
, SPR_RPR
, "RPR",
8160 SPR_NOACCESS
, SPR_NOACCESS
,
8161 SPR_NOACCESS
, SPR_NOACCESS
,
8162 &spr_read_generic
, &spr_write_generic
,
8163 0x00000103070F1F3F);
8167 static void init_proc_book3s_common(CPUPPCState
*env
)
8169 gen_spr_ne_601(env
);
8171 gen_spr_usprg3(env
);
8172 gen_spr_book3s_altivec(env
);
8173 gen_spr_book3s_pmu_sup(env
);
8174 gen_spr_book3s_pmu_user(env
);
8175 gen_spr_book3s_ctrl(env
);
8178 static void init_proc_970(CPUPPCState
*env
)
8180 /* Common Registers */
8181 init_proc_book3s_common(env
);
8183 gen_spr_book3s_dbg(env
);
8185 /* 970 Specific Registers */
8186 gen_spr_970_hid(env
);
8187 gen_spr_970_hior(env
);
8189 gen_spr_970_pmu_sup(env
);
8190 gen_spr_970_pmu_user(env
);
8191 gen_spr_970_lpar(env
);
8192 gen_spr_970_dbg(env
);
8195 #if !defined(CONFIG_USER_ONLY)
8198 env
->dcache_line_size
= 128;
8199 env
->icache_line_size
= 128;
8201 /* Allocate hardware IRQ controller */
8203 ppc970_irq_init(ppc_env_get_cpu(env
));
8206 POWERPC_FAMILY(970)(ObjectClass
*oc
, void *data
)
8208 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8209 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8211 dc
->desc
= "PowerPC 970";
8212 pcc
->init_proc
= init_proc_970
;
8213 pcc
->check_pow
= check_pow_970
;
8214 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
8215 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8216 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8218 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8219 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8220 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8221 PPC_64B
| PPC_ALTIVEC
|
8222 PPC_SEGMENT_64B
| PPC_SLBI
;
8223 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
8224 pcc
->msr_mask
= (1ull << MSR_SF
) |
8239 pcc
->mmu_model
= POWERPC_MMU_64B
;
8240 #if defined(CONFIG_SOFTMMU)
8241 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8243 pcc
->excp_model
= POWERPC_EXCP_970
;
8244 pcc
->bus_model
= PPC_FLAGS_INPUT_970
;
8245 pcc
->bfd_mach
= bfd_mach_ppc64
;
8246 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8247 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8248 POWERPC_FLAG_BUS_CLK
;
8249 pcc
->l1_dcache_size
= 0x8000;
8250 pcc
->l1_icache_size
= 0x10000;
8253 static void init_proc_power5plus(CPUPPCState
*env
)
8255 /* Common Registers */
8256 init_proc_book3s_common(env
);
8258 gen_spr_book3s_dbg(env
);
8260 /* POWER5+ Specific Registers */
8261 gen_spr_970_hid(env
);
8262 gen_spr_970_hior(env
);
8264 gen_spr_970_pmu_sup(env
);
8265 gen_spr_970_pmu_user(env
);
8266 gen_spr_power5p_common(env
);
8267 gen_spr_power5p_lpar(env
);
8268 gen_spr_power5p_ear(env
);
8271 #if !defined(CONFIG_USER_ONLY)
8274 env
->dcache_line_size
= 128;
8275 env
->icache_line_size
= 128;
8277 /* Allocate hardware IRQ controller */
8279 ppc970_irq_init(ppc_env_get_cpu(env
));
8282 POWERPC_FAMILY(POWER5P
)(ObjectClass
*oc
, void *data
)
8284 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8285 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8287 dc
->fw_name
= "PowerPC,POWER5";
8288 dc
->desc
= "POWER5+";
8289 pcc
->init_proc
= init_proc_power5plus
;
8290 pcc
->check_pow
= check_pow_970
;
8291 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
8292 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8293 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8295 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8296 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8297 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8299 PPC_SEGMENT_64B
| PPC_SLBI
;
8300 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
8301 pcc
->msr_mask
= (1ull << MSR_SF
) |
8316 pcc
->mmu_model
= POWERPC_MMU_2_03
;
8317 #if defined(CONFIG_SOFTMMU)
8318 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8320 pcc
->excp_model
= POWERPC_EXCP_970
;
8321 pcc
->bus_model
= PPC_FLAGS_INPUT_970
;
8322 pcc
->bfd_mach
= bfd_mach_ppc64
;
8323 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8324 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8325 POWERPC_FLAG_BUS_CLK
;
8326 pcc
->l1_dcache_size
= 0x8000;
8327 pcc
->l1_icache_size
= 0x10000;
8331 * The CPU used to have a "compat" property which set the
8332 * compatibility mode PVR. However, this was conceptually broken - it
8333 * only makes sense on the pseries machine type (otherwise the guest
8334 * owns the PCR and can control the compatibility mode itself). It's
8335 * been replaced with the 'max-cpu-compat' property on the pseries
8336 * machine type. For backwards compatibility, pseries specially
8337 * parses the -cpu parameter and converts old compat= parameters into
8338 * the appropriate machine parameters. This stub implementation of
8339 * the parameter catches any uses on explicitly created CPUs.
8341 static void getset_compat_deprecated(Object
*obj
, Visitor
*v
, const char *name
,
8342 void *opaque
, Error
**errp
)
8346 if (!qtest_enabled()) {
8347 error_report("CPU 'compat' property is deprecated and has no effect; "
8348 "use max-cpu-compat machine property instead");
8350 visit_type_null(v
, name
, &null
, NULL
);
8354 static const PropertyInfo ppc_compat_deprecated_propinfo
= {
8356 .description
= "compatibility mode (deprecated)",
8357 .get
= getset_compat_deprecated
,
8358 .set
= getset_compat_deprecated
,
8360 static Property powerpc_servercpu_properties
[] = {
8363 .info
= &ppc_compat_deprecated_propinfo
,
8365 DEFINE_PROP_END_OF_LIST(),
8368 #ifdef CONFIG_SOFTMMU
8369 static const struct ppc_segment_page_sizes POWER7_POWER8_sps
= {
8372 .page_shift
= 12, /* 4K */
8374 .enc
= { { .page_shift
= 12, .pte_enc
= 0 },
8375 { .page_shift
= 16, .pte_enc
= 0x7 },
8376 { .page_shift
= 24, .pte_enc
= 0x38 }, },
8379 .page_shift
= 16, /* 64K */
8380 .slb_enc
= SLB_VSID_64K
,
8381 .enc
= { { .page_shift
= 16, .pte_enc
= 0x1 },
8382 { .page_shift
= 24, .pte_enc
= 0x8 }, },
8385 .page_shift
= 24, /* 16M */
8386 .slb_enc
= SLB_VSID_16M
,
8387 .enc
= { { .page_shift
= 24, .pte_enc
= 0 }, },
8390 .page_shift
= 34, /* 16G */
8391 .slb_enc
= SLB_VSID_16G
,
8392 .enc
= { { .page_shift
= 34, .pte_enc
= 0x3 }, },
8396 #endif /* CONFIG_SOFTMMU */
8398 static void init_proc_POWER7(CPUPPCState
*env
)
8400 /* Common Registers */
8401 init_proc_book3s_common(env
);
8403 gen_spr_book3s_dbg(env
);
8405 /* POWER7 Specific Registers */
8406 gen_spr_book3s_ids(env
);
8408 gen_spr_book3s_purr(env
);
8409 gen_spr_power5p_common(env
);
8410 gen_spr_power5p_lpar(env
);
8411 gen_spr_power5p_ear(env
);
8412 gen_spr_power6_common(env
);
8413 gen_spr_power6_dbg(env
);
8414 gen_spr_power7_book4(env
);
8417 #if !defined(CONFIG_USER_ONLY)
8420 env
->ci_large_pages
= true;
8421 env
->dcache_line_size
= 128;
8422 env
->icache_line_size
= 128;
8424 /* Allocate hardware IRQ controller */
8425 init_excp_POWER7(env
);
8426 ppcPOWER7_irq_init(ppc_env_get_cpu(env
));
8429 static bool ppc_pvr_match_power7(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8431 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER7P_BASE
) {
8434 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER7_BASE
) {
8440 static bool cpu_has_work_POWER7(CPUState
*cs
)
8442 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8443 CPUPPCState
*env
= &cpu
->env
;
8446 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8449 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8450 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE0
)) {
8453 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8454 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE1
)) {
8457 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
)) &&
8458 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE2
)) {
8461 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HMI
)) &&
8462 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE2
)) {
8465 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8470 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8474 POWERPC_FAMILY(POWER7
)(ObjectClass
*oc
, void *data
)
8476 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8477 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8478 CPUClass
*cc
= CPU_CLASS(oc
);
8480 dc
->fw_name
= "PowerPC,POWER7";
8481 dc
->desc
= "POWER7";
8482 dc
->props
= powerpc_servercpu_properties
;
8483 pcc
->pvr_match
= ppc_pvr_match_power7
;
8484 pcc
->pcr_mask
= PCR_VEC_DIS
| PCR_VSX_DIS
| PCR_COMPAT_2_05
;
8485 pcc
->pcr_supported
= PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8486 pcc
->init_proc
= init_proc_POWER7
;
8487 pcc
->check_pow
= check_pow_nocheck
;
8488 cc
->has_work
= cpu_has_work_POWER7
;
8489 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8490 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8491 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8492 PPC_FLOAT_FRSQRTES
|
8495 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8496 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8497 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8498 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
8499 PPC_SEGMENT_64B
| PPC_SLBI
|
8500 PPC_POPCNTB
| PPC_POPCNTWD
|
8502 pcc
->insns_flags2
= PPC2_VSX
| PPC2_DFP
| PPC2_DBRX
| PPC2_ISA205
|
8503 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8504 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8505 PPC2_FP_TST_ISA206
| PPC2_FP_CVT_S64
|
8507 pcc
->msr_mask
= (1ull << MSR_SF
) |
8523 pcc
->mmu_model
= POWERPC_MMU_2_06
;
8524 #if defined(CONFIG_SOFTMMU)
8525 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8526 pcc
->sps
= &POWER7_POWER8_sps
;
8528 pcc
->excp_model
= POWERPC_EXCP_POWER7
;
8529 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8530 pcc
->bfd_mach
= bfd_mach_ppc64
;
8531 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8532 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8533 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8535 pcc
->l1_dcache_size
= 0x8000;
8536 pcc
->l1_icache_size
= 0x8000;
8537 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8538 pcc
->lpcr_pm
= LPCR_P7_PECE0
| LPCR_P7_PECE1
| LPCR_P7_PECE2
;
8541 static void init_proc_POWER8(CPUPPCState
*env
)
8543 /* Common Registers */
8544 init_proc_book3s_common(env
);
8546 gen_spr_book3s_207_dbg(env
);
8548 /* POWER8 Specific Registers */
8549 gen_spr_book3s_ids(env
);
8552 gen_spr_book3s_purr(env
);
8553 gen_spr_power5p_common(env
);
8554 gen_spr_power5p_lpar(env
);
8555 gen_spr_power5p_ear(env
);
8556 gen_spr_power6_common(env
);
8557 gen_spr_power6_dbg(env
);
8558 gen_spr_power8_tce_address_control(env
);
8559 gen_spr_power8_ids(env
);
8560 gen_spr_power8_ebb(env
);
8561 gen_spr_power8_fscr(env
);
8562 gen_spr_power8_pmu_sup(env
);
8563 gen_spr_power8_pmu_user(env
);
8564 gen_spr_power8_tm(env
);
8565 gen_spr_power8_pspb(env
);
8567 gen_spr_power8_ic(env
);
8568 gen_spr_power8_book4(env
);
8569 gen_spr_power8_rpr(env
);
8572 #if !defined(CONFIG_USER_ONLY)
8575 env
->ci_large_pages
= true;
8576 env
->dcache_line_size
= 128;
8577 env
->icache_line_size
= 128;
8579 /* Allocate hardware IRQ controller */
8580 init_excp_POWER8(env
);
8581 ppcPOWER7_irq_init(ppc_env_get_cpu(env
));
8584 static bool ppc_pvr_match_power8(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8586 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8NVL_BASE
) {
8589 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8E_BASE
) {
8592 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8_BASE
) {
8598 static bool cpu_has_work_POWER8(CPUState
*cs
)
8600 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8601 CPUPPCState
*env
= &cpu
->env
;
8604 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8607 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8608 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE2
)) {
8611 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8612 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE3
)) {
8615 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
)) &&
8616 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE4
)) {
8619 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HMI
)) &&
8620 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE4
)) {
8623 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DOORBELL
)) &&
8624 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE0
)) {
8627 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HDOORBELL
)) &&
8628 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE1
)) {
8631 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8636 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8640 POWERPC_FAMILY(POWER8
)(ObjectClass
*oc
, void *data
)
8642 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8643 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8644 CPUClass
*cc
= CPU_CLASS(oc
);
8646 dc
->fw_name
= "PowerPC,POWER8";
8647 dc
->desc
= "POWER8";
8648 dc
->props
= powerpc_servercpu_properties
;
8649 pcc
->pvr_match
= ppc_pvr_match_power8
;
8650 pcc
->pcr_mask
= PCR_TM_DIS
| PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8651 pcc
->pcr_supported
= PCR_COMPAT_2_07
| PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8652 pcc
->init_proc
= init_proc_POWER8
;
8653 pcc
->check_pow
= check_pow_nocheck
;
8654 cc
->has_work
= cpu_has_work_POWER8
;
8655 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8656 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8657 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8658 PPC_FLOAT_FRSQRTES
|
8661 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8662 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8663 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8664 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
8665 PPC_SEGMENT_64B
| PPC_SLBI
|
8666 PPC_POPCNTB
| PPC_POPCNTWD
|
8668 pcc
->insns_flags2
= PPC2_VSX
| PPC2_VSX207
| PPC2_DFP
| PPC2_DBRX
|
8669 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8670 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8671 PPC2_FP_TST_ISA206
| PPC2_BCTAR_ISA207
|
8672 PPC2_LSQ_ISA207
| PPC2_ALTIVEC_207
|
8673 PPC2_ISA205
| PPC2_ISA207S
| PPC2_FP_CVT_S64
|
8674 PPC2_TM
| PPC2_PM_ISA206
;
8675 pcc
->msr_mask
= (1ull << MSR_SF
) |
8693 pcc
->mmu_model
= POWERPC_MMU_2_07
;
8694 #if defined(CONFIG_SOFTMMU)
8695 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8696 pcc
->sps
= &POWER7_POWER8_sps
;
8698 pcc
->excp_model
= POWERPC_EXCP_POWER8
;
8699 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8700 pcc
->bfd_mach
= bfd_mach_ppc64
;
8701 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8702 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8703 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8704 POWERPC_FLAG_VSX
| POWERPC_FLAG_TM
;
8705 pcc
->l1_dcache_size
= 0x8000;
8706 pcc
->l1_icache_size
= 0x8000;
8707 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8708 pcc
->lpcr_pm
= LPCR_P8_PECE0
| LPCR_P8_PECE1
| LPCR_P8_PECE2
|
8709 LPCR_P8_PECE3
| LPCR_P8_PECE4
;
8712 #ifdef CONFIG_SOFTMMU
8714 * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
8715 * Encoded as array of int_32s in the form:
8716 * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
8718 * y -> radix mode supported page size (encoded as a shift)
8720 static struct ppc_radix_page_info POWER9_radix_page_info
= {
8723 0x0000000c, /* 4K - enc: 0x0 */
8724 0xa0000010, /* 64K - enc: 0x5 */
8725 0x20000015, /* 2M - enc: 0x1 */
8726 0x4000001e /* 1G - enc: 0x2 */
8729 #endif /* CONFIG_SOFTMMU */
8731 static void init_proc_POWER9(CPUPPCState
*env
)
8733 /* Common Registers */
8734 init_proc_book3s_common(env
);
8735 gen_spr_book3s_207_dbg(env
);
8737 /* POWER8 Specific Registers */
8738 gen_spr_book3s_ids(env
);
8741 gen_spr_book3s_purr(env
);
8742 gen_spr_power5p_common(env
);
8743 gen_spr_power5p_lpar(env
);
8744 gen_spr_power5p_ear(env
);
8745 gen_spr_power6_common(env
);
8746 gen_spr_power6_dbg(env
);
8747 gen_spr_power8_tce_address_control(env
);
8748 gen_spr_power8_ids(env
);
8749 gen_spr_power8_ebb(env
);
8750 gen_spr_power8_fscr(env
);
8751 gen_spr_power8_pmu_sup(env
);
8752 gen_spr_power8_pmu_user(env
);
8753 gen_spr_power8_tm(env
);
8754 gen_spr_power8_pspb(env
);
8756 gen_spr_power8_ic(env
);
8757 gen_spr_power8_book4(env
);
8758 gen_spr_power8_rpr(env
);
8760 /* POWER9 Specific registers */
8761 spr_register_kvm(env
, SPR_TIDR
, "TIDR", NULL
, NULL
,
8762 spr_read_generic
, spr_write_generic
,
8763 KVM_REG_PPC_TIDR
, 0);
8765 /* FIXME: Filter fields properly based on privilege level */
8766 spr_register_kvm_hv(env
, SPR_PSSCR
, "PSSCR", NULL
, NULL
, NULL
, NULL
,
8767 spr_read_generic
, spr_write_generic
,
8768 KVM_REG_PPC_PSSCR
, 0);
8771 #if !defined(CONFIG_USER_ONLY)
8774 env
->ci_large_pages
= true;
8775 env
->dcache_line_size
= 128;
8776 env
->icache_line_size
= 128;
8778 /* Allocate hardware IRQ controller */
8779 init_excp_POWER8(env
);
8780 ppcPOWER7_irq_init(ppc_env_get_cpu(env
));
8783 static bool ppc_pvr_match_power9(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8785 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER9_BASE
) {
8791 static bool cpu_has_work_POWER9(CPUState
*cs
)
8793 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8794 CPUPPCState
*env
= &cpu
->env
;
8797 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8800 /* External Exception */
8801 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8802 (env
->spr
[SPR_LPCR
] & LPCR_EEE
)) {
8805 /* Decrementer Exception */
8806 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8807 (env
->spr
[SPR_LPCR
] & LPCR_DEE
)) {
8810 /* Machine Check or Hypervisor Maintenance Exception */
8811 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
|
8812 1u << PPC_INTERRUPT_HMI
)) && (env
->spr
[SPR_LPCR
] & LPCR_OEE
)) {
8815 /* Privileged Doorbell Exception */
8816 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DOORBELL
)) &&
8817 (env
->spr
[SPR_LPCR
] & LPCR_PDEE
)) {
8820 /* Hypervisor Doorbell Exception */
8821 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HDOORBELL
)) &&
8822 (env
->spr
[SPR_LPCR
] & LPCR_HDEE
)) {
8825 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8830 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8834 POWERPC_FAMILY(POWER9
)(ObjectClass
*oc
, void *data
)
8836 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8837 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8838 CPUClass
*cc
= CPU_CLASS(oc
);
8840 dc
->fw_name
= "PowerPC,POWER9";
8841 dc
->desc
= "POWER9";
8842 dc
->props
= powerpc_servercpu_properties
;
8843 pcc
->pvr_match
= ppc_pvr_match_power9
;
8844 pcc
->pcr_mask
= PCR_COMPAT_2_05
| PCR_COMPAT_2_06
| PCR_COMPAT_2_07
;
8845 pcc
->pcr_supported
= PCR_COMPAT_3_00
| PCR_COMPAT_2_07
| PCR_COMPAT_2_06
|
8847 pcc
->init_proc
= init_proc_POWER9
;
8848 pcc
->check_pow
= check_pow_nocheck
;
8849 cc
->has_work
= cpu_has_work_POWER9
;
8850 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8851 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8852 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8853 PPC_FLOAT_FRSQRTES
|
8856 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8857 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8859 PPC_64B
| PPC_64BX
| PPC_ALTIVEC
|
8860 PPC_SEGMENT_64B
| PPC_SLBI
|
8861 PPC_POPCNTB
| PPC_POPCNTWD
|
8863 pcc
->insns_flags2
= PPC2_VSX
| PPC2_VSX207
| PPC2_DFP
| PPC2_DBRX
|
8864 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8865 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8866 PPC2_FP_TST_ISA206
| PPC2_BCTAR_ISA207
|
8867 PPC2_LSQ_ISA207
| PPC2_ALTIVEC_207
|
8868 PPC2_ISA205
| PPC2_ISA207S
| PPC2_FP_CVT_S64
|
8869 PPC2_TM
| PPC2_PM_ISA206
| PPC2_ISA300
;
8870 pcc
->msr_mask
= (1ull << MSR_SF
) |
8887 pcc
->mmu_model
= POWERPC_MMU_3_00
;
8888 #if defined(CONFIG_SOFTMMU)
8889 pcc
->handle_mmu_fault
= ppc64_v3_handle_mmu_fault
;
8890 /* segment page size remain the same */
8891 pcc
->sps
= &POWER7_POWER8_sps
;
8892 pcc
->radix_page_info
= &POWER9_radix_page_info
;
8894 pcc
->excp_model
= POWERPC_EXCP_POWER8
;
8895 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8896 pcc
->bfd_mach
= bfd_mach_ppc64
;
8897 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8898 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8899 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8900 POWERPC_FLAG_VSX
| POWERPC_FLAG_TM
;
8901 pcc
->l1_dcache_size
= 0x8000;
8902 pcc
->l1_icache_size
= 0x8000;
8903 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8904 pcc
->lpcr_pm
= LPCR_PDEE
| LPCR_HDEE
| LPCR_EEE
| LPCR_DEE
| LPCR_OEE
;
8907 #if !defined(CONFIG_USER_ONLY)
8908 void cpu_ppc_set_papr(PowerPCCPU
*cpu
, PPCVirtualHypervisor
*vhyp
)
8910 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
8911 CPUPPCState
*env
= &cpu
->env
;
8912 ppc_spr_t
*lpcr
= &env
->spr_cb
[SPR_LPCR
];
8913 ppc_spr_t
*amor
= &env
->spr_cb
[SPR_AMOR
];
8914 CPUState
*cs
= CPU(cpu
);
8918 /* PAPR always has exception vectors in RAM not ROM. To ensure this,
8919 * MSR[IP] should never be set.
8921 * We also disallow setting of MSR_HV
8923 env
->msr_mask
&= ~((1ull << MSR_EP
) | MSR_HVB
);
8925 /* Set emulated LPCR to not send interrupts to hypervisor. Note that
8926 * under KVM, the actual HW LPCR will be set differently by KVM itself,
8927 * the settings below ensure proper operations with TCG in absence of
8928 * a real hypervisor.
8930 * Clearing VPM0 will also cause us to use RMOR in mmu-hash64.c for
8931 * real mode accesses, which thankfully defaults to 0 and isn't
8932 * accessible in guest mode.
8934 lpcr
->default_value
&= ~(LPCR_VPM0
| LPCR_VPM1
| LPCR_ISL
| LPCR_KBV
);
8935 lpcr
->default_value
|= LPCR_LPES0
| LPCR_LPES1
;
8937 /* Set RMLS to the max (ie, 16G) */
8938 lpcr
->default_value
&= ~LPCR_RMLS
;
8939 lpcr
->default_value
|= 1ull << LPCR_RMLS_SHIFT
;
8941 if (env
->mmu_model
== POWERPC_MMU_3_00
) {
8942 /* By default we choose legacy mode and switch to new hash or radix
8943 * when a register process table hcall is made. So disable process
8944 * tables and guest translation shootdown by default
8946 * Hot-plugged CPUs inherit from the guest radix setting under
8947 * KVM but not under TCG. Update the default LPCR to keep new
8948 * CPUs in sync when radix is enabled.
8950 if (ppc64_radix_guest(cpu
)) {
8951 lpcr
->default_value
|= LPCR_UPRT
| LPCR_GTSE
;
8953 lpcr
->default_value
&= ~(LPCR_UPRT
| LPCR_GTSE
);
8957 /* Only enable Power-saving mode Exit Cause exceptions on the boot
8958 * CPU. The RTAS command start-cpu will enable them on secondaries.
8960 if (cs
== first_cpu
) {
8961 lpcr
->default_value
|= pcc
->lpcr_pm
;
8964 /* We should be followed by a CPU reset but update the active value
8967 env
->spr
[SPR_LPCR
] = lpcr
->default_value
;
8969 /* Set a full AMOR so guest can use the AMR as it sees fit */
8970 env
->spr
[SPR_AMOR
] = amor
->default_value
= 0xffffffffffffffffull
;
8972 /* Update some env bits based on new LPCR value */
8973 ppc_hash64_update_rmls(env
);
8974 ppc_hash64_update_vrma(env
);
8976 /* Tell KVM that we're in PAPR mode */
8977 if (kvm_enabled()) {
8978 kvmppc_set_papr(cpu
);
8982 #endif /* !defined(CONFIG_USER_ONLY) */
8984 #endif /* defined(TARGET_PPC64) */
8986 /*****************************************************************************/
8987 /* Generic CPU instantiation routine */
8988 static void init_ppc_proc(PowerPCCPU
*cpu
)
8990 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
8991 CPUPPCState
*env
= &cpu
->env
;
8992 #if !defined(CONFIG_USER_ONLY)
8995 env
->irq_inputs
= NULL
;
8996 /* Set all exception vectors to an invalid address */
8997 for (i
= 0; i
< POWERPC_EXCP_NB
; i
++)
8998 env
->excp_vectors
[i
] = (target_ulong
)(-1ULL);
8999 env
->ivor_mask
= 0x00000000;
9000 env
->ivpr_mask
= 0x00000000;
9001 /* Default MMU definitions */
9005 env
->tlb_type
= TLB_NONE
;
9007 /* Register SPR common to all PowerPC implementations */
9008 gen_spr_generic(env
);
9009 spr_register(env
, SPR_PVR
, "PVR",
9010 /* Linux permits userspace to read PVR */
9011 #if defined(CONFIG_LINUX_USER)
9017 &spr_read_generic
, SPR_NOACCESS
,
9019 /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
9020 if (pcc
->svr
!= POWERPC_SVR_NONE
) {
9021 if (pcc
->svr
& POWERPC_SVR_E500
) {
9022 spr_register(env
, SPR_E500_SVR
, "SVR",
9023 SPR_NOACCESS
, SPR_NOACCESS
,
9024 &spr_read_generic
, SPR_NOACCESS
,
9025 pcc
->svr
& ~POWERPC_SVR_E500
);
9027 spr_register(env
, SPR_SVR
, "SVR",
9028 SPR_NOACCESS
, SPR_NOACCESS
,
9029 &spr_read_generic
, SPR_NOACCESS
,
9033 /* PowerPC implementation specific initialisations (SPRs, timers, ...) */
9034 (*pcc
->init_proc
)(env
);
9036 /* MSR bits & flags consistency checks */
9037 if (env
->msr_mask
& (1 << 25)) {
9038 switch (env
->flags
& (POWERPC_FLAG_SPE
| POWERPC_FLAG_VRE
)) {
9039 case POWERPC_FLAG_SPE
:
9040 case POWERPC_FLAG_VRE
:
9043 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9044 "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n");
9047 } else if (env
->flags
& (POWERPC_FLAG_SPE
| POWERPC_FLAG_VRE
)) {
9048 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9049 "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n");
9052 if (env
->msr_mask
& (1 << 17)) {
9053 switch (env
->flags
& (POWERPC_FLAG_TGPR
| POWERPC_FLAG_CE
)) {
9054 case POWERPC_FLAG_TGPR
:
9055 case POWERPC_FLAG_CE
:
9058 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9059 "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n");
9062 } else if (env
->flags
& (POWERPC_FLAG_TGPR
| POWERPC_FLAG_CE
)) {
9063 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9064 "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n");
9067 if (env
->msr_mask
& (1 << 10)) {
9068 switch (env
->flags
& (POWERPC_FLAG_SE
| POWERPC_FLAG_DWE
|
9069 POWERPC_FLAG_UBLE
)) {
9070 case POWERPC_FLAG_SE
:
9071 case POWERPC_FLAG_DWE
:
9072 case POWERPC_FLAG_UBLE
:
9075 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9076 "Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE or "
9077 "POWERPC_FLAG_UBLE\n");
9080 } else if (env
->flags
& (POWERPC_FLAG_SE
| POWERPC_FLAG_DWE
|
9081 POWERPC_FLAG_UBLE
)) {
9082 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9083 "Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE nor "
9084 "POWERPC_FLAG_UBLE\n");
9087 if (env
->msr_mask
& (1 << 9)) {
9088 switch (env
->flags
& (POWERPC_FLAG_BE
| POWERPC_FLAG_DE
)) {
9089 case POWERPC_FLAG_BE
:
9090 case POWERPC_FLAG_DE
:
9093 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9094 "Should define POWERPC_FLAG_BE or POWERPC_FLAG_DE\n");
9097 } else if (env
->flags
& (POWERPC_FLAG_BE
| POWERPC_FLAG_DE
)) {
9098 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9099 "Should not define POWERPC_FLAG_BE nor POWERPC_FLAG_DE\n");
9102 if (env
->msr_mask
& (1 << 2)) {
9103 switch (env
->flags
& (POWERPC_FLAG_PX
| POWERPC_FLAG_PMM
)) {
9104 case POWERPC_FLAG_PX
:
9105 case POWERPC_FLAG_PMM
:
9108 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9109 "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n");
9112 } else if (env
->flags
& (POWERPC_FLAG_PX
| POWERPC_FLAG_PMM
)) {
9113 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9114 "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
9117 if ((env
->flags
& (POWERPC_FLAG_RTC_CLK
| POWERPC_FLAG_BUS_CLK
)) == 0) {
9118 fprintf(stderr
, "PowerPC flags inconsistency\n"
9119 "Should define the time-base and decrementer clock source\n");
9122 /* Allocate TLBs buffer when needed */
9123 #if !defined(CONFIG_USER_ONLY)
9124 if (env
->nb_tlb
!= 0) {
9125 int nb_tlb
= env
->nb_tlb
;
9126 if (env
->id_tlbs
!= 0)
9128 switch (env
->tlb_type
) {
9130 env
->tlb
.tlb6
= g_malloc0(nb_tlb
* sizeof(ppc6xx_tlb_t
));
9133 env
->tlb
.tlbe
= g_malloc0(nb_tlb
* sizeof(ppcemb_tlb_t
));
9136 env
->tlb
.tlbm
= g_malloc0(nb_tlb
* sizeof(ppcmas_tlb_t
));
9139 /* Pre-compute some useful values */
9140 env
->tlb_per_way
= env
->nb_tlb
/ env
->nb_ways
;
9142 if (env
->irq_inputs
== NULL
) {
9143 warn_report("no internal IRQ controller registered."
9144 " Attempt QEMU to crash very soon !");
9147 if (env
->check_pow
== NULL
) {
9148 warn_report("no power management check handler registered."
9149 " Attempt QEMU to crash very soon !");
9153 #if defined(PPC_DUMP_CPU)
9154 static void dump_ppc_sprs(CPUPPCState
*env
)
9157 #if !defined(CONFIG_USER_ONLY)
9163 printf("Special purpose registers:\n");
9164 for (i
= 0; i
< 32; i
++) {
9165 for (j
= 0; j
< 32; j
++) {
9167 spr
= &env
->spr_cb
[n
];
9168 uw
= spr
->uea_write
!= NULL
&& spr
->uea_write
!= SPR_NOACCESS
;
9169 ur
= spr
->uea_read
!= NULL
&& spr
->uea_read
!= SPR_NOACCESS
;
9170 #if !defined(CONFIG_USER_ONLY)
9171 sw
= spr
->oea_write
!= NULL
&& spr
->oea_write
!= SPR_NOACCESS
;
9172 sr
= spr
->oea_read
!= NULL
&& spr
->oea_read
!= SPR_NOACCESS
;
9173 if (sw
|| sr
|| uw
|| ur
) {
9174 printf("SPR: %4d (%03x) %-8s s%c%c u%c%c\n",
9175 (i
<< 5) | j
, (i
<< 5) | j
, spr
->name
,
9176 sw
? 'w' : '-', sr
? 'r' : '-',
9177 uw
? 'w' : '-', ur
? 'r' : '-');
9181 printf("SPR: %4d (%03x) %-8s u%c%c\n",
9182 (i
<< 5) | j
, (i
<< 5) | j
, spr
->name
,
9183 uw
? 'w' : '-', ur
? 'r' : '-');
9193 /*****************************************************************************/
9197 PPC_DIRECT
= 0, /* Opcode routine */
9198 PPC_INDIRECT
= 1, /* Indirect opcode table */
9201 #define PPC_OPCODE_MASK 0x3
9203 static inline int is_indirect_opcode(void *handler
)
9205 return ((uintptr_t)handler
& PPC_OPCODE_MASK
) == PPC_INDIRECT
;
9208 static inline opc_handler_t
**ind_table(void *handler
)
9210 return (opc_handler_t
**)((uintptr_t)handler
& ~PPC_OPCODE_MASK
);
9213 /* Instruction table creation */
9214 /* Opcodes tables creation */
9215 static void fill_new_table(opc_handler_t
**table
, int len
)
9219 for (i
= 0; i
< len
; i
++)
9220 table
[i
] = &invalid_handler
;
9223 static int create_new_table(opc_handler_t
**table
, unsigned char idx
)
9225 opc_handler_t
**tmp
;
9227 tmp
= g_new(opc_handler_t
*, PPC_CPU_INDIRECT_OPCODES_LEN
);
9228 fill_new_table(tmp
, PPC_CPU_INDIRECT_OPCODES_LEN
);
9229 table
[idx
] = (opc_handler_t
*)((uintptr_t)tmp
| PPC_INDIRECT
);
9234 static int insert_in_table(opc_handler_t
**table
, unsigned char idx
,
9235 opc_handler_t
*handler
)
9237 if (table
[idx
] != &invalid_handler
)
9239 table
[idx
] = handler
;
9244 static int register_direct_insn(opc_handler_t
**ppc_opcodes
,
9245 unsigned char idx
, opc_handler_t
*handler
)
9247 if (insert_in_table(ppc_opcodes
, idx
, handler
) < 0) {
9248 printf("*** ERROR: opcode %02x already assigned in main "
9249 "opcode table\n", idx
);
9250 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9251 printf(" Registered handler '%s' - new handler '%s'\n",
9252 ppc_opcodes
[idx
]->oname
, handler
->oname
);
9260 static int register_ind_in_table(opc_handler_t
**table
,
9261 unsigned char idx1
, unsigned char idx2
,
9262 opc_handler_t
*handler
)
9264 if (table
[idx1
] == &invalid_handler
) {
9265 if (create_new_table(table
, idx1
) < 0) {
9266 printf("*** ERROR: unable to create indirect table "
9267 "idx=%02x\n", idx1
);
9271 if (!is_indirect_opcode(table
[idx1
])) {
9272 printf("*** ERROR: idx %02x already assigned to a direct "
9274 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9275 printf(" Registered handler '%s' - new handler '%s'\n",
9276 ind_table(table
[idx1
])[idx2
]->oname
, handler
->oname
);
9281 if (handler
!= NULL
&&
9282 insert_in_table(ind_table(table
[idx1
]), idx2
, handler
) < 0) {
9283 printf("*** ERROR: opcode %02x already assigned in "
9284 "opcode table %02x\n", idx2
, idx1
);
9285 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9286 printf(" Registered handler '%s' - new handler '%s'\n",
9287 ind_table(table
[idx1
])[idx2
]->oname
, handler
->oname
);
9295 static int register_ind_insn(opc_handler_t
**ppc_opcodes
,
9296 unsigned char idx1
, unsigned char idx2
,
9297 opc_handler_t
*handler
)
9299 return register_ind_in_table(ppc_opcodes
, idx1
, idx2
, handler
);
9302 static int register_dblind_insn(opc_handler_t
**ppc_opcodes
,
9303 unsigned char idx1
, unsigned char idx2
,
9304 unsigned char idx3
, opc_handler_t
*handler
)
9306 if (register_ind_in_table(ppc_opcodes
, idx1
, idx2
, NULL
) < 0) {
9307 printf("*** ERROR: unable to join indirect table idx "
9308 "[%02x-%02x]\n", idx1
, idx2
);
9311 if (register_ind_in_table(ind_table(ppc_opcodes
[idx1
]), idx2
, idx3
,
9313 printf("*** ERROR: unable to insert opcode "
9314 "[%02x-%02x-%02x]\n", idx1
, idx2
, idx3
);
9321 static int register_trplind_insn(opc_handler_t
**ppc_opcodes
,
9322 unsigned char idx1
, unsigned char idx2
,
9323 unsigned char idx3
, unsigned char idx4
,
9324 opc_handler_t
*handler
)
9326 opc_handler_t
**table
;
9328 if (register_ind_in_table(ppc_opcodes
, idx1
, idx2
, NULL
) < 0) {
9329 printf("*** ERROR: unable to join indirect table idx "
9330 "[%02x-%02x]\n", idx1
, idx2
);
9333 table
= ind_table(ppc_opcodes
[idx1
]);
9334 if (register_ind_in_table(table
, idx2
, idx3
, NULL
) < 0) {
9335 printf("*** ERROR: unable to join 2nd-level indirect table idx "
9336 "[%02x-%02x-%02x]\n", idx1
, idx2
, idx3
);
9339 table
= ind_table(table
[idx2
]);
9340 if (register_ind_in_table(table
, idx3
, idx4
, handler
) < 0) {
9341 printf("*** ERROR: unable to insert opcode "
9342 "[%02x-%02x-%02x-%02x]\n", idx1
, idx2
, idx3
, idx4
);
9347 static int register_insn(opc_handler_t
**ppc_opcodes
, opcode_t
*insn
)
9349 if (insn
->opc2
!= 0xFF) {
9350 if (insn
->opc3
!= 0xFF) {
9351 if (insn
->opc4
!= 0xFF) {
9352 if (register_trplind_insn(ppc_opcodes
, insn
->opc1
, insn
->opc2
,
9353 insn
->opc3
, insn
->opc4
,
9354 &insn
->handler
) < 0) {
9358 if (register_dblind_insn(ppc_opcodes
, insn
->opc1
, insn
->opc2
,
9359 insn
->opc3
, &insn
->handler
) < 0)
9363 if (register_ind_insn(ppc_opcodes
, insn
->opc1
,
9364 insn
->opc2
, &insn
->handler
) < 0)
9368 if (register_direct_insn(ppc_opcodes
, insn
->opc1
, &insn
->handler
) < 0)
9375 static int test_opcode_table(opc_handler_t
**table
, int len
)
9379 for (i
= 0, count
= 0; i
< len
; i
++) {
9380 /* Consistency fixup */
9381 if (table
[i
] == NULL
)
9382 table
[i
] = &invalid_handler
;
9383 if (table
[i
] != &invalid_handler
) {
9384 if (is_indirect_opcode(table
[i
])) {
9385 tmp
= test_opcode_table(ind_table(table
[i
]),
9386 PPC_CPU_INDIRECT_OPCODES_LEN
);
9389 table
[i
] = &invalid_handler
;
9402 static void fix_opcode_tables(opc_handler_t
**ppc_opcodes
)
9404 if (test_opcode_table(ppc_opcodes
, PPC_CPU_OPCODES_LEN
) == 0)
9405 printf("*** WARNING: no opcode defined !\n");
9408 /*****************************************************************************/
9409 static void create_ppc_opcodes(PowerPCCPU
*cpu
, Error
**errp
)
9411 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9412 CPUPPCState
*env
= &cpu
->env
;
9415 fill_new_table(env
->opcodes
, PPC_CPU_OPCODES_LEN
);
9416 for (opc
= opcodes
; opc
< &opcodes
[ARRAY_SIZE(opcodes
)]; opc
++) {
9417 if (((opc
->handler
.type
& pcc
->insns_flags
) != 0) ||
9418 ((opc
->handler
.type2
& pcc
->insns_flags2
) != 0)) {
9419 if (register_insn(env
->opcodes
, opc
) < 0) {
9420 error_setg(errp
, "ERROR initializing PowerPC instruction "
9421 "0x%02x 0x%02x 0x%02x", opc
->opc1
, opc
->opc2
,
9427 fix_opcode_tables(env
->opcodes
);
9432 #if defined(PPC_DUMP_CPU)
9433 static void dump_ppc_insns(CPUPPCState
*env
)
9435 opc_handler_t
**table
, *handler
;
9437 uint8_t opc1
, opc2
, opc3
, opc4
;
9439 printf("Instructions set:\n");
9440 /* opc1 is 6 bits long */
9441 for (opc1
= 0x00; opc1
< PPC_CPU_OPCODES_LEN
; opc1
++) {
9442 table
= env
->opcodes
;
9443 handler
= table
[opc1
];
9444 if (is_indirect_opcode(handler
)) {
9445 /* opc2 is 5 bits long */
9446 for (opc2
= 0; opc2
< PPC_CPU_INDIRECT_OPCODES_LEN
; opc2
++) {
9447 table
= env
->opcodes
;
9448 handler
= env
->opcodes
[opc1
];
9449 table
= ind_table(handler
);
9450 handler
= table
[opc2
];
9451 if (is_indirect_opcode(handler
)) {
9452 table
= ind_table(handler
);
9453 /* opc3 is 5 bits long */
9454 for (opc3
= 0; opc3
< PPC_CPU_INDIRECT_OPCODES_LEN
;
9456 handler
= table
[opc3
];
9457 if (is_indirect_opcode(handler
)) {
9458 table
= ind_table(handler
);
9459 /* opc4 is 5 bits long */
9460 for (opc4
= 0; opc4
< PPC_CPU_INDIRECT_OPCODES_LEN
;
9462 handler
= table
[opc4
];
9463 if (handler
->handler
!= &gen_invalid
) {
9464 printf("INSN: %02x %02x %02x %02x -- "
9465 "(%02d %04d %02d) : %s\n",
9466 opc1
, opc2
, opc3
, opc4
,
9467 opc1
, (opc3
<< 5) | opc2
, opc4
,
9472 if (handler
->handler
!= &gen_invalid
) {
9473 /* Special hack to properly dump SPE insns */
9474 p
= strchr(handler
->oname
, '_');
9476 printf("INSN: %02x %02x %02x (%02d %04d) : "
9478 opc1
, opc2
, opc3
, opc1
,
9483 if ((p
- handler
->oname
) != strlen(q
)
9484 || (memcmp(handler
->oname
, q
, strlen(q
))
9486 /* First instruction */
9487 printf("INSN: %02x %02x %02x"
9488 "(%02d %04d) : %.*s\n",
9489 opc1
, opc2
<< 1, opc3
, opc1
,
9490 (opc3
<< 6) | (opc2
<< 1),
9491 (int)(p
- handler
->oname
),
9494 if (strcmp(p
+ 1, q
) != 0) {
9495 /* Second instruction */
9496 printf("INSN: %02x %02x %02x "
9497 "(%02d %04d) : %s\n", opc1
,
9498 (opc2
<< 1) | 1, opc3
, opc1
,
9499 (opc3
<< 6) | (opc2
<< 1) | 1,
9507 if (handler
->handler
!= &gen_invalid
) {
9508 printf("INSN: %02x %02x -- (%02d %04d) : %s\n",
9509 opc1
, opc2
, opc1
, opc2
, handler
->oname
);
9514 if (handler
->handler
!= &gen_invalid
) {
9515 printf("INSN: %02x -- -- (%02d ----) : %s\n",
9516 opc1
, opc1
, handler
->oname
);
9523 static bool avr_need_swap(CPUPPCState
*env
)
9525 #ifdef HOST_WORDS_BIGENDIAN
9532 static int gdb_get_float_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9535 stfq_p(mem_buf
, env
->fpr
[n
]);
9536 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9540 stl_p(mem_buf
, env
->fpscr
);
9541 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9547 static int gdb_set_float_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9550 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9551 env
->fpr
[n
] = ldfq_p(mem_buf
);
9555 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9556 helper_store_fpscr(env
, ldl_p(mem_buf
), 0xffffffff);
9562 static int gdb_get_avr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9565 if (!avr_need_swap(env
)) {
9566 stq_p(mem_buf
, env
->avr
[n
].u64
[0]);
9567 stq_p(mem_buf
+8, env
->avr
[n
].u64
[1]);
9569 stq_p(mem_buf
, env
->avr
[n
].u64
[1]);
9570 stq_p(mem_buf
+8, env
->avr
[n
].u64
[0]);
9572 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9573 ppc_maybe_bswap_register(env
, mem_buf
+ 8, 8);
9577 stl_p(mem_buf
, env
->vscr
);
9578 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9582 stl_p(mem_buf
, (uint32_t)env
->spr
[SPR_VRSAVE
]);
9583 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9589 static int gdb_set_avr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9592 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9593 ppc_maybe_bswap_register(env
, mem_buf
+ 8, 8);
9594 if (!avr_need_swap(env
)) {
9595 env
->avr
[n
].u64
[0] = ldq_p(mem_buf
);
9596 env
->avr
[n
].u64
[1] = ldq_p(mem_buf
+8);
9598 env
->avr
[n
].u64
[1] = ldq_p(mem_buf
);
9599 env
->avr
[n
].u64
[0] = ldq_p(mem_buf
+8);
9604 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9605 env
->vscr
= ldl_p(mem_buf
);
9609 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9610 env
->spr
[SPR_VRSAVE
] = (target_ulong
)ldl_p(mem_buf
);
9616 static int gdb_get_spe_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9619 #if defined(TARGET_PPC64)
9620 stl_p(mem_buf
, env
->gpr
[n
] >> 32);
9621 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9623 stl_p(mem_buf
, env
->gprh
[n
]);
9628 stq_p(mem_buf
, env
->spe_acc
);
9629 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9633 stl_p(mem_buf
, env
->spe_fscr
);
9634 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9640 static int gdb_set_spe_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9643 #if defined(TARGET_PPC64)
9644 target_ulong lo
= (uint32_t)env
->gpr
[n
];
9647 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9649 hi
= (target_ulong
)ldl_p(mem_buf
) << 32;
9650 env
->gpr
[n
] = lo
| hi
;
9652 env
->gprh
[n
] = ldl_p(mem_buf
);
9657 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9658 env
->spe_acc
= ldq_p(mem_buf
);
9662 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9663 env
->spe_fscr
= ldl_p(mem_buf
);
9669 static int gdb_get_vsx_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9672 stq_p(mem_buf
, env
->vsr
[n
]);
9673 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9679 static int gdb_set_vsx_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9682 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9683 env
->vsr
[n
] = ldq_p(mem_buf
);
9689 static int ppc_fixup_cpu(PowerPCCPU
*cpu
)
9691 CPUPPCState
*env
= &cpu
->env
;
9693 /* TCG doesn't (yet) emulate some groups of instructions that
9694 * are implemented on some otherwise supported CPUs (e.g. VSX
9695 * and decimal floating point instructions on POWER7). We
9696 * remove unsupported instruction groups from the cpu state's
9697 * instruction masks and hope the guest can cope. For at
9698 * least the pseries machine, the unavailability of these
9699 * instructions can be advertised to the guest via the device
9701 if ((env
->insns_flags
& ~PPC_TCG_INSNS
)
9702 || (env
->insns_flags2
& ~PPC_TCG_INSNS2
)) {
9703 warn_report("Disabling some instructions which are not "
9704 "emulated by TCG (0x%" PRIx64
", 0x%" PRIx64
")",
9705 env
->insns_flags
& ~PPC_TCG_INSNS
,
9706 env
->insns_flags2
& ~PPC_TCG_INSNS2
);
9708 env
->insns_flags
&= PPC_TCG_INSNS
;
9709 env
->insns_flags2
&= PPC_TCG_INSNS2
;
9713 static inline bool ppc_cpu_is_valid(PowerPCCPUClass
*pcc
)
9715 #ifdef TARGET_PPCEMB
9716 return pcc
->mmu_model
== POWERPC_MMU_BOOKE
||
9717 pcc
->mmu_model
== POWERPC_MMU_SOFT_4xx
||
9718 pcc
->mmu_model
== POWERPC_MMU_SOFT_4xx_Z
;
9724 static void ppc_cpu_realizefn(DeviceState
*dev
, Error
**errp
)
9726 CPUState
*cs
= CPU(dev
);
9727 PowerPCCPU
*cpu
= POWERPC_CPU(dev
);
9728 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9729 Error
*local_err
= NULL
;
9731 cpu_exec_realizefn(cs
, &local_err
);
9732 if (local_err
!= NULL
) {
9733 error_propagate(errp
, local_err
);
9736 if (cpu
->vcpu_id
== UNASSIGNED_CPU_INDEX
) {
9737 cpu
->vcpu_id
= cs
->cpu_index
;
9740 if (tcg_enabled()) {
9741 if (ppc_fixup_cpu(cpu
) != 0) {
9742 error_setg(errp
, "Unable to emulate selected CPU with TCG");
9747 #if defined(TARGET_PPCEMB)
9748 if (!ppc_cpu_is_valid(pcc
)) {
9749 error_setg(errp
, "CPU does not possess a BookE or 4xx MMU. "
9750 "Please use qemu-system-ppc or qemu-system-ppc64 instead "
9751 "or choose another CPU model.");
9756 create_ppc_opcodes(cpu
, &local_err
);
9757 if (local_err
!= NULL
) {
9758 error_propagate(errp
, local_err
);
9763 if (pcc
->insns_flags
& PPC_FLOAT
) {
9764 gdb_register_coprocessor(cs
, gdb_get_float_reg
, gdb_set_float_reg
,
9765 33, "power-fpu.xml", 0);
9767 if (pcc
->insns_flags
& PPC_ALTIVEC
) {
9768 gdb_register_coprocessor(cs
, gdb_get_avr_reg
, gdb_set_avr_reg
,
9769 34, "power-altivec.xml", 0);
9771 if (pcc
->insns_flags
& PPC_SPE
) {
9772 gdb_register_coprocessor(cs
, gdb_get_spe_reg
, gdb_set_spe_reg
,
9773 34, "power-spe.xml", 0);
9775 if (pcc
->insns_flags2
& PPC2_VSX
) {
9776 gdb_register_coprocessor(cs
, gdb_get_vsx_reg
, gdb_set_vsx_reg
,
9777 32, "power-vsx.xml", 0);
9782 pcc
->parent_realize(dev
, errp
);
9784 #if defined(PPC_DUMP_CPU)
9786 CPUPPCState
*env
= &cpu
->env
;
9787 const char *mmu_model
, *excp_model
, *bus_model
;
9788 switch (env
->mmu_model
) {
9789 case POWERPC_MMU_32B
:
9790 mmu_model
= "PowerPC 32";
9792 case POWERPC_MMU_SOFT_6xx
:
9793 mmu_model
= "PowerPC 6xx/7xx with software driven TLBs";
9795 case POWERPC_MMU_SOFT_74xx
:
9796 mmu_model
= "PowerPC 74xx with software driven TLBs";
9798 case POWERPC_MMU_SOFT_4xx
:
9799 mmu_model
= "PowerPC 4xx with software driven TLBs";
9801 case POWERPC_MMU_SOFT_4xx_Z
:
9802 mmu_model
= "PowerPC 4xx with software driven TLBs "
9803 "and zones protections";
9805 case POWERPC_MMU_REAL
:
9806 mmu_model
= "PowerPC real mode only";
9808 case POWERPC_MMU_MPC8xx
:
9809 mmu_model
= "PowerPC MPC8xx";
9811 case POWERPC_MMU_BOOKE
:
9812 mmu_model
= "PowerPC BookE";
9814 case POWERPC_MMU_BOOKE206
:
9815 mmu_model
= "PowerPC BookE 2.06";
9817 case POWERPC_MMU_601
:
9818 mmu_model
= "PowerPC 601";
9820 #if defined(TARGET_PPC64)
9821 case POWERPC_MMU_64B
:
9822 mmu_model
= "PowerPC 64";
9826 mmu_model
= "Unknown or invalid";
9829 switch (env
->excp_model
) {
9830 case POWERPC_EXCP_STD
:
9831 excp_model
= "PowerPC";
9833 case POWERPC_EXCP_40x
:
9834 excp_model
= "PowerPC 40x";
9836 case POWERPC_EXCP_601
:
9837 excp_model
= "PowerPC 601";
9839 case POWERPC_EXCP_602
:
9840 excp_model
= "PowerPC 602";
9842 case POWERPC_EXCP_603
:
9843 excp_model
= "PowerPC 603";
9845 case POWERPC_EXCP_603E
:
9846 excp_model
= "PowerPC 603e";
9848 case POWERPC_EXCP_604
:
9849 excp_model
= "PowerPC 604";
9851 case POWERPC_EXCP_7x0
:
9852 excp_model
= "PowerPC 740/750";
9854 case POWERPC_EXCP_7x5
:
9855 excp_model
= "PowerPC 745/755";
9857 case POWERPC_EXCP_74xx
:
9858 excp_model
= "PowerPC 74xx";
9860 case POWERPC_EXCP_BOOKE
:
9861 excp_model
= "PowerPC BookE";
9863 #if defined(TARGET_PPC64)
9864 case POWERPC_EXCP_970
:
9865 excp_model
= "PowerPC 970";
9869 excp_model
= "Unknown or invalid";
9872 switch (env
->bus_model
) {
9873 case PPC_FLAGS_INPUT_6xx
:
9874 bus_model
= "PowerPC 6xx";
9876 case PPC_FLAGS_INPUT_BookE
:
9877 bus_model
= "PowerPC BookE";
9879 case PPC_FLAGS_INPUT_405
:
9880 bus_model
= "PowerPC 405";
9882 case PPC_FLAGS_INPUT_401
:
9883 bus_model
= "PowerPC 401/403";
9885 case PPC_FLAGS_INPUT_RCPU
:
9886 bus_model
= "RCPU / MPC8xx";
9888 #if defined(TARGET_PPC64)
9889 case PPC_FLAGS_INPUT_970
:
9890 bus_model
= "PowerPC 970";
9894 bus_model
= "Unknown or invalid";
9897 printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64
"\n"
9898 " MMU model : %s\n",
9899 object_class_get_name(OBJECT_CLASS(pcc
)),
9900 pcc
->pvr
, pcc
->msr_mask
, mmu_model
);
9901 #if !defined(CONFIG_USER_ONLY)
9902 if (env
->tlb
.tlb6
) {
9903 printf(" %d %s TLB in %d ways\n",
9904 env
->nb_tlb
, env
->id_tlbs
? "splitted" : "merged",
9908 printf(" Exceptions model : %s\n"
9909 " Bus model : %s\n",
9910 excp_model
, bus_model
);
9911 printf(" MSR features :\n");
9912 if (env
->flags
& POWERPC_FLAG_SPE
)
9913 printf(" signal processing engine enable"
9915 else if (env
->flags
& POWERPC_FLAG_VRE
)
9916 printf(" vector processor enable\n");
9917 if (env
->flags
& POWERPC_FLAG_TGPR
)
9918 printf(" temporary GPRs\n");
9919 else if (env
->flags
& POWERPC_FLAG_CE
)
9920 printf(" critical input enable\n");
9921 if (env
->flags
& POWERPC_FLAG_SE
)
9922 printf(" single-step trace mode\n");
9923 else if (env
->flags
& POWERPC_FLAG_DWE
)
9924 printf(" debug wait enable\n");
9925 else if (env
->flags
& POWERPC_FLAG_UBLE
)
9926 printf(" user BTB lock enable\n");
9927 if (env
->flags
& POWERPC_FLAG_BE
)
9928 printf(" branch-step trace mode\n");
9929 else if (env
->flags
& POWERPC_FLAG_DE
)
9930 printf(" debug interrupt enable\n");
9931 if (env
->flags
& POWERPC_FLAG_PX
)
9932 printf(" inclusive protection\n");
9933 else if (env
->flags
& POWERPC_FLAG_PMM
)
9934 printf(" performance monitor mark\n");
9935 if (env
->flags
== POWERPC_FLAG_NONE
)
9937 printf(" Time-base/decrementer clock source: %s\n",
9938 env
->flags
& POWERPC_FLAG_RTC_CLK
? "RTC clock" : "bus clock");
9939 dump_ppc_insns(env
);
9947 cpu_exec_unrealizefn(cs
);
9950 static void ppc_cpu_unrealizefn(DeviceState
*dev
, Error
**errp
)
9952 PowerPCCPU
*cpu
= POWERPC_CPU(dev
);
9953 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9954 CPUPPCState
*env
= &cpu
->env
;
9955 Error
*local_err
= NULL
;
9956 opc_handler_t
**table
, **table_2
;
9959 pcc
->parent_unrealize(dev
, &local_err
);
9960 if (local_err
!= NULL
) {
9961 error_propagate(errp
, local_err
);
9965 for (i
= 0; i
< PPC_CPU_OPCODES_LEN
; i
++) {
9966 if (env
->opcodes
[i
] == &invalid_handler
) {
9969 if (is_indirect_opcode(env
->opcodes
[i
])) {
9970 table
= ind_table(env
->opcodes
[i
]);
9971 for (j
= 0; j
< PPC_CPU_INDIRECT_OPCODES_LEN
; j
++) {
9972 if (table
[j
] == &invalid_handler
) {
9975 if (is_indirect_opcode(table
[j
])) {
9976 table_2
= ind_table(table
[j
]);
9977 for (k
= 0; k
< PPC_CPU_INDIRECT_OPCODES_LEN
; k
++) {
9978 if (table_2
[k
] != &invalid_handler
&&
9979 is_indirect_opcode(table_2
[k
])) {
9980 g_free((opc_handler_t
*)((uintptr_t)table_2
[k
] &
9984 g_free((opc_handler_t
*)((uintptr_t)table
[j
] &
9988 g_free((opc_handler_t
*)((uintptr_t)env
->opcodes
[i
] &
9994 static gint
ppc_cpu_compare_class_pvr(gconstpointer a
, gconstpointer b
)
9996 ObjectClass
*oc
= (ObjectClass
*)a
;
9997 uint32_t pvr
= *(uint32_t *)b
;
9998 PowerPCCPUClass
*pcc
= (PowerPCCPUClass
*)a
;
10000 /* -cpu host does a PVR lookup during construction */
10001 if (unlikely(strcmp(object_class_get_name(oc
),
10002 TYPE_HOST_POWERPC_CPU
) == 0)) {
10006 if (!ppc_cpu_is_valid(pcc
)) {
10010 return pcc
->pvr
== pvr
? 0 : -1;
10013 PowerPCCPUClass
*ppc_cpu_class_by_pvr(uint32_t pvr
)
10015 GSList
*list
, *item
;
10016 PowerPCCPUClass
*pcc
= NULL
;
10018 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10019 item
= g_slist_find_custom(list
, &pvr
, ppc_cpu_compare_class_pvr
);
10020 if (item
!= NULL
) {
10021 pcc
= POWERPC_CPU_CLASS(item
->data
);
10023 g_slist_free(list
);
10028 static gint
ppc_cpu_compare_class_pvr_mask(gconstpointer a
, gconstpointer b
)
10030 ObjectClass
*oc
= (ObjectClass
*)a
;
10031 uint32_t pvr
= *(uint32_t *)b
;
10032 PowerPCCPUClass
*pcc
= (PowerPCCPUClass
*)a
;
10034 /* -cpu host does a PVR lookup during construction */
10035 if (unlikely(strcmp(object_class_get_name(oc
),
10036 TYPE_HOST_POWERPC_CPU
) == 0)) {
10040 if (!ppc_cpu_is_valid(pcc
)) {
10044 if (pcc
->pvr_match(pcc
, pvr
)) {
10051 PowerPCCPUClass
*ppc_cpu_class_by_pvr_mask(uint32_t pvr
)
10053 GSList
*list
, *item
;
10054 PowerPCCPUClass
*pcc
= NULL
;
10056 list
= object_class_get_list(TYPE_POWERPC_CPU
, true);
10057 item
= g_slist_find_custom(list
, &pvr
, ppc_cpu_compare_class_pvr_mask
);
10058 if (item
!= NULL
) {
10059 pcc
= POWERPC_CPU_CLASS(item
->data
);
10061 g_slist_free(list
);
10066 static const char *ppc_cpu_lookup_alias(const char *alias
)
10070 for (ai
= 0; ppc_cpu_aliases
[ai
].alias
!= NULL
; ai
++) {
10071 if (strcmp(ppc_cpu_aliases
[ai
].alias
, alias
) == 0) {
10072 return ppc_cpu_aliases
[ai
].model
;
10079 static ObjectClass
*ppc_cpu_class_by_name(const char *name
)
10081 char *cpu_model
, *typename
;
10086 /* Lookup by PVR if cpu_model is valid 8 digit hex number
10087 * (excl: 0x prefix if present)
10089 if (!qemu_strtoul(name
, &p
, 16, &pvr
)) {
10090 int len
= p
- name
;
10091 len
= (len
== 10) && (name
[1] == 'x') ? len
- 2 : len
;
10092 if ((len
== 8) && (*p
== '\0')) {
10093 return OBJECT_CLASS(ppc_cpu_class_by_pvr(pvr
));
10097 cpu_model
= g_ascii_strdown(name
, -1);
10098 p
= ppc_cpu_lookup_alias(cpu_model
);
10101 cpu_model
= g_strdup(p
);
10104 typename
= g_strdup_printf("%s" POWERPC_CPU_TYPE_SUFFIX
, cpu_model
);
10105 oc
= object_class_by_name(typename
);
10109 if (oc
&& ppc_cpu_is_valid(POWERPC_CPU_CLASS(oc
))) {
10116 static void ppc_cpu_parse_featurestr(const char *type
, char *features
,
10119 Object
*machine
= qdev_get_machine();
10120 const PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(object_class_by_name(type
));
10126 if (object_property_find(machine
, "max-cpu-compat", NULL
)) {
10129 char *s
= features
;
10130 Error
*local_err
= NULL
;
10131 char *compat_str
= NULL
;
10134 * Backwards compatibility hack:
10136 * CPUs had a "compat=" property which didn't make sense for
10137 * anything except pseries. It was replaced by "max-cpu-compat"
10138 * machine option. This supports old command lines like
10139 * -cpu POWER8,compat=power7
10140 * By stripping the compat option and applying it to the machine
10141 * before passing it on to the cpu level parser.
10143 inpieces
= g_strsplit(features
, ",", 0);
10145 for (i
= 0; inpieces
[i
]; i
++) {
10146 if (g_str_has_prefix(inpieces
[i
], "compat=")) {
10147 compat_str
= inpieces
[i
];
10150 if ((i
!= 0) && (s
!= features
)) {
10151 s
= g_stpcpy(s
, ",");
10153 s
= g_stpcpy(s
, inpieces
[i
]);
10157 char *v
= compat_str
+ strlen("compat=");
10158 object_property_set_str(machine
, v
, "max-cpu-compat", &local_err
);
10160 g_strfreev(inpieces
);
10162 error_propagate(errp
, local_err
);
10167 /* do property processing with generic handler */
10168 pcc
->parent_parse_features(type
, features
, errp
);
10171 PowerPCCPUClass
*ppc_cpu_get_family_class(PowerPCCPUClass
*pcc
)
10173 ObjectClass
*oc
= OBJECT_CLASS(pcc
);
10175 while (oc
&& !object_class_is_abstract(oc
)) {
10176 oc
= object_class_get_parent(oc
);
10180 return POWERPC_CPU_CLASS(oc
);
10183 /* Sort by PVR, ordering special case "host" last. */
10184 static gint
ppc_cpu_list_compare(gconstpointer a
, gconstpointer b
)
10186 ObjectClass
*oc_a
= (ObjectClass
*)a
;
10187 ObjectClass
*oc_b
= (ObjectClass
*)b
;
10188 PowerPCCPUClass
*pcc_a
= POWERPC_CPU_CLASS(oc_a
);
10189 PowerPCCPUClass
*pcc_b
= POWERPC_CPU_CLASS(oc_b
);
10190 const char *name_a
= object_class_get_name(oc_a
);
10191 const char *name_b
= object_class_get_name(oc_b
);
10193 if (strcmp(name_a
, TYPE_HOST_POWERPC_CPU
) == 0) {
10195 } else if (strcmp(name_b
, TYPE_HOST_POWERPC_CPU
) == 0) {
10198 /* Avoid an integer overflow during subtraction */
10199 if (pcc_a
->pvr
< pcc_b
->pvr
) {
10201 } else if (pcc_a
->pvr
> pcc_b
->pvr
) {
10209 static void ppc_cpu_list_entry(gpointer data
, gpointer user_data
)
10211 ObjectClass
*oc
= data
;
10212 CPUListState
*s
= user_data
;
10213 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10214 DeviceClass
*family
= DEVICE_CLASS(ppc_cpu_get_family_class(pcc
));
10215 const char *typename
= object_class_get_name(oc
);
10219 if (!ppc_cpu_is_valid(pcc
)) {
10222 if (unlikely(strcmp(typename
, TYPE_HOST_POWERPC_CPU
) == 0)) {
10226 name
= g_strndup(typename
,
10227 strlen(typename
) - strlen(POWERPC_CPU_TYPE_SUFFIX
));
10228 (*s
->cpu_fprintf
)(s
->file
, "PowerPC %-16s PVR %08x\n",
10230 for (i
= 0; ppc_cpu_aliases
[i
].alias
!= NULL
; i
++) {
10231 PowerPCCPUAlias
*alias
= &ppc_cpu_aliases
[i
];
10232 ObjectClass
*alias_oc
= ppc_cpu_class_by_name(alias
->model
);
10234 if (alias_oc
!= oc
) {
10238 * If running with KVM, we might update the family alias later, so
10239 * avoid printing the wrong alias here and use "preferred" instead
10241 if (strcmp(alias
->alias
, family
->desc
) == 0) {
10242 (*s
->cpu_fprintf
)(s
->file
,
10243 "PowerPC %-16s (alias for preferred %s CPU)\n",
10244 alias
->alias
, family
->desc
);
10246 (*s
->cpu_fprintf
)(s
->file
, "PowerPC %-16s (alias for %s)\n",
10247 alias
->alias
, name
);
10253 void ppc_cpu_list(FILE *f
, fprintf_function cpu_fprintf
)
10257 .cpu_fprintf
= cpu_fprintf
,
10261 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10262 list
= g_slist_sort(list
, ppc_cpu_list_compare
);
10263 g_slist_foreach(list
, ppc_cpu_list_entry
, &s
);
10264 g_slist_free(list
);
10267 cpu_fprintf(f
, "\n");
10268 cpu_fprintf(f
, "PowerPC %-16s\n", "host");
10272 static void ppc_cpu_defs_entry(gpointer data
, gpointer user_data
)
10274 ObjectClass
*oc
= data
;
10275 CpuDefinitionInfoList
**first
= user_data
;
10276 const char *typename
;
10277 CpuDefinitionInfoList
*entry
;
10278 CpuDefinitionInfo
*info
;
10279 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10281 if (!ppc_cpu_is_valid(pcc
)) {
10285 typename
= object_class_get_name(oc
);
10286 info
= g_malloc0(sizeof(*info
));
10287 info
->name
= g_strndup(typename
,
10288 strlen(typename
) - strlen(POWERPC_CPU_TYPE_SUFFIX
));
10290 entry
= g_malloc0(sizeof(*entry
));
10291 entry
->value
= info
;
10292 entry
->next
= *first
;
10296 CpuDefinitionInfoList
*arch_query_cpu_definitions(Error
**errp
)
10298 CpuDefinitionInfoList
*cpu_list
= NULL
;
10302 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10303 g_slist_foreach(list
, ppc_cpu_defs_entry
, &cpu_list
);
10304 g_slist_free(list
);
10306 for (i
= 0; ppc_cpu_aliases
[i
].alias
!= NULL
; i
++) {
10307 PowerPCCPUAlias
*alias
= &ppc_cpu_aliases
[i
];
10309 CpuDefinitionInfoList
*entry
;
10310 CpuDefinitionInfo
*info
;
10312 oc
= ppc_cpu_class_by_name(alias
->model
);
10317 info
= g_malloc0(sizeof(*info
));
10318 info
->name
= g_strdup(alias
->alias
);
10319 info
->q_typename
= g_strdup(object_class_get_name(oc
));
10321 entry
= g_malloc0(sizeof(*entry
));
10322 entry
->value
= info
;
10323 entry
->next
= cpu_list
;
10330 static void ppc_cpu_set_pc(CPUState
*cs
, vaddr value
)
10332 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10334 cpu
->env
.nip
= value
;
10337 static bool ppc_cpu_has_work(CPUState
*cs
)
10339 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10340 CPUPPCState
*env
= &cpu
->env
;
10342 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
10345 /* CPUClass::reset() */
10346 static void ppc_cpu_reset(CPUState
*s
)
10348 PowerPCCPU
*cpu
= POWERPC_CPU(s
);
10349 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10350 CPUPPCState
*env
= &cpu
->env
;
10354 pcc
->parent_reset(s
);
10356 msr
= (target_ulong
)0;
10357 msr
|= (target_ulong
)MSR_HVB
;
10358 msr
|= (target_ulong
)0 << MSR_AP
; /* TO BE CHECKED */
10359 msr
|= (target_ulong
)0 << MSR_SA
; /* TO BE CHECKED */
10360 msr
|= (target_ulong
)1 << MSR_EP
;
10361 #if defined(DO_SINGLE_STEP) && 0
10362 /* Single step trace mode */
10363 msr
|= (target_ulong
)1 << MSR_SE
;
10364 msr
|= (target_ulong
)1 << MSR_BE
;
10366 #if defined(CONFIG_USER_ONLY)
10367 msr
|= (target_ulong
)1 << MSR_FP
; /* Allow floating point usage */
10368 msr
|= (target_ulong
)1 << MSR_VR
; /* Allow altivec usage */
10369 msr
|= (target_ulong
)1 << MSR_VSX
; /* Allow VSX usage */
10370 msr
|= (target_ulong
)1 << MSR_SPE
; /* Allow SPE usage */
10371 msr
|= (target_ulong
)1 << MSR_PR
;
10372 #if defined(TARGET_PPC64)
10373 msr
|= (target_ulong
)1 << MSR_TM
; /* Transactional memory */
10375 #if !defined(TARGET_WORDS_BIGENDIAN)
10376 msr
|= (target_ulong
)1 << MSR_LE
; /* Little-endian user mode */
10377 if (!((env
->msr_mask
>> MSR_LE
) & 1)) {
10378 fprintf(stderr
, "Selected CPU does not support little-endian.\n");
10384 #if defined(TARGET_PPC64)
10385 if (env
->mmu_model
& POWERPC_MMU_64
) {
10386 msr
|= (1ULL << MSR_SF
);
10390 hreg_store_msr(env
, msr
, 1);
10392 #if !defined(CONFIG_USER_ONLY)
10393 env
->nip
= env
->hreset_vector
| env
->excp_prefix
;
10394 if (env
->mmu_model
!= POWERPC_MMU_REAL
) {
10395 ppc_tlb_invalidate_all(env
);
10399 hreg_compute_hflags(env
);
10400 env
->reserve_addr
= (target_ulong
)-1ULL;
10401 /* Be sure no exception or interrupt is pending */
10402 env
->pending_interrupts
= 0;
10403 s
->exception_index
= POWERPC_EXCP_NONE
;
10404 env
->error_code
= 0;
10406 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
10408 env
->slb_shadow_addr
= 0;
10409 env
->slb_shadow_size
= 0;
10412 #endif /* TARGET_PPC64 */
10414 for (i
= 0; i
< ARRAY_SIZE(env
->spr_cb
); i
++) {
10415 ppc_spr_t
*spr
= &env
->spr_cb
[i
];
10420 env
->spr
[i
] = spr
->default_value
;
10424 #ifndef CONFIG_USER_ONLY
10425 static bool ppc_cpu_is_big_endian(CPUState
*cs
)
10427 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10428 CPUPPCState
*env
= &cpu
->env
;
10430 cpu_synchronize_state(cs
);
10436 static void ppc_cpu_initfn(Object
*obj
)
10438 CPUState
*cs
= CPU(obj
);
10439 PowerPCCPU
*cpu
= POWERPC_CPU(obj
);
10440 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10441 CPUPPCState
*env
= &cpu
->env
;
10444 cpu
->vcpu_id
= UNASSIGNED_CPU_INDEX
;
10446 env
->msr_mask
= pcc
->msr_mask
;
10447 env
->mmu_model
= pcc
->mmu_model
;
10448 env
->excp_model
= pcc
->excp_model
;
10449 env
->bus_model
= pcc
->bus_model
;
10450 env
->insns_flags
= pcc
->insns_flags
;
10451 env
->insns_flags2
= pcc
->insns_flags2
;
10452 env
->flags
= pcc
->flags
;
10453 env
->bfd_mach
= pcc
->bfd_mach
;
10454 env
->check_pow
= pcc
->check_pow
;
10456 /* Mark HV mode as supported if the CPU has an MSR_HV bit
10457 * in the msr_mask. The mask can later be cleared by PAPR
10458 * mode but the hv mode support will remain, thus enforcing
10459 * that we cannot use priv. instructions in guest in PAPR
10460 * mode. For 970 we currently simply don't set HV in msr_mask
10461 * thus simulating an "Apple mode" 970. If we ever want to
10462 * support 970 HV mode, we'll have to add a processor attribute
10465 #if !defined(CONFIG_USER_ONLY)
10466 env
->has_hv_mode
= !!(env
->msr_mask
& MSR_HVB
);
10469 #if defined(TARGET_PPC64)
10471 env
->sps
= *pcc
->sps
;
10472 } else if (env
->mmu_model
& POWERPC_MMU_64
) {
10473 /* Use default sets of page sizes. We don't support MPSS */
10474 static const struct ppc_segment_page_sizes defsps_4k
= {
10476 { .page_shift
= 12, /* 4K */
10478 .enc
= { { .page_shift
= 12, .pte_enc
= 0 } }
10480 { .page_shift
= 24, /* 16M */
10482 .enc
= { { .page_shift
= 24, .pte_enc
= 0 } }
10486 static const struct ppc_segment_page_sizes defsps_64k
= {
10488 { .page_shift
= 12, /* 4K */
10490 .enc
= { { .page_shift
= 12, .pte_enc
= 0 } }
10492 { .page_shift
= 16, /* 64K */
10494 .enc
= { { .page_shift
= 16, .pte_enc
= 1 } }
10496 { .page_shift
= 24, /* 16M */
10498 .enc
= { { .page_shift
= 24, .pte_enc
= 0 } }
10502 env
->sps
= (env
->mmu_model
& POWERPC_MMU_64K
) ? defsps_64k
: defsps_4k
;
10504 #endif /* defined(TARGET_PPC64) */
10507 static bool ppc_pvr_match_default(PowerPCCPUClass
*pcc
, uint32_t pvr
)
10509 return pcc
->pvr
== pvr
;
10512 static gchar
*ppc_gdb_arch_name(CPUState
*cs
)
10514 #if defined(TARGET_PPC64)
10515 return g_strdup("powerpc:common64");
10517 return g_strdup("powerpc:common");
10521 static void ppc_disas_set_info(CPUState
*cs
, disassemble_info
*info
)
10523 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10524 CPUPPCState
*env
= &cpu
->env
;
10526 if ((env
->hflags
>> MSR_LE
) & 1) {
10527 info
->endian
= BFD_ENDIAN_LITTLE
;
10529 info
->mach
= env
->bfd_mach
;
10530 if (!env
->bfd_mach
) {
10531 #ifdef TARGET_PPC64
10532 info
->mach
= bfd_mach_ppc64
;
10534 info
->mach
= bfd_mach_ppc
;
10537 info
->disassembler_options
= (char *)"any";
10538 info
->print_insn
= print_insn_ppc
;
10540 info
->cap_arch
= CS_ARCH_PPC
;
10541 #ifdef TARGET_PPC64
10542 info
->cap_mode
= CS_MODE_64
;
10546 static Property ppc_cpu_properties
[] = {
10547 DEFINE_PROP_BOOL("pre-2.8-migration", PowerPCCPU
, pre_2_8_migration
, false),
10548 DEFINE_PROP_BOOL("pre-2.10-migration", PowerPCCPU
, pre_2_10_migration
,
10550 DEFINE_PROP_END_OF_LIST(),
10553 static void ppc_cpu_class_init(ObjectClass
*oc
, void *data
)
10555 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10556 CPUClass
*cc
= CPU_CLASS(oc
);
10557 DeviceClass
*dc
= DEVICE_CLASS(oc
);
10559 pcc
->parent_realize
= dc
->realize
;
10560 pcc
->parent_unrealize
= dc
->unrealize
;
10561 pcc
->pvr_match
= ppc_pvr_match_default
;
10562 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_always
;
10563 dc
->realize
= ppc_cpu_realizefn
;
10564 dc
->unrealize
= ppc_cpu_unrealizefn
;
10565 dc
->props
= ppc_cpu_properties
;
10567 pcc
->parent_reset
= cc
->reset
;
10568 cc
->reset
= ppc_cpu_reset
;
10570 cc
->class_by_name
= ppc_cpu_class_by_name
;
10571 pcc
->parent_parse_features
= cc
->parse_features
;
10572 cc
->parse_features
= ppc_cpu_parse_featurestr
;
10573 cc
->has_work
= ppc_cpu_has_work
;
10574 cc
->do_interrupt
= ppc_cpu_do_interrupt
;
10575 cc
->cpu_exec_interrupt
= ppc_cpu_exec_interrupt
;
10576 cc
->dump_state
= ppc_cpu_dump_state
;
10577 cc
->dump_statistics
= ppc_cpu_dump_statistics
;
10578 cc
->set_pc
= ppc_cpu_set_pc
;
10579 cc
->gdb_read_register
= ppc_cpu_gdb_read_register
;
10580 cc
->gdb_write_register
= ppc_cpu_gdb_write_register
;
10581 #ifdef CONFIG_USER_ONLY
10582 cc
->handle_mmu_fault
= ppc_cpu_handle_mmu_fault
;
10584 cc
->get_phys_page_debug
= ppc_cpu_get_phys_page_debug
;
10585 cc
->vmsd
= &vmstate_ppc_cpu
;
10587 #if defined(CONFIG_SOFTMMU)
10588 cc
->write_elf64_note
= ppc64_cpu_write_elf64_note
;
10589 cc
->write_elf32_note
= ppc32_cpu_write_elf32_note
;
10592 cc
->gdb_num_core_regs
= 71;
10594 #ifdef USE_APPLE_GDB
10595 cc
->gdb_read_register
= ppc_cpu_gdb_read_register_apple
;
10596 cc
->gdb_write_register
= ppc_cpu_gdb_write_register_apple
;
10597 cc
->gdb_num_core_regs
= 71 + 32;
10600 cc
->gdb_arch_name
= ppc_gdb_arch_name
;
10601 #if defined(TARGET_PPC64)
10602 cc
->gdb_core_xml_file
= "power64-core.xml";
10604 cc
->gdb_core_xml_file
= "power-core.xml";
10606 #ifndef CONFIG_USER_ONLY
10607 cc
->virtio_is_big_endian
= ppc_cpu_is_big_endian
;
10610 cc
->tcg_initialize
= ppc_translate_init
;
10612 cc
->disas_set_info
= ppc_disas_set_info
;
10614 dc
->fw_name
= "PowerPC,UNKNOWN";
10617 static const TypeInfo ppc_cpu_type_info
= {
10618 .name
= TYPE_POWERPC_CPU
,
10619 .parent
= TYPE_CPU
,
10620 .instance_size
= sizeof(PowerPCCPU
),
10621 .instance_init
= ppc_cpu_initfn
,
10623 .class_size
= sizeof(PowerPCCPUClass
),
10624 .class_init
= ppc_cpu_class_init
,
10627 static const TypeInfo ppc_vhyp_type_info
= {
10628 .name
= TYPE_PPC_VIRTUAL_HYPERVISOR
,
10629 .parent
= TYPE_INTERFACE
,
10630 .class_size
= sizeof(PPCVirtualHypervisorClass
),
10633 static void ppc_cpu_register_types(void)
10635 type_register_static(&ppc_cpu_type_info
);
10636 type_register_static(&ppc_vhyp_type_info
);
10639 type_init(ppc_cpu_register_types
)