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 "disas/bfd.h"
22 #include "exec/gdbstub.h"
24 #include "sysemu/arch_init.h"
25 #include "sysemu/cpus.h"
26 #include "sysemu/hw_accel.h"
27 #include "cpu-models.h"
28 #include "mmu-hash32.h"
29 #include "mmu-hash64.h"
30 #include "qemu/error-report.h"
31 #include "qapi/error.h"
32 #include "qapi/qmp/qnull.h"
33 #include "qapi/visitor.h"
34 #include "hw/qdev-properties.h"
35 #include "hw/ppc/ppc.h"
36 #include "mmu-book3s-v3.h"
37 #include "sysemu/qtest.h"
38 #include "qemu/cutils.h"
39 #include "disas/capstone.h"
40 #include "fpu/softfloat.h"
42 //#define PPC_DUMP_CPU
43 //#define PPC_DEBUG_SPR
44 //#define PPC_DUMP_SPR_ACCESSES
45 /* #define USE_APPLE_GDB */
48 * do nothing but store/retrieve spr value
50 static void spr_load_dump_spr(int sprn
)
52 #ifdef PPC_DUMP_SPR_ACCESSES
53 TCGv_i32 t0
= tcg_const_i32(sprn
);
54 gen_helper_load_dump_spr(cpu_env
, t0
);
55 tcg_temp_free_i32(t0
);
59 static void spr_read_generic (DisasContext
*ctx
, int gprn
, int sprn
)
61 gen_load_spr(cpu_gpr
[gprn
], sprn
);
62 spr_load_dump_spr(sprn
);
65 static void spr_store_dump_spr(int sprn
)
67 #ifdef PPC_DUMP_SPR_ACCESSES
68 TCGv_i32 t0
= tcg_const_i32(sprn
);
69 gen_helper_store_dump_spr(cpu_env
, t0
);
70 tcg_temp_free_i32(t0
);
74 static void spr_write_generic(DisasContext
*ctx
, int sprn
, int gprn
)
76 gen_store_spr(sprn
, cpu_gpr
[gprn
]);
77 spr_store_dump_spr(sprn
);
80 #if !defined(CONFIG_USER_ONLY)
81 static void spr_write_generic32(DisasContext
*ctx
, int sprn
, int gprn
)
84 TCGv t0
= tcg_temp_new();
85 tcg_gen_ext32u_tl(t0
, cpu_gpr
[gprn
]);
86 gen_store_spr(sprn
, t0
);
88 spr_store_dump_spr(sprn
);
90 spr_write_generic(ctx
, sprn
, gprn
);
94 static void spr_write_clear(DisasContext
*ctx
, int sprn
, int gprn
)
96 TCGv t0
= tcg_temp_new();
97 TCGv t1
= tcg_temp_new();
98 gen_load_spr(t0
, sprn
);
99 tcg_gen_neg_tl(t1
, cpu_gpr
[gprn
]);
100 tcg_gen_and_tl(t0
, t0
, t1
);
101 gen_store_spr(sprn
, t0
);
106 static void spr_access_nop(DisasContext
*ctx
, int sprn
, int gprn
)
112 /* SPR common to all PowerPC */
114 static void spr_read_xer(DisasContext
*ctx
, int gprn
, int sprn
)
116 gen_read_xer(ctx
, cpu_gpr
[gprn
]);
119 static void spr_write_xer(DisasContext
*ctx
, int sprn
, int gprn
)
121 gen_write_xer(cpu_gpr
[gprn
]);
125 static void spr_read_lr(DisasContext
*ctx
, int gprn
, int sprn
)
127 tcg_gen_mov_tl(cpu_gpr
[gprn
], cpu_lr
);
130 static void spr_write_lr(DisasContext
*ctx
, int sprn
, int gprn
)
132 tcg_gen_mov_tl(cpu_lr
, cpu_gpr
[gprn
]);
136 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
137 static void spr_read_cfar(DisasContext
*ctx
, int gprn
, int sprn
)
139 tcg_gen_mov_tl(cpu_gpr
[gprn
], cpu_cfar
);
142 static void spr_write_cfar(DisasContext
*ctx
, int sprn
, int gprn
)
144 tcg_gen_mov_tl(cpu_cfar
, cpu_gpr
[gprn
]);
146 #endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
149 static void spr_read_ctr(DisasContext
*ctx
, int gprn
, int sprn
)
151 tcg_gen_mov_tl(cpu_gpr
[gprn
], cpu_ctr
);
154 static void spr_write_ctr(DisasContext
*ctx
, int sprn
, int gprn
)
156 tcg_gen_mov_tl(cpu_ctr
, cpu_gpr
[gprn
]);
159 /* User read access to SPR */
165 static void spr_read_ureg(DisasContext
*ctx
, int gprn
, int sprn
)
167 gen_load_spr(cpu_gpr
[gprn
], sprn
+ 0x10);
170 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
171 static void spr_write_ureg(DisasContext
*ctx
, int sprn
, int gprn
)
173 gen_store_spr(sprn
+ 0x10, cpu_gpr
[gprn
]);
177 /* SPR common to all non-embedded PowerPC */
179 #if !defined(CONFIG_USER_ONLY)
180 static void spr_read_decr(DisasContext
*ctx
, int gprn
, int sprn
)
182 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
185 gen_helper_load_decr(cpu_gpr
[gprn
], cpu_env
);
186 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
188 gen_stop_exception(ctx
);
192 static void spr_write_decr(DisasContext
*ctx
, int sprn
, int gprn
)
194 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
197 gen_helper_store_decr(cpu_env
, cpu_gpr
[gprn
]);
198 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
200 gen_stop_exception(ctx
);
205 /* SPR common to all non-embedded PowerPC, except 601 */
207 static void spr_read_tbl(DisasContext
*ctx
, int gprn
, int sprn
)
209 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
212 gen_helper_load_tbl(cpu_gpr
[gprn
], cpu_env
);
213 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
215 gen_stop_exception(ctx
);
219 static void spr_read_tbu(DisasContext
*ctx
, int gprn
, int sprn
)
221 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
224 gen_helper_load_tbu(cpu_gpr
[gprn
], cpu_env
);
225 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
227 gen_stop_exception(ctx
);
231 __attribute__ (( unused
))
232 static void spr_read_atbl(DisasContext
*ctx
, int gprn
, int sprn
)
234 gen_helper_load_atbl(cpu_gpr
[gprn
], cpu_env
);
237 __attribute__ (( unused
))
238 static void spr_read_atbu(DisasContext
*ctx
, int gprn
, int sprn
)
240 gen_helper_load_atbu(cpu_gpr
[gprn
], cpu_env
);
243 #if !defined(CONFIG_USER_ONLY)
244 static void spr_write_tbl(DisasContext
*ctx
, int sprn
, int gprn
)
246 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
249 gen_helper_store_tbl(cpu_env
, cpu_gpr
[gprn
]);
250 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
252 gen_stop_exception(ctx
);
256 static void spr_write_tbu(DisasContext
*ctx
, int sprn
, int gprn
)
258 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
261 gen_helper_store_tbu(cpu_env
, cpu_gpr
[gprn
]);
262 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
264 gen_stop_exception(ctx
);
268 __attribute__ (( unused
))
269 static void spr_write_atbl(DisasContext
*ctx
, int sprn
, int gprn
)
271 gen_helper_store_atbl(cpu_env
, cpu_gpr
[gprn
]);
274 __attribute__ (( unused
))
275 static void spr_write_atbu(DisasContext
*ctx
, int sprn
, int gprn
)
277 gen_helper_store_atbu(cpu_env
, cpu_gpr
[gprn
]);
280 #if defined(TARGET_PPC64)
281 __attribute__ (( unused
))
282 static void spr_read_purr(DisasContext
*ctx
, int gprn
, int sprn
)
284 gen_helper_load_purr(cpu_gpr
[gprn
], cpu_env
);
288 static void spr_read_hdecr(DisasContext
*ctx
, int gprn
, int sprn
)
290 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
293 gen_helper_load_hdecr(cpu_gpr
[gprn
], cpu_env
);
294 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
296 gen_stop_exception(ctx
);
300 static void spr_write_hdecr(DisasContext
*ctx
, int sprn
, int gprn
)
302 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
305 gen_helper_store_hdecr(cpu_env
, cpu_gpr
[gprn
]);
306 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
308 gen_stop_exception(ctx
);
315 #if !defined(CONFIG_USER_ONLY)
316 /* IBAT0U...IBAT0U */
317 /* IBAT0L...IBAT7L */
318 static void spr_read_ibat(DisasContext
*ctx
, int gprn
, int sprn
)
320 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, IBAT
[sprn
& 1][(sprn
- SPR_IBAT0U
) / 2]));
323 static void spr_read_ibat_h(DisasContext
*ctx
, int gprn
, int sprn
)
325 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, IBAT
[sprn
& 1][((sprn
- SPR_IBAT4U
) / 2) + 4]));
328 static void spr_write_ibatu(DisasContext
*ctx
, int sprn
, int gprn
)
330 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0U
) / 2);
331 gen_helper_store_ibatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
332 tcg_temp_free_i32(t0
);
335 static void spr_write_ibatu_h(DisasContext
*ctx
, int sprn
, int gprn
)
337 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_IBAT4U
) / 2) + 4);
338 gen_helper_store_ibatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
339 tcg_temp_free_i32(t0
);
342 static void spr_write_ibatl(DisasContext
*ctx
, int sprn
, int gprn
)
344 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0L
) / 2);
345 gen_helper_store_ibatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
346 tcg_temp_free_i32(t0
);
349 static void spr_write_ibatl_h(DisasContext
*ctx
, int sprn
, int gprn
)
351 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_IBAT4L
) / 2) + 4);
352 gen_helper_store_ibatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
353 tcg_temp_free_i32(t0
);
356 /* DBAT0U...DBAT7U */
357 /* DBAT0L...DBAT7L */
358 static void spr_read_dbat(DisasContext
*ctx
, int gprn
, int sprn
)
360 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, DBAT
[sprn
& 1][(sprn
- SPR_DBAT0U
) / 2]));
363 static void spr_read_dbat_h(DisasContext
*ctx
, int gprn
, int sprn
)
365 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, DBAT
[sprn
& 1][((sprn
- SPR_DBAT4U
) / 2) + 4]));
368 static void spr_write_dbatu(DisasContext
*ctx
, int sprn
, int gprn
)
370 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_DBAT0U
) / 2);
371 gen_helper_store_dbatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
372 tcg_temp_free_i32(t0
);
375 static void spr_write_dbatu_h(DisasContext
*ctx
, int sprn
, int gprn
)
377 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_DBAT4U
) / 2) + 4);
378 gen_helper_store_dbatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
379 tcg_temp_free_i32(t0
);
382 static void spr_write_dbatl(DisasContext
*ctx
, int sprn
, int gprn
)
384 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_DBAT0L
) / 2);
385 gen_helper_store_dbatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
386 tcg_temp_free_i32(t0
);
389 static void spr_write_dbatl_h(DisasContext
*ctx
, int sprn
, int gprn
)
391 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_DBAT4L
) / 2) + 4);
392 gen_helper_store_dbatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
393 tcg_temp_free_i32(t0
);
397 static void spr_write_sdr1(DisasContext
*ctx
, int sprn
, int gprn
)
399 gen_helper_store_sdr1(cpu_env
, cpu_gpr
[gprn
]);
402 #if defined(TARGET_PPC64)
403 /* 64 bits PowerPC specific SPRs */
405 static void spr_write_pidr(DisasContext
*ctx
, int sprn
, int gprn
)
407 gen_helper_store_pidr(cpu_env
, cpu_gpr
[gprn
]);
410 static void spr_read_hior(DisasContext
*ctx
, int gprn
, int sprn
)
412 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, excp_prefix
));
415 static void spr_write_hior(DisasContext
*ctx
, int sprn
, int gprn
)
417 TCGv t0
= tcg_temp_new();
418 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], 0x3FFFFF00000ULL
);
419 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_prefix
));
422 static void spr_write_ptcr(DisasContext
*ctx
, int sprn
, int gprn
)
424 gen_helper_store_ptcr(cpu_env
, cpu_gpr
[gprn
]);
427 static void spr_write_pcr(DisasContext
*ctx
, int sprn
, int gprn
)
429 gen_helper_store_pcr(cpu_env
, cpu_gpr
[gprn
]);
434 /* PowerPC 601 specific registers */
436 static void spr_read_601_rtcl(DisasContext
*ctx
, int gprn
, int sprn
)
438 gen_helper_load_601_rtcl(cpu_gpr
[gprn
], cpu_env
);
441 static void spr_read_601_rtcu(DisasContext
*ctx
, int gprn
, int sprn
)
443 gen_helper_load_601_rtcu(cpu_gpr
[gprn
], cpu_env
);
446 #if !defined(CONFIG_USER_ONLY)
447 static void spr_write_601_rtcu(DisasContext
*ctx
, int sprn
, int gprn
)
449 gen_helper_store_601_rtcu(cpu_env
, cpu_gpr
[gprn
]);
452 static void spr_write_601_rtcl(DisasContext
*ctx
, int sprn
, int gprn
)
454 gen_helper_store_601_rtcl(cpu_env
, cpu_gpr
[gprn
]);
457 static void spr_write_hid0_601(DisasContext
*ctx
, int sprn
, int gprn
)
459 gen_helper_store_hid0_601(cpu_env
, cpu_gpr
[gprn
]);
460 /* Must stop the translation as endianness may have changed */
461 gen_stop_exception(ctx
);
466 #if !defined(CONFIG_USER_ONLY)
467 static void spr_read_601_ubat(DisasContext
*ctx
, int gprn
, int sprn
)
469 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, IBAT
[sprn
& 1][(sprn
- SPR_IBAT0U
) / 2]));
472 static void spr_write_601_ubatu(DisasContext
*ctx
, int sprn
, int gprn
)
474 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0U
) / 2);
475 gen_helper_store_601_batl(cpu_env
, t0
, cpu_gpr
[gprn
]);
476 tcg_temp_free_i32(t0
);
479 static void spr_write_601_ubatl(DisasContext
*ctx
, int sprn
, int gprn
)
481 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0U
) / 2);
482 gen_helper_store_601_batu(cpu_env
, t0
, cpu_gpr
[gprn
]);
483 tcg_temp_free_i32(t0
);
487 /* PowerPC 40x specific registers */
488 #if !defined(CONFIG_USER_ONLY)
489 static void spr_read_40x_pit(DisasContext
*ctx
, int gprn
, int sprn
)
491 gen_helper_load_40x_pit(cpu_gpr
[gprn
], cpu_env
);
494 static void spr_write_40x_pit(DisasContext
*ctx
, int sprn
, int gprn
)
496 gen_helper_store_40x_pit(cpu_env
, cpu_gpr
[gprn
]);
499 static void spr_write_40x_dbcr0(DisasContext
*ctx
, int sprn
, int gprn
)
501 gen_helper_store_40x_dbcr0(cpu_env
, cpu_gpr
[gprn
]);
502 /* We must stop translation as we may have rebooted */
503 gen_stop_exception(ctx
);
506 static void spr_write_40x_sler(DisasContext
*ctx
, int sprn
, int gprn
)
508 gen_helper_store_40x_sler(cpu_env
, cpu_gpr
[gprn
]);
511 static void spr_write_booke_tcr(DisasContext
*ctx
, int sprn
, int gprn
)
513 gen_helper_store_booke_tcr(cpu_env
, cpu_gpr
[gprn
]);
516 static void spr_write_booke_tsr(DisasContext
*ctx
, int sprn
, int gprn
)
518 gen_helper_store_booke_tsr(cpu_env
, cpu_gpr
[gprn
]);
522 /* PowerPC 403 specific registers */
523 /* PBL1 / PBU1 / PBL2 / PBU2 */
524 #if !defined(CONFIG_USER_ONLY)
525 static void spr_read_403_pbr(DisasContext
*ctx
, int gprn
, int sprn
)
527 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, pb
[sprn
- SPR_403_PBL1
]));
530 static void spr_write_403_pbr(DisasContext
*ctx
, int sprn
, int gprn
)
532 TCGv_i32 t0
= tcg_const_i32(sprn
- SPR_403_PBL1
);
533 gen_helper_store_403_pbr(cpu_env
, t0
, cpu_gpr
[gprn
]);
534 tcg_temp_free_i32(t0
);
537 static void spr_write_pir(DisasContext
*ctx
, int sprn
, int gprn
)
539 TCGv t0
= tcg_temp_new();
540 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], 0xF);
541 gen_store_spr(SPR_PIR
, t0
);
546 /* SPE specific registers */
547 static void spr_read_spefscr(DisasContext
*ctx
, int gprn
, int sprn
)
549 TCGv_i32 t0
= tcg_temp_new_i32();
550 tcg_gen_ld_i32(t0
, cpu_env
, offsetof(CPUPPCState
, spe_fscr
));
551 tcg_gen_extu_i32_tl(cpu_gpr
[gprn
], t0
);
552 tcg_temp_free_i32(t0
);
555 static void spr_write_spefscr(DisasContext
*ctx
, int sprn
, int gprn
)
557 TCGv_i32 t0
= tcg_temp_new_i32();
558 tcg_gen_trunc_tl_i32(t0
, cpu_gpr
[gprn
]);
559 tcg_gen_st_i32(t0
, cpu_env
, offsetof(CPUPPCState
, spe_fscr
));
560 tcg_temp_free_i32(t0
);
563 #if !defined(CONFIG_USER_ONLY)
564 /* Callback used to write the exception vector base */
565 static void spr_write_excp_prefix(DisasContext
*ctx
, int sprn
, int gprn
)
567 TCGv t0
= tcg_temp_new();
568 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUPPCState
, ivpr_mask
));
569 tcg_gen_and_tl(t0
, t0
, cpu_gpr
[gprn
]);
570 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_prefix
));
571 gen_store_spr(sprn
, t0
);
575 static void spr_write_excp_vector(DisasContext
*ctx
, int sprn
, int gprn
)
579 if (sprn
>= SPR_BOOKE_IVOR0
&& sprn
<= SPR_BOOKE_IVOR15
) {
580 sprn_offs
= sprn
- SPR_BOOKE_IVOR0
;
581 } else if (sprn
>= SPR_BOOKE_IVOR32
&& sprn
<= SPR_BOOKE_IVOR37
) {
582 sprn_offs
= sprn
- SPR_BOOKE_IVOR32
+ 32;
583 } else if (sprn
>= SPR_BOOKE_IVOR38
&& sprn
<= SPR_BOOKE_IVOR42
) {
584 sprn_offs
= sprn
- SPR_BOOKE_IVOR38
+ 38;
586 printf("Trying to write an unknown exception vector %d %03x\n",
588 gen_inval_exception(ctx
, POWERPC_EXCP_PRIV_REG
);
592 TCGv t0
= tcg_temp_new();
593 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUPPCState
, ivor_mask
));
594 tcg_gen_and_tl(t0
, t0
, cpu_gpr
[gprn
]);
595 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_vectors
[sprn_offs
]));
596 gen_store_spr(sprn
, t0
);
601 static inline void vscr_init(CPUPPCState
*env
, uint32_t val
)
604 /* Altivec always uses round-to-nearest */
605 set_float_rounding_mode(float_round_nearest_even
, &env
->vec_status
);
606 set_flush_to_zero(vscr_nj
, &env
->vec_status
);
609 #ifdef CONFIG_USER_ONLY
610 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
611 oea_read, oea_write, one_reg_id, initial_value) \
612 _spr_register(env, num, name, uea_read, uea_write, initial_value)
613 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
614 oea_read, oea_write, hea_read, hea_write, \
615 one_reg_id, initial_value) \
616 _spr_register(env, num, name, uea_read, uea_write, initial_value)
618 #if !defined(CONFIG_KVM)
619 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
620 oea_read, oea_write, one_reg_id, initial_value) \
621 _spr_register(env, num, name, uea_read, uea_write, \
622 oea_read, oea_write, oea_read, oea_write, 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, initial_value)
629 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
630 oea_read, oea_write, one_reg_id, initial_value) \
631 _spr_register(env, num, name, uea_read, uea_write, \
632 oea_read, oea_write, oea_read, oea_write, \
633 one_reg_id, initial_value)
634 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
635 oea_read, oea_write, hea_read, hea_write, \
636 one_reg_id, initial_value) \
637 _spr_register(env, num, name, uea_read, uea_write, \
638 oea_read, oea_write, hea_read, hea_write, \
639 one_reg_id, initial_value)
643 #define spr_register(env, num, name, uea_read, uea_write, \
644 oea_read, oea_write, initial_value) \
645 spr_register_kvm(env, num, name, uea_read, uea_write, \
646 oea_read, oea_write, 0, initial_value)
648 #define spr_register_hv(env, num, name, uea_read, uea_write, \
649 oea_read, oea_write, hea_read, hea_write, \
651 spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
652 oea_read, oea_write, hea_read, hea_write, \
655 static inline void _spr_register(CPUPPCState
*env
, int num
,
657 void (*uea_read
)(DisasContext
*ctx
, int gprn
, int sprn
),
658 void (*uea_write
)(DisasContext
*ctx
, int sprn
, int gprn
),
659 #if !defined(CONFIG_USER_ONLY)
661 void (*oea_read
)(DisasContext
*ctx
, int gprn
, int sprn
),
662 void (*oea_write
)(DisasContext
*ctx
, int sprn
, int gprn
),
663 void (*hea_read
)(DisasContext
*opaque
, int gprn
, int sprn
),
664 void (*hea_write
)(DisasContext
*opaque
, int sprn
, int gprn
),
666 #if defined(CONFIG_KVM)
669 target_ulong initial_value
)
673 spr
= &env
->spr_cb
[num
];
674 if (spr
->name
!= NULL
||env
-> spr
[num
] != 0x00000000 ||
675 #if !defined(CONFIG_USER_ONLY)
676 spr
->oea_read
!= NULL
|| spr
->oea_write
!= NULL
||
678 spr
->uea_read
!= NULL
|| spr
->uea_write
!= NULL
) {
679 printf("Error: Trying to register SPR %d (%03x) twice !\n", num
, num
);
682 #if defined(PPC_DEBUG_SPR)
683 printf("*** register spr %d (%03x) %s val " TARGET_FMT_lx
"\n", num
, num
,
684 name
, initial_value
);
687 spr
->uea_read
= uea_read
;
688 spr
->uea_write
= uea_write
;
689 #if !defined(CONFIG_USER_ONLY)
690 spr
->oea_read
= oea_read
;
691 spr
->oea_write
= oea_write
;
692 spr
->hea_read
= hea_read
;
693 spr
->hea_write
= hea_write
;
695 #if defined(CONFIG_KVM)
696 spr
->one_reg_id
= one_reg_id
,
698 env
->spr
[num
] = spr
->default_value
= initial_value
;
701 /* Generic PowerPC SPRs */
702 static void gen_spr_generic(CPUPPCState
*env
)
704 /* Integer processing */
705 spr_register(env
, SPR_XER
, "XER",
706 &spr_read_xer
, &spr_write_xer
,
707 &spr_read_xer
, &spr_write_xer
,
710 spr_register(env
, SPR_LR
, "LR",
711 &spr_read_lr
, &spr_write_lr
,
712 &spr_read_lr
, &spr_write_lr
,
714 spr_register(env
, SPR_CTR
, "CTR",
715 &spr_read_ctr
, &spr_write_ctr
,
716 &spr_read_ctr
, &spr_write_ctr
,
718 /* Interrupt processing */
719 spr_register(env
, SPR_SRR0
, "SRR0",
720 SPR_NOACCESS
, SPR_NOACCESS
,
721 &spr_read_generic
, &spr_write_generic
,
723 spr_register(env
, SPR_SRR1
, "SRR1",
724 SPR_NOACCESS
, SPR_NOACCESS
,
725 &spr_read_generic
, &spr_write_generic
,
727 /* Processor control */
728 spr_register(env
, SPR_SPRG0
, "SPRG0",
729 SPR_NOACCESS
, SPR_NOACCESS
,
730 &spr_read_generic
, &spr_write_generic
,
732 spr_register(env
, SPR_SPRG1
, "SPRG1",
733 SPR_NOACCESS
, SPR_NOACCESS
,
734 &spr_read_generic
, &spr_write_generic
,
736 spr_register(env
, SPR_SPRG2
, "SPRG2",
737 SPR_NOACCESS
, SPR_NOACCESS
,
738 &spr_read_generic
, &spr_write_generic
,
740 spr_register(env
, SPR_SPRG3
, "SPRG3",
741 SPR_NOACCESS
, SPR_NOACCESS
,
742 &spr_read_generic
, &spr_write_generic
,
746 /* SPR common to all non-embedded PowerPC, including 601 */
747 static void gen_spr_ne_601(CPUPPCState
*env
)
749 /* Exception processing */
750 spr_register_kvm(env
, SPR_DSISR
, "DSISR",
751 SPR_NOACCESS
, SPR_NOACCESS
,
752 &spr_read_generic
, &spr_write_generic
,
753 KVM_REG_PPC_DSISR
, 0x00000000);
754 spr_register_kvm(env
, SPR_DAR
, "DAR",
755 SPR_NOACCESS
, SPR_NOACCESS
,
756 &spr_read_generic
, &spr_write_generic
,
757 KVM_REG_PPC_DAR
, 0x00000000);
759 spr_register(env
, SPR_DECR
, "DECR",
760 SPR_NOACCESS
, SPR_NOACCESS
,
761 &spr_read_decr
, &spr_write_decr
,
765 /* Storage Description Register 1 */
766 static void gen_spr_sdr1(CPUPPCState
*env
)
768 #ifndef CONFIG_USER_ONLY
769 if (env
->has_hv_mode
) {
770 /* SDR1 is a hypervisor resource on CPUs which have a
772 spr_register_hv(env
, SPR_SDR1
, "SDR1",
773 SPR_NOACCESS
, SPR_NOACCESS
,
774 SPR_NOACCESS
, SPR_NOACCESS
,
775 &spr_read_generic
, &spr_write_sdr1
,
778 spr_register(env
, SPR_SDR1
, "SDR1",
779 SPR_NOACCESS
, SPR_NOACCESS
,
780 &spr_read_generic
, &spr_write_sdr1
,
787 static void gen_low_BATs(CPUPPCState
*env
)
789 #if !defined(CONFIG_USER_ONLY)
790 spr_register(env
, SPR_IBAT0U
, "IBAT0U",
791 SPR_NOACCESS
, SPR_NOACCESS
,
792 &spr_read_ibat
, &spr_write_ibatu
,
794 spr_register(env
, SPR_IBAT0L
, "IBAT0L",
795 SPR_NOACCESS
, SPR_NOACCESS
,
796 &spr_read_ibat
, &spr_write_ibatl
,
798 spr_register(env
, SPR_IBAT1U
, "IBAT1U",
799 SPR_NOACCESS
, SPR_NOACCESS
,
800 &spr_read_ibat
, &spr_write_ibatu
,
802 spr_register(env
, SPR_IBAT1L
, "IBAT1L",
803 SPR_NOACCESS
, SPR_NOACCESS
,
804 &spr_read_ibat
, &spr_write_ibatl
,
806 spr_register(env
, SPR_IBAT2U
, "IBAT2U",
807 SPR_NOACCESS
, SPR_NOACCESS
,
808 &spr_read_ibat
, &spr_write_ibatu
,
810 spr_register(env
, SPR_IBAT2L
, "IBAT2L",
811 SPR_NOACCESS
, SPR_NOACCESS
,
812 &spr_read_ibat
, &spr_write_ibatl
,
814 spr_register(env
, SPR_IBAT3U
, "IBAT3U",
815 SPR_NOACCESS
, SPR_NOACCESS
,
816 &spr_read_ibat
, &spr_write_ibatu
,
818 spr_register(env
, SPR_IBAT3L
, "IBAT3L",
819 SPR_NOACCESS
, SPR_NOACCESS
,
820 &spr_read_ibat
, &spr_write_ibatl
,
822 spr_register(env
, SPR_DBAT0U
, "DBAT0U",
823 SPR_NOACCESS
, SPR_NOACCESS
,
824 &spr_read_dbat
, &spr_write_dbatu
,
826 spr_register(env
, SPR_DBAT0L
, "DBAT0L",
827 SPR_NOACCESS
, SPR_NOACCESS
,
828 &spr_read_dbat
, &spr_write_dbatl
,
830 spr_register(env
, SPR_DBAT1U
, "DBAT1U",
831 SPR_NOACCESS
, SPR_NOACCESS
,
832 &spr_read_dbat
, &spr_write_dbatu
,
834 spr_register(env
, SPR_DBAT1L
, "DBAT1L",
835 SPR_NOACCESS
, SPR_NOACCESS
,
836 &spr_read_dbat
, &spr_write_dbatl
,
838 spr_register(env
, SPR_DBAT2U
, "DBAT2U",
839 SPR_NOACCESS
, SPR_NOACCESS
,
840 &spr_read_dbat
, &spr_write_dbatu
,
842 spr_register(env
, SPR_DBAT2L
, "DBAT2L",
843 SPR_NOACCESS
, SPR_NOACCESS
,
844 &spr_read_dbat
, &spr_write_dbatl
,
846 spr_register(env
, SPR_DBAT3U
, "DBAT3U",
847 SPR_NOACCESS
, SPR_NOACCESS
,
848 &spr_read_dbat
, &spr_write_dbatu
,
850 spr_register(env
, SPR_DBAT3L
, "DBAT3L",
851 SPR_NOACCESS
, SPR_NOACCESS
,
852 &spr_read_dbat
, &spr_write_dbatl
,
859 static void gen_high_BATs(CPUPPCState
*env
)
861 #if !defined(CONFIG_USER_ONLY)
862 spr_register(env
, SPR_IBAT4U
, "IBAT4U",
863 SPR_NOACCESS
, SPR_NOACCESS
,
864 &spr_read_ibat_h
, &spr_write_ibatu_h
,
866 spr_register(env
, SPR_IBAT4L
, "IBAT4L",
867 SPR_NOACCESS
, SPR_NOACCESS
,
868 &spr_read_ibat_h
, &spr_write_ibatl_h
,
870 spr_register(env
, SPR_IBAT5U
, "IBAT5U",
871 SPR_NOACCESS
, SPR_NOACCESS
,
872 &spr_read_ibat_h
, &spr_write_ibatu_h
,
874 spr_register(env
, SPR_IBAT5L
, "IBAT5L",
875 SPR_NOACCESS
, SPR_NOACCESS
,
876 &spr_read_ibat_h
, &spr_write_ibatl_h
,
878 spr_register(env
, SPR_IBAT6U
, "IBAT6U",
879 SPR_NOACCESS
, SPR_NOACCESS
,
880 &spr_read_ibat_h
, &spr_write_ibatu_h
,
882 spr_register(env
, SPR_IBAT6L
, "IBAT6L",
883 SPR_NOACCESS
, SPR_NOACCESS
,
884 &spr_read_ibat_h
, &spr_write_ibatl_h
,
886 spr_register(env
, SPR_IBAT7U
, "IBAT7U",
887 SPR_NOACCESS
, SPR_NOACCESS
,
888 &spr_read_ibat_h
, &spr_write_ibatu_h
,
890 spr_register(env
, SPR_IBAT7L
, "IBAT7L",
891 SPR_NOACCESS
, SPR_NOACCESS
,
892 &spr_read_ibat_h
, &spr_write_ibatl_h
,
894 spr_register(env
, SPR_DBAT4U
, "DBAT4U",
895 SPR_NOACCESS
, SPR_NOACCESS
,
896 &spr_read_dbat_h
, &spr_write_dbatu_h
,
898 spr_register(env
, SPR_DBAT4L
, "DBAT4L",
899 SPR_NOACCESS
, SPR_NOACCESS
,
900 &spr_read_dbat_h
, &spr_write_dbatl_h
,
902 spr_register(env
, SPR_DBAT5U
, "DBAT5U",
903 SPR_NOACCESS
, SPR_NOACCESS
,
904 &spr_read_dbat_h
, &spr_write_dbatu_h
,
906 spr_register(env
, SPR_DBAT5L
, "DBAT5L",
907 SPR_NOACCESS
, SPR_NOACCESS
,
908 &spr_read_dbat_h
, &spr_write_dbatl_h
,
910 spr_register(env
, SPR_DBAT6U
, "DBAT6U",
911 SPR_NOACCESS
, SPR_NOACCESS
,
912 &spr_read_dbat_h
, &spr_write_dbatu_h
,
914 spr_register(env
, SPR_DBAT6L
, "DBAT6L",
915 SPR_NOACCESS
, SPR_NOACCESS
,
916 &spr_read_dbat_h
, &spr_write_dbatl_h
,
918 spr_register(env
, SPR_DBAT7U
, "DBAT7U",
919 SPR_NOACCESS
, SPR_NOACCESS
,
920 &spr_read_dbat_h
, &spr_write_dbatu_h
,
922 spr_register(env
, SPR_DBAT7L
, "DBAT7L",
923 SPR_NOACCESS
, SPR_NOACCESS
,
924 &spr_read_dbat_h
, &spr_write_dbatl_h
,
930 /* Generic PowerPC time base */
931 static void gen_tbl(CPUPPCState
*env
)
933 spr_register(env
, SPR_VTBL
, "TBL",
934 &spr_read_tbl
, SPR_NOACCESS
,
935 &spr_read_tbl
, SPR_NOACCESS
,
937 spr_register(env
, SPR_TBL
, "TBL",
938 &spr_read_tbl
, SPR_NOACCESS
,
939 &spr_read_tbl
, &spr_write_tbl
,
941 spr_register(env
, SPR_VTBU
, "TBU",
942 &spr_read_tbu
, SPR_NOACCESS
,
943 &spr_read_tbu
, SPR_NOACCESS
,
945 spr_register(env
, SPR_TBU
, "TBU",
946 &spr_read_tbu
, SPR_NOACCESS
,
947 &spr_read_tbu
, &spr_write_tbu
,
951 /* Softare table search registers */
952 static void gen_6xx_7xx_soft_tlb(CPUPPCState
*env
, int nb_tlbs
, int nb_ways
)
954 #if !defined(CONFIG_USER_ONLY)
955 env
->nb_tlb
= nb_tlbs
;
956 env
->nb_ways
= nb_ways
;
958 env
->tlb_type
= TLB_6XX
;
959 spr_register(env
, SPR_DMISS
, "DMISS",
960 SPR_NOACCESS
, SPR_NOACCESS
,
961 &spr_read_generic
, SPR_NOACCESS
,
963 spr_register(env
, SPR_DCMP
, "DCMP",
964 SPR_NOACCESS
, SPR_NOACCESS
,
965 &spr_read_generic
, SPR_NOACCESS
,
967 spr_register(env
, SPR_HASH1
, "HASH1",
968 SPR_NOACCESS
, SPR_NOACCESS
,
969 &spr_read_generic
, SPR_NOACCESS
,
971 spr_register(env
, SPR_HASH2
, "HASH2",
972 SPR_NOACCESS
, SPR_NOACCESS
,
973 &spr_read_generic
, SPR_NOACCESS
,
975 spr_register(env
, SPR_IMISS
, "IMISS",
976 SPR_NOACCESS
, SPR_NOACCESS
,
977 &spr_read_generic
, SPR_NOACCESS
,
979 spr_register(env
, SPR_ICMP
, "ICMP",
980 SPR_NOACCESS
, SPR_NOACCESS
,
981 &spr_read_generic
, SPR_NOACCESS
,
983 spr_register(env
, SPR_RPA
, "RPA",
984 SPR_NOACCESS
, SPR_NOACCESS
,
985 &spr_read_generic
, &spr_write_generic
,
990 /* SPR common to MPC755 and G2 */
991 static void gen_spr_G2_755(CPUPPCState
*env
)
994 spr_register(env
, SPR_SPRG4
, "SPRG4",
995 SPR_NOACCESS
, SPR_NOACCESS
,
996 &spr_read_generic
, &spr_write_generic
,
998 spr_register(env
, SPR_SPRG5
, "SPRG5",
999 SPR_NOACCESS
, SPR_NOACCESS
,
1000 &spr_read_generic
, &spr_write_generic
,
1002 spr_register(env
, SPR_SPRG6
, "SPRG6",
1003 SPR_NOACCESS
, SPR_NOACCESS
,
1004 &spr_read_generic
, &spr_write_generic
,
1006 spr_register(env
, SPR_SPRG7
, "SPRG7",
1007 SPR_NOACCESS
, SPR_NOACCESS
,
1008 &spr_read_generic
, &spr_write_generic
,
1012 /* SPR common to all 7xx PowerPC implementations */
1013 static void gen_spr_7xx(CPUPPCState
*env
)
1016 /* XXX : not implemented */
1017 spr_register_kvm(env
, SPR_DABR
, "DABR",
1018 SPR_NOACCESS
, SPR_NOACCESS
,
1019 &spr_read_generic
, &spr_write_generic
,
1020 KVM_REG_PPC_DABR
, 0x00000000);
1021 /* XXX : not implemented */
1022 spr_register(env
, SPR_IABR
, "IABR",
1023 SPR_NOACCESS
, SPR_NOACCESS
,
1024 &spr_read_generic
, &spr_write_generic
,
1026 /* Cache management */
1027 /* XXX : not implemented */
1028 spr_register(env
, SPR_ICTC
, "ICTC",
1029 SPR_NOACCESS
, SPR_NOACCESS
,
1030 &spr_read_generic
, &spr_write_generic
,
1032 /* Performance monitors */
1033 /* XXX : not implemented */
1034 spr_register(env
, SPR_7XX_MMCR0
, "MMCR0",
1035 SPR_NOACCESS
, SPR_NOACCESS
,
1036 &spr_read_generic
, &spr_write_generic
,
1038 /* XXX : not implemented */
1039 spr_register(env
, SPR_7XX_MMCR1
, "MMCR1",
1040 SPR_NOACCESS
, SPR_NOACCESS
,
1041 &spr_read_generic
, &spr_write_generic
,
1043 /* XXX : not implemented */
1044 spr_register(env
, SPR_7XX_PMC1
, "PMC1",
1045 SPR_NOACCESS
, SPR_NOACCESS
,
1046 &spr_read_generic
, &spr_write_generic
,
1048 /* XXX : not implemented */
1049 spr_register(env
, SPR_7XX_PMC2
, "PMC2",
1050 SPR_NOACCESS
, SPR_NOACCESS
,
1051 &spr_read_generic
, &spr_write_generic
,
1053 /* XXX : not implemented */
1054 spr_register(env
, SPR_7XX_PMC3
, "PMC3",
1055 SPR_NOACCESS
, SPR_NOACCESS
,
1056 &spr_read_generic
, &spr_write_generic
,
1058 /* XXX : not implemented */
1059 spr_register(env
, SPR_7XX_PMC4
, "PMC4",
1060 SPR_NOACCESS
, SPR_NOACCESS
,
1061 &spr_read_generic
, &spr_write_generic
,
1063 /* XXX : not implemented */
1064 spr_register(env
, SPR_7XX_SIAR
, "SIAR",
1065 SPR_NOACCESS
, SPR_NOACCESS
,
1066 &spr_read_generic
, SPR_NOACCESS
,
1068 /* XXX : not implemented */
1069 spr_register(env
, SPR_7XX_UMMCR0
, "UMMCR0",
1070 &spr_read_ureg
, SPR_NOACCESS
,
1071 &spr_read_ureg
, SPR_NOACCESS
,
1073 /* XXX : not implemented */
1074 spr_register(env
, SPR_7XX_UMMCR1
, "UMMCR1",
1075 &spr_read_ureg
, SPR_NOACCESS
,
1076 &spr_read_ureg
, SPR_NOACCESS
,
1078 /* XXX : not implemented */
1079 spr_register(env
, SPR_7XX_UPMC1
, "UPMC1",
1080 &spr_read_ureg
, SPR_NOACCESS
,
1081 &spr_read_ureg
, SPR_NOACCESS
,
1083 /* XXX : not implemented */
1084 spr_register(env
, SPR_7XX_UPMC2
, "UPMC2",
1085 &spr_read_ureg
, SPR_NOACCESS
,
1086 &spr_read_ureg
, SPR_NOACCESS
,
1088 /* XXX : not implemented */
1089 spr_register(env
, SPR_7XX_UPMC3
, "UPMC3",
1090 &spr_read_ureg
, SPR_NOACCESS
,
1091 &spr_read_ureg
, SPR_NOACCESS
,
1093 /* XXX : not implemented */
1094 spr_register(env
, SPR_7XX_UPMC4
, "UPMC4",
1095 &spr_read_ureg
, SPR_NOACCESS
,
1096 &spr_read_ureg
, SPR_NOACCESS
,
1098 /* XXX : not implemented */
1099 spr_register(env
, SPR_7XX_USIAR
, "USIAR",
1100 &spr_read_ureg
, SPR_NOACCESS
,
1101 &spr_read_ureg
, SPR_NOACCESS
,
1103 /* External access control */
1104 /* XXX : not implemented */
1105 spr_register(env
, SPR_EAR
, "EAR",
1106 SPR_NOACCESS
, SPR_NOACCESS
,
1107 &spr_read_generic
, &spr_write_generic
,
1112 #ifndef CONFIG_USER_ONLY
1113 static void spr_write_amr(DisasContext
*ctx
, int sprn
, int gprn
)
1115 TCGv t0
= tcg_temp_new();
1116 TCGv t1
= tcg_temp_new();
1117 TCGv t2
= tcg_temp_new();
1119 /* Note, the HV=1 PR=0 case is handled earlier by simply using
1120 * spr_write_generic for HV mode in the SPR table
1123 /* Build insertion mask into t1 based on context */
1125 gen_load_spr(t1
, SPR_UAMOR
);
1127 gen_load_spr(t1
, SPR_AMOR
);
1130 /* Mask new bits into t2 */
1131 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1133 /* Load AMR and clear new bits in t0 */
1134 gen_load_spr(t0
, SPR_AMR
);
1135 tcg_gen_andc_tl(t0
, t0
, t1
);
1137 /* Or'in new bits and write it out */
1138 tcg_gen_or_tl(t0
, t0
, t2
);
1139 gen_store_spr(SPR_AMR
, t0
);
1140 spr_store_dump_spr(SPR_AMR
);
1147 static void spr_write_uamor(DisasContext
*ctx
, int sprn
, int gprn
)
1149 TCGv t0
= tcg_temp_new();
1150 TCGv t1
= tcg_temp_new();
1151 TCGv t2
= tcg_temp_new();
1153 /* Note, the HV=1 case is handled earlier by simply using
1154 * spr_write_generic for HV mode in the SPR table
1157 /* Build insertion mask into t1 based on context */
1158 gen_load_spr(t1
, SPR_AMOR
);
1160 /* Mask new bits into t2 */
1161 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1163 /* Load AMR and clear new bits in t0 */
1164 gen_load_spr(t0
, SPR_UAMOR
);
1165 tcg_gen_andc_tl(t0
, t0
, t1
);
1167 /* Or'in new bits and write it out */
1168 tcg_gen_or_tl(t0
, t0
, t2
);
1169 gen_store_spr(SPR_UAMOR
, t0
);
1170 spr_store_dump_spr(SPR_UAMOR
);
1177 static void spr_write_iamr(DisasContext
*ctx
, int sprn
, int gprn
)
1179 TCGv t0
= tcg_temp_new();
1180 TCGv t1
= tcg_temp_new();
1181 TCGv t2
= tcg_temp_new();
1183 /* Note, the HV=1 case is handled earlier by simply using
1184 * spr_write_generic for HV mode in the SPR table
1187 /* Build insertion mask into t1 based on context */
1188 gen_load_spr(t1
, SPR_AMOR
);
1190 /* Mask new bits into t2 */
1191 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1193 /* Load AMR and clear new bits in t0 */
1194 gen_load_spr(t0
, SPR_IAMR
);
1195 tcg_gen_andc_tl(t0
, t0
, t1
);
1197 /* Or'in new bits and write it out */
1198 tcg_gen_or_tl(t0
, t0
, t2
);
1199 gen_store_spr(SPR_IAMR
, t0
);
1200 spr_store_dump_spr(SPR_IAMR
);
1206 #endif /* CONFIG_USER_ONLY */
1208 static void gen_spr_amr(CPUPPCState
*env
)
1210 #ifndef CONFIG_USER_ONLY
1211 /* Virtual Page Class Key protection */
1212 /* The AMR is accessible either via SPR 13 or SPR 29. 13 is
1213 * userspace accessible, 29 is privileged. So we only need to set
1214 * the kvm ONE_REG id on one of them, we use 29 */
1215 spr_register(env
, SPR_UAMR
, "UAMR",
1216 &spr_read_generic
, &spr_write_amr
,
1217 &spr_read_generic
, &spr_write_amr
,
1219 spr_register_kvm_hv(env
, SPR_AMR
, "AMR",
1220 SPR_NOACCESS
, SPR_NOACCESS
,
1221 &spr_read_generic
, &spr_write_amr
,
1222 &spr_read_generic
, &spr_write_generic
,
1223 KVM_REG_PPC_AMR
, 0);
1224 spr_register_kvm_hv(env
, SPR_UAMOR
, "UAMOR",
1225 SPR_NOACCESS
, SPR_NOACCESS
,
1226 &spr_read_generic
, &spr_write_uamor
,
1227 &spr_read_generic
, &spr_write_generic
,
1228 KVM_REG_PPC_UAMOR
, 0);
1229 spr_register_hv(env
, SPR_AMOR
, "AMOR",
1230 SPR_NOACCESS
, SPR_NOACCESS
,
1231 SPR_NOACCESS
, SPR_NOACCESS
,
1232 &spr_read_generic
, &spr_write_generic
,
1234 #endif /* !CONFIG_USER_ONLY */
1237 static void gen_spr_iamr(CPUPPCState
*env
)
1239 #ifndef CONFIG_USER_ONLY
1240 spr_register_kvm_hv(env
, SPR_IAMR
, "IAMR",
1241 SPR_NOACCESS
, SPR_NOACCESS
,
1242 &spr_read_generic
, &spr_write_iamr
,
1243 &spr_read_generic
, &spr_write_generic
,
1244 KVM_REG_PPC_IAMR
, 0);
1245 #endif /* !CONFIG_USER_ONLY */
1247 #endif /* TARGET_PPC64 */
1249 #ifndef CONFIG_USER_ONLY
1250 static void spr_read_thrm(DisasContext
*ctx
, int gprn
, int sprn
)
1252 gen_helper_fixup_thrm(cpu_env
);
1253 gen_load_spr(cpu_gpr
[gprn
], sprn
);
1254 spr_load_dump_spr(sprn
);
1256 #endif /* !CONFIG_USER_ONLY */
1258 static void gen_spr_thrm(CPUPPCState
*env
)
1260 /* Thermal management */
1261 /* XXX : not implemented */
1262 spr_register(env
, SPR_THRM1
, "THRM1",
1263 SPR_NOACCESS
, SPR_NOACCESS
,
1264 &spr_read_thrm
, &spr_write_generic
,
1266 /* XXX : not implemented */
1267 spr_register(env
, SPR_THRM2
, "THRM2",
1268 SPR_NOACCESS
, SPR_NOACCESS
,
1269 &spr_read_thrm
, &spr_write_generic
,
1271 /* XXX : not implemented */
1272 spr_register(env
, SPR_THRM3
, "THRM3",
1273 SPR_NOACCESS
, SPR_NOACCESS
,
1274 &spr_read_thrm
, &spr_write_generic
,
1278 /* SPR specific to PowerPC 604 implementation */
1279 static void gen_spr_604(CPUPPCState
*env
)
1281 /* Processor identification */
1282 spr_register(env
, SPR_PIR
, "PIR",
1283 SPR_NOACCESS
, SPR_NOACCESS
,
1284 &spr_read_generic
, &spr_write_pir
,
1287 /* XXX : not implemented */
1288 spr_register(env
, SPR_IABR
, "IABR",
1289 SPR_NOACCESS
, SPR_NOACCESS
,
1290 &spr_read_generic
, &spr_write_generic
,
1292 /* XXX : not implemented */
1293 spr_register_kvm(env
, SPR_DABR
, "DABR",
1294 SPR_NOACCESS
, SPR_NOACCESS
,
1295 &spr_read_generic
, &spr_write_generic
,
1296 KVM_REG_PPC_DABR
, 0x00000000);
1297 /* Performance counters */
1298 /* XXX : not implemented */
1299 spr_register(env
, SPR_7XX_MMCR0
, "MMCR0",
1300 SPR_NOACCESS
, SPR_NOACCESS
,
1301 &spr_read_generic
, &spr_write_generic
,
1303 /* XXX : not implemented */
1304 spr_register(env
, SPR_7XX_PMC1
, "PMC1",
1305 SPR_NOACCESS
, SPR_NOACCESS
,
1306 &spr_read_generic
, &spr_write_generic
,
1308 /* XXX : not implemented */
1309 spr_register(env
, SPR_7XX_PMC2
, "PMC2",
1310 SPR_NOACCESS
, SPR_NOACCESS
,
1311 &spr_read_generic
, &spr_write_generic
,
1313 /* XXX : not implemented */
1314 spr_register(env
, SPR_7XX_SIAR
, "SIAR",
1315 SPR_NOACCESS
, SPR_NOACCESS
,
1316 &spr_read_generic
, SPR_NOACCESS
,
1318 /* XXX : not implemented */
1319 spr_register(env
, SPR_SDA
, "SDA",
1320 SPR_NOACCESS
, SPR_NOACCESS
,
1321 &spr_read_generic
, SPR_NOACCESS
,
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
,
1331 /* SPR specific to PowerPC 603 implementation */
1332 static void gen_spr_603(CPUPPCState
*env
)
1334 /* External access control */
1335 /* XXX : not implemented */
1336 spr_register(env
, SPR_EAR
, "EAR",
1337 SPR_NOACCESS
, SPR_NOACCESS
,
1338 &spr_read_generic
, &spr_write_generic
,
1341 /* XXX : not implemented */
1342 spr_register(env
, SPR_IABR
, "IABR",
1343 SPR_NOACCESS
, SPR_NOACCESS
,
1344 &spr_read_generic
, &spr_write_generic
,
1349 /* SPR specific to PowerPC G2 implementation */
1350 static void gen_spr_G2(CPUPPCState
*env
)
1352 /* Memory base address */
1354 /* XXX : not implemented */
1355 spr_register(env
, SPR_MBAR
, "MBAR",
1356 SPR_NOACCESS
, SPR_NOACCESS
,
1357 &spr_read_generic
, &spr_write_generic
,
1359 /* Exception processing */
1360 spr_register(env
, SPR_BOOKE_CSRR0
, "CSRR0",
1361 SPR_NOACCESS
, SPR_NOACCESS
,
1362 &spr_read_generic
, &spr_write_generic
,
1364 spr_register(env
, SPR_BOOKE_CSRR1
, "CSRR1",
1365 SPR_NOACCESS
, SPR_NOACCESS
,
1366 &spr_read_generic
, &spr_write_generic
,
1369 /* XXX : not implemented */
1370 spr_register(env
, SPR_DABR
, "DABR",
1371 SPR_NOACCESS
, SPR_NOACCESS
,
1372 &spr_read_generic
, &spr_write_generic
,
1374 /* XXX : not implemented */
1375 spr_register(env
, SPR_DABR2
, "DABR2",
1376 SPR_NOACCESS
, SPR_NOACCESS
,
1377 &spr_read_generic
, &spr_write_generic
,
1379 /* XXX : not implemented */
1380 spr_register(env
, SPR_IABR
, "IABR",
1381 SPR_NOACCESS
, SPR_NOACCESS
,
1382 &spr_read_generic
, &spr_write_generic
,
1384 /* XXX : not implemented */
1385 spr_register(env
, SPR_IABR2
, "IABR2",
1386 SPR_NOACCESS
, SPR_NOACCESS
,
1387 &spr_read_generic
, &spr_write_generic
,
1389 /* XXX : not implemented */
1390 spr_register(env
, SPR_IBCR
, "IBCR",
1391 SPR_NOACCESS
, SPR_NOACCESS
,
1392 &spr_read_generic
, &spr_write_generic
,
1394 /* XXX : not implemented */
1395 spr_register(env
, SPR_DBCR
, "DBCR",
1396 SPR_NOACCESS
, SPR_NOACCESS
,
1397 &spr_read_generic
, &spr_write_generic
,
1401 /* SPR specific to PowerPC 602 implementation */
1402 static void gen_spr_602(CPUPPCState
*env
)
1405 /* XXX : not implemented */
1406 spr_register(env
, SPR_SER
, "SER",
1407 SPR_NOACCESS
, SPR_NOACCESS
,
1408 &spr_read_generic
, &spr_write_generic
,
1410 /* XXX : not implemented */
1411 spr_register(env
, SPR_SEBR
, "SEBR",
1412 SPR_NOACCESS
, SPR_NOACCESS
,
1413 &spr_read_generic
, &spr_write_generic
,
1415 /* XXX : not implemented */
1416 spr_register(env
, SPR_ESASRR
, "ESASRR",
1417 SPR_NOACCESS
, SPR_NOACCESS
,
1418 &spr_read_generic
, &spr_write_generic
,
1420 /* Floating point status */
1421 /* XXX : not implemented */
1422 spr_register(env
, SPR_SP
, "SP",
1423 SPR_NOACCESS
, SPR_NOACCESS
,
1424 &spr_read_generic
, &spr_write_generic
,
1426 /* XXX : not implemented */
1427 spr_register(env
, SPR_LT
, "LT",
1428 SPR_NOACCESS
, SPR_NOACCESS
,
1429 &spr_read_generic
, &spr_write_generic
,
1431 /* Watchdog timer */
1432 /* XXX : not implemented */
1433 spr_register(env
, SPR_TCR
, "TCR",
1434 SPR_NOACCESS
, SPR_NOACCESS
,
1435 &spr_read_generic
, &spr_write_generic
,
1437 /* Interrupt base */
1438 spr_register(env
, SPR_IBR
, "IBR",
1439 SPR_NOACCESS
, SPR_NOACCESS
,
1440 &spr_read_generic
, &spr_write_generic
,
1442 /* XXX : not implemented */
1443 spr_register(env
, SPR_IABR
, "IABR",
1444 SPR_NOACCESS
, SPR_NOACCESS
,
1445 &spr_read_generic
, &spr_write_generic
,
1449 /* SPR specific to PowerPC 601 implementation */
1450 static void gen_spr_601(CPUPPCState
*env
)
1452 /* Multiplication/division register */
1454 spr_register(env
, SPR_MQ
, "MQ",
1455 &spr_read_generic
, &spr_write_generic
,
1456 &spr_read_generic
, &spr_write_generic
,
1459 spr_register(env
, SPR_601_RTCU
, "RTCU",
1460 SPR_NOACCESS
, SPR_NOACCESS
,
1461 SPR_NOACCESS
, &spr_write_601_rtcu
,
1463 spr_register(env
, SPR_601_VRTCU
, "RTCU",
1464 &spr_read_601_rtcu
, SPR_NOACCESS
,
1465 &spr_read_601_rtcu
, SPR_NOACCESS
,
1467 spr_register(env
, SPR_601_RTCL
, "RTCL",
1468 SPR_NOACCESS
, SPR_NOACCESS
,
1469 SPR_NOACCESS
, &spr_write_601_rtcl
,
1471 spr_register(env
, SPR_601_VRTCL
, "RTCL",
1472 &spr_read_601_rtcl
, SPR_NOACCESS
,
1473 &spr_read_601_rtcl
, SPR_NOACCESS
,
1477 spr_register(env
, SPR_601_UDECR
, "UDECR",
1478 &spr_read_decr
, SPR_NOACCESS
,
1479 &spr_read_decr
, SPR_NOACCESS
,
1482 /* External access control */
1483 /* XXX : not implemented */
1484 spr_register(env
, SPR_EAR
, "EAR",
1485 SPR_NOACCESS
, SPR_NOACCESS
,
1486 &spr_read_generic
, &spr_write_generic
,
1488 /* Memory management */
1489 #if !defined(CONFIG_USER_ONLY)
1490 spr_register(env
, SPR_IBAT0U
, "IBAT0U",
1491 SPR_NOACCESS
, SPR_NOACCESS
,
1492 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1494 spr_register(env
, SPR_IBAT0L
, "IBAT0L",
1495 SPR_NOACCESS
, SPR_NOACCESS
,
1496 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1498 spr_register(env
, SPR_IBAT1U
, "IBAT1U",
1499 SPR_NOACCESS
, SPR_NOACCESS
,
1500 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1502 spr_register(env
, SPR_IBAT1L
, "IBAT1L",
1503 SPR_NOACCESS
, SPR_NOACCESS
,
1504 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1506 spr_register(env
, SPR_IBAT2U
, "IBAT2U",
1507 SPR_NOACCESS
, SPR_NOACCESS
,
1508 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1510 spr_register(env
, SPR_IBAT2L
, "IBAT2L",
1511 SPR_NOACCESS
, SPR_NOACCESS
,
1512 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1514 spr_register(env
, SPR_IBAT3U
, "IBAT3U",
1515 SPR_NOACCESS
, SPR_NOACCESS
,
1516 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1518 spr_register(env
, SPR_IBAT3L
, "IBAT3L",
1519 SPR_NOACCESS
, SPR_NOACCESS
,
1520 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1526 static void gen_spr_74xx(CPUPPCState
*env
)
1528 /* Processor identification */
1529 spr_register(env
, SPR_PIR
, "PIR",
1530 SPR_NOACCESS
, SPR_NOACCESS
,
1531 &spr_read_generic
, &spr_write_pir
,
1533 /* XXX : not implemented */
1534 spr_register(env
, SPR_74XX_MMCR2
, "MMCR2",
1535 SPR_NOACCESS
, SPR_NOACCESS
,
1536 &spr_read_generic
, &spr_write_generic
,
1538 /* XXX : not implemented */
1539 spr_register(env
, SPR_74XX_UMMCR2
, "UMMCR2",
1540 &spr_read_ureg
, SPR_NOACCESS
,
1541 &spr_read_ureg
, SPR_NOACCESS
,
1543 /* XXX: not implemented */
1544 spr_register(env
, SPR_BAMR
, "BAMR",
1545 SPR_NOACCESS
, SPR_NOACCESS
,
1546 &spr_read_generic
, &spr_write_generic
,
1548 /* XXX : not implemented */
1549 spr_register(env
, SPR_MSSCR0
, "MSSCR0",
1550 SPR_NOACCESS
, SPR_NOACCESS
,
1551 &spr_read_generic
, &spr_write_generic
,
1553 /* Hardware implementation registers */
1554 /* XXX : not implemented */
1555 spr_register(env
, SPR_HID0
, "HID0",
1556 SPR_NOACCESS
, SPR_NOACCESS
,
1557 &spr_read_generic
, &spr_write_generic
,
1559 /* XXX : not implemented */
1560 spr_register(env
, SPR_HID1
, "HID1",
1561 SPR_NOACCESS
, SPR_NOACCESS
,
1562 &spr_read_generic
, &spr_write_generic
,
1565 spr_register(env
, SPR_VRSAVE
, "VRSAVE",
1566 &spr_read_generic
, &spr_write_generic
,
1567 &spr_read_generic
, &spr_write_generic
,
1569 /* XXX : not implemented */
1570 spr_register(env
, SPR_L2CR
, "L2CR",
1571 SPR_NOACCESS
, SPR_NOACCESS
,
1572 &spr_read_generic
, spr_access_nop
,
1574 /* Not strictly an SPR */
1575 vscr_init(env
, 0x00010000);
1578 static void gen_l3_ctrl(CPUPPCState
*env
)
1581 /* XXX : not implemented */
1582 spr_register(env
, SPR_L3CR
, "L3CR",
1583 SPR_NOACCESS
, SPR_NOACCESS
,
1584 &spr_read_generic
, &spr_write_generic
,
1587 /* XXX : not implemented */
1588 spr_register(env
, SPR_L3ITCR0
, "L3ITCR0",
1589 SPR_NOACCESS
, SPR_NOACCESS
,
1590 &spr_read_generic
, &spr_write_generic
,
1593 /* XXX : not implemented */
1594 spr_register(env
, SPR_L3PM
, "L3PM",
1595 SPR_NOACCESS
, SPR_NOACCESS
,
1596 &spr_read_generic
, &spr_write_generic
,
1600 static void gen_74xx_soft_tlb(CPUPPCState
*env
, int nb_tlbs
, int nb_ways
)
1602 #if !defined(CONFIG_USER_ONLY)
1603 env
->nb_tlb
= nb_tlbs
;
1604 env
->nb_ways
= nb_ways
;
1606 env
->tlb_type
= TLB_6XX
;
1607 /* XXX : not implemented */
1608 spr_register(env
, SPR_PTEHI
, "PTEHI",
1609 SPR_NOACCESS
, SPR_NOACCESS
,
1610 &spr_read_generic
, &spr_write_generic
,
1612 /* XXX : not implemented */
1613 spr_register(env
, SPR_PTELO
, "PTELO",
1614 SPR_NOACCESS
, SPR_NOACCESS
,
1615 &spr_read_generic
, &spr_write_generic
,
1617 /* XXX : not implemented */
1618 spr_register(env
, SPR_TLBMISS
, "TLBMISS",
1619 SPR_NOACCESS
, SPR_NOACCESS
,
1620 &spr_read_generic
, &spr_write_generic
,
1625 #if !defined(CONFIG_USER_ONLY)
1626 static void spr_write_e500_l1csr0(DisasContext
*ctx
, int sprn
, int gprn
)
1628 TCGv t0
= tcg_temp_new();
1630 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], L1CSR0_DCE
| L1CSR0_CPE
);
1631 gen_store_spr(sprn
, t0
);
1635 static void spr_write_e500_l1csr1(DisasContext
*ctx
, int sprn
, int gprn
)
1637 TCGv t0
= tcg_temp_new();
1639 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], L1CSR1_ICE
| L1CSR1_CPE
);
1640 gen_store_spr(sprn
, t0
);
1644 static void spr_write_booke206_mmucsr0(DisasContext
*ctx
, int sprn
, int gprn
)
1646 gen_helper_booke206_tlbflush(cpu_env
, cpu_gpr
[gprn
]);
1649 static void spr_write_booke_pid(DisasContext
*ctx
, int sprn
, int gprn
)
1651 TCGv_i32 t0
= tcg_const_i32(sprn
);
1652 gen_helper_booke_setpid(cpu_env
, t0
, cpu_gpr
[gprn
]);
1653 tcg_temp_free_i32(t0
);
1657 static void gen_spr_usprg3(CPUPPCState
*env
)
1659 spr_register(env
, SPR_USPRG3
, "USPRG3",
1660 &spr_read_ureg
, SPR_NOACCESS
,
1661 &spr_read_ureg
, SPR_NOACCESS
,
1665 static void gen_spr_usprgh(CPUPPCState
*env
)
1667 spr_register(env
, SPR_USPRG4
, "USPRG4",
1668 &spr_read_ureg
, SPR_NOACCESS
,
1669 &spr_read_ureg
, SPR_NOACCESS
,
1671 spr_register(env
, SPR_USPRG5
, "USPRG5",
1672 &spr_read_ureg
, SPR_NOACCESS
,
1673 &spr_read_ureg
, SPR_NOACCESS
,
1675 spr_register(env
, SPR_USPRG6
, "USPRG6",
1676 &spr_read_ureg
, SPR_NOACCESS
,
1677 &spr_read_ureg
, SPR_NOACCESS
,
1679 spr_register(env
, SPR_USPRG7
, "USPRG7",
1680 &spr_read_ureg
, SPR_NOACCESS
,
1681 &spr_read_ureg
, SPR_NOACCESS
,
1685 /* PowerPC BookE SPR */
1686 static void gen_spr_BookE(CPUPPCState
*env
, uint64_t ivor_mask
)
1688 const char *ivor_names
[64] = {
1689 "IVOR0", "IVOR1", "IVOR2", "IVOR3",
1690 "IVOR4", "IVOR5", "IVOR6", "IVOR7",
1691 "IVOR8", "IVOR9", "IVOR10", "IVOR11",
1692 "IVOR12", "IVOR13", "IVOR14", "IVOR15",
1693 "IVOR16", "IVOR17", "IVOR18", "IVOR19",
1694 "IVOR20", "IVOR21", "IVOR22", "IVOR23",
1695 "IVOR24", "IVOR25", "IVOR26", "IVOR27",
1696 "IVOR28", "IVOR29", "IVOR30", "IVOR31",
1697 "IVOR32", "IVOR33", "IVOR34", "IVOR35",
1698 "IVOR36", "IVOR37", "IVOR38", "IVOR39",
1699 "IVOR40", "IVOR41", "IVOR42", "IVOR43",
1700 "IVOR44", "IVOR45", "IVOR46", "IVOR47",
1701 "IVOR48", "IVOR49", "IVOR50", "IVOR51",
1702 "IVOR52", "IVOR53", "IVOR54", "IVOR55",
1703 "IVOR56", "IVOR57", "IVOR58", "IVOR59",
1704 "IVOR60", "IVOR61", "IVOR62", "IVOR63",
1706 #define SPR_BOOKE_IVORxx (-1)
1707 int ivor_sprn
[64] = {
1708 SPR_BOOKE_IVOR0
, SPR_BOOKE_IVOR1
, SPR_BOOKE_IVOR2
, SPR_BOOKE_IVOR3
,
1709 SPR_BOOKE_IVOR4
, SPR_BOOKE_IVOR5
, SPR_BOOKE_IVOR6
, SPR_BOOKE_IVOR7
,
1710 SPR_BOOKE_IVOR8
, SPR_BOOKE_IVOR9
, SPR_BOOKE_IVOR10
, SPR_BOOKE_IVOR11
,
1711 SPR_BOOKE_IVOR12
, SPR_BOOKE_IVOR13
, SPR_BOOKE_IVOR14
, SPR_BOOKE_IVOR15
,
1712 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1713 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1714 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1715 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1716 SPR_BOOKE_IVOR32
, SPR_BOOKE_IVOR33
, SPR_BOOKE_IVOR34
, SPR_BOOKE_IVOR35
,
1717 SPR_BOOKE_IVOR36
, SPR_BOOKE_IVOR37
, SPR_BOOKE_IVOR38
, SPR_BOOKE_IVOR39
,
1718 SPR_BOOKE_IVOR40
, SPR_BOOKE_IVOR41
, SPR_BOOKE_IVOR42
, SPR_BOOKE_IVORxx
,
1719 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1720 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1721 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1722 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1723 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1727 /* Interrupt processing */
1728 spr_register(env
, SPR_BOOKE_CSRR0
, "CSRR0",
1729 SPR_NOACCESS
, SPR_NOACCESS
,
1730 &spr_read_generic
, &spr_write_generic
,
1732 spr_register(env
, SPR_BOOKE_CSRR1
, "CSRR1",
1733 SPR_NOACCESS
, SPR_NOACCESS
,
1734 &spr_read_generic
, &spr_write_generic
,
1737 /* XXX : not implemented */
1738 spr_register(env
, SPR_BOOKE_IAC1
, "IAC1",
1739 SPR_NOACCESS
, SPR_NOACCESS
,
1740 &spr_read_generic
, &spr_write_generic
,
1742 /* XXX : not implemented */
1743 spr_register(env
, SPR_BOOKE_IAC2
, "IAC2",
1744 SPR_NOACCESS
, SPR_NOACCESS
,
1745 &spr_read_generic
, &spr_write_generic
,
1747 /* XXX : not implemented */
1748 spr_register(env
, SPR_BOOKE_DAC1
, "DAC1",
1749 SPR_NOACCESS
, SPR_NOACCESS
,
1750 &spr_read_generic
, &spr_write_generic
,
1752 /* XXX : not implemented */
1753 spr_register(env
, SPR_BOOKE_DAC2
, "DAC2",
1754 SPR_NOACCESS
, SPR_NOACCESS
,
1755 &spr_read_generic
, &spr_write_generic
,
1757 /* XXX : not implemented */
1758 spr_register(env
, SPR_BOOKE_DBCR0
, "DBCR0",
1759 SPR_NOACCESS
, SPR_NOACCESS
,
1760 &spr_read_generic
, &spr_write_40x_dbcr0
,
1762 /* XXX : not implemented */
1763 spr_register(env
, SPR_BOOKE_DBCR1
, "DBCR1",
1764 SPR_NOACCESS
, SPR_NOACCESS
,
1765 &spr_read_generic
, &spr_write_generic
,
1767 /* XXX : not implemented */
1768 spr_register(env
, SPR_BOOKE_DBCR2
, "DBCR2",
1769 SPR_NOACCESS
, SPR_NOACCESS
,
1770 &spr_read_generic
, &spr_write_generic
,
1772 /* XXX : not implemented */
1773 spr_register(env
, SPR_BOOKE_DBSR
, "DBSR",
1774 SPR_NOACCESS
, SPR_NOACCESS
,
1775 &spr_read_generic
, &spr_write_clear
,
1777 spr_register(env
, SPR_BOOKE_DEAR
, "DEAR",
1778 SPR_NOACCESS
, SPR_NOACCESS
,
1779 &spr_read_generic
, &spr_write_generic
,
1781 spr_register(env
, SPR_BOOKE_ESR
, "ESR",
1782 SPR_NOACCESS
, SPR_NOACCESS
,
1783 &spr_read_generic
, &spr_write_generic
,
1785 spr_register(env
, SPR_BOOKE_IVPR
, "IVPR",
1786 SPR_NOACCESS
, SPR_NOACCESS
,
1787 &spr_read_generic
, &spr_write_excp_prefix
,
1789 /* Exception vectors */
1790 for (i
= 0; i
< 64; i
++) {
1791 if (ivor_mask
& (1ULL << i
)) {
1792 if (ivor_sprn
[i
] == SPR_BOOKE_IVORxx
) {
1793 fprintf(stderr
, "ERROR: IVOR %d SPR is not defined\n", i
);
1796 spr_register(env
, ivor_sprn
[i
], ivor_names
[i
],
1797 SPR_NOACCESS
, SPR_NOACCESS
,
1798 &spr_read_generic
, &spr_write_excp_vector
,
1802 spr_register(env
, SPR_BOOKE_PID
, "PID",
1803 SPR_NOACCESS
, SPR_NOACCESS
,
1804 &spr_read_generic
, &spr_write_booke_pid
,
1806 spr_register(env
, SPR_BOOKE_TCR
, "TCR",
1807 SPR_NOACCESS
, SPR_NOACCESS
,
1808 &spr_read_generic
, &spr_write_booke_tcr
,
1810 spr_register(env
, SPR_BOOKE_TSR
, "TSR",
1811 SPR_NOACCESS
, SPR_NOACCESS
,
1812 &spr_read_generic
, &spr_write_booke_tsr
,
1815 spr_register(env
, SPR_DECR
, "DECR",
1816 SPR_NOACCESS
, SPR_NOACCESS
,
1817 &spr_read_decr
, &spr_write_decr
,
1819 spr_register(env
, SPR_BOOKE_DECAR
, "DECAR",
1820 SPR_NOACCESS
, SPR_NOACCESS
,
1821 SPR_NOACCESS
, &spr_write_generic
,
1824 spr_register(env
, SPR_USPRG0
, "USPRG0",
1825 &spr_read_generic
, &spr_write_generic
,
1826 &spr_read_generic
, &spr_write_generic
,
1828 spr_register(env
, SPR_SPRG4
, "SPRG4",
1829 SPR_NOACCESS
, SPR_NOACCESS
,
1830 &spr_read_generic
, &spr_write_generic
,
1832 spr_register(env
, SPR_SPRG5
, "SPRG5",
1833 SPR_NOACCESS
, SPR_NOACCESS
,
1834 &spr_read_generic
, &spr_write_generic
,
1836 spr_register(env
, SPR_SPRG6
, "SPRG6",
1837 SPR_NOACCESS
, SPR_NOACCESS
,
1838 &spr_read_generic
, &spr_write_generic
,
1840 spr_register(env
, SPR_SPRG7
, "SPRG7",
1841 SPR_NOACCESS
, SPR_NOACCESS
,
1842 &spr_read_generic
, &spr_write_generic
,
1846 static inline uint32_t gen_tlbncfg(uint32_t assoc
, uint32_t minsize
,
1847 uint32_t maxsize
, uint32_t flags
,
1850 return (assoc
<< TLBnCFG_ASSOC_SHIFT
) |
1851 (minsize
<< TLBnCFG_MINSIZE_SHIFT
) |
1852 (maxsize
<< TLBnCFG_MAXSIZE_SHIFT
) |
1856 /* BookE 2.06 storage control registers */
1857 static void gen_spr_BookE206(CPUPPCState
*env
, uint32_t mas_mask
,
1858 uint32_t *tlbncfg
, uint32_t mmucfg
)
1860 #if !defined(CONFIG_USER_ONLY)
1861 const char *mas_names
[8] = {
1862 "MAS0", "MAS1", "MAS2", "MAS3", "MAS4", "MAS5", "MAS6", "MAS7",
1865 SPR_BOOKE_MAS0
, SPR_BOOKE_MAS1
, SPR_BOOKE_MAS2
, SPR_BOOKE_MAS3
,
1866 SPR_BOOKE_MAS4
, SPR_BOOKE_MAS5
, SPR_BOOKE_MAS6
, SPR_BOOKE_MAS7
,
1870 /* TLB assist registers */
1871 /* XXX : not implemented */
1872 for (i
= 0; i
< 8; i
++) {
1873 void (*uea_write
)(DisasContext
*ctx
, int sprn
, int gprn
) = &spr_write_generic32
;
1874 if (i
== 2 && (mas_mask
& (1 << i
)) && (env
->insns_flags
& PPC_64B
)) {
1875 uea_write
= &spr_write_generic
;
1877 if (mas_mask
& (1 << i
)) {
1878 spr_register(env
, mas_sprn
[i
], mas_names
[i
],
1879 SPR_NOACCESS
, SPR_NOACCESS
,
1880 &spr_read_generic
, uea_write
,
1884 if (env
->nb_pids
> 1) {
1885 /* XXX : not implemented */
1886 spr_register(env
, SPR_BOOKE_PID1
, "PID1",
1887 SPR_NOACCESS
, SPR_NOACCESS
,
1888 &spr_read_generic
, &spr_write_booke_pid
,
1891 if (env
->nb_pids
> 2) {
1892 /* XXX : not implemented */
1893 spr_register(env
, SPR_BOOKE_PID2
, "PID2",
1894 SPR_NOACCESS
, SPR_NOACCESS
,
1895 &spr_read_generic
, &spr_write_booke_pid
,
1898 /* XXX : not implemented */
1899 spr_register(env
, SPR_MMUCFG
, "MMUCFG",
1900 SPR_NOACCESS
, SPR_NOACCESS
,
1901 &spr_read_generic
, SPR_NOACCESS
,
1903 switch (env
->nb_ways
) {
1905 spr_register(env
, SPR_BOOKE_TLB3CFG
, "TLB3CFG",
1906 SPR_NOACCESS
, SPR_NOACCESS
,
1907 &spr_read_generic
, SPR_NOACCESS
,
1911 spr_register(env
, SPR_BOOKE_TLB2CFG
, "TLB2CFG",
1912 SPR_NOACCESS
, SPR_NOACCESS
,
1913 &spr_read_generic
, SPR_NOACCESS
,
1917 spr_register(env
, SPR_BOOKE_TLB1CFG
, "TLB1CFG",
1918 SPR_NOACCESS
, SPR_NOACCESS
,
1919 &spr_read_generic
, SPR_NOACCESS
,
1923 spr_register(env
, SPR_BOOKE_TLB0CFG
, "TLB0CFG",
1924 SPR_NOACCESS
, SPR_NOACCESS
,
1925 &spr_read_generic
, SPR_NOACCESS
,
1934 gen_spr_usprgh(env
);
1937 /* SPR specific to PowerPC 440 implementation */
1938 static void gen_spr_440(CPUPPCState
*env
)
1941 /* XXX : not implemented */
1942 spr_register(env
, SPR_440_DNV0
, "DNV0",
1943 SPR_NOACCESS
, SPR_NOACCESS
,
1944 &spr_read_generic
, &spr_write_generic
,
1946 /* XXX : not implemented */
1947 spr_register(env
, SPR_440_DNV1
, "DNV1",
1948 SPR_NOACCESS
, SPR_NOACCESS
,
1949 &spr_read_generic
, &spr_write_generic
,
1951 /* XXX : not implemented */
1952 spr_register(env
, SPR_440_DNV2
, "DNV2",
1953 SPR_NOACCESS
, SPR_NOACCESS
,
1954 &spr_read_generic
, &spr_write_generic
,
1956 /* XXX : not implemented */
1957 spr_register(env
, SPR_440_DNV3
, "DNV3",
1958 SPR_NOACCESS
, SPR_NOACCESS
,
1959 &spr_read_generic
, &spr_write_generic
,
1961 /* XXX : not implemented */
1962 spr_register(env
, SPR_440_DTV0
, "DTV0",
1963 SPR_NOACCESS
, SPR_NOACCESS
,
1964 &spr_read_generic
, &spr_write_generic
,
1966 /* XXX : not implemented */
1967 spr_register(env
, SPR_440_DTV1
, "DTV1",
1968 SPR_NOACCESS
, SPR_NOACCESS
,
1969 &spr_read_generic
, &spr_write_generic
,
1971 /* XXX : not implemented */
1972 spr_register(env
, SPR_440_DTV2
, "DTV2",
1973 SPR_NOACCESS
, SPR_NOACCESS
,
1974 &spr_read_generic
, &spr_write_generic
,
1976 /* XXX : not implemented */
1977 spr_register(env
, SPR_440_DTV3
, "DTV3",
1978 SPR_NOACCESS
, SPR_NOACCESS
,
1979 &spr_read_generic
, &spr_write_generic
,
1981 /* XXX : not implemented */
1982 spr_register(env
, SPR_440_DVLIM
, "DVLIM",
1983 SPR_NOACCESS
, SPR_NOACCESS
,
1984 &spr_read_generic
, &spr_write_generic
,
1986 /* XXX : not implemented */
1987 spr_register(env
, SPR_440_INV0
, "INV0",
1988 SPR_NOACCESS
, SPR_NOACCESS
,
1989 &spr_read_generic
, &spr_write_generic
,
1991 /* XXX : not implemented */
1992 spr_register(env
, SPR_440_INV1
, "INV1",
1993 SPR_NOACCESS
, SPR_NOACCESS
,
1994 &spr_read_generic
, &spr_write_generic
,
1996 /* XXX : not implemented */
1997 spr_register(env
, SPR_440_INV2
, "INV2",
1998 SPR_NOACCESS
, SPR_NOACCESS
,
1999 &spr_read_generic
, &spr_write_generic
,
2001 /* XXX : not implemented */
2002 spr_register(env
, SPR_440_INV3
, "INV3",
2003 SPR_NOACCESS
, SPR_NOACCESS
,
2004 &spr_read_generic
, &spr_write_generic
,
2006 /* XXX : not implemented */
2007 spr_register(env
, SPR_440_ITV0
, "ITV0",
2008 SPR_NOACCESS
, SPR_NOACCESS
,
2009 &spr_read_generic
, &spr_write_generic
,
2011 /* XXX : not implemented */
2012 spr_register(env
, SPR_440_ITV1
, "ITV1",
2013 SPR_NOACCESS
, SPR_NOACCESS
,
2014 &spr_read_generic
, &spr_write_generic
,
2016 /* XXX : not implemented */
2017 spr_register(env
, SPR_440_ITV2
, "ITV2",
2018 SPR_NOACCESS
, SPR_NOACCESS
,
2019 &spr_read_generic
, &spr_write_generic
,
2021 /* XXX : not implemented */
2022 spr_register(env
, SPR_440_ITV3
, "ITV3",
2023 SPR_NOACCESS
, SPR_NOACCESS
,
2024 &spr_read_generic
, &spr_write_generic
,
2026 /* XXX : not implemented */
2027 spr_register(env
, SPR_440_IVLIM
, "IVLIM",
2028 SPR_NOACCESS
, SPR_NOACCESS
,
2029 &spr_read_generic
, &spr_write_generic
,
2032 /* XXX : not implemented */
2033 spr_register(env
, SPR_BOOKE_DCDBTRH
, "DCDBTRH",
2034 SPR_NOACCESS
, SPR_NOACCESS
,
2035 &spr_read_generic
, SPR_NOACCESS
,
2037 /* XXX : not implemented */
2038 spr_register(env
, SPR_BOOKE_DCDBTRL
, "DCDBTRL",
2039 SPR_NOACCESS
, SPR_NOACCESS
,
2040 &spr_read_generic
, SPR_NOACCESS
,
2042 /* XXX : not implemented */
2043 spr_register(env
, SPR_BOOKE_ICDBDR
, "ICDBDR",
2044 SPR_NOACCESS
, SPR_NOACCESS
,
2045 &spr_read_generic
, SPR_NOACCESS
,
2047 /* XXX : not implemented */
2048 spr_register(env
, SPR_BOOKE_ICDBTRH
, "ICDBTRH",
2049 SPR_NOACCESS
, SPR_NOACCESS
,
2050 &spr_read_generic
, SPR_NOACCESS
,
2052 /* XXX : not implemented */
2053 spr_register(env
, SPR_BOOKE_ICDBTRL
, "ICDBTRL",
2054 SPR_NOACCESS
, SPR_NOACCESS
,
2055 &spr_read_generic
, SPR_NOACCESS
,
2057 /* XXX : not implemented */
2058 spr_register(env
, SPR_440_DBDR
, "DBDR",
2059 SPR_NOACCESS
, SPR_NOACCESS
,
2060 &spr_read_generic
, &spr_write_generic
,
2062 /* Processor control */
2063 spr_register(env
, SPR_4xx_CCR0
, "CCR0",
2064 SPR_NOACCESS
, SPR_NOACCESS
,
2065 &spr_read_generic
, &spr_write_generic
,
2067 spr_register(env
, SPR_440_RSTCFG
, "RSTCFG",
2068 SPR_NOACCESS
, SPR_NOACCESS
,
2069 &spr_read_generic
, SPR_NOACCESS
,
2071 /* Storage control */
2072 spr_register(env
, SPR_440_MMUCR
, "MMUCR",
2073 SPR_NOACCESS
, SPR_NOACCESS
,
2074 &spr_read_generic
, &spr_write_generic
,
2078 /* SPR shared between PowerPC 40x implementations */
2079 static void gen_spr_40x(CPUPPCState
*env
)
2082 /* not emulated, as QEMU do not emulate caches */
2083 spr_register(env
, SPR_40x_DCCR
, "DCCR",
2084 SPR_NOACCESS
, SPR_NOACCESS
,
2085 &spr_read_generic
, &spr_write_generic
,
2087 /* not emulated, as QEMU do not emulate caches */
2088 spr_register(env
, SPR_40x_ICCR
, "ICCR",
2089 SPR_NOACCESS
, SPR_NOACCESS
,
2090 &spr_read_generic
, &spr_write_generic
,
2092 /* not emulated, as QEMU do not emulate caches */
2093 spr_register(env
, SPR_BOOKE_ICDBDR
, "ICDBDR",
2094 SPR_NOACCESS
, SPR_NOACCESS
,
2095 &spr_read_generic
, SPR_NOACCESS
,
2098 spr_register(env
, SPR_40x_DEAR
, "DEAR",
2099 SPR_NOACCESS
, SPR_NOACCESS
,
2100 &spr_read_generic
, &spr_write_generic
,
2102 spr_register(env
, SPR_40x_ESR
, "ESR",
2103 SPR_NOACCESS
, SPR_NOACCESS
,
2104 &spr_read_generic
, &spr_write_generic
,
2106 spr_register(env
, SPR_40x_EVPR
, "EVPR",
2107 SPR_NOACCESS
, SPR_NOACCESS
,
2108 &spr_read_generic
, &spr_write_excp_prefix
,
2110 spr_register(env
, SPR_40x_SRR2
, "SRR2",
2111 &spr_read_generic
, &spr_write_generic
,
2112 &spr_read_generic
, &spr_write_generic
,
2114 spr_register(env
, SPR_40x_SRR3
, "SRR3",
2115 &spr_read_generic
, &spr_write_generic
,
2116 &spr_read_generic
, &spr_write_generic
,
2119 spr_register(env
, SPR_40x_PIT
, "PIT",
2120 SPR_NOACCESS
, SPR_NOACCESS
,
2121 &spr_read_40x_pit
, &spr_write_40x_pit
,
2123 spr_register(env
, SPR_40x_TCR
, "TCR",
2124 SPR_NOACCESS
, SPR_NOACCESS
,
2125 &spr_read_generic
, &spr_write_booke_tcr
,
2127 spr_register(env
, SPR_40x_TSR
, "TSR",
2128 SPR_NOACCESS
, SPR_NOACCESS
,
2129 &spr_read_generic
, &spr_write_booke_tsr
,
2133 /* SPR specific to PowerPC 405 implementation */
2134 static void gen_spr_405(CPUPPCState
*env
)
2137 spr_register(env
, SPR_40x_PID
, "PID",
2138 SPR_NOACCESS
, SPR_NOACCESS
,
2139 &spr_read_generic
, &spr_write_generic
,
2141 spr_register(env
, SPR_4xx_CCR0
, "CCR0",
2142 SPR_NOACCESS
, SPR_NOACCESS
,
2143 &spr_read_generic
, &spr_write_generic
,
2145 /* Debug interface */
2146 /* XXX : not implemented */
2147 spr_register(env
, SPR_40x_DBCR0
, "DBCR0",
2148 SPR_NOACCESS
, SPR_NOACCESS
,
2149 &spr_read_generic
, &spr_write_40x_dbcr0
,
2151 /* XXX : not implemented */
2152 spr_register(env
, SPR_405_DBCR1
, "DBCR1",
2153 SPR_NOACCESS
, SPR_NOACCESS
,
2154 &spr_read_generic
, &spr_write_generic
,
2156 /* XXX : not implemented */
2157 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2158 SPR_NOACCESS
, SPR_NOACCESS
,
2159 &spr_read_generic
, &spr_write_clear
,
2160 /* Last reset was system reset */
2162 /* XXX : not implemented */
2163 spr_register(env
, SPR_40x_DAC1
, "DAC1",
2164 SPR_NOACCESS
, SPR_NOACCESS
,
2165 &spr_read_generic
, &spr_write_generic
,
2167 spr_register(env
, SPR_40x_DAC2
, "DAC2",
2168 SPR_NOACCESS
, SPR_NOACCESS
,
2169 &spr_read_generic
, &spr_write_generic
,
2171 /* XXX : not implemented */
2172 spr_register(env
, SPR_405_DVC1
, "DVC1",
2173 SPR_NOACCESS
, SPR_NOACCESS
,
2174 &spr_read_generic
, &spr_write_generic
,
2176 /* XXX : not implemented */
2177 spr_register(env
, SPR_405_DVC2
, "DVC2",
2178 SPR_NOACCESS
, SPR_NOACCESS
,
2179 &spr_read_generic
, &spr_write_generic
,
2181 /* XXX : not implemented */
2182 spr_register(env
, SPR_40x_IAC1
, "IAC1",
2183 SPR_NOACCESS
, SPR_NOACCESS
,
2184 &spr_read_generic
, &spr_write_generic
,
2186 spr_register(env
, SPR_40x_IAC2
, "IAC2",
2187 SPR_NOACCESS
, SPR_NOACCESS
,
2188 &spr_read_generic
, &spr_write_generic
,
2190 /* XXX : not implemented */
2191 spr_register(env
, SPR_405_IAC3
, "IAC3",
2192 SPR_NOACCESS
, SPR_NOACCESS
,
2193 &spr_read_generic
, &spr_write_generic
,
2195 /* XXX : not implemented */
2196 spr_register(env
, SPR_405_IAC4
, "IAC4",
2197 SPR_NOACCESS
, SPR_NOACCESS
,
2198 &spr_read_generic
, &spr_write_generic
,
2200 /* Storage control */
2201 /* XXX: TODO: not implemented */
2202 spr_register(env
, SPR_405_SLER
, "SLER",
2203 SPR_NOACCESS
, SPR_NOACCESS
,
2204 &spr_read_generic
, &spr_write_40x_sler
,
2206 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2207 SPR_NOACCESS
, SPR_NOACCESS
,
2208 &spr_read_generic
, &spr_write_generic
,
2210 /* XXX : not implemented */
2211 spr_register(env
, SPR_405_SU0R
, "SU0R",
2212 SPR_NOACCESS
, SPR_NOACCESS
,
2213 &spr_read_generic
, &spr_write_generic
,
2216 spr_register(env
, SPR_USPRG0
, "USPRG0",
2217 &spr_read_ureg
, SPR_NOACCESS
,
2218 &spr_read_ureg
, SPR_NOACCESS
,
2220 spr_register(env
, SPR_SPRG4
, "SPRG4",
2221 SPR_NOACCESS
, SPR_NOACCESS
,
2222 &spr_read_generic
, &spr_write_generic
,
2224 spr_register(env
, SPR_SPRG5
, "SPRG5",
2225 SPR_NOACCESS
, SPR_NOACCESS
,
2226 spr_read_generic
, &spr_write_generic
,
2228 spr_register(env
, SPR_SPRG6
, "SPRG6",
2229 SPR_NOACCESS
, SPR_NOACCESS
,
2230 spr_read_generic
, &spr_write_generic
,
2232 spr_register(env
, SPR_SPRG7
, "SPRG7",
2233 SPR_NOACCESS
, SPR_NOACCESS
,
2234 spr_read_generic
, &spr_write_generic
,
2236 gen_spr_usprgh(env
);
2239 /* SPR shared between PowerPC 401 & 403 implementations */
2240 static void gen_spr_401_403(CPUPPCState
*env
)
2243 spr_register(env
, SPR_403_VTBL
, "TBL",
2244 &spr_read_tbl
, SPR_NOACCESS
,
2245 &spr_read_tbl
, SPR_NOACCESS
,
2247 spr_register(env
, SPR_403_TBL
, "TBL",
2248 SPR_NOACCESS
, SPR_NOACCESS
,
2249 SPR_NOACCESS
, &spr_write_tbl
,
2251 spr_register(env
, SPR_403_VTBU
, "TBU",
2252 &spr_read_tbu
, SPR_NOACCESS
,
2253 &spr_read_tbu
, SPR_NOACCESS
,
2255 spr_register(env
, SPR_403_TBU
, "TBU",
2256 SPR_NOACCESS
, SPR_NOACCESS
,
2257 SPR_NOACCESS
, &spr_write_tbu
,
2260 /* not emulated, as QEMU do not emulate caches */
2261 spr_register(env
, SPR_403_CDBCR
, "CDBCR",
2262 SPR_NOACCESS
, SPR_NOACCESS
,
2263 &spr_read_generic
, &spr_write_generic
,
2267 /* SPR specific to PowerPC 401 implementation */
2268 static void gen_spr_401(CPUPPCState
*env
)
2270 /* Debug interface */
2271 /* XXX : not implemented */
2272 spr_register(env
, SPR_40x_DBCR0
, "DBCR",
2273 SPR_NOACCESS
, SPR_NOACCESS
,
2274 &spr_read_generic
, &spr_write_40x_dbcr0
,
2276 /* XXX : not implemented */
2277 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2278 SPR_NOACCESS
, SPR_NOACCESS
,
2279 &spr_read_generic
, &spr_write_clear
,
2280 /* Last reset was system reset */
2282 /* XXX : not implemented */
2283 spr_register(env
, SPR_40x_DAC1
, "DAC",
2284 SPR_NOACCESS
, SPR_NOACCESS
,
2285 &spr_read_generic
, &spr_write_generic
,
2287 /* XXX : not implemented */
2288 spr_register(env
, SPR_40x_IAC1
, "IAC",
2289 SPR_NOACCESS
, SPR_NOACCESS
,
2290 &spr_read_generic
, &spr_write_generic
,
2292 /* Storage control */
2293 /* XXX: TODO: not implemented */
2294 spr_register(env
, SPR_405_SLER
, "SLER",
2295 SPR_NOACCESS
, SPR_NOACCESS
,
2296 &spr_read_generic
, &spr_write_40x_sler
,
2298 /* not emulated, as QEMU never does speculative access */
2299 spr_register(env
, SPR_40x_SGR
, "SGR",
2300 SPR_NOACCESS
, SPR_NOACCESS
,
2301 &spr_read_generic
, &spr_write_generic
,
2303 /* not emulated, as QEMU do not emulate caches */
2304 spr_register(env
, SPR_40x_DCWR
, "DCWR",
2305 SPR_NOACCESS
, SPR_NOACCESS
,
2306 &spr_read_generic
, &spr_write_generic
,
2310 static void gen_spr_401x2(CPUPPCState
*env
)
2313 spr_register(env
, SPR_40x_PID
, "PID",
2314 SPR_NOACCESS
, SPR_NOACCESS
,
2315 &spr_read_generic
, &spr_write_generic
,
2317 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2318 SPR_NOACCESS
, SPR_NOACCESS
,
2319 &spr_read_generic
, &spr_write_generic
,
2323 /* SPR specific to PowerPC 403 implementation */
2324 static void gen_spr_403(CPUPPCState
*env
)
2326 /* Debug interface */
2327 /* XXX : not implemented */
2328 spr_register(env
, SPR_40x_DBCR0
, "DBCR0",
2329 SPR_NOACCESS
, SPR_NOACCESS
,
2330 &spr_read_generic
, &spr_write_40x_dbcr0
,
2332 /* XXX : not implemented */
2333 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2334 SPR_NOACCESS
, SPR_NOACCESS
,
2335 &spr_read_generic
, &spr_write_clear
,
2336 /* Last reset was system reset */
2338 /* XXX : not implemented */
2339 spr_register(env
, SPR_40x_DAC1
, "DAC1",
2340 SPR_NOACCESS
, SPR_NOACCESS
,
2341 &spr_read_generic
, &spr_write_generic
,
2343 /* XXX : not implemented */
2344 spr_register(env
, SPR_40x_DAC2
, "DAC2",
2345 SPR_NOACCESS
, SPR_NOACCESS
,
2346 &spr_read_generic
, &spr_write_generic
,
2348 /* XXX : not implemented */
2349 spr_register(env
, SPR_40x_IAC1
, "IAC1",
2350 SPR_NOACCESS
, SPR_NOACCESS
,
2351 &spr_read_generic
, &spr_write_generic
,
2353 /* XXX : not implemented */
2354 spr_register(env
, SPR_40x_IAC2
, "IAC2",
2355 SPR_NOACCESS
, SPR_NOACCESS
,
2356 &spr_read_generic
, &spr_write_generic
,
2360 static void gen_spr_403_real(CPUPPCState
*env
)
2362 spr_register(env
, SPR_403_PBL1
, "PBL1",
2363 SPR_NOACCESS
, SPR_NOACCESS
,
2364 &spr_read_403_pbr
, &spr_write_403_pbr
,
2366 spr_register(env
, SPR_403_PBU1
, "PBU1",
2367 SPR_NOACCESS
, SPR_NOACCESS
,
2368 &spr_read_403_pbr
, &spr_write_403_pbr
,
2370 spr_register(env
, SPR_403_PBL2
, "PBL2",
2371 SPR_NOACCESS
, SPR_NOACCESS
,
2372 &spr_read_403_pbr
, &spr_write_403_pbr
,
2374 spr_register(env
, SPR_403_PBU2
, "PBU2",
2375 SPR_NOACCESS
, SPR_NOACCESS
,
2376 &spr_read_403_pbr
, &spr_write_403_pbr
,
2380 static void gen_spr_403_mmu(CPUPPCState
*env
)
2383 spr_register(env
, SPR_40x_PID
, "PID",
2384 SPR_NOACCESS
, SPR_NOACCESS
,
2385 &spr_read_generic
, &spr_write_generic
,
2387 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2388 SPR_NOACCESS
, SPR_NOACCESS
,
2389 &spr_read_generic
, &spr_write_generic
,
2393 /* SPR specific to PowerPC compression coprocessor extension */
2394 static void gen_spr_compress(CPUPPCState
*env
)
2396 /* XXX : not implemented */
2397 spr_register(env
, SPR_401_SKR
, "SKR",
2398 SPR_NOACCESS
, SPR_NOACCESS
,
2399 &spr_read_generic
, &spr_write_generic
,
2403 static void gen_spr_5xx_8xx(CPUPPCState
*env
)
2405 /* Exception processing */
2406 spr_register_kvm(env
, SPR_DSISR
, "DSISR",
2407 SPR_NOACCESS
, SPR_NOACCESS
,
2408 &spr_read_generic
, &spr_write_generic
,
2409 KVM_REG_PPC_DSISR
, 0x00000000);
2410 spr_register_kvm(env
, SPR_DAR
, "DAR",
2411 SPR_NOACCESS
, SPR_NOACCESS
,
2412 &spr_read_generic
, &spr_write_generic
,
2413 KVM_REG_PPC_DAR
, 0x00000000);
2415 spr_register(env
, SPR_DECR
, "DECR",
2416 SPR_NOACCESS
, SPR_NOACCESS
,
2417 &spr_read_decr
, &spr_write_decr
,
2419 /* XXX : not implemented */
2420 spr_register(env
, SPR_MPC_EIE
, "EIE",
2421 SPR_NOACCESS
, SPR_NOACCESS
,
2422 &spr_read_generic
, &spr_write_generic
,
2424 /* XXX : not implemented */
2425 spr_register(env
, SPR_MPC_EID
, "EID",
2426 SPR_NOACCESS
, SPR_NOACCESS
,
2427 &spr_read_generic
, &spr_write_generic
,
2429 /* XXX : not implemented */
2430 spr_register(env
, SPR_MPC_NRI
, "NRI",
2431 SPR_NOACCESS
, SPR_NOACCESS
,
2432 &spr_read_generic
, &spr_write_generic
,
2434 /* XXX : not implemented */
2435 spr_register(env
, SPR_MPC_CMPA
, "CMPA",
2436 SPR_NOACCESS
, SPR_NOACCESS
,
2437 &spr_read_generic
, &spr_write_generic
,
2439 /* XXX : not implemented */
2440 spr_register(env
, SPR_MPC_CMPB
, "CMPB",
2441 SPR_NOACCESS
, SPR_NOACCESS
,
2442 &spr_read_generic
, &spr_write_generic
,
2444 /* XXX : not implemented */
2445 spr_register(env
, SPR_MPC_CMPC
, "CMPC",
2446 SPR_NOACCESS
, SPR_NOACCESS
,
2447 &spr_read_generic
, &spr_write_generic
,
2449 /* XXX : not implemented */
2450 spr_register(env
, SPR_MPC_CMPD
, "CMPD",
2451 SPR_NOACCESS
, SPR_NOACCESS
,
2452 &spr_read_generic
, &spr_write_generic
,
2454 /* XXX : not implemented */
2455 spr_register(env
, SPR_MPC_ECR
, "ECR",
2456 SPR_NOACCESS
, SPR_NOACCESS
,
2457 &spr_read_generic
, &spr_write_generic
,
2459 /* XXX : not implemented */
2460 spr_register(env
, SPR_MPC_DER
, "DER",
2461 SPR_NOACCESS
, SPR_NOACCESS
,
2462 &spr_read_generic
, &spr_write_generic
,
2464 /* XXX : not implemented */
2465 spr_register(env
, SPR_MPC_COUNTA
, "COUNTA",
2466 SPR_NOACCESS
, SPR_NOACCESS
,
2467 &spr_read_generic
, &spr_write_generic
,
2469 /* XXX : not implemented */
2470 spr_register(env
, SPR_MPC_COUNTB
, "COUNTB",
2471 SPR_NOACCESS
, SPR_NOACCESS
,
2472 &spr_read_generic
, &spr_write_generic
,
2474 /* XXX : not implemented */
2475 spr_register(env
, SPR_MPC_CMPE
, "CMPE",
2476 SPR_NOACCESS
, SPR_NOACCESS
,
2477 &spr_read_generic
, &spr_write_generic
,
2479 /* XXX : not implemented */
2480 spr_register(env
, SPR_MPC_CMPF
, "CMPF",
2481 SPR_NOACCESS
, SPR_NOACCESS
,
2482 &spr_read_generic
, &spr_write_generic
,
2484 /* XXX : not implemented */
2485 spr_register(env
, SPR_MPC_CMPG
, "CMPG",
2486 SPR_NOACCESS
, SPR_NOACCESS
,
2487 &spr_read_generic
, &spr_write_generic
,
2489 /* XXX : not implemented */
2490 spr_register(env
, SPR_MPC_CMPH
, "CMPH",
2491 SPR_NOACCESS
, SPR_NOACCESS
,
2492 &spr_read_generic
, &spr_write_generic
,
2494 /* XXX : not implemented */
2495 spr_register(env
, SPR_MPC_LCTRL1
, "LCTRL1",
2496 SPR_NOACCESS
, SPR_NOACCESS
,
2497 &spr_read_generic
, &spr_write_generic
,
2499 /* XXX : not implemented */
2500 spr_register(env
, SPR_MPC_LCTRL2
, "LCTRL2",
2501 SPR_NOACCESS
, SPR_NOACCESS
,
2502 &spr_read_generic
, &spr_write_generic
,
2504 /* XXX : not implemented */
2505 spr_register(env
, SPR_MPC_BAR
, "BAR",
2506 SPR_NOACCESS
, SPR_NOACCESS
,
2507 &spr_read_generic
, &spr_write_generic
,
2509 /* XXX : not implemented */
2510 spr_register(env
, SPR_MPC_DPDR
, "DPDR",
2511 SPR_NOACCESS
, SPR_NOACCESS
,
2512 &spr_read_generic
, &spr_write_generic
,
2514 /* XXX : not implemented */
2515 spr_register(env
, SPR_MPC_IMMR
, "IMMR",
2516 SPR_NOACCESS
, SPR_NOACCESS
,
2517 &spr_read_generic
, &spr_write_generic
,
2521 static void gen_spr_5xx(CPUPPCState
*env
)
2523 /* XXX : not implemented */
2524 spr_register(env
, SPR_RCPU_MI_GRA
, "MI_GRA",
2525 SPR_NOACCESS
, SPR_NOACCESS
,
2526 &spr_read_generic
, &spr_write_generic
,
2528 /* XXX : not implemented */
2529 spr_register(env
, SPR_RCPU_L2U_GRA
, "L2U_GRA",
2530 SPR_NOACCESS
, SPR_NOACCESS
,
2531 &spr_read_generic
, &spr_write_generic
,
2533 /* XXX : not implemented */
2534 spr_register(env
, SPR_RPCU_BBCMCR
, "L2U_BBCMCR",
2535 SPR_NOACCESS
, SPR_NOACCESS
,
2536 &spr_read_generic
, &spr_write_generic
,
2538 /* XXX : not implemented */
2539 spr_register(env
, SPR_RCPU_L2U_MCR
, "L2U_MCR",
2540 SPR_NOACCESS
, SPR_NOACCESS
,
2541 &spr_read_generic
, &spr_write_generic
,
2543 /* XXX : not implemented */
2544 spr_register(env
, SPR_RCPU_MI_RBA0
, "MI_RBA0",
2545 SPR_NOACCESS
, SPR_NOACCESS
,
2546 &spr_read_generic
, &spr_write_generic
,
2548 /* XXX : not implemented */
2549 spr_register(env
, SPR_RCPU_MI_RBA1
, "MI_RBA1",
2550 SPR_NOACCESS
, SPR_NOACCESS
,
2551 &spr_read_generic
, &spr_write_generic
,
2553 /* XXX : not implemented */
2554 spr_register(env
, SPR_RCPU_MI_RBA2
, "MI_RBA2",
2555 SPR_NOACCESS
, SPR_NOACCESS
,
2556 &spr_read_generic
, &spr_write_generic
,
2558 /* XXX : not implemented */
2559 spr_register(env
, SPR_RCPU_MI_RBA3
, "MI_RBA3",
2560 SPR_NOACCESS
, SPR_NOACCESS
,
2561 &spr_read_generic
, &spr_write_generic
,
2563 /* XXX : not implemented */
2564 spr_register(env
, SPR_RCPU_L2U_RBA0
, "L2U_RBA0",
2565 SPR_NOACCESS
, SPR_NOACCESS
,
2566 &spr_read_generic
, &spr_write_generic
,
2568 /* XXX : not implemented */
2569 spr_register(env
, SPR_RCPU_L2U_RBA1
, "L2U_RBA1",
2570 SPR_NOACCESS
, SPR_NOACCESS
,
2571 &spr_read_generic
, &spr_write_generic
,
2573 /* XXX : not implemented */
2574 spr_register(env
, SPR_RCPU_L2U_RBA2
, "L2U_RBA2",
2575 SPR_NOACCESS
, SPR_NOACCESS
,
2576 &spr_read_generic
, &spr_write_generic
,
2578 /* XXX : not implemented */
2579 spr_register(env
, SPR_RCPU_L2U_RBA3
, "L2U_RBA3",
2580 SPR_NOACCESS
, SPR_NOACCESS
,
2581 &spr_read_generic
, &spr_write_generic
,
2583 /* XXX : not implemented */
2584 spr_register(env
, SPR_RCPU_MI_RA0
, "MI_RA0",
2585 SPR_NOACCESS
, SPR_NOACCESS
,
2586 &spr_read_generic
, &spr_write_generic
,
2588 /* XXX : not implemented */
2589 spr_register(env
, SPR_RCPU_MI_RA1
, "MI_RA1",
2590 SPR_NOACCESS
, SPR_NOACCESS
,
2591 &spr_read_generic
, &spr_write_generic
,
2593 /* XXX : not implemented */
2594 spr_register(env
, SPR_RCPU_MI_RA2
, "MI_RA2",
2595 SPR_NOACCESS
, SPR_NOACCESS
,
2596 &spr_read_generic
, &spr_write_generic
,
2598 /* XXX : not implemented */
2599 spr_register(env
, SPR_RCPU_MI_RA3
, "MI_RA3",
2600 SPR_NOACCESS
, SPR_NOACCESS
,
2601 &spr_read_generic
, &spr_write_generic
,
2603 /* XXX : not implemented */
2604 spr_register(env
, SPR_RCPU_L2U_RA0
, "L2U_RA0",
2605 SPR_NOACCESS
, SPR_NOACCESS
,
2606 &spr_read_generic
, &spr_write_generic
,
2608 /* XXX : not implemented */
2609 spr_register(env
, SPR_RCPU_L2U_RA1
, "L2U_RA1",
2610 SPR_NOACCESS
, SPR_NOACCESS
,
2611 &spr_read_generic
, &spr_write_generic
,
2613 /* XXX : not implemented */
2614 spr_register(env
, SPR_RCPU_L2U_RA2
, "L2U_RA2",
2615 SPR_NOACCESS
, SPR_NOACCESS
,
2616 &spr_read_generic
, &spr_write_generic
,
2618 /* XXX : not implemented */
2619 spr_register(env
, SPR_RCPU_L2U_RA3
, "L2U_RA3",
2620 SPR_NOACCESS
, SPR_NOACCESS
,
2621 &spr_read_generic
, &spr_write_generic
,
2623 /* XXX : not implemented */
2624 spr_register(env
, SPR_RCPU_FPECR
, "FPECR",
2625 SPR_NOACCESS
, SPR_NOACCESS
,
2626 &spr_read_generic
, &spr_write_generic
,
2630 static void gen_spr_8xx(CPUPPCState
*env
)
2632 /* XXX : not implemented */
2633 spr_register(env
, SPR_MPC_IC_CST
, "IC_CST",
2634 SPR_NOACCESS
, SPR_NOACCESS
,
2635 &spr_read_generic
, &spr_write_generic
,
2637 /* XXX : not implemented */
2638 spr_register(env
, SPR_MPC_IC_ADR
, "IC_ADR",
2639 SPR_NOACCESS
, SPR_NOACCESS
,
2640 &spr_read_generic
, &spr_write_generic
,
2642 /* XXX : not implemented */
2643 spr_register(env
, SPR_MPC_IC_DAT
, "IC_DAT",
2644 SPR_NOACCESS
, SPR_NOACCESS
,
2645 &spr_read_generic
, &spr_write_generic
,
2647 /* XXX : not implemented */
2648 spr_register(env
, SPR_MPC_DC_CST
, "DC_CST",
2649 SPR_NOACCESS
, SPR_NOACCESS
,
2650 &spr_read_generic
, &spr_write_generic
,
2652 /* XXX : not implemented */
2653 spr_register(env
, SPR_MPC_DC_ADR
, "DC_ADR",
2654 SPR_NOACCESS
, SPR_NOACCESS
,
2655 &spr_read_generic
, &spr_write_generic
,
2657 /* XXX : not implemented */
2658 spr_register(env
, SPR_MPC_DC_DAT
, "DC_DAT",
2659 SPR_NOACCESS
, SPR_NOACCESS
,
2660 &spr_read_generic
, &spr_write_generic
,
2662 /* XXX : not implemented */
2663 spr_register(env
, SPR_MPC_MI_CTR
, "MI_CTR",
2664 SPR_NOACCESS
, SPR_NOACCESS
,
2665 &spr_read_generic
, &spr_write_generic
,
2667 /* XXX : not implemented */
2668 spr_register(env
, SPR_MPC_MI_AP
, "MI_AP",
2669 SPR_NOACCESS
, SPR_NOACCESS
,
2670 &spr_read_generic
, &spr_write_generic
,
2672 /* XXX : not implemented */
2673 spr_register(env
, SPR_MPC_MI_EPN
, "MI_EPN",
2674 SPR_NOACCESS
, SPR_NOACCESS
,
2675 &spr_read_generic
, &spr_write_generic
,
2677 /* XXX : not implemented */
2678 spr_register(env
, SPR_MPC_MI_TWC
, "MI_TWC",
2679 SPR_NOACCESS
, SPR_NOACCESS
,
2680 &spr_read_generic
, &spr_write_generic
,
2682 /* XXX : not implemented */
2683 spr_register(env
, SPR_MPC_MI_RPN
, "MI_RPN",
2684 SPR_NOACCESS
, SPR_NOACCESS
,
2685 &spr_read_generic
, &spr_write_generic
,
2687 /* XXX : not implemented */
2688 spr_register(env
, SPR_MPC_MI_DBCAM
, "MI_DBCAM",
2689 SPR_NOACCESS
, SPR_NOACCESS
,
2690 &spr_read_generic
, &spr_write_generic
,
2692 /* XXX : not implemented */
2693 spr_register(env
, SPR_MPC_MI_DBRAM0
, "MI_DBRAM0",
2694 SPR_NOACCESS
, SPR_NOACCESS
,
2695 &spr_read_generic
, &spr_write_generic
,
2697 /* XXX : not implemented */
2698 spr_register(env
, SPR_MPC_MI_DBRAM1
, "MI_DBRAM1",
2699 SPR_NOACCESS
, SPR_NOACCESS
,
2700 &spr_read_generic
, &spr_write_generic
,
2702 /* XXX : not implemented */
2703 spr_register(env
, SPR_MPC_MD_CTR
, "MD_CTR",
2704 SPR_NOACCESS
, SPR_NOACCESS
,
2705 &spr_read_generic
, &spr_write_generic
,
2707 /* XXX : not implemented */
2708 spr_register(env
, SPR_MPC_MD_CASID
, "MD_CASID",
2709 SPR_NOACCESS
, SPR_NOACCESS
,
2710 &spr_read_generic
, &spr_write_generic
,
2712 /* XXX : not implemented */
2713 spr_register(env
, SPR_MPC_MD_AP
, "MD_AP",
2714 SPR_NOACCESS
, SPR_NOACCESS
,
2715 &spr_read_generic
, &spr_write_generic
,
2717 /* XXX : not implemented */
2718 spr_register(env
, SPR_MPC_MD_EPN
, "MD_EPN",
2719 SPR_NOACCESS
, SPR_NOACCESS
,
2720 &spr_read_generic
, &spr_write_generic
,
2722 /* XXX : not implemented */
2723 spr_register(env
, SPR_MPC_MD_TWB
, "MD_TWB",
2724 SPR_NOACCESS
, SPR_NOACCESS
,
2725 &spr_read_generic
, &spr_write_generic
,
2727 /* XXX : not implemented */
2728 spr_register(env
, SPR_MPC_MD_TWC
, "MD_TWC",
2729 SPR_NOACCESS
, SPR_NOACCESS
,
2730 &spr_read_generic
, &spr_write_generic
,
2732 /* XXX : not implemented */
2733 spr_register(env
, SPR_MPC_MD_RPN
, "MD_RPN",
2734 SPR_NOACCESS
, SPR_NOACCESS
,
2735 &spr_read_generic
, &spr_write_generic
,
2737 /* XXX : not implemented */
2738 spr_register(env
, SPR_MPC_MD_TW
, "MD_TW",
2739 SPR_NOACCESS
, SPR_NOACCESS
,
2740 &spr_read_generic
, &spr_write_generic
,
2742 /* XXX : not implemented */
2743 spr_register(env
, SPR_MPC_MD_DBCAM
, "MD_DBCAM",
2744 SPR_NOACCESS
, SPR_NOACCESS
,
2745 &spr_read_generic
, &spr_write_generic
,
2747 /* XXX : not implemented */
2748 spr_register(env
, SPR_MPC_MD_DBRAM0
, "MD_DBRAM0",
2749 SPR_NOACCESS
, SPR_NOACCESS
,
2750 &spr_read_generic
, &spr_write_generic
,
2752 /* XXX : not implemented */
2753 spr_register(env
, SPR_MPC_MD_DBRAM1
, "MD_DBRAM1",
2754 SPR_NOACCESS
, SPR_NOACCESS
,
2755 &spr_read_generic
, &spr_write_generic
,
2761 * AMR => SPR 29 (Power 2.04)
2762 * CTRL => SPR 136 (Power 2.04)
2763 * CTRL => SPR 152 (Power 2.04)
2764 * SCOMC => SPR 276 (64 bits ?)
2765 * SCOMD => SPR 277 (64 bits ?)
2766 * TBU40 => SPR 286 (Power 2.04 hypv)
2767 * HSPRG0 => SPR 304 (Power 2.04 hypv)
2768 * HSPRG1 => SPR 305 (Power 2.04 hypv)
2769 * HDSISR => SPR 306 (Power 2.04 hypv)
2770 * HDAR => SPR 307 (Power 2.04 hypv)
2771 * PURR => SPR 309 (Power 2.04 hypv)
2772 * HDEC => SPR 310 (Power 2.04 hypv)
2773 * HIOR => SPR 311 (hypv)
2774 * RMOR => SPR 312 (970)
2775 * HRMOR => SPR 313 (Power 2.04 hypv)
2776 * HSRR0 => SPR 314 (Power 2.04 hypv)
2777 * HSRR1 => SPR 315 (Power 2.04 hypv)
2778 * LPIDR => SPR 317 (970)
2779 * EPR => SPR 702 (Power 2.04 emb)
2780 * perf => 768-783 (Power 2.04)
2781 * perf => 784-799 (Power 2.04)
2782 * PPR => SPR 896 (Power 2.04)
2783 * EPLC => SPR 947 (Power 2.04 emb)
2784 * EPSC => SPR 948 (Power 2.04 emb)
2785 * DABRX => 1015 (Power 2.04 hypv)
2786 * FPECR => SPR 1022 (?)
2787 * ... and more (thermal management, performance counters, ...)
2790 /*****************************************************************************/
2791 /* Exception vectors models */
2792 static void init_excp_4xx_real(CPUPPCState
*env
)
2794 #if !defined(CONFIG_USER_ONLY)
2795 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000100;
2796 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2797 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2798 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2799 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2800 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2801 env
->excp_vectors
[POWERPC_EXCP_PIT
] = 0x00001000;
2802 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00001010;
2803 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001020;
2804 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00002000;
2805 env
->ivor_mask
= 0x0000FFF0UL
;
2806 env
->ivpr_mask
= 0xFFFF0000UL
;
2807 /* Hardware reset vector */
2808 env
->hreset_vector
= 0xFFFFFFFCUL
;
2812 static void init_excp_4xx_softmmu(CPUPPCState
*env
)
2814 #if !defined(CONFIG_USER_ONLY)
2815 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000100;
2816 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2817 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2818 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2819 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2820 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2821 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2822 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2823 env
->excp_vectors
[POWERPC_EXCP_PIT
] = 0x00001000;
2824 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00001010;
2825 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001020;
2826 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00001100;
2827 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00001200;
2828 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00002000;
2829 env
->ivor_mask
= 0x0000FFF0UL
;
2830 env
->ivpr_mask
= 0xFFFF0000UL
;
2831 /* Hardware reset vector */
2832 env
->hreset_vector
= 0xFFFFFFFCUL
;
2836 static void init_excp_MPC5xx(CPUPPCState
*env
)
2838 #if !defined(CONFIG_USER_ONLY)
2839 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2840 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2841 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2842 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2843 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2844 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000900;
2845 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2846 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2847 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2848 env
->excp_vectors
[POWERPC_EXCP_FPA
] = 0x00000E00;
2849 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001000;
2850 env
->excp_vectors
[POWERPC_EXCP_DABR
] = 0x00001C00;
2851 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001C00;
2852 env
->excp_vectors
[POWERPC_EXCP_MEXTBR
] = 0x00001E00;
2853 env
->excp_vectors
[POWERPC_EXCP_NMEXTBR
] = 0x00001F00;
2854 env
->ivor_mask
= 0x0000FFF0UL
;
2855 env
->ivpr_mask
= 0xFFFF0000UL
;
2856 /* Hardware reset vector */
2857 env
->hreset_vector
= 0x00000100UL
;
2861 static void init_excp_MPC8xx(CPUPPCState
*env
)
2863 #if !defined(CONFIG_USER_ONLY)
2864 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2865 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2866 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2867 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2868 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2869 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2870 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2871 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000900;
2872 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2873 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2874 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2875 env
->excp_vectors
[POWERPC_EXCP_FPA
] = 0x00000E00;
2876 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001000;
2877 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00001100;
2878 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00001200;
2879 env
->excp_vectors
[POWERPC_EXCP_ITLBE
] = 0x00001300;
2880 env
->excp_vectors
[POWERPC_EXCP_DTLBE
] = 0x00001400;
2881 env
->excp_vectors
[POWERPC_EXCP_DABR
] = 0x00001C00;
2882 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001C00;
2883 env
->excp_vectors
[POWERPC_EXCP_MEXTBR
] = 0x00001E00;
2884 env
->excp_vectors
[POWERPC_EXCP_NMEXTBR
] = 0x00001F00;
2885 env
->ivor_mask
= 0x0000FFF0UL
;
2886 env
->ivpr_mask
= 0xFFFF0000UL
;
2887 /* Hardware reset vector */
2888 env
->hreset_vector
= 0x00000100UL
;
2892 static void init_excp_G2(CPUPPCState
*env
)
2894 #if !defined(CONFIG_USER_ONLY)
2895 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2896 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2897 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2898 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2899 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2900 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2901 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2902 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
2903 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2904 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000A00;
2905 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2906 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2907 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
2908 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
2909 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
2910 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
2911 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
2912 /* Hardware reset vector */
2913 env
->hreset_vector
= 0x00000100UL
;
2917 static void init_excp_e200(CPUPPCState
*env
, target_ulong ivpr_mask
)
2919 #if !defined(CONFIG_USER_ONLY)
2920 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000FFC;
2921 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000000;
2922 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000000;
2923 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000000;
2924 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000000;
2925 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000000;
2926 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000000;
2927 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000000;
2928 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000000;
2929 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000000;
2930 env
->excp_vectors
[POWERPC_EXCP_APU
] = 0x00000000;
2931 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000000;
2932 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00000000;
2933 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00000000;
2934 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00000000;
2935 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00000000;
2936 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00000000;
2937 env
->excp_vectors
[POWERPC_EXCP_SPEU
] = 0x00000000;
2938 env
->excp_vectors
[POWERPC_EXCP_EFPDI
] = 0x00000000;
2939 env
->excp_vectors
[POWERPC_EXCP_EFPRI
] = 0x00000000;
2940 env
->ivor_mask
= 0x0000FFF7UL
;
2941 env
->ivpr_mask
= ivpr_mask
;
2942 /* Hardware reset vector */
2943 env
->hreset_vector
= 0xFFFFFFFCUL
;
2947 static void init_excp_BookE(CPUPPCState
*env
)
2949 #if !defined(CONFIG_USER_ONLY)
2950 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000000;
2951 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000000;
2952 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000000;
2953 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000000;
2954 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000000;
2955 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000000;
2956 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000000;
2957 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000000;
2958 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000000;
2959 env
->excp_vectors
[POWERPC_EXCP_APU
] = 0x00000000;
2960 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000000;
2961 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00000000;
2962 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00000000;
2963 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00000000;
2964 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00000000;
2965 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00000000;
2966 env
->ivor_mask
= 0x0000FFF0UL
;
2967 env
->ivpr_mask
= 0xFFFF0000UL
;
2968 /* Hardware reset vector */
2969 env
->hreset_vector
= 0xFFFFFFFCUL
;
2973 static void init_excp_601(CPUPPCState
*env
)
2975 #if !defined(CONFIG_USER_ONLY)
2976 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2977 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2978 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2979 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2980 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2981 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2982 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2983 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
2984 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2985 env
->excp_vectors
[POWERPC_EXCP_IO
] = 0x00000A00;
2986 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2987 env
->excp_vectors
[POWERPC_EXCP_RUNM
] = 0x00002000;
2988 /* Hardware reset vector */
2989 env
->hreset_vector
= 0x00000100UL
;
2993 static void init_excp_602(CPUPPCState
*env
)
2995 #if !defined(CONFIG_USER_ONLY)
2996 /* XXX: exception prefix has a special behavior on 602 */
2997 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2998 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2999 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3000 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3001 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3002 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3003 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3004 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3005 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3006 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3007 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3008 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3009 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3010 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3011 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3012 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3013 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001500;
3014 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001600;
3015 /* Hardware reset vector */
3016 env
->hreset_vector
= 0x00000100UL
;
3020 static void init_excp_603(CPUPPCState
*env
)
3022 #if !defined(CONFIG_USER_ONLY)
3023 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3024 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3025 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3026 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3027 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3028 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3029 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3030 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3031 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3032 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3033 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3034 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3035 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3036 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3037 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3038 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3039 /* Hardware reset vector */
3040 env
->hreset_vector
= 0x00000100UL
;
3044 static void init_excp_604(CPUPPCState
*env
)
3046 #if !defined(CONFIG_USER_ONLY)
3047 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3048 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3049 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3050 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3051 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3052 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3053 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3054 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3055 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3056 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3057 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3058 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3059 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3060 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3061 /* Hardware reset vector */
3062 env
->hreset_vector
= 0x00000100UL
;
3066 static void init_excp_7x0(CPUPPCState
*env
)
3068 #if !defined(CONFIG_USER_ONLY)
3069 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3070 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3071 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3072 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3073 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3074 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3075 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3076 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3077 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3078 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3079 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3080 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3081 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3082 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3083 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3084 /* Hardware reset vector */
3085 env
->hreset_vector
= 0x00000100UL
;
3089 static void init_excp_750cl(CPUPPCState
*env
)
3091 #if !defined(CONFIG_USER_ONLY)
3092 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3093 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3094 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3095 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3096 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3097 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3098 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3099 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3100 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3101 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3102 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3103 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3104 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3105 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3106 /* Hardware reset vector */
3107 env
->hreset_vector
= 0x00000100UL
;
3111 static void init_excp_750cx(CPUPPCState
*env
)
3113 #if !defined(CONFIG_USER_ONLY)
3114 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3115 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3116 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3117 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3118 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3119 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3120 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3121 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3122 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3123 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3124 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3125 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3126 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3127 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3128 /* Hardware reset vector */
3129 env
->hreset_vector
= 0x00000100UL
;
3133 /* XXX: Check if this is correct */
3134 static void init_excp_7x5(CPUPPCState
*env
)
3136 #if !defined(CONFIG_USER_ONLY)
3137 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3138 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3139 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3140 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3141 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3142 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3143 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3144 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3145 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3146 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3147 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3148 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3149 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3150 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3151 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3152 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3153 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3154 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3155 /* Hardware reset vector */
3156 env
->hreset_vector
= 0x00000100UL
;
3160 static void init_excp_7400(CPUPPCState
*env
)
3162 #if !defined(CONFIG_USER_ONLY)
3163 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3164 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3165 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3166 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3167 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3168 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3169 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3170 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3171 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3172 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3173 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3174 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3175 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3176 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3177 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3178 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001600;
3179 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3180 /* Hardware reset vector */
3181 env
->hreset_vector
= 0x00000100UL
;
3185 static void init_excp_7450(CPUPPCState
*env
)
3187 #if !defined(CONFIG_USER_ONLY)
3188 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3189 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3190 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3191 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3192 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3193 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3194 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3195 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3196 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3197 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3198 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3199 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3200 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3201 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3202 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3203 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3204 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3205 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3206 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001600;
3207 /* Hardware reset vector */
3208 env
->hreset_vector
= 0x00000100UL
;
3212 #if defined(TARGET_PPC64)
3213 static void init_excp_970(CPUPPCState
*env
)
3215 #if !defined(CONFIG_USER_ONLY)
3216 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3217 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3218 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3219 env
->excp_vectors
[POWERPC_EXCP_DSEG
] = 0x00000380;
3220 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3221 env
->excp_vectors
[POWERPC_EXCP_ISEG
] = 0x00000480;
3222 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3223 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3224 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3225 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3226 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3227 env
->excp_vectors
[POWERPC_EXCP_HDECR
] = 0x00000980;
3228 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3229 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3230 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3231 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3232 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3233 env
->excp_vectors
[POWERPC_EXCP_MAINT
] = 0x00001600;
3234 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001700;
3235 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001800;
3236 /* Hardware reset vector */
3237 env
->hreset_vector
= 0x0000000000000100ULL
;
3241 static void init_excp_POWER7(CPUPPCState
*env
)
3243 #if !defined(CONFIG_USER_ONLY)
3244 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3245 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3246 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3247 env
->excp_vectors
[POWERPC_EXCP_DSEG
] = 0x00000380;
3248 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3249 env
->excp_vectors
[POWERPC_EXCP_ISEG
] = 0x00000480;
3250 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3251 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3252 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3253 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3254 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3255 env
->excp_vectors
[POWERPC_EXCP_HDECR
] = 0x00000980;
3256 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3257 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3258 env
->excp_vectors
[POWERPC_EXCP_HDSI
] = 0x00000E00;
3259 env
->excp_vectors
[POWERPC_EXCP_HISI
] = 0x00000E20;
3260 env
->excp_vectors
[POWERPC_EXCP_HV_EMU
] = 0x00000E40;
3261 env
->excp_vectors
[POWERPC_EXCP_HV_MAINT
] = 0x00000E60;
3262 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3263 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3264 env
->excp_vectors
[POWERPC_EXCP_VSXU
] = 0x00000F40;
3265 /* Hardware reset vector */
3266 env
->hreset_vector
= 0x0000000000000100ULL
;
3270 static void init_excp_POWER8(CPUPPCState
*env
)
3272 init_excp_POWER7(env
);
3274 #if !defined(CONFIG_USER_ONLY)
3275 env
->excp_vectors
[POWERPC_EXCP_SDOOR
] = 0x00000A00;
3276 env
->excp_vectors
[POWERPC_EXCP_FU
] = 0x00000F60;
3277 env
->excp_vectors
[POWERPC_EXCP_HV_FU
] = 0x00000F80;
3278 env
->excp_vectors
[POWERPC_EXCP_SDOOR_HV
] = 0x00000E80;
3284 /*****************************************************************************/
3285 /* Power management enable checks */
3286 static int check_pow_none(CPUPPCState
*env
)
3291 static int check_pow_nocheck(CPUPPCState
*env
)
3296 static int check_pow_hid0(CPUPPCState
*env
)
3298 if (env
->spr
[SPR_HID0
] & 0x00E00000)
3304 static int check_pow_hid0_74xx(CPUPPCState
*env
)
3306 if (env
->spr
[SPR_HID0
] & 0x00600000)
3312 static bool ppc_cpu_interrupts_big_endian_always(PowerPCCPU
*cpu
)
3318 static bool ppc_cpu_interrupts_big_endian_lpcr(PowerPCCPU
*cpu
)
3320 return !(cpu
->env
.spr
[SPR_LPCR
] & LPCR_ILE
);
3324 /*****************************************************************************/
3325 /* PowerPC implementations definitions */
3327 #define POWERPC_FAMILY(_name) \
3329 glue(glue(ppc_, _name), _cpu_family_class_init)(ObjectClass *, void *); \
3331 static const TypeInfo \
3332 glue(glue(ppc_, _name), _cpu_family_type_info) = { \
3333 .name = stringify(_name) "-family-" TYPE_POWERPC_CPU, \
3334 .parent = TYPE_POWERPC_CPU, \
3336 .class_init = glue(glue(ppc_, _name), _cpu_family_class_init), \
3339 static void glue(glue(ppc_, _name), _cpu_family_register_types)(void) \
3341 type_register_static( \
3342 &glue(glue(ppc_, _name), _cpu_family_type_info)); \
3345 type_init(glue(glue(ppc_, _name), _cpu_family_register_types)) \
3347 static void glue(glue(ppc_, _name), _cpu_family_class_init)
3349 static void init_proc_401(CPUPPCState
*env
)
3352 gen_spr_401_403(env
);
3354 init_excp_4xx_real(env
);
3355 env
->dcache_line_size
= 32;
3356 env
->icache_line_size
= 32;
3357 /* Allocate hardware IRQ controller */
3358 ppc40x_irq_init(ppc_env_get_cpu(env
));
3360 SET_FIT_PERIOD(12, 16, 20, 24);
3361 SET_WDT_PERIOD(16, 20, 24, 28);
3364 POWERPC_FAMILY(401)(ObjectClass
*oc
, void *data
)
3366 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3367 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3369 dc
->desc
= "PowerPC 401";
3370 pcc
->init_proc
= init_proc_401
;
3371 pcc
->check_pow
= check_pow_nocheck
;
3372 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3373 PPC_WRTEE
| PPC_DCR
|
3374 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3376 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3377 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3378 pcc
->msr_mask
= (1ull << MSR_KEY
) |
3387 pcc
->mmu_model
= POWERPC_MMU_REAL
;
3388 pcc
->excp_model
= POWERPC_EXCP_40x
;
3389 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3390 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3391 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3392 POWERPC_FLAG_BUS_CLK
;
3395 static void init_proc_401x2(CPUPPCState
*env
)
3398 gen_spr_401_403(env
);
3400 gen_spr_compress(env
);
3401 /* Memory management */
3402 #if !defined(CONFIG_USER_ONLY)
3406 env
->tlb_type
= TLB_EMB
;
3408 init_excp_4xx_softmmu(env
);
3409 env
->dcache_line_size
= 32;
3410 env
->icache_line_size
= 32;
3411 /* Allocate hardware IRQ controller */
3412 ppc40x_irq_init(ppc_env_get_cpu(env
));
3414 SET_FIT_PERIOD(12, 16, 20, 24);
3415 SET_WDT_PERIOD(16, 20, 24, 28);
3418 POWERPC_FAMILY(401x2
)(ObjectClass
*oc
, void *data
)
3420 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3421 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3423 dc
->desc
= "PowerPC 401x2";
3424 pcc
->init_proc
= init_proc_401x2
;
3425 pcc
->check_pow
= check_pow_nocheck
;
3426 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3427 PPC_DCR
| PPC_WRTEE
|
3428 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3429 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3430 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3431 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3432 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3433 pcc
->msr_mask
= (1ull << 20) |
3445 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3446 pcc
->excp_model
= POWERPC_EXCP_40x
;
3447 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3448 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3449 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3450 POWERPC_FLAG_BUS_CLK
;
3453 static void init_proc_401x3(CPUPPCState
*env
)
3456 gen_spr_401_403(env
);
3459 gen_spr_compress(env
);
3460 init_excp_4xx_softmmu(env
);
3461 env
->dcache_line_size
= 32;
3462 env
->icache_line_size
= 32;
3463 /* Allocate hardware IRQ controller */
3464 ppc40x_irq_init(ppc_env_get_cpu(env
));
3466 SET_FIT_PERIOD(12, 16, 20, 24);
3467 SET_WDT_PERIOD(16, 20, 24, 28);
3470 POWERPC_FAMILY(401x3
)(ObjectClass
*oc
, void *data
)
3472 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3473 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3475 dc
->desc
= "PowerPC 401x3";
3476 pcc
->init_proc
= init_proc_401x3
;
3477 pcc
->check_pow
= check_pow_nocheck
;
3478 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3479 PPC_DCR
| PPC_WRTEE
|
3480 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3481 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3482 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3483 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3484 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3485 pcc
->msr_mask
= (1ull << 20) |
3498 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3499 pcc
->excp_model
= POWERPC_EXCP_40x
;
3500 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3501 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3502 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3503 POWERPC_FLAG_BUS_CLK
;
3506 static void init_proc_IOP480(CPUPPCState
*env
)
3509 gen_spr_401_403(env
);
3511 gen_spr_compress(env
);
3512 /* Memory management */
3513 #if !defined(CONFIG_USER_ONLY)
3517 env
->tlb_type
= TLB_EMB
;
3519 init_excp_4xx_softmmu(env
);
3520 env
->dcache_line_size
= 32;
3521 env
->icache_line_size
= 32;
3522 /* Allocate hardware IRQ controller */
3523 ppc40x_irq_init(ppc_env_get_cpu(env
));
3525 SET_FIT_PERIOD(8, 12, 16, 20);
3526 SET_WDT_PERIOD(16, 20, 24, 28);
3529 POWERPC_FAMILY(IOP480
)(ObjectClass
*oc
, void *data
)
3531 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3532 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3534 dc
->desc
= "IOP480";
3535 pcc
->init_proc
= init_proc_IOP480
;
3536 pcc
->check_pow
= check_pow_nocheck
;
3537 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3538 PPC_DCR
| PPC_WRTEE
|
3539 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3540 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3541 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3542 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3543 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3544 pcc
->msr_mask
= (1ull << 20) |
3556 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3557 pcc
->excp_model
= POWERPC_EXCP_40x
;
3558 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3559 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3560 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3561 POWERPC_FLAG_BUS_CLK
;
3564 static void init_proc_403(CPUPPCState
*env
)
3567 gen_spr_401_403(env
);
3569 gen_spr_403_real(env
);
3570 init_excp_4xx_real(env
);
3571 env
->dcache_line_size
= 32;
3572 env
->icache_line_size
= 32;
3573 /* Allocate hardware IRQ controller */
3574 ppc40x_irq_init(ppc_env_get_cpu(env
));
3576 SET_FIT_PERIOD(8, 12, 16, 20);
3577 SET_WDT_PERIOD(16, 20, 24, 28);
3580 POWERPC_FAMILY(403)(ObjectClass
*oc
, void *data
)
3582 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3583 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3585 dc
->desc
= "PowerPC 403";
3586 pcc
->init_proc
= init_proc_403
;
3587 pcc
->check_pow
= check_pow_nocheck
;
3588 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3589 PPC_DCR
| PPC_WRTEE
|
3590 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3592 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3593 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3594 pcc
->msr_mask
= (1ull << MSR_POW
) |
3603 pcc
->mmu_model
= POWERPC_MMU_REAL
;
3604 pcc
->excp_model
= POWERPC_EXCP_40x
;
3605 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3606 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3607 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_PX
|
3608 POWERPC_FLAG_BUS_CLK
;
3611 static void init_proc_403GCX(CPUPPCState
*env
)
3614 gen_spr_401_403(env
);
3616 gen_spr_403_real(env
);
3617 gen_spr_403_mmu(env
);
3618 /* Bus access control */
3619 /* not emulated, as QEMU never does speculative access */
3620 spr_register(env
, SPR_40x_SGR
, "SGR",
3621 SPR_NOACCESS
, SPR_NOACCESS
,
3622 &spr_read_generic
, &spr_write_generic
,
3624 /* not emulated, as QEMU do not emulate caches */
3625 spr_register(env
, SPR_40x_DCWR
, "DCWR",
3626 SPR_NOACCESS
, SPR_NOACCESS
,
3627 &spr_read_generic
, &spr_write_generic
,
3629 /* Memory management */
3630 #if !defined(CONFIG_USER_ONLY)
3634 env
->tlb_type
= TLB_EMB
;
3636 init_excp_4xx_softmmu(env
);
3637 env
->dcache_line_size
= 32;
3638 env
->icache_line_size
= 32;
3639 /* Allocate hardware IRQ controller */
3640 ppc40x_irq_init(ppc_env_get_cpu(env
));
3642 SET_FIT_PERIOD(8, 12, 16, 20);
3643 SET_WDT_PERIOD(16, 20, 24, 28);
3646 POWERPC_FAMILY(403GCX
)(ObjectClass
*oc
, void *data
)
3648 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3649 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3651 dc
->desc
= "PowerPC 403 GCX";
3652 pcc
->init_proc
= init_proc_403GCX
;
3653 pcc
->check_pow
= check_pow_nocheck
;
3654 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3655 PPC_DCR
| PPC_WRTEE
|
3656 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3658 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3659 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3660 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3661 pcc
->msr_mask
= (1ull << MSR_POW
) |
3670 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3671 pcc
->excp_model
= POWERPC_EXCP_40x
;
3672 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3673 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3674 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_PX
|
3675 POWERPC_FLAG_BUS_CLK
;
3678 static void init_proc_405(CPUPPCState
*env
)
3684 /* Bus access control */
3685 /* not emulated, as QEMU never does speculative access */
3686 spr_register(env
, SPR_40x_SGR
, "SGR",
3687 SPR_NOACCESS
, SPR_NOACCESS
,
3688 &spr_read_generic
, &spr_write_generic
,
3690 /* not emulated, as QEMU do not emulate caches */
3691 spr_register(env
, SPR_40x_DCWR
, "DCWR",
3692 SPR_NOACCESS
, SPR_NOACCESS
,
3693 &spr_read_generic
, &spr_write_generic
,
3695 /* Memory management */
3696 #if !defined(CONFIG_USER_ONLY)
3700 env
->tlb_type
= TLB_EMB
;
3702 init_excp_4xx_softmmu(env
);
3703 env
->dcache_line_size
= 32;
3704 env
->icache_line_size
= 32;
3705 /* Allocate hardware IRQ controller */
3706 ppc40x_irq_init(ppc_env_get_cpu(env
));
3708 SET_FIT_PERIOD(8, 12, 16, 20);
3709 SET_WDT_PERIOD(16, 20, 24, 28);
3712 POWERPC_FAMILY(405)(ObjectClass
*oc
, void *data
)
3714 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3715 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3717 dc
->desc
= "PowerPC 405";
3718 pcc
->init_proc
= init_proc_405
;
3719 pcc
->check_pow
= check_pow_nocheck
;
3720 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3721 PPC_DCR
| PPC_WRTEE
|
3722 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3723 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3724 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3725 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3726 PPC_4xx_COMMON
| PPC_405_MAC
| PPC_40x_EXCP
;
3727 pcc
->msr_mask
= (1ull << MSR_POW
) |
3736 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx
;
3737 pcc
->excp_model
= POWERPC_EXCP_40x
;
3738 pcc
->bus_model
= PPC_FLAGS_INPUT_405
;
3739 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3740 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3741 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3744 static void init_proc_440EP(CPUPPCState
*env
)
3748 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3750 gen_spr_usprgh(env
);
3751 /* Processor identification */
3752 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3753 SPR_NOACCESS
, SPR_NOACCESS
,
3754 &spr_read_generic
, &spr_write_pir
,
3756 /* XXX : not implemented */
3757 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
3758 SPR_NOACCESS
, SPR_NOACCESS
,
3759 &spr_read_generic
, &spr_write_generic
,
3761 /* XXX : not implemented */
3762 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
3763 SPR_NOACCESS
, SPR_NOACCESS
,
3764 &spr_read_generic
, &spr_write_generic
,
3766 /* XXX : not implemented */
3767 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
3768 SPR_NOACCESS
, SPR_NOACCESS
,
3769 &spr_read_generic
, &spr_write_generic
,
3771 /* XXX : not implemented */
3772 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
3773 SPR_NOACCESS
, SPR_NOACCESS
,
3774 &spr_read_generic
, &spr_write_generic
,
3776 /* XXX : not implemented */
3777 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
3778 SPR_NOACCESS
, SPR_NOACCESS
,
3779 &spr_read_generic
, &spr_write_generic
,
3781 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
3782 SPR_NOACCESS
, SPR_NOACCESS
,
3783 &spr_read_generic
, &spr_write_generic
,
3785 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
3786 SPR_NOACCESS
, SPR_NOACCESS
,
3787 &spr_read_generic
, &spr_write_generic
,
3789 /* XXX : not implemented */
3790 spr_register(env
, SPR_440_CCR1
, "CCR1",
3791 SPR_NOACCESS
, SPR_NOACCESS
,
3792 &spr_read_generic
, &spr_write_generic
,
3794 /* Memory management */
3795 #if !defined(CONFIG_USER_ONLY)
3799 env
->tlb_type
= TLB_EMB
;
3801 init_excp_BookE(env
);
3802 env
->dcache_line_size
= 32;
3803 env
->icache_line_size
= 32;
3804 ppc40x_irq_init(ppc_env_get_cpu(env
));
3806 SET_FIT_PERIOD(12, 16, 20, 24);
3807 SET_WDT_PERIOD(20, 24, 28, 32);
3810 POWERPC_FAMILY(440EP
)(ObjectClass
*oc
, void *data
)
3812 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3813 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3815 dc
->desc
= "PowerPC 440 EP";
3816 pcc
->init_proc
= init_proc_440EP
;
3817 pcc
->check_pow
= check_pow_nocheck
;
3818 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3819 PPC_FLOAT
| PPC_FLOAT_FRES
| PPC_FLOAT_FSEL
|
3820 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
3822 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
3823 PPC_CACHE
| PPC_CACHE_ICBI
|
3824 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3825 PPC_MEM_TLBSYNC
| PPC_MFTB
|
3826 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3828 pcc
->msr_mask
= (1ull << MSR_POW
) |
3840 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3841 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3842 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3843 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3844 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3845 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3848 POWERPC_FAMILY(460EX
)(ObjectClass
*oc
, void *data
)
3850 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3851 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3853 dc
->desc
= "PowerPC 460 EX";
3854 pcc
->init_proc
= init_proc_440EP
;
3855 pcc
->check_pow
= check_pow_nocheck
;
3856 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3857 PPC_FLOAT
| PPC_FLOAT_FRES
| PPC_FLOAT_FSEL
|
3858 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
3860 PPC_DCR
| PPC_DCRX
| PPC_WRTEE
| PPC_RFMCI
|
3861 PPC_CACHE
| PPC_CACHE_ICBI
|
3862 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3863 PPC_MEM_TLBSYNC
| PPC_MFTB
|
3864 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3866 pcc
->msr_mask
= (1ull << MSR_POW
) |
3878 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3879 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3880 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3881 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3882 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3883 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3886 static void init_proc_440GP(CPUPPCState
*env
)
3890 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3892 gen_spr_usprgh(env
);
3893 /* Processor identification */
3894 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3895 SPR_NOACCESS
, SPR_NOACCESS
,
3896 &spr_read_generic
, &spr_write_pir
,
3898 /* XXX : not implemented */
3899 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
3900 SPR_NOACCESS
, SPR_NOACCESS
,
3901 &spr_read_generic
, &spr_write_generic
,
3903 /* XXX : not implemented */
3904 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
3905 SPR_NOACCESS
, SPR_NOACCESS
,
3906 &spr_read_generic
, &spr_write_generic
,
3908 /* XXX : not implemented */
3909 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
3910 SPR_NOACCESS
, SPR_NOACCESS
,
3911 &spr_read_generic
, &spr_write_generic
,
3913 /* XXX : not implemented */
3914 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
3915 SPR_NOACCESS
, SPR_NOACCESS
,
3916 &spr_read_generic
, &spr_write_generic
,
3918 /* Memory management */
3919 #if !defined(CONFIG_USER_ONLY)
3923 env
->tlb_type
= TLB_EMB
;
3925 init_excp_BookE(env
);
3926 env
->dcache_line_size
= 32;
3927 env
->icache_line_size
= 32;
3928 /* XXX: TODO: allocate internal IRQ controller */
3930 SET_FIT_PERIOD(12, 16, 20, 24);
3931 SET_WDT_PERIOD(20, 24, 28, 32);
3934 POWERPC_FAMILY(440GP
)(ObjectClass
*oc
, void *data
)
3936 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3937 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3939 dc
->desc
= "PowerPC 440 GP";
3940 pcc
->init_proc
= init_proc_440GP
;
3941 pcc
->check_pow
= check_pow_nocheck
;
3942 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3943 PPC_DCR
| PPC_DCRX
| PPC_WRTEE
| PPC_MFAPIDI
|
3944 PPC_CACHE
| PPC_CACHE_ICBI
|
3945 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3946 PPC_MEM_TLBSYNC
| PPC_TLBIVA
| PPC_MFTB
|
3947 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3949 pcc
->msr_mask
= (1ull << MSR_POW
) |
3961 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3962 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3963 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3964 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3965 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3966 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3969 static void init_proc_440x4(CPUPPCState
*env
)
3973 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3975 gen_spr_usprgh(env
);
3976 /* Processor identification */
3977 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3978 SPR_NOACCESS
, SPR_NOACCESS
,
3979 &spr_read_generic
, &spr_write_pir
,
3981 /* XXX : not implemented */
3982 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
3983 SPR_NOACCESS
, SPR_NOACCESS
,
3984 &spr_read_generic
, &spr_write_generic
,
3986 /* XXX : not implemented */
3987 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
3988 SPR_NOACCESS
, SPR_NOACCESS
,
3989 &spr_read_generic
, &spr_write_generic
,
3991 /* XXX : not implemented */
3992 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
3993 SPR_NOACCESS
, SPR_NOACCESS
,
3994 &spr_read_generic
, &spr_write_generic
,
3996 /* XXX : not implemented */
3997 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
3998 SPR_NOACCESS
, SPR_NOACCESS
,
3999 &spr_read_generic
, &spr_write_generic
,
4001 /* Memory management */
4002 #if !defined(CONFIG_USER_ONLY)
4006 env
->tlb_type
= TLB_EMB
;
4008 init_excp_BookE(env
);
4009 env
->dcache_line_size
= 32;
4010 env
->icache_line_size
= 32;
4011 /* XXX: TODO: allocate internal IRQ controller */
4013 SET_FIT_PERIOD(12, 16, 20, 24);
4014 SET_WDT_PERIOD(20, 24, 28, 32);
4017 POWERPC_FAMILY(440x4
)(ObjectClass
*oc
, void *data
)
4019 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4020 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4022 dc
->desc
= "PowerPC 440x4";
4023 pcc
->init_proc
= init_proc_440x4
;
4024 pcc
->check_pow
= check_pow_nocheck
;
4025 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4026 PPC_DCR
| PPC_WRTEE
|
4027 PPC_CACHE
| PPC_CACHE_ICBI
|
4028 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4029 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4030 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4032 pcc
->msr_mask
= (1ull << MSR_POW
) |
4044 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4045 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4046 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4047 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4048 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4049 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4052 static void init_proc_440x5(CPUPPCState
*env
)
4056 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
4058 gen_spr_usprgh(env
);
4059 /* Processor identification */
4060 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4061 SPR_NOACCESS
, SPR_NOACCESS
,
4062 &spr_read_generic
, &spr_write_pir
,
4064 /* XXX : not implemented */
4065 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4066 SPR_NOACCESS
, SPR_NOACCESS
,
4067 &spr_read_generic
, &spr_write_generic
,
4069 /* XXX : not implemented */
4070 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4071 SPR_NOACCESS
, SPR_NOACCESS
,
4072 &spr_read_generic
, &spr_write_generic
,
4074 /* XXX : not implemented */
4075 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
4076 SPR_NOACCESS
, SPR_NOACCESS
,
4077 &spr_read_generic
, &spr_write_generic
,
4079 /* XXX : not implemented */
4080 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
4081 SPR_NOACCESS
, SPR_NOACCESS
,
4082 &spr_read_generic
, &spr_write_generic
,
4084 /* XXX : not implemented */
4085 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
4086 SPR_NOACCESS
, SPR_NOACCESS
,
4087 &spr_read_generic
, &spr_write_generic
,
4089 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
4090 SPR_NOACCESS
, SPR_NOACCESS
,
4091 &spr_read_generic
, &spr_write_generic
,
4093 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
4094 SPR_NOACCESS
, SPR_NOACCESS
,
4095 &spr_read_generic
, &spr_write_generic
,
4097 /* XXX : not implemented */
4098 spr_register(env
, SPR_440_CCR1
, "CCR1",
4099 SPR_NOACCESS
, SPR_NOACCESS
,
4100 &spr_read_generic
, &spr_write_generic
,
4102 /* Memory management */
4103 #if !defined(CONFIG_USER_ONLY)
4107 env
->tlb_type
= TLB_EMB
;
4109 init_excp_BookE(env
);
4110 env
->dcache_line_size
= 32;
4111 env
->icache_line_size
= 32;
4112 ppc40x_irq_init(ppc_env_get_cpu(env
));
4114 SET_FIT_PERIOD(12, 16, 20, 24);
4115 SET_WDT_PERIOD(20, 24, 28, 32);
4118 POWERPC_FAMILY(440x5
)(ObjectClass
*oc
, void *data
)
4120 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4121 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4123 dc
->desc
= "PowerPC 440x5";
4124 pcc
->init_proc
= init_proc_440x5
;
4125 pcc
->check_pow
= check_pow_nocheck
;
4126 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4127 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
4128 PPC_CACHE
| PPC_CACHE_ICBI
|
4129 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4130 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4131 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4133 pcc
->msr_mask
= (1ull << MSR_POW
) |
4145 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4146 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4147 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4148 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4149 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4150 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4153 POWERPC_FAMILY(440x5wDFPU
)(ObjectClass
*oc
, void *data
)
4155 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4156 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4158 dc
->desc
= "PowerPC 440x5 with double precision FPU";
4159 pcc
->init_proc
= init_proc_440x5
;
4160 pcc
->check_pow
= check_pow_nocheck
;
4161 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4162 PPC_FLOAT
| PPC_FLOAT_FSQRT
|
4164 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
4165 PPC_CACHE
| PPC_CACHE_ICBI
|
4166 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4167 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4168 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4170 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
4171 pcc
->msr_mask
= (1ull << MSR_POW
) |
4183 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4184 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4185 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4186 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4187 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4188 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4191 static void init_proc_MPC5xx(CPUPPCState
*env
)
4195 gen_spr_5xx_8xx(env
);
4197 init_excp_MPC5xx(env
);
4198 env
->dcache_line_size
= 32;
4199 env
->icache_line_size
= 32;
4200 /* XXX: TODO: allocate internal IRQ controller */
4203 POWERPC_FAMILY(MPC5xx
)(ObjectClass
*oc
, void *data
)
4205 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4206 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4208 dc
->desc
= "Freescale 5xx cores (aka RCPU)";
4209 pcc
->init_proc
= init_proc_MPC5xx
;
4210 pcc
->check_pow
= check_pow_none
;
4211 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4212 PPC_MEM_EIEIO
| PPC_MEM_SYNC
|
4213 PPC_CACHE_ICBI
| PPC_FLOAT
| PPC_FLOAT_STFIWX
|
4215 pcc
->msr_mask
= (1ull << MSR_ILE
) |
4227 pcc
->mmu_model
= POWERPC_MMU_REAL
;
4228 pcc
->excp_model
= POWERPC_EXCP_603
;
4229 pcc
->bus_model
= PPC_FLAGS_INPUT_RCPU
;
4230 pcc
->bfd_mach
= bfd_mach_ppc_505
;
4231 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
4232 POWERPC_FLAG_BUS_CLK
;
4235 static void init_proc_MPC8xx(CPUPPCState
*env
)
4239 gen_spr_5xx_8xx(env
);
4241 init_excp_MPC8xx(env
);
4242 env
->dcache_line_size
= 32;
4243 env
->icache_line_size
= 32;
4244 /* XXX: TODO: allocate internal IRQ controller */
4247 POWERPC_FAMILY(MPC8xx
)(ObjectClass
*oc
, void *data
)
4249 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4250 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4252 dc
->desc
= "Freescale 8xx cores (aka PowerQUICC)";
4253 pcc
->init_proc
= init_proc_MPC8xx
;
4254 pcc
->check_pow
= check_pow_none
;
4255 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4256 PPC_MEM_EIEIO
| PPC_MEM_SYNC
|
4257 PPC_CACHE_ICBI
| PPC_MFTB
;
4258 pcc
->msr_mask
= (1ull << MSR_ILE
) |
4270 pcc
->mmu_model
= POWERPC_MMU_MPC8xx
;
4271 pcc
->excp_model
= POWERPC_EXCP_603
;
4272 pcc
->bus_model
= PPC_FLAGS_INPUT_RCPU
;
4273 pcc
->bfd_mach
= bfd_mach_ppc_860
;
4274 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
4275 POWERPC_FLAG_BUS_CLK
;
4278 /* Freescale 82xx cores (aka PowerQUICC-II) */
4280 static void init_proc_G2(CPUPPCState
*env
)
4282 gen_spr_ne_601(env
);
4284 gen_spr_G2_755(env
);
4288 /* External access control */
4289 /* XXX : not implemented */
4290 spr_register(env
, SPR_EAR
, "EAR",
4291 SPR_NOACCESS
, SPR_NOACCESS
,
4292 &spr_read_generic
, &spr_write_generic
,
4294 /* Hardware implementation register */
4295 /* XXX : not implemented */
4296 spr_register(env
, SPR_HID0
, "HID0",
4297 SPR_NOACCESS
, SPR_NOACCESS
,
4298 &spr_read_generic
, &spr_write_generic
,
4300 /* XXX : not implemented */
4301 spr_register(env
, SPR_HID1
, "HID1",
4302 SPR_NOACCESS
, SPR_NOACCESS
,
4303 &spr_read_generic
, &spr_write_generic
,
4305 /* XXX : not implemented */
4306 spr_register(env
, SPR_HID2
, "HID2",
4307 SPR_NOACCESS
, SPR_NOACCESS
,
4308 &spr_read_generic
, &spr_write_generic
,
4310 /* Memory management */
4313 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4315 env
->dcache_line_size
= 32;
4316 env
->icache_line_size
= 32;
4317 /* Allocate hardware IRQ controller */
4318 ppc6xx_irq_init(ppc_env_get_cpu(env
));
4321 POWERPC_FAMILY(G2
)(ObjectClass
*oc
, void *data
)
4323 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4324 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4326 dc
->desc
= "PowerPC G2";
4327 pcc
->init_proc
= init_proc_G2
;
4328 pcc
->check_pow
= check_pow_hid0
;
4329 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4330 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4332 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4333 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4334 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4335 PPC_SEGMENT
| PPC_EXTERN
;
4336 pcc
->msr_mask
= (1ull << MSR_POW
) |
4337 (1ull << MSR_TGPR
) |
4351 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4352 pcc
->excp_model
= POWERPC_EXCP_G2
;
4353 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4354 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
4355 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4356 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4359 static void init_proc_G2LE(CPUPPCState
*env
)
4361 gen_spr_ne_601(env
);
4363 gen_spr_G2_755(env
);
4367 /* External access control */
4368 /* XXX : not implemented */
4369 spr_register(env
, SPR_EAR
, "EAR",
4370 SPR_NOACCESS
, SPR_NOACCESS
,
4371 &spr_read_generic
, &spr_write_generic
,
4373 /* Hardware implementation register */
4374 /* XXX : not implemented */
4375 spr_register(env
, SPR_HID0
, "HID0",
4376 SPR_NOACCESS
, SPR_NOACCESS
,
4377 &spr_read_generic
, &spr_write_generic
,
4379 /* XXX : not implemented */
4380 spr_register(env
, SPR_HID1
, "HID1",
4381 SPR_NOACCESS
, SPR_NOACCESS
,
4382 &spr_read_generic
, &spr_write_generic
,
4384 /* XXX : not implemented */
4385 spr_register(env
, SPR_HID2
, "HID2",
4386 SPR_NOACCESS
, SPR_NOACCESS
,
4387 &spr_read_generic
, &spr_write_generic
,
4390 /* Memory management */
4393 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4395 env
->dcache_line_size
= 32;
4396 env
->icache_line_size
= 32;
4397 /* Allocate hardware IRQ controller */
4398 ppc6xx_irq_init(ppc_env_get_cpu(env
));
4401 POWERPC_FAMILY(G2LE
)(ObjectClass
*oc
, void *data
)
4403 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4404 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4406 dc
->desc
= "PowerPC G2LE";
4407 pcc
->init_proc
= init_proc_G2LE
;
4408 pcc
->check_pow
= check_pow_hid0
;
4409 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4410 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4412 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4413 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4414 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4415 PPC_SEGMENT
| PPC_EXTERN
;
4416 pcc
->msr_mask
= (1ull << MSR_POW
) |
4417 (1ull << MSR_TGPR
) |
4433 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4434 pcc
->excp_model
= POWERPC_EXCP_G2
;
4435 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4436 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
4437 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4438 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4441 static void init_proc_e200(CPUPPCState
*env
)
4445 gen_spr_BookE(env
, 0x000000070000FFFFULL
);
4446 /* XXX : not implemented */
4447 spr_register(env
, SPR_BOOKE_SPEFSCR
, "SPEFSCR",
4448 &spr_read_spefscr
, &spr_write_spefscr
,
4449 &spr_read_spefscr
, &spr_write_spefscr
,
4451 /* Memory management */
4452 gen_spr_BookE206(env
, 0x0000005D, NULL
, 0);
4453 /* XXX : not implemented */
4454 spr_register(env
, SPR_HID0
, "HID0",
4455 SPR_NOACCESS
, SPR_NOACCESS
,
4456 &spr_read_generic
, &spr_write_generic
,
4458 /* XXX : not implemented */
4459 spr_register(env
, SPR_HID1
, "HID1",
4460 SPR_NOACCESS
, SPR_NOACCESS
,
4461 &spr_read_generic
, &spr_write_generic
,
4463 /* XXX : not implemented */
4464 spr_register(env
, SPR_Exxx_ALTCTXCR
, "ALTCTXCR",
4465 SPR_NOACCESS
, SPR_NOACCESS
,
4466 &spr_read_generic
, &spr_write_generic
,
4468 /* XXX : not implemented */
4469 spr_register(env
, SPR_Exxx_BUCSR
, "BUCSR",
4470 SPR_NOACCESS
, SPR_NOACCESS
,
4471 &spr_read_generic
, &spr_write_generic
,
4473 /* XXX : not implemented */
4474 spr_register(env
, SPR_Exxx_CTXCR
, "CTXCR",
4475 SPR_NOACCESS
, SPR_NOACCESS
,
4476 &spr_read_generic
, &spr_write_generic
,
4478 /* XXX : not implemented */
4479 spr_register(env
, SPR_Exxx_DBCNT
, "DBCNT",
4480 SPR_NOACCESS
, SPR_NOACCESS
,
4481 &spr_read_generic
, &spr_write_generic
,
4483 /* XXX : not implemented */
4484 spr_register(env
, SPR_Exxx_DBCR3
, "DBCR3",
4485 SPR_NOACCESS
, SPR_NOACCESS
,
4486 &spr_read_generic
, &spr_write_generic
,
4488 /* XXX : not implemented */
4489 spr_register(env
, SPR_Exxx_L1CFG0
, "L1CFG0",
4490 &spr_read_generic
, SPR_NOACCESS
,
4491 &spr_read_generic
, SPR_NOACCESS
,
4493 /* XXX : not implemented */
4494 spr_register(env
, SPR_Exxx_L1CSR0
, "L1CSR0",
4495 SPR_NOACCESS
, SPR_NOACCESS
,
4496 &spr_read_generic
, &spr_write_generic
,
4498 /* XXX : not implemented */
4499 spr_register(env
, SPR_Exxx_L1FINV0
, "L1FINV0",
4500 SPR_NOACCESS
, SPR_NOACCESS
,
4501 &spr_read_generic
, &spr_write_generic
,
4503 /* XXX : not implemented */
4504 spr_register(env
, SPR_BOOKE_TLB0CFG
, "TLB0CFG",
4505 SPR_NOACCESS
, SPR_NOACCESS
,
4506 &spr_read_generic
, &spr_write_generic
,
4508 /* XXX : not implemented */
4509 spr_register(env
, SPR_BOOKE_TLB1CFG
, "TLB1CFG",
4510 SPR_NOACCESS
, SPR_NOACCESS
,
4511 &spr_read_generic
, &spr_write_generic
,
4513 /* XXX : not implemented */
4514 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4515 SPR_NOACCESS
, SPR_NOACCESS
,
4516 &spr_read_generic
, &spr_write_generic
,
4518 /* XXX : not implemented */
4519 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4520 SPR_NOACCESS
, SPR_NOACCESS
,
4521 &spr_read_generic
, &spr_write_generic
,
4523 /* XXX : not implemented */
4524 spr_register(env
, SPR_MMUCSR0
, "MMUCSR0",
4525 SPR_NOACCESS
, SPR_NOACCESS
,
4526 &spr_read_generic
, &spr_write_generic
,
4527 0x00000000); /* TOFIX */
4528 spr_register(env
, SPR_BOOKE_DSRR0
, "DSRR0",
4529 SPR_NOACCESS
, SPR_NOACCESS
,
4530 &spr_read_generic
, &spr_write_generic
,
4532 spr_register(env
, SPR_BOOKE_DSRR1
, "DSRR1",
4533 SPR_NOACCESS
, SPR_NOACCESS
,
4534 &spr_read_generic
, &spr_write_generic
,
4536 #if !defined(CONFIG_USER_ONLY)
4540 env
->tlb_type
= TLB_EMB
;
4542 init_excp_e200(env
, 0xFFFF0000UL
);
4543 env
->dcache_line_size
= 32;
4544 env
->icache_line_size
= 32;
4545 /* XXX: TODO: allocate internal IRQ controller */
4548 POWERPC_FAMILY(e200
)(ObjectClass
*oc
, void *data
)
4550 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4551 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4553 dc
->desc
= "e200 core";
4554 pcc
->init_proc
= init_proc_e200
;
4555 pcc
->check_pow
= check_pow_hid0
;
4556 /* XXX: unimplemented instructions:
4563 * all SPE multiply-accumulate instructions
4565 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
4566 PPC_SPE
| PPC_SPE_SINGLE
|
4567 PPC_WRTEE
| PPC_RFDI
|
4568 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
4569 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4570 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
|
4572 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
4586 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
4587 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4588 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4589 pcc
->bfd_mach
= bfd_mach_ppc_860
;
4590 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
4591 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
4592 POWERPC_FLAG_BUS_CLK
;
4595 static void init_proc_e300(CPUPPCState
*env
)
4597 gen_spr_ne_601(env
);
4602 /* hardware implementation registers */
4603 /* XXX : not implemented */
4604 spr_register(env
, SPR_HID0
, "HID0",
4605 SPR_NOACCESS
, SPR_NOACCESS
,
4606 &spr_read_generic
, &spr_write_generic
,
4608 /* XXX : not implemented */
4609 spr_register(env
, SPR_HID1
, "HID1",
4610 SPR_NOACCESS
, SPR_NOACCESS
,
4611 &spr_read_generic
, &spr_write_generic
,
4613 /* XXX : not implemented */
4614 spr_register(env
, SPR_HID2
, "HID2",
4615 SPR_NOACCESS
, SPR_NOACCESS
,
4616 &spr_read_generic
, &spr_write_generic
,
4619 /* XXX : not implemented */
4620 spr_register(env
, SPR_DABR
, "DABR",
4621 SPR_NOACCESS
, SPR_NOACCESS
,
4622 &spr_read_generic
, &spr_write_generic
,
4624 /* XXX : not implemented */
4625 spr_register(env
, SPR_DABR2
, "DABR2",
4626 SPR_NOACCESS
, SPR_NOACCESS
,
4627 &spr_read_generic
, &spr_write_generic
,
4629 /* XXX : not implemented */
4630 spr_register(env
, SPR_IABR2
, "IABR2",
4631 SPR_NOACCESS
, SPR_NOACCESS
,
4632 &spr_read_generic
, &spr_write_generic
,
4634 /* XXX : not implemented */
4635 spr_register(env
, SPR_IBCR
, "IBCR",
4636 SPR_NOACCESS
, SPR_NOACCESS
,
4637 &spr_read_generic
, &spr_write_generic
,
4639 /* XXX : not implemented */
4640 spr_register(env
, SPR_DBCR
, "DBCR",
4641 SPR_NOACCESS
, SPR_NOACCESS
,
4642 &spr_read_generic
, &spr_write_generic
,
4644 /* Memory management */
4647 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4649 env
->dcache_line_size
= 32;
4650 env
->icache_line_size
= 32;
4651 /* Allocate hardware IRQ controller */
4652 ppc6xx_irq_init(ppc_env_get_cpu(env
));
4655 POWERPC_FAMILY(e300
)(ObjectClass
*oc
, void *data
)
4657 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4658 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4660 dc
->desc
= "e300 core";
4661 pcc
->init_proc
= init_proc_e300
;
4662 pcc
->check_pow
= check_pow_hid0
;
4663 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4664 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4666 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4667 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4668 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4669 PPC_SEGMENT
| PPC_EXTERN
;
4670 pcc
->msr_mask
= (1ull << MSR_POW
) |
4671 (1ull << MSR_TGPR
) |
4687 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4688 pcc
->excp_model
= POWERPC_EXCP_603
;
4689 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4690 pcc
->bfd_mach
= bfd_mach_ppc_603
;
4691 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4692 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4695 #if !defined(CONFIG_USER_ONLY)
4696 static void spr_write_mas73(DisasContext
*ctx
, int sprn
, int gprn
)
4698 TCGv val
= tcg_temp_new();
4699 tcg_gen_ext32u_tl(val
, cpu_gpr
[gprn
]);
4700 gen_store_spr(SPR_BOOKE_MAS3
, val
);
4701 tcg_gen_shri_tl(val
, cpu_gpr
[gprn
], 32);
4702 gen_store_spr(SPR_BOOKE_MAS7
, val
);
4706 static void spr_read_mas73(DisasContext
*ctx
, int gprn
, int sprn
)
4708 TCGv mas7
= tcg_temp_new();
4709 TCGv mas3
= tcg_temp_new();
4710 gen_load_spr(mas7
, SPR_BOOKE_MAS7
);
4711 tcg_gen_shli_tl(mas7
, mas7
, 32);
4712 gen_load_spr(mas3
, SPR_BOOKE_MAS3
);
4713 tcg_gen_or_tl(cpu_gpr
[gprn
], mas3
, mas7
);
4714 tcg_temp_free(mas3
);
4715 tcg_temp_free(mas7
);
4720 enum fsl_e500_version
{
4728 static void init_proc_e500(CPUPPCState
*env
, int version
)
4730 PowerPCCPU
*cpu
= ppc_env_get_cpu(env
);
4731 uint32_t tlbncfg
[2];
4733 uint64_t ivpr_mask
= 0xFFFF0000ULL
;
4734 uint32_t l1cfg0
= 0x3800 /* 8 ways */
4735 | 0x0020; /* 32 kb */
4736 uint32_t l1cfg1
= 0x3800 /* 8 ways */
4737 | 0x0020; /* 32 kb */
4738 uint32_t mmucfg
= 0;
4739 #if !defined(CONFIG_USER_ONLY)
4746 * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't
4747 * complain when accessing them.
4748 * gen_spr_BookE(env, 0x0000000F0000FD7FULL);
4754 ivor_mask
= 0x0000000F0000FFFFULL
;
4758 ivor_mask
= 0x000003FE0000FFFFULL
;
4761 ivor_mask
= 0x000003FF0000FFFFULL
;
4764 gen_spr_BookE(env
, ivor_mask
);
4765 gen_spr_usprg3(env
);
4766 /* Processor identification */
4767 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4768 SPR_NOACCESS
, SPR_NOACCESS
,
4769 &spr_read_generic
, &spr_write_pir
,
4771 /* XXX : not implemented */
4772 spr_register(env
, SPR_BOOKE_SPEFSCR
, "SPEFSCR",
4773 &spr_read_spefscr
, &spr_write_spefscr
,
4774 &spr_read_spefscr
, &spr_write_spefscr
,
4776 #if !defined(CONFIG_USER_ONLY)
4777 /* Memory management */
4783 tlbncfg
[0] = gen_tlbncfg(2, 1, 1, 0, 256);
4784 tlbncfg
[1] = gen_tlbncfg(16, 1, 9, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 16);
4787 tlbncfg
[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4788 tlbncfg
[1] = gen_tlbncfg(16, 1, 12, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 16);
4792 tlbncfg
[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4793 tlbncfg
[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 64);
4798 tlbncfg
[0] = 0x08052400;
4799 tlbncfg
[1] = 0x40028040;
4802 cpu_abort(CPU(cpu
), "Unknown CPU: " TARGET_FMT_lx
"\n", env
->spr
[SPR_PVR
]);
4809 env
->dcache_line_size
= 32;
4810 env
->icache_line_size
= 32;
4814 env
->dcache_line_size
= 64;
4815 env
->icache_line_size
= 64;
4816 l1cfg0
|= 0x1000000; /* 64 byte cache block size */
4817 l1cfg1
|= 0x1000000; /* 64 byte cache block size */
4820 env
->dcache_line_size
= 32;
4821 env
->icache_line_size
= 32;
4822 l1cfg0
|= 0x0F83820;
4823 l1cfg1
|= 0x0B83820;
4826 cpu_abort(CPU(cpu
), "Unknown CPU: " TARGET_FMT_lx
"\n", env
->spr
[SPR_PVR
]);
4828 gen_spr_BookE206(env
, 0x000000DF, tlbncfg
, mmucfg
);
4829 /* XXX : not implemented */
4830 spr_register(env
, SPR_HID0
, "HID0",
4831 SPR_NOACCESS
, SPR_NOACCESS
,
4832 &spr_read_generic
, &spr_write_generic
,
4834 /* XXX : not implemented */
4835 spr_register(env
, SPR_HID1
, "HID1",
4836 SPR_NOACCESS
, SPR_NOACCESS
,
4837 &spr_read_generic
, &spr_write_generic
,
4839 /* XXX : not implemented */
4840 spr_register(env
, SPR_Exxx_BBEAR
, "BBEAR",
4841 SPR_NOACCESS
, SPR_NOACCESS
,
4842 &spr_read_generic
, &spr_write_generic
,
4844 /* XXX : not implemented */
4845 spr_register(env
, SPR_Exxx_BBTAR
, "BBTAR",
4846 SPR_NOACCESS
, SPR_NOACCESS
,
4847 &spr_read_generic
, &spr_write_generic
,
4849 /* XXX : not implemented */
4850 spr_register(env
, SPR_Exxx_MCAR
, "MCAR",
4851 SPR_NOACCESS
, SPR_NOACCESS
,
4852 &spr_read_generic
, &spr_write_generic
,
4854 /* XXX : not implemented */
4855 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
4856 SPR_NOACCESS
, SPR_NOACCESS
,
4857 &spr_read_generic
, &spr_write_generic
,
4859 /* XXX : not implemented */
4860 spr_register(env
, SPR_Exxx_NPIDR
, "NPIDR",
4861 SPR_NOACCESS
, SPR_NOACCESS
,
4862 &spr_read_generic
, &spr_write_generic
,
4864 /* XXX : not implemented */
4865 spr_register(env
, SPR_Exxx_BUCSR
, "BUCSR",
4866 SPR_NOACCESS
, SPR_NOACCESS
,
4867 &spr_read_generic
, &spr_write_generic
,
4869 /* XXX : not implemented */
4870 spr_register(env
, SPR_Exxx_L1CFG0
, "L1CFG0",
4871 &spr_read_generic
, SPR_NOACCESS
,
4872 &spr_read_generic
, SPR_NOACCESS
,
4874 spr_register(env
, SPR_Exxx_L1CFG1
, "L1CFG1",
4875 &spr_read_generic
, SPR_NOACCESS
,
4876 &spr_read_generic
, SPR_NOACCESS
,
4878 spr_register(env
, SPR_Exxx_L1CSR0
, "L1CSR0",
4879 SPR_NOACCESS
, SPR_NOACCESS
,
4880 &spr_read_generic
, &spr_write_e500_l1csr0
,
4882 spr_register(env
, SPR_Exxx_L1CSR1
, "L1CSR1",
4883 SPR_NOACCESS
, SPR_NOACCESS
,
4884 &spr_read_generic
, &spr_write_e500_l1csr1
,
4886 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
4887 SPR_NOACCESS
, SPR_NOACCESS
,
4888 &spr_read_generic
, &spr_write_generic
,
4890 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
4891 SPR_NOACCESS
, SPR_NOACCESS
,
4892 &spr_read_generic
, &spr_write_generic
,
4894 spr_register(env
, SPR_MMUCSR0
, "MMUCSR0",
4895 SPR_NOACCESS
, SPR_NOACCESS
,
4896 &spr_read_generic
, &spr_write_booke206_mmucsr0
,
4898 spr_register(env
, SPR_BOOKE_EPR
, "EPR",
4899 SPR_NOACCESS
, SPR_NOACCESS
,
4900 &spr_read_generic
, SPR_NOACCESS
,
4902 /* XXX better abstract into Emb.xxx features */
4903 if ((version
== fsl_e5500
) || (version
== fsl_e6500
)) {
4904 spr_register(env
, SPR_BOOKE_EPCR
, "EPCR",
4905 SPR_NOACCESS
, SPR_NOACCESS
,
4906 &spr_read_generic
, &spr_write_generic
,
4908 spr_register(env
, SPR_BOOKE_MAS7_MAS3
, "MAS7_MAS3",
4909 SPR_NOACCESS
, SPR_NOACCESS
,
4910 &spr_read_mas73
, &spr_write_mas73
,
4912 ivpr_mask
= (target_ulong
)~0xFFFFULL
;
4915 if (version
== fsl_e6500
) {
4916 spr_register(env
, SPR_BOOKE_SPRG8
, "SPRG8",
4917 SPR_NOACCESS
, SPR_NOACCESS
,
4918 &spr_read_generic
, &spr_write_generic
,
4920 spr_register(env
, SPR_BOOKE_SPRG9
, "SPRG9",
4921 SPR_NOACCESS
, SPR_NOACCESS
,
4922 &spr_read_generic
, &spr_write_generic
,
4924 /* Thread identification */
4925 spr_register(env
, SPR_TIR
, "TIR",
4926 SPR_NOACCESS
, SPR_NOACCESS
,
4927 &spr_read_generic
, SPR_NOACCESS
,
4929 spr_register(env
, SPR_BOOKE_TLB0PS
, "TLB0PS",
4930 SPR_NOACCESS
, SPR_NOACCESS
,
4931 &spr_read_generic
, SPR_NOACCESS
,
4933 spr_register(env
, SPR_BOOKE_TLB1PS
, "TLB1PS",
4934 SPR_NOACCESS
, SPR_NOACCESS
,
4935 &spr_read_generic
, SPR_NOACCESS
,
4939 #if !defined(CONFIG_USER_ONLY)
4941 env
->tlb_type
= TLB_MAS
;
4942 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
4943 env
->nb_tlb
+= booke206_tlb_size(env
, i
);
4947 init_excp_e200(env
, ivpr_mask
);
4948 /* Allocate hardware IRQ controller */
4949 ppce500_irq_init(ppc_env_get_cpu(env
));
4952 static void init_proc_e500v1(CPUPPCState
*env
)
4954 init_proc_e500(env
, fsl_e500v1
);
4957 POWERPC_FAMILY(e500v1
)(ObjectClass
*oc
, void *data
)
4959 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4960 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4962 dc
->desc
= "e500v1 core";
4963 pcc
->init_proc
= init_proc_e500v1
;
4964 pcc
->check_pow
= check_pow_hid0
;
4965 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
4966 PPC_SPE
| PPC_SPE_SINGLE
|
4967 PPC_WRTEE
| PPC_RFDI
|
4968 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
4969 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4970 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
4971 pcc
->insns_flags2
= PPC2_BOOKE206
;
4972 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
4986 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
4987 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4988 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4989 pcc
->bfd_mach
= bfd_mach_ppc_860
;
4990 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
4991 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
4992 POWERPC_FLAG_BUS_CLK
;
4995 static void init_proc_e500v2(CPUPPCState
*env
)
4997 init_proc_e500(env
, fsl_e500v2
);
5000 POWERPC_FAMILY(e500v2
)(ObjectClass
*oc
, void *data
)
5002 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5003 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5005 dc
->desc
= "e500v2 core";
5006 pcc
->init_proc
= init_proc_e500v2
;
5007 pcc
->check_pow
= check_pow_hid0
;
5008 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
5009 PPC_SPE
| PPC_SPE_SINGLE
| PPC_SPE_DOUBLE
|
5010 PPC_WRTEE
| PPC_RFDI
|
5011 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5012 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5013 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5014 pcc
->insns_flags2
= PPC2_BOOKE206
;
5015 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
5029 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5030 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5031 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5032 pcc
->bfd_mach
= bfd_mach_ppc_860
;
5033 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
5034 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
5035 POWERPC_FLAG_BUS_CLK
;
5038 static void init_proc_e500mc(CPUPPCState
*env
)
5040 init_proc_e500(env
, fsl_e500mc
);
5043 POWERPC_FAMILY(e500mc
)(ObjectClass
*oc
, void *data
)
5045 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5046 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5048 dc
->desc
= "e500mc core";
5049 pcc
->init_proc
= init_proc_e500mc
;
5050 pcc
->check_pow
= check_pow_none
;
5051 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5052 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5053 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5054 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5055 PPC_FLOAT
| PPC_FLOAT_FRES
|
5056 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5057 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5058 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5059 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
;
5060 pcc
->msr_mask
= (1ull << MSR_GS
) |
5061 (1ull << MSR_UCLE
) |
5074 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5075 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5076 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5077 /* FIXME: figure out the correct flag for e500mc */
5078 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5079 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5080 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5084 static void init_proc_e5500(CPUPPCState
*env
)
5086 init_proc_e500(env
, fsl_e5500
);
5089 POWERPC_FAMILY(e5500
)(ObjectClass
*oc
, void *data
)
5091 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5092 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5094 dc
->desc
= "e5500 core";
5095 pcc
->init_proc
= init_proc_e5500
;
5096 pcc
->check_pow
= check_pow_none
;
5097 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5098 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5099 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5100 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5101 PPC_FLOAT
| PPC_FLOAT_FRES
|
5102 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5103 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5104 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
|
5105 PPC_64B
| PPC_POPCNTB
| PPC_POPCNTWD
;
5106 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
| PPC2_PERM_ISA206
| \
5108 pcc
->msr_mask
= (1ull << MSR_CM
) |
5110 (1ull << MSR_UCLE
) |
5123 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5124 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5125 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5126 /* FIXME: figure out the correct flag for e5500 */
5127 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5128 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5129 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5132 static void init_proc_e6500(CPUPPCState
*env
)
5134 init_proc_e500(env
, fsl_e6500
);
5137 POWERPC_FAMILY(e6500
)(ObjectClass
*oc
, void *data
)
5139 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5140 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5142 dc
->desc
= "e6500 core";
5143 pcc
->init_proc
= init_proc_e6500
;
5144 pcc
->check_pow
= check_pow_none
;
5145 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5146 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5147 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5148 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5149 PPC_FLOAT
| PPC_FLOAT_FRES
|
5150 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5151 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5152 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
|
5153 PPC_64B
| PPC_POPCNTB
| PPC_POPCNTWD
| PPC_ALTIVEC
;
5154 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
| PPC2_PERM_ISA206
| \
5155 PPC2_FP_CVT_S64
| PPC2_ATOMIC_ISA206
;
5156 pcc
->msr_mask
= (1ull << MSR_CM
) |
5158 (1ull << MSR_UCLE
) |
5172 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5173 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5174 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5175 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5176 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5177 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_VRE
;
5182 /* Non-embedded PowerPC */
5184 #define POWERPC_MSRR_601 (0x0000000000001040ULL)
5186 static void init_proc_601(CPUPPCState
*env
)
5188 gen_spr_ne_601(env
);
5191 /* Hardware implementation registers */
5192 /* XXX : not implemented */
5193 spr_register(env
, SPR_HID0
, "HID0",
5194 SPR_NOACCESS
, SPR_NOACCESS
,
5195 &spr_read_generic
, &spr_write_hid0_601
,
5197 /* XXX : not implemented */
5198 spr_register(env
, SPR_HID1
, "HID1",
5199 SPR_NOACCESS
, SPR_NOACCESS
,
5200 &spr_read_generic
, &spr_write_generic
,
5202 /* XXX : not implemented */
5203 spr_register(env
, SPR_601_HID2
, "HID2",
5204 SPR_NOACCESS
, SPR_NOACCESS
,
5205 &spr_read_generic
, &spr_write_generic
,
5207 /* XXX : not implemented */
5208 spr_register(env
, SPR_601_HID5
, "HID5",
5209 SPR_NOACCESS
, SPR_NOACCESS
,
5210 &spr_read_generic
, &spr_write_generic
,
5212 /* Memory management */
5214 /* XXX: beware that dcache line size is 64
5215 * but dcbz uses 32 bytes "sectors"
5216 * XXX: this breaks clcs instruction !
5218 env
->dcache_line_size
= 32;
5219 env
->icache_line_size
= 64;
5220 /* Allocate hardware IRQ controller */
5221 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5224 POWERPC_FAMILY(601)(ObjectClass
*oc
, void *data
)
5226 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5227 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5229 dc
->desc
= "PowerPC 601";
5230 pcc
->init_proc
= init_proc_601
;
5231 pcc
->check_pow
= check_pow_none
;
5232 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_POWER_BR
|
5234 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5235 PPC_MEM_SYNC
| PPC_MEM_EIEIO
| PPC_MEM_TLBIE
|
5236 PPC_SEGMENT
| PPC_EXTERN
;
5237 pcc
->msr_mask
= (1ull << MSR_EE
) |
5247 pcc
->mmu_model
= POWERPC_MMU_601
;
5248 #if defined(CONFIG_SOFTMMU)
5249 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5251 pcc
->excp_model
= POWERPC_EXCP_601
;
5252 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5253 pcc
->bfd_mach
= bfd_mach_ppc_601
;
5254 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_RTC_CLK
;
5257 #define POWERPC_MSRR_601v (0x0000000000001040ULL)
5259 static void init_proc_601v(CPUPPCState
*env
)
5262 /* XXX : not implemented */
5263 spr_register(env
, SPR_601_HID15
, "HID15",
5264 SPR_NOACCESS
, SPR_NOACCESS
,
5265 &spr_read_generic
, &spr_write_generic
,
5269 POWERPC_FAMILY(601v
)(ObjectClass
*oc
, void *data
)
5271 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5272 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5274 dc
->desc
= "PowerPC 601v";
5275 pcc
->init_proc
= init_proc_601v
;
5276 pcc
->check_pow
= check_pow_none
;
5277 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_POWER_BR
|
5279 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5280 PPC_MEM_SYNC
| PPC_MEM_EIEIO
| PPC_MEM_TLBIE
|
5281 PPC_SEGMENT
| PPC_EXTERN
;
5282 pcc
->msr_mask
= (1ull << MSR_EE
) |
5292 pcc
->mmu_model
= POWERPC_MMU_601
;
5293 #if defined(CONFIG_SOFTMMU)
5294 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5296 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5297 pcc
->bfd_mach
= bfd_mach_ppc_601
;
5298 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_RTC_CLK
;
5301 static void init_proc_602(CPUPPCState
*env
)
5303 gen_spr_ne_601(env
);
5308 /* hardware implementation registers */
5309 /* XXX : not implemented */
5310 spr_register(env
, SPR_HID0
, "HID0",
5311 SPR_NOACCESS
, SPR_NOACCESS
,
5312 &spr_read_generic
, &spr_write_generic
,
5314 /* XXX : not implemented */
5315 spr_register(env
, SPR_HID1
, "HID1",
5316 SPR_NOACCESS
, SPR_NOACCESS
,
5317 &spr_read_generic
, &spr_write_generic
,
5319 /* Memory management */
5321 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5323 env
->dcache_line_size
= 32;
5324 env
->icache_line_size
= 32;
5325 /* Allocate hardware IRQ controller */
5326 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5329 POWERPC_FAMILY(602)(ObjectClass
*oc
, void *data
)
5331 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5332 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5334 dc
->desc
= "PowerPC 602";
5335 pcc
->init_proc
= init_proc_602
;
5336 pcc
->check_pow
= check_pow_hid0
;
5337 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5338 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5339 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5340 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5341 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5342 PPC_MEM_TLBIE
| PPC_6xx_TLB
| PPC_MEM_TLBSYNC
|
5343 PPC_SEGMENT
| PPC_602_SPEC
;
5344 pcc
->msr_mask
= (1ull << MSR_VSX
) |
5347 (1ull << MSR_TGPR
) |
5362 /* XXX: 602 MMU is quite specific. Should add a special case */
5363 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5364 pcc
->excp_model
= POWERPC_EXCP_602
;
5365 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5366 pcc
->bfd_mach
= bfd_mach_ppc_602
;
5367 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5368 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5371 static void init_proc_603(CPUPPCState
*env
)
5373 gen_spr_ne_601(env
);
5378 /* hardware implementation registers */
5379 /* XXX : not implemented */
5380 spr_register(env
, SPR_HID0
, "HID0",
5381 SPR_NOACCESS
, SPR_NOACCESS
,
5382 &spr_read_generic
, &spr_write_generic
,
5384 /* XXX : not implemented */
5385 spr_register(env
, SPR_HID1
, "HID1",
5386 SPR_NOACCESS
, SPR_NOACCESS
,
5387 &spr_read_generic
, &spr_write_generic
,
5389 /* Memory management */
5391 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5393 env
->dcache_line_size
= 32;
5394 env
->icache_line_size
= 32;
5395 /* Allocate hardware IRQ controller */
5396 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5399 POWERPC_FAMILY(603)(ObjectClass
*oc
, void *data
)
5401 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5402 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5404 dc
->desc
= "PowerPC 603";
5405 pcc
->init_proc
= init_proc_603
;
5406 pcc
->check_pow
= check_pow_hid0
;
5407 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5408 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5409 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5410 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5411 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5412 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
5413 PPC_SEGMENT
| PPC_EXTERN
;
5414 pcc
->msr_mask
= (1ull << MSR_POW
) |
5415 (1ull << MSR_TGPR
) |
5430 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5431 pcc
->excp_model
= POWERPC_EXCP_603
;
5432 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5433 pcc
->bfd_mach
= bfd_mach_ppc_603
;
5434 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5435 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5438 static void init_proc_603E(CPUPPCState
*env
)
5440 gen_spr_ne_601(env
);
5445 /* hardware implementation registers */
5446 /* XXX : not implemented */
5447 spr_register(env
, SPR_HID0
, "HID0",
5448 SPR_NOACCESS
, SPR_NOACCESS
,
5449 &spr_read_generic
, &spr_write_generic
,
5451 /* XXX : not implemented */
5452 spr_register(env
, SPR_HID1
, "HID1",
5453 SPR_NOACCESS
, SPR_NOACCESS
,
5454 &spr_read_generic
, &spr_write_generic
,
5456 /* Memory management */
5458 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5460 env
->dcache_line_size
= 32;
5461 env
->icache_line_size
= 32;
5462 /* Allocate hardware IRQ controller */
5463 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5466 POWERPC_FAMILY(603E
)(ObjectClass
*oc
, void *data
)
5468 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5469 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5471 dc
->desc
= "PowerPC 603e";
5472 pcc
->init_proc
= init_proc_603E
;
5473 pcc
->check_pow
= check_pow_hid0
;
5474 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5475 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5476 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5477 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5478 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5479 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
5480 PPC_SEGMENT
| PPC_EXTERN
;
5481 pcc
->msr_mask
= (1ull << MSR_POW
) |
5482 (1ull << MSR_TGPR
) |
5497 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5498 pcc
->excp_model
= POWERPC_EXCP_603E
;
5499 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5500 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
5501 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5502 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5505 static void init_proc_604(CPUPPCState
*env
)
5507 gen_spr_ne_601(env
);
5512 /* Hardware implementation registers */
5513 /* XXX : not implemented */
5514 spr_register(env
, SPR_HID0
, "HID0",
5515 SPR_NOACCESS
, SPR_NOACCESS
,
5516 &spr_read_generic
, &spr_write_generic
,
5518 /* Memory management */
5521 env
->dcache_line_size
= 32;
5522 env
->icache_line_size
= 32;
5523 /* Allocate hardware IRQ controller */
5524 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5527 POWERPC_FAMILY(604)(ObjectClass
*oc
, void *data
)
5529 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5530 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5532 dc
->desc
= "PowerPC 604";
5533 pcc
->init_proc
= init_proc_604
;
5534 pcc
->check_pow
= check_pow_nocheck
;
5535 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5536 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5537 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5538 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5539 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5540 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5541 PPC_SEGMENT
| PPC_EXTERN
;
5542 pcc
->msr_mask
= (1ull << MSR_POW
) |
5558 pcc
->mmu_model
= POWERPC_MMU_32B
;
5559 #if defined(CONFIG_SOFTMMU)
5560 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5562 pcc
->excp_model
= POWERPC_EXCP_604
;
5563 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5564 pcc
->bfd_mach
= bfd_mach_ppc_604
;
5565 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5566 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5569 static void init_proc_604E(CPUPPCState
*env
)
5571 gen_spr_ne_601(env
);
5574 /* XXX : not implemented */
5575 spr_register(env
, SPR_7XX_MMCR1
, "MMCR1",
5576 SPR_NOACCESS
, SPR_NOACCESS
,
5577 &spr_read_generic
, &spr_write_generic
,
5579 /* XXX : not implemented */
5580 spr_register(env
, SPR_7XX_PMC3
, "PMC3",
5581 SPR_NOACCESS
, SPR_NOACCESS
,
5582 &spr_read_generic
, &spr_write_generic
,
5584 /* XXX : not implemented */
5585 spr_register(env
, SPR_7XX_PMC4
, "PMC4",
5586 SPR_NOACCESS
, SPR_NOACCESS
,
5587 &spr_read_generic
, &spr_write_generic
,
5591 /* Hardware implementation registers */
5592 /* XXX : not implemented */
5593 spr_register(env
, SPR_HID0
, "HID0",
5594 SPR_NOACCESS
, SPR_NOACCESS
,
5595 &spr_read_generic
, &spr_write_generic
,
5597 /* XXX : not implemented */
5598 spr_register(env
, SPR_HID1
, "HID1",
5599 SPR_NOACCESS
, SPR_NOACCESS
,
5600 &spr_read_generic
, &spr_write_generic
,
5602 /* Memory management */
5605 env
->dcache_line_size
= 32;
5606 env
->icache_line_size
= 32;
5607 /* Allocate hardware IRQ controller */
5608 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5611 POWERPC_FAMILY(604E
)(ObjectClass
*oc
, void *data
)
5613 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5614 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5616 dc
->desc
= "PowerPC 604E";
5617 pcc
->init_proc
= init_proc_604E
;
5618 pcc
->check_pow
= check_pow_nocheck
;
5619 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5620 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5621 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5622 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5623 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5624 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5625 PPC_SEGMENT
| PPC_EXTERN
;
5626 pcc
->msr_mask
= (1ull << MSR_POW
) |
5642 pcc
->mmu_model
= POWERPC_MMU_32B
;
5643 #if defined(CONFIG_SOFTMMU)
5644 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5646 pcc
->excp_model
= POWERPC_EXCP_604
;
5647 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5648 pcc
->bfd_mach
= bfd_mach_ppc_604
;
5649 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5650 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5653 static void init_proc_740(CPUPPCState
*env
)
5655 gen_spr_ne_601(env
);
5660 /* Thermal management */
5662 /* Hardware implementation registers */
5663 /* XXX : not implemented */
5664 spr_register(env
, SPR_HID0
, "HID0",
5665 SPR_NOACCESS
, SPR_NOACCESS
,
5666 &spr_read_generic
, &spr_write_generic
,
5668 /* XXX : not implemented */
5669 spr_register(env
, SPR_HID1
, "HID1",
5670 SPR_NOACCESS
, SPR_NOACCESS
,
5671 &spr_read_generic
, &spr_write_generic
,
5673 /* Memory management */
5676 env
->dcache_line_size
= 32;
5677 env
->icache_line_size
= 32;
5678 /* Allocate hardware IRQ controller */
5679 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5682 POWERPC_FAMILY(740)(ObjectClass
*oc
, void *data
)
5684 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5685 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5687 dc
->desc
= "PowerPC 740";
5688 pcc
->init_proc
= init_proc_740
;
5689 pcc
->check_pow
= check_pow_hid0
;
5690 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5691 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5692 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5693 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5694 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5695 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5696 PPC_SEGMENT
| PPC_EXTERN
;
5697 pcc
->msr_mask
= (1ull << MSR_POW
) |
5713 pcc
->mmu_model
= POWERPC_MMU_32B
;
5714 #if defined(CONFIG_SOFTMMU)
5715 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5717 pcc
->excp_model
= POWERPC_EXCP_7x0
;
5718 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5719 pcc
->bfd_mach
= bfd_mach_ppc_750
;
5720 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5721 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5724 static void init_proc_750(CPUPPCState
*env
)
5726 gen_spr_ne_601(env
);
5729 /* XXX : not implemented */
5730 spr_register(env
, SPR_L2CR
, "L2CR",
5731 SPR_NOACCESS
, SPR_NOACCESS
,
5732 &spr_read_generic
, spr_access_nop
,
5736 /* Thermal management */
5738 /* Hardware implementation registers */
5739 /* XXX : not implemented */
5740 spr_register(env
, SPR_HID0
, "HID0",
5741 SPR_NOACCESS
, SPR_NOACCESS
,
5742 &spr_read_generic
, &spr_write_generic
,
5744 /* XXX : not implemented */
5745 spr_register(env
, SPR_HID1
, "HID1",
5746 SPR_NOACCESS
, SPR_NOACCESS
,
5747 &spr_read_generic
, &spr_write_generic
,
5749 /* Memory management */
5751 /* XXX: high BATs are also present but are known to be bugged on
5755 env
->dcache_line_size
= 32;
5756 env
->icache_line_size
= 32;
5757 /* Allocate hardware IRQ controller */
5758 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5761 POWERPC_FAMILY(750)(ObjectClass
*oc
, void *data
)
5763 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5764 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5766 dc
->desc
= "PowerPC 750";
5767 pcc
->init_proc
= init_proc_750
;
5768 pcc
->check_pow
= check_pow_hid0
;
5769 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5770 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5771 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5772 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5773 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5774 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5775 PPC_SEGMENT
| PPC_EXTERN
;
5776 pcc
->msr_mask
= (1ull << MSR_POW
) |
5792 pcc
->mmu_model
= POWERPC_MMU_32B
;
5793 #if defined(CONFIG_SOFTMMU)
5794 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5796 pcc
->excp_model
= POWERPC_EXCP_7x0
;
5797 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5798 pcc
->bfd_mach
= bfd_mach_ppc_750
;
5799 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5800 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5803 static void init_proc_750cl(CPUPPCState
*env
)
5805 gen_spr_ne_601(env
);
5808 /* XXX : not implemented */
5809 spr_register(env
, SPR_L2CR
, "L2CR",
5810 SPR_NOACCESS
, SPR_NOACCESS
,
5811 &spr_read_generic
, spr_access_nop
,
5815 /* Thermal management */
5816 /* Those registers are fake on 750CL */
5817 spr_register(env
, SPR_THRM1
, "THRM1",
5818 SPR_NOACCESS
, SPR_NOACCESS
,
5819 &spr_read_generic
, &spr_write_generic
,
5821 spr_register(env
, SPR_THRM2
, "THRM2",
5822 SPR_NOACCESS
, SPR_NOACCESS
,
5823 &spr_read_generic
, &spr_write_generic
,
5825 spr_register(env
, SPR_THRM3
, "THRM3",
5826 SPR_NOACCESS
, SPR_NOACCESS
,
5827 &spr_read_generic
, &spr_write_generic
,
5829 /* XXX: not implemented */
5830 spr_register(env
, SPR_750_TDCL
, "TDCL",
5831 SPR_NOACCESS
, SPR_NOACCESS
,
5832 &spr_read_generic
, &spr_write_generic
,
5834 spr_register(env
, SPR_750_TDCH
, "TDCH",
5835 SPR_NOACCESS
, SPR_NOACCESS
,
5836 &spr_read_generic
, &spr_write_generic
,
5839 /* XXX : not implemented */
5840 spr_register(env
, SPR_750_WPAR
, "WPAR",
5841 SPR_NOACCESS
, SPR_NOACCESS
,
5842 &spr_read_generic
, &spr_write_generic
,
5844 spr_register(env
, SPR_750_DMAL
, "DMAL",
5845 SPR_NOACCESS
, SPR_NOACCESS
,
5846 &spr_read_generic
, &spr_write_generic
,
5848 spr_register(env
, SPR_750_DMAU
, "DMAU",
5849 SPR_NOACCESS
, SPR_NOACCESS
,
5850 &spr_read_generic
, &spr_write_generic
,
5852 /* Hardware implementation registers */
5853 /* XXX : not implemented */
5854 spr_register(env
, SPR_HID0
, "HID0",
5855 SPR_NOACCESS
, SPR_NOACCESS
,
5856 &spr_read_generic
, &spr_write_generic
,
5858 /* XXX : not implemented */
5859 spr_register(env
, SPR_HID1
, "HID1",
5860 SPR_NOACCESS
, SPR_NOACCESS
,
5861 &spr_read_generic
, &spr_write_generic
,
5863 /* XXX : not implemented */
5864 spr_register(env
, SPR_750CL_HID2
, "HID2",
5865 SPR_NOACCESS
, SPR_NOACCESS
,
5866 &spr_read_generic
, &spr_write_generic
,
5868 /* XXX : not implemented */
5869 spr_register(env
, SPR_750CL_HID4
, "HID4",
5870 SPR_NOACCESS
, SPR_NOACCESS
,
5871 &spr_read_generic
, &spr_write_generic
,
5873 /* Quantization registers */
5874 /* XXX : not implemented */
5875 spr_register(env
, SPR_750_GQR0
, "GQR0",
5876 SPR_NOACCESS
, SPR_NOACCESS
,
5877 &spr_read_generic
, &spr_write_generic
,
5879 /* XXX : not implemented */
5880 spr_register(env
, SPR_750_GQR1
, "GQR1",
5881 SPR_NOACCESS
, SPR_NOACCESS
,
5882 &spr_read_generic
, &spr_write_generic
,
5884 /* XXX : not implemented */
5885 spr_register(env
, SPR_750_GQR2
, "GQR2",
5886 SPR_NOACCESS
, SPR_NOACCESS
,
5887 &spr_read_generic
, &spr_write_generic
,
5889 /* XXX : not implemented */
5890 spr_register(env
, SPR_750_GQR3
, "GQR3",
5891 SPR_NOACCESS
, SPR_NOACCESS
,
5892 &spr_read_generic
, &spr_write_generic
,
5894 /* XXX : not implemented */
5895 spr_register(env
, SPR_750_GQR4
, "GQR4",
5896 SPR_NOACCESS
, SPR_NOACCESS
,
5897 &spr_read_generic
, &spr_write_generic
,
5899 /* XXX : not implemented */
5900 spr_register(env
, SPR_750_GQR5
, "GQR5",
5901 SPR_NOACCESS
, SPR_NOACCESS
,
5902 &spr_read_generic
, &spr_write_generic
,
5904 /* XXX : not implemented */
5905 spr_register(env
, SPR_750_GQR6
, "GQR6",
5906 SPR_NOACCESS
, SPR_NOACCESS
,
5907 &spr_read_generic
, &spr_write_generic
,
5909 /* XXX : not implemented */
5910 spr_register(env
, SPR_750_GQR7
, "GQR7",
5911 SPR_NOACCESS
, SPR_NOACCESS
,
5912 &spr_read_generic
, &spr_write_generic
,
5914 /* Memory management */
5916 /* PowerPC 750cl has 8 DBATs and 8 IBATs */
5918 init_excp_750cl(env
);
5919 env
->dcache_line_size
= 32;
5920 env
->icache_line_size
= 32;
5921 /* Allocate hardware IRQ controller */
5922 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5925 POWERPC_FAMILY(750cl
)(ObjectClass
*oc
, void *data
)
5927 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5928 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5930 dc
->desc
= "PowerPC 750 CL";
5931 pcc
->init_proc
= init_proc_750cl
;
5932 pcc
->check_pow
= check_pow_hid0
;
5933 /* XXX: not implemented:
5934 * cache lock instructions:
5936 * floating point paired instructions
5971 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5972 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5973 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5974 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5975 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5976 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5977 PPC_SEGMENT
| PPC_EXTERN
;
5978 pcc
->msr_mask
= (1ull << MSR_POW
) |
5994 pcc
->mmu_model
= POWERPC_MMU_32B
;
5995 #if defined(CONFIG_SOFTMMU)
5996 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5998 pcc
->excp_model
= POWERPC_EXCP_7x0
;
5999 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6000 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6001 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6002 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6005 static void init_proc_750cx(CPUPPCState
*env
)
6007 gen_spr_ne_601(env
);
6010 /* XXX : not implemented */
6011 spr_register(env
, SPR_L2CR
, "L2CR",
6012 SPR_NOACCESS
, SPR_NOACCESS
,
6013 &spr_read_generic
, spr_access_nop
,
6017 /* Thermal management */
6019 /* This register is not implemented but is present for compatibility */
6020 spr_register(env
, SPR_SDA
, "SDA",
6021 SPR_NOACCESS
, SPR_NOACCESS
,
6022 &spr_read_generic
, &spr_write_generic
,
6024 /* Hardware implementation registers */
6025 /* XXX : not implemented */
6026 spr_register(env
, SPR_HID0
, "HID0",
6027 SPR_NOACCESS
, SPR_NOACCESS
,
6028 &spr_read_generic
, &spr_write_generic
,
6030 /* XXX : not implemented */
6031 spr_register(env
, SPR_HID1
, "HID1",
6032 SPR_NOACCESS
, SPR_NOACCESS
,
6033 &spr_read_generic
, &spr_write_generic
,
6035 /* Memory management */
6037 /* PowerPC 750cx has 8 DBATs and 8 IBATs */
6039 init_excp_750cx(env
);
6040 env
->dcache_line_size
= 32;
6041 env
->icache_line_size
= 32;
6042 /* Allocate hardware IRQ controller */
6043 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6046 POWERPC_FAMILY(750cx
)(ObjectClass
*oc
, void *data
)
6048 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6049 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6051 dc
->desc
= "PowerPC 750CX";
6052 pcc
->init_proc
= init_proc_750cx
;
6053 pcc
->check_pow
= check_pow_hid0
;
6054 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6055 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6056 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6057 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6058 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6059 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6060 PPC_SEGMENT
| PPC_EXTERN
;
6061 pcc
->msr_mask
= (1ull << MSR_POW
) |
6077 pcc
->mmu_model
= POWERPC_MMU_32B
;
6078 #if defined(CONFIG_SOFTMMU)
6079 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6081 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6082 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6083 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6084 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6085 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6088 static void init_proc_750fx(CPUPPCState
*env
)
6090 gen_spr_ne_601(env
);
6093 /* XXX : not implemented */
6094 spr_register(env
, SPR_L2CR
, "L2CR",
6095 SPR_NOACCESS
, SPR_NOACCESS
,
6096 &spr_read_generic
, spr_access_nop
,
6100 /* Thermal management */
6102 /* XXX : not implemented */
6103 spr_register(env
, SPR_750_THRM4
, "THRM4",
6104 SPR_NOACCESS
, SPR_NOACCESS
,
6105 &spr_read_generic
, &spr_write_generic
,
6107 /* Hardware implementation registers */
6108 /* XXX : not implemented */
6109 spr_register(env
, SPR_HID0
, "HID0",
6110 SPR_NOACCESS
, SPR_NOACCESS
,
6111 &spr_read_generic
, &spr_write_generic
,
6113 /* XXX : not implemented */
6114 spr_register(env
, SPR_HID1
, "HID1",
6115 SPR_NOACCESS
, SPR_NOACCESS
,
6116 &spr_read_generic
, &spr_write_generic
,
6118 /* XXX : not implemented */
6119 spr_register(env
, SPR_750FX_HID2
, "HID2",
6120 SPR_NOACCESS
, SPR_NOACCESS
,
6121 &spr_read_generic
, &spr_write_generic
,
6123 /* Memory management */
6125 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6128 env
->dcache_line_size
= 32;
6129 env
->icache_line_size
= 32;
6130 /* Allocate hardware IRQ controller */
6131 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6134 POWERPC_FAMILY(750fx
)(ObjectClass
*oc
, void *data
)
6136 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6137 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6139 dc
->desc
= "PowerPC 750FX";
6140 pcc
->init_proc
= init_proc_750fx
;
6141 pcc
->check_pow
= check_pow_hid0
;
6142 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6143 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6144 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6145 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6146 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6147 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6148 PPC_SEGMENT
| PPC_EXTERN
;
6149 pcc
->msr_mask
= (1ull << MSR_POW
) |
6165 pcc
->mmu_model
= POWERPC_MMU_32B
;
6166 #if defined(CONFIG_SOFTMMU)
6167 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6169 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6170 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6171 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6172 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6173 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6176 static void init_proc_750gx(CPUPPCState
*env
)
6178 gen_spr_ne_601(env
);
6181 /* XXX : not implemented (XXX: different from 750fx) */
6182 spr_register(env
, SPR_L2CR
, "L2CR",
6183 SPR_NOACCESS
, SPR_NOACCESS
,
6184 &spr_read_generic
, spr_access_nop
,
6188 /* Thermal management */
6190 /* XXX : not implemented */
6191 spr_register(env
, SPR_750_THRM4
, "THRM4",
6192 SPR_NOACCESS
, SPR_NOACCESS
,
6193 &spr_read_generic
, &spr_write_generic
,
6195 /* Hardware implementation registers */
6196 /* XXX : not implemented (XXX: different from 750fx) */
6197 spr_register(env
, SPR_HID0
, "HID0",
6198 SPR_NOACCESS
, SPR_NOACCESS
,
6199 &spr_read_generic
, &spr_write_generic
,
6201 /* XXX : not implemented */
6202 spr_register(env
, SPR_HID1
, "HID1",
6203 SPR_NOACCESS
, SPR_NOACCESS
,
6204 &spr_read_generic
, &spr_write_generic
,
6206 /* XXX : not implemented (XXX: different from 750fx) */
6207 spr_register(env
, SPR_750FX_HID2
, "HID2",
6208 SPR_NOACCESS
, SPR_NOACCESS
,
6209 &spr_read_generic
, &spr_write_generic
,
6211 /* Memory management */
6213 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6216 env
->dcache_line_size
= 32;
6217 env
->icache_line_size
= 32;
6218 /* Allocate hardware IRQ controller */
6219 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6222 POWERPC_FAMILY(750gx
)(ObjectClass
*oc
, void *data
)
6224 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6225 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6227 dc
->desc
= "PowerPC 750GX";
6228 pcc
->init_proc
= init_proc_750gx
;
6229 pcc
->check_pow
= check_pow_hid0
;
6230 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6231 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6232 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6233 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6234 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6235 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6236 PPC_SEGMENT
| PPC_EXTERN
;
6237 pcc
->msr_mask
= (1ull << MSR_POW
) |
6253 pcc
->mmu_model
= POWERPC_MMU_32B
;
6254 #if defined(CONFIG_SOFTMMU)
6255 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6257 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6258 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6259 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6260 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6261 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6264 static void init_proc_745(CPUPPCState
*env
)
6266 gen_spr_ne_601(env
);
6269 gen_spr_G2_755(env
);
6272 /* Thermal management */
6274 /* Hardware implementation registers */
6275 /* XXX : not implemented */
6276 spr_register(env
, SPR_HID0
, "HID0",
6277 SPR_NOACCESS
, SPR_NOACCESS
,
6278 &spr_read_generic
, &spr_write_generic
,
6280 /* XXX : not implemented */
6281 spr_register(env
, SPR_HID1
, "HID1",
6282 SPR_NOACCESS
, SPR_NOACCESS
,
6283 &spr_read_generic
, &spr_write_generic
,
6285 /* XXX : not implemented */
6286 spr_register(env
, SPR_HID2
, "HID2",
6287 SPR_NOACCESS
, SPR_NOACCESS
,
6288 &spr_read_generic
, &spr_write_generic
,
6290 /* Memory management */
6293 gen_6xx_7xx_soft_tlb(env
, 64, 2);
6295 env
->dcache_line_size
= 32;
6296 env
->icache_line_size
= 32;
6297 /* Allocate hardware IRQ controller */
6298 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6301 POWERPC_FAMILY(745)(ObjectClass
*oc
, void *data
)
6303 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6304 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6306 dc
->desc
= "PowerPC 745";
6307 pcc
->init_proc
= init_proc_745
;
6308 pcc
->check_pow
= check_pow_hid0
;
6309 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6310 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6311 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6312 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6313 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6314 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
6315 PPC_SEGMENT
| PPC_EXTERN
;
6316 pcc
->msr_mask
= (1ull << MSR_POW
) |
6332 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
6333 pcc
->excp_model
= POWERPC_EXCP_7x5
;
6334 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6335 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6336 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6337 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6340 static void init_proc_755(CPUPPCState
*env
)
6342 gen_spr_ne_601(env
);
6345 gen_spr_G2_755(env
);
6348 /* L2 cache control */
6349 /* XXX : not implemented */
6350 spr_register(env
, SPR_L2CR
, "L2CR",
6351 SPR_NOACCESS
, SPR_NOACCESS
,
6352 &spr_read_generic
, spr_access_nop
,
6354 /* XXX : not implemented */
6355 spr_register(env
, SPR_L2PMCR
, "L2PMCR",
6356 SPR_NOACCESS
, SPR_NOACCESS
,
6357 &spr_read_generic
, &spr_write_generic
,
6359 /* Thermal management */
6361 /* Hardware implementation registers */
6362 /* XXX : not implemented */
6363 spr_register(env
, SPR_HID0
, "HID0",
6364 SPR_NOACCESS
, SPR_NOACCESS
,
6365 &spr_read_generic
, &spr_write_generic
,
6367 /* XXX : not implemented */
6368 spr_register(env
, SPR_HID1
, "HID1",
6369 SPR_NOACCESS
, SPR_NOACCESS
,
6370 &spr_read_generic
, &spr_write_generic
,
6372 /* XXX : not implemented */
6373 spr_register(env
, SPR_HID2
, "HID2",
6374 SPR_NOACCESS
, SPR_NOACCESS
,
6375 &spr_read_generic
, &spr_write_generic
,
6377 /* Memory management */
6380 gen_6xx_7xx_soft_tlb(env
, 64, 2);
6382 env
->dcache_line_size
= 32;
6383 env
->icache_line_size
= 32;
6384 /* Allocate hardware IRQ controller */
6385 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6388 POWERPC_FAMILY(755)(ObjectClass
*oc
, void *data
)
6390 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6391 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6393 dc
->desc
= "PowerPC 755";
6394 pcc
->init_proc
= init_proc_755
;
6395 pcc
->check_pow
= check_pow_hid0
;
6396 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6397 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6398 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6399 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6400 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6401 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
6402 PPC_SEGMENT
| PPC_EXTERN
;
6403 pcc
->msr_mask
= (1ull << MSR_POW
) |
6419 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
6420 pcc
->excp_model
= POWERPC_EXCP_7x5
;
6421 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6422 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6423 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6424 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6427 static void init_proc_7400(CPUPPCState
*env
)
6429 gen_spr_ne_601(env
);
6434 /* 74xx specific SPR */
6436 /* XXX : not implemented */
6437 spr_register(env
, SPR_UBAMR
, "UBAMR",
6438 &spr_read_ureg
, SPR_NOACCESS
,
6439 &spr_read_ureg
, SPR_NOACCESS
,
6441 /* XXX: this seems not implemented on all revisions. */
6442 /* XXX : not implemented */
6443 spr_register(env
, SPR_MSSCR1
, "MSSCR1",
6444 SPR_NOACCESS
, SPR_NOACCESS
,
6445 &spr_read_generic
, &spr_write_generic
,
6447 /* Thermal management */
6449 /* Memory management */
6451 init_excp_7400(env
);
6452 env
->dcache_line_size
= 32;
6453 env
->icache_line_size
= 32;
6454 /* Allocate hardware IRQ controller */
6455 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6458 POWERPC_FAMILY(7400)(ObjectClass
*oc
, void *data
)
6460 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6461 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6463 dc
->desc
= "PowerPC 7400 (aka G4)";
6464 pcc
->init_proc
= init_proc_7400
;
6465 pcc
->check_pow
= check_pow_hid0
;
6466 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6467 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6468 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6470 PPC_CACHE
| PPC_CACHE_ICBI
|
6471 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6472 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6473 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6475 PPC_SEGMENT
| PPC_EXTERN
|
6477 pcc
->msr_mask
= (1ull << MSR_VR
) |
6494 pcc
->mmu_model
= POWERPC_MMU_32B
;
6495 #if defined(CONFIG_SOFTMMU)
6496 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6498 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6499 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6500 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6501 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6502 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6503 POWERPC_FLAG_BUS_CLK
;
6506 static void init_proc_7410(CPUPPCState
*env
)
6508 gen_spr_ne_601(env
);
6513 /* 74xx specific SPR */
6515 /* XXX : not implemented */
6516 spr_register(env
, SPR_UBAMR
, "UBAMR",
6517 &spr_read_ureg
, SPR_NOACCESS
,
6518 &spr_read_ureg
, SPR_NOACCESS
,
6520 /* Thermal management */
6523 /* XXX : not implemented */
6524 spr_register(env
, SPR_L2PMCR
, "L2PMCR",
6525 SPR_NOACCESS
, SPR_NOACCESS
,
6526 &spr_read_generic
, &spr_write_generic
,
6529 /* XXX : not implemented */
6530 spr_register(env
, SPR_LDSTDB
, "LDSTDB",
6531 SPR_NOACCESS
, SPR_NOACCESS
,
6532 &spr_read_generic
, &spr_write_generic
,
6534 /* Memory management */
6536 init_excp_7400(env
);
6537 env
->dcache_line_size
= 32;
6538 env
->icache_line_size
= 32;
6539 /* Allocate hardware IRQ controller */
6540 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6543 POWERPC_FAMILY(7410)(ObjectClass
*oc
, void *data
)
6545 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6546 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6548 dc
->desc
= "PowerPC 7410 (aka G4)";
6549 pcc
->init_proc
= init_proc_7410
;
6550 pcc
->check_pow
= check_pow_hid0
;
6551 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6552 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6553 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6555 PPC_CACHE
| PPC_CACHE_ICBI
|
6556 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6557 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6558 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6560 PPC_SEGMENT
| PPC_EXTERN
|
6562 pcc
->msr_mask
= (1ull << MSR_VR
) |
6579 pcc
->mmu_model
= POWERPC_MMU_32B
;
6580 #if defined(CONFIG_SOFTMMU)
6581 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6583 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6584 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6585 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6586 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6587 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6588 POWERPC_FLAG_BUS_CLK
;
6591 static void init_proc_7440(CPUPPCState
*env
)
6593 gen_spr_ne_601(env
);
6598 /* 74xx specific SPR */
6600 /* XXX : not implemented */
6601 spr_register(env
, SPR_UBAMR
, "UBAMR",
6602 &spr_read_ureg
, SPR_NOACCESS
,
6603 &spr_read_ureg
, SPR_NOACCESS
,
6606 /* XXX : not implemented */
6607 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6608 SPR_NOACCESS
, SPR_NOACCESS
,
6609 &spr_read_generic
, &spr_write_generic
,
6612 /* XXX : not implemented */
6613 spr_register(env
, SPR_ICTRL
, "ICTRL",
6614 SPR_NOACCESS
, SPR_NOACCESS
,
6615 &spr_read_generic
, &spr_write_generic
,
6618 /* XXX : not implemented */
6619 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6620 SPR_NOACCESS
, SPR_NOACCESS
,
6621 &spr_read_generic
, &spr_write_generic
,
6624 /* XXX : not implemented */
6625 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6626 SPR_NOACCESS
, SPR_NOACCESS
,
6627 &spr_read_generic
, &spr_write_generic
,
6629 /* XXX : not implemented */
6630 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6631 &spr_read_ureg
, SPR_NOACCESS
,
6632 &spr_read_ureg
, SPR_NOACCESS
,
6634 /* XXX : not implemented */
6635 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6636 SPR_NOACCESS
, SPR_NOACCESS
,
6637 &spr_read_generic
, &spr_write_generic
,
6639 /* XXX : not implemented */
6640 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6641 &spr_read_ureg
, SPR_NOACCESS
,
6642 &spr_read_ureg
, SPR_NOACCESS
,
6644 /* Memory management */
6646 gen_74xx_soft_tlb(env
, 128, 2);
6647 init_excp_7450(env
);
6648 env
->dcache_line_size
= 32;
6649 env
->icache_line_size
= 32;
6650 /* Allocate hardware IRQ controller */
6651 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6654 POWERPC_FAMILY(7440)(ObjectClass
*oc
, void *data
)
6656 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6657 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6659 dc
->desc
= "PowerPC 7440 (aka G4)";
6660 pcc
->init_proc
= init_proc_7440
;
6661 pcc
->check_pow
= check_pow_hid0_74xx
;
6662 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6663 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6664 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6666 PPC_CACHE
| PPC_CACHE_ICBI
|
6667 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6668 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6669 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6670 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6671 PPC_SEGMENT
| PPC_EXTERN
|
6673 pcc
->msr_mask
= (1ull << MSR_VR
) |
6690 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6691 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6692 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6693 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6694 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6695 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6696 POWERPC_FLAG_BUS_CLK
;
6699 static void init_proc_7450(CPUPPCState
*env
)
6701 gen_spr_ne_601(env
);
6706 /* 74xx specific SPR */
6708 /* Level 3 cache control */
6711 /* XXX : not implemented */
6712 spr_register(env
, SPR_L3ITCR1
, "L3ITCR1",
6713 SPR_NOACCESS
, SPR_NOACCESS
,
6714 &spr_read_generic
, &spr_write_generic
,
6717 /* XXX : not implemented */
6718 spr_register(env
, SPR_L3ITCR2
, "L3ITCR2",
6719 SPR_NOACCESS
, SPR_NOACCESS
,
6720 &spr_read_generic
, &spr_write_generic
,
6723 /* XXX : not implemented */
6724 spr_register(env
, SPR_L3ITCR3
, "L3ITCR3",
6725 SPR_NOACCESS
, SPR_NOACCESS
,
6726 &spr_read_generic
, &spr_write_generic
,
6729 /* XXX : not implemented */
6730 spr_register(env
, SPR_L3OHCR
, "L3OHCR",
6731 SPR_NOACCESS
, SPR_NOACCESS
,
6732 &spr_read_generic
, &spr_write_generic
,
6734 /* XXX : not implemented */
6735 spr_register(env
, SPR_UBAMR
, "UBAMR",
6736 &spr_read_ureg
, SPR_NOACCESS
,
6737 &spr_read_ureg
, SPR_NOACCESS
,
6740 /* XXX : not implemented */
6741 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6742 SPR_NOACCESS
, SPR_NOACCESS
,
6743 &spr_read_generic
, &spr_write_generic
,
6746 /* XXX : not implemented */
6747 spr_register(env
, SPR_ICTRL
, "ICTRL",
6748 SPR_NOACCESS
, SPR_NOACCESS
,
6749 &spr_read_generic
, &spr_write_generic
,
6752 /* XXX : not implemented */
6753 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6754 SPR_NOACCESS
, SPR_NOACCESS
,
6755 &spr_read_generic
, &spr_write_generic
,
6758 /* XXX : not implemented */
6759 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6760 SPR_NOACCESS
, SPR_NOACCESS
,
6761 &spr_read_generic
, &spr_write_generic
,
6763 /* XXX : not implemented */
6764 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6765 &spr_read_ureg
, SPR_NOACCESS
,
6766 &spr_read_ureg
, SPR_NOACCESS
,
6768 /* XXX : not implemented */
6769 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6770 SPR_NOACCESS
, SPR_NOACCESS
,
6771 &spr_read_generic
, &spr_write_generic
,
6773 /* XXX : not implemented */
6774 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6775 &spr_read_ureg
, SPR_NOACCESS
,
6776 &spr_read_ureg
, SPR_NOACCESS
,
6778 /* Memory management */
6780 gen_74xx_soft_tlb(env
, 128, 2);
6781 init_excp_7450(env
);
6782 env
->dcache_line_size
= 32;
6783 env
->icache_line_size
= 32;
6784 /* Allocate hardware IRQ controller */
6785 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6788 POWERPC_FAMILY(7450)(ObjectClass
*oc
, void *data
)
6790 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6791 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6793 dc
->desc
= "PowerPC 7450 (aka G4)";
6794 pcc
->init_proc
= init_proc_7450
;
6795 pcc
->check_pow
= check_pow_hid0_74xx
;
6796 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6797 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6798 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6800 PPC_CACHE
| PPC_CACHE_ICBI
|
6801 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6802 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6803 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6804 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6805 PPC_SEGMENT
| PPC_EXTERN
|
6807 pcc
->msr_mask
= (1ull << MSR_VR
) |
6824 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6825 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6826 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6827 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6828 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6829 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6830 POWERPC_FLAG_BUS_CLK
;
6833 static void init_proc_7445(CPUPPCState
*env
)
6835 gen_spr_ne_601(env
);
6840 /* 74xx specific SPR */
6843 /* XXX : not implemented */
6844 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6845 SPR_NOACCESS
, SPR_NOACCESS
,
6846 &spr_read_generic
, &spr_write_generic
,
6849 /* XXX : not implemented */
6850 spr_register(env
, SPR_ICTRL
, "ICTRL",
6851 SPR_NOACCESS
, SPR_NOACCESS
,
6852 &spr_read_generic
, &spr_write_generic
,
6855 /* XXX : not implemented */
6856 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6857 SPR_NOACCESS
, SPR_NOACCESS
,
6858 &spr_read_generic
, &spr_write_generic
,
6861 /* XXX : not implemented */
6862 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6863 SPR_NOACCESS
, SPR_NOACCESS
,
6864 &spr_read_generic
, &spr_write_generic
,
6866 /* XXX : not implemented */
6867 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6868 &spr_read_ureg
, SPR_NOACCESS
,
6869 &spr_read_ureg
, SPR_NOACCESS
,
6871 /* XXX : not implemented */
6872 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6873 SPR_NOACCESS
, SPR_NOACCESS
,
6874 &spr_read_generic
, &spr_write_generic
,
6876 /* XXX : not implemented */
6877 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6878 &spr_read_ureg
, SPR_NOACCESS
,
6879 &spr_read_ureg
, SPR_NOACCESS
,
6882 spr_register(env
, SPR_SPRG4
, "SPRG4",
6883 SPR_NOACCESS
, SPR_NOACCESS
,
6884 &spr_read_generic
, &spr_write_generic
,
6886 spr_register(env
, SPR_USPRG4
, "USPRG4",
6887 &spr_read_ureg
, SPR_NOACCESS
,
6888 &spr_read_ureg
, SPR_NOACCESS
,
6890 spr_register(env
, SPR_SPRG5
, "SPRG5",
6891 SPR_NOACCESS
, SPR_NOACCESS
,
6892 &spr_read_generic
, &spr_write_generic
,
6894 spr_register(env
, SPR_USPRG5
, "USPRG5",
6895 &spr_read_ureg
, SPR_NOACCESS
,
6896 &spr_read_ureg
, SPR_NOACCESS
,
6898 spr_register(env
, SPR_SPRG6
, "SPRG6",
6899 SPR_NOACCESS
, SPR_NOACCESS
,
6900 &spr_read_generic
, &spr_write_generic
,
6902 spr_register(env
, SPR_USPRG6
, "USPRG6",
6903 &spr_read_ureg
, SPR_NOACCESS
,
6904 &spr_read_ureg
, SPR_NOACCESS
,
6906 spr_register(env
, SPR_SPRG7
, "SPRG7",
6907 SPR_NOACCESS
, SPR_NOACCESS
,
6908 &spr_read_generic
, &spr_write_generic
,
6910 spr_register(env
, SPR_USPRG7
, "USPRG7",
6911 &spr_read_ureg
, SPR_NOACCESS
,
6912 &spr_read_ureg
, SPR_NOACCESS
,
6914 /* Memory management */
6917 gen_74xx_soft_tlb(env
, 128, 2);
6918 init_excp_7450(env
);
6919 env
->dcache_line_size
= 32;
6920 env
->icache_line_size
= 32;
6921 /* Allocate hardware IRQ controller */
6922 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6925 POWERPC_FAMILY(7445)(ObjectClass
*oc
, void *data
)
6927 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6928 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6930 dc
->desc
= "PowerPC 7445 (aka G4)";
6931 pcc
->init_proc
= init_proc_7445
;
6932 pcc
->check_pow
= check_pow_hid0_74xx
;
6933 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6934 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6935 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6937 PPC_CACHE
| PPC_CACHE_ICBI
|
6938 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6939 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6940 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6941 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6942 PPC_SEGMENT
| PPC_EXTERN
|
6944 pcc
->msr_mask
= (1ull << MSR_VR
) |
6961 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6962 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6963 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6964 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6965 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6966 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6967 POWERPC_FLAG_BUS_CLK
;
6970 static void init_proc_7455(CPUPPCState
*env
)
6972 gen_spr_ne_601(env
);
6977 /* 74xx specific SPR */
6979 /* Level 3 cache control */
6982 /* XXX : not implemented */
6983 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6984 SPR_NOACCESS
, SPR_NOACCESS
,
6985 &spr_read_generic
, &spr_write_generic
,
6988 /* XXX : not implemented */
6989 spr_register(env
, SPR_ICTRL
, "ICTRL",
6990 SPR_NOACCESS
, SPR_NOACCESS
,
6991 &spr_read_generic
, &spr_write_generic
,
6994 /* XXX : not implemented */
6995 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6996 SPR_NOACCESS
, SPR_NOACCESS
,
6997 &spr_read_generic
, &spr_write_generic
,
7000 /* XXX : not implemented */
7001 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7002 SPR_NOACCESS
, SPR_NOACCESS
,
7003 &spr_read_generic
, &spr_write_generic
,
7005 /* XXX : not implemented */
7006 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7007 &spr_read_ureg
, SPR_NOACCESS
,
7008 &spr_read_ureg
, SPR_NOACCESS
,
7010 /* XXX : not implemented */
7011 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7012 SPR_NOACCESS
, SPR_NOACCESS
,
7013 &spr_read_generic
, &spr_write_generic
,
7015 /* XXX : not implemented */
7016 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7017 &spr_read_ureg
, SPR_NOACCESS
,
7018 &spr_read_ureg
, SPR_NOACCESS
,
7021 spr_register(env
, SPR_SPRG4
, "SPRG4",
7022 SPR_NOACCESS
, SPR_NOACCESS
,
7023 &spr_read_generic
, &spr_write_generic
,
7025 spr_register(env
, SPR_USPRG4
, "USPRG4",
7026 &spr_read_ureg
, SPR_NOACCESS
,
7027 &spr_read_ureg
, SPR_NOACCESS
,
7029 spr_register(env
, SPR_SPRG5
, "SPRG5",
7030 SPR_NOACCESS
, SPR_NOACCESS
,
7031 &spr_read_generic
, &spr_write_generic
,
7033 spr_register(env
, SPR_USPRG5
, "USPRG5",
7034 &spr_read_ureg
, SPR_NOACCESS
,
7035 &spr_read_ureg
, SPR_NOACCESS
,
7037 spr_register(env
, SPR_SPRG6
, "SPRG6",
7038 SPR_NOACCESS
, SPR_NOACCESS
,
7039 &spr_read_generic
, &spr_write_generic
,
7041 spr_register(env
, SPR_USPRG6
, "USPRG6",
7042 &spr_read_ureg
, SPR_NOACCESS
,
7043 &spr_read_ureg
, SPR_NOACCESS
,
7045 spr_register(env
, SPR_SPRG7
, "SPRG7",
7046 SPR_NOACCESS
, SPR_NOACCESS
,
7047 &spr_read_generic
, &spr_write_generic
,
7049 spr_register(env
, SPR_USPRG7
, "USPRG7",
7050 &spr_read_ureg
, SPR_NOACCESS
,
7051 &spr_read_ureg
, SPR_NOACCESS
,
7053 /* Memory management */
7056 gen_74xx_soft_tlb(env
, 128, 2);
7057 init_excp_7450(env
);
7058 env
->dcache_line_size
= 32;
7059 env
->icache_line_size
= 32;
7060 /* Allocate hardware IRQ controller */
7061 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7064 POWERPC_FAMILY(7455)(ObjectClass
*oc
, void *data
)
7066 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7067 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7069 dc
->desc
= "PowerPC 7455 (aka G4)";
7070 pcc
->init_proc
= init_proc_7455
;
7071 pcc
->check_pow
= check_pow_hid0_74xx
;
7072 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7073 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7074 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7076 PPC_CACHE
| PPC_CACHE_ICBI
|
7077 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7078 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7079 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7080 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7081 PPC_SEGMENT
| PPC_EXTERN
|
7083 pcc
->msr_mask
= (1ull << MSR_VR
) |
7100 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7101 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7102 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7103 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7104 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7105 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7106 POWERPC_FLAG_BUS_CLK
;
7109 static void init_proc_7457(CPUPPCState
*env
)
7111 gen_spr_ne_601(env
);
7116 /* 74xx specific SPR */
7118 /* Level 3 cache control */
7121 /* XXX : not implemented */
7122 spr_register(env
, SPR_L3ITCR1
, "L3ITCR1",
7123 SPR_NOACCESS
, SPR_NOACCESS
,
7124 &spr_read_generic
, &spr_write_generic
,
7127 /* XXX : not implemented */
7128 spr_register(env
, SPR_L3ITCR2
, "L3ITCR2",
7129 SPR_NOACCESS
, SPR_NOACCESS
,
7130 &spr_read_generic
, &spr_write_generic
,
7133 /* XXX : not implemented */
7134 spr_register(env
, SPR_L3ITCR3
, "L3ITCR3",
7135 SPR_NOACCESS
, SPR_NOACCESS
,
7136 &spr_read_generic
, &spr_write_generic
,
7139 /* XXX : not implemented */
7140 spr_register(env
, SPR_L3OHCR
, "L3OHCR",
7141 SPR_NOACCESS
, SPR_NOACCESS
,
7142 &spr_read_generic
, &spr_write_generic
,
7145 /* XXX : not implemented */
7146 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7147 SPR_NOACCESS
, SPR_NOACCESS
,
7148 &spr_read_generic
, &spr_write_generic
,
7151 /* XXX : not implemented */
7152 spr_register(env
, SPR_ICTRL
, "ICTRL",
7153 SPR_NOACCESS
, SPR_NOACCESS
,
7154 &spr_read_generic
, &spr_write_generic
,
7157 /* XXX : not implemented */
7158 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7159 SPR_NOACCESS
, SPR_NOACCESS
,
7160 &spr_read_generic
, &spr_write_generic
,
7163 /* XXX : not implemented */
7164 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7165 SPR_NOACCESS
, SPR_NOACCESS
,
7166 &spr_read_generic
, &spr_write_generic
,
7168 /* XXX : not implemented */
7169 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7170 &spr_read_ureg
, SPR_NOACCESS
,
7171 &spr_read_ureg
, SPR_NOACCESS
,
7173 /* XXX : not implemented */
7174 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7175 SPR_NOACCESS
, SPR_NOACCESS
,
7176 &spr_read_generic
, &spr_write_generic
,
7178 /* XXX : not implemented */
7179 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7180 &spr_read_ureg
, SPR_NOACCESS
,
7181 &spr_read_ureg
, SPR_NOACCESS
,
7184 spr_register(env
, SPR_SPRG4
, "SPRG4",
7185 SPR_NOACCESS
, SPR_NOACCESS
,
7186 &spr_read_generic
, &spr_write_generic
,
7188 spr_register(env
, SPR_USPRG4
, "USPRG4",
7189 &spr_read_ureg
, SPR_NOACCESS
,
7190 &spr_read_ureg
, SPR_NOACCESS
,
7192 spr_register(env
, SPR_SPRG5
, "SPRG5",
7193 SPR_NOACCESS
, SPR_NOACCESS
,
7194 &spr_read_generic
, &spr_write_generic
,
7196 spr_register(env
, SPR_USPRG5
, "USPRG5",
7197 &spr_read_ureg
, SPR_NOACCESS
,
7198 &spr_read_ureg
, SPR_NOACCESS
,
7200 spr_register(env
, SPR_SPRG6
, "SPRG6",
7201 SPR_NOACCESS
, SPR_NOACCESS
,
7202 &spr_read_generic
, &spr_write_generic
,
7204 spr_register(env
, SPR_USPRG6
, "USPRG6",
7205 &spr_read_ureg
, SPR_NOACCESS
,
7206 &spr_read_ureg
, SPR_NOACCESS
,
7208 spr_register(env
, SPR_SPRG7
, "SPRG7",
7209 SPR_NOACCESS
, SPR_NOACCESS
,
7210 &spr_read_generic
, &spr_write_generic
,
7212 spr_register(env
, SPR_USPRG7
, "USPRG7",
7213 &spr_read_ureg
, SPR_NOACCESS
,
7214 &spr_read_ureg
, SPR_NOACCESS
,
7216 /* Memory management */
7219 gen_74xx_soft_tlb(env
, 128, 2);
7220 init_excp_7450(env
);
7221 env
->dcache_line_size
= 32;
7222 env
->icache_line_size
= 32;
7223 /* Allocate hardware IRQ controller */
7224 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7227 POWERPC_FAMILY(7457)(ObjectClass
*oc
, void *data
)
7229 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7230 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7232 dc
->desc
= "PowerPC 7457 (aka G4)";
7233 pcc
->init_proc
= init_proc_7457
;
7234 pcc
->check_pow
= check_pow_hid0_74xx
;
7235 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7236 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7237 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7239 PPC_CACHE
| PPC_CACHE_ICBI
|
7240 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7241 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7242 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7243 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7244 PPC_SEGMENT
| PPC_EXTERN
|
7246 pcc
->msr_mask
= (1ull << MSR_VR
) |
7263 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7264 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7265 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7266 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7267 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7268 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7269 POWERPC_FLAG_BUS_CLK
;
7272 static void init_proc_e600(CPUPPCState
*env
)
7274 gen_spr_ne_601(env
);
7279 /* 74xx specific SPR */
7281 /* XXX : not implemented */
7282 spr_register(env
, SPR_UBAMR
, "UBAMR",
7283 &spr_read_ureg
, SPR_NOACCESS
,
7284 &spr_read_ureg
, SPR_NOACCESS
,
7286 /* XXX : not implemented */
7287 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7288 SPR_NOACCESS
, SPR_NOACCESS
,
7289 &spr_read_generic
, &spr_write_generic
,
7291 /* XXX : not implemented */
7292 spr_register(env
, SPR_ICTRL
, "ICTRL",
7293 SPR_NOACCESS
, SPR_NOACCESS
,
7294 &spr_read_generic
, &spr_write_generic
,
7296 /* XXX : not implemented */
7297 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7298 SPR_NOACCESS
, SPR_NOACCESS
,
7299 &spr_read_generic
, &spr_write_generic
,
7301 /* XXX : not implemented */
7302 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7303 SPR_NOACCESS
, SPR_NOACCESS
,
7304 &spr_read_generic
, &spr_write_generic
,
7306 /* XXX : not implemented */
7307 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7308 &spr_read_ureg
, SPR_NOACCESS
,
7309 &spr_read_ureg
, SPR_NOACCESS
,
7311 /* XXX : not implemented */
7312 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7313 SPR_NOACCESS
, SPR_NOACCESS
,
7314 &spr_read_generic
, &spr_write_generic
,
7316 /* XXX : not implemented */
7317 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7318 &spr_read_ureg
, SPR_NOACCESS
,
7319 &spr_read_ureg
, SPR_NOACCESS
,
7322 spr_register(env
, SPR_SPRG4
, "SPRG4",
7323 SPR_NOACCESS
, SPR_NOACCESS
,
7324 &spr_read_generic
, &spr_write_generic
,
7326 spr_register(env
, SPR_USPRG4
, "USPRG4",
7327 &spr_read_ureg
, SPR_NOACCESS
,
7328 &spr_read_ureg
, SPR_NOACCESS
,
7330 spr_register(env
, SPR_SPRG5
, "SPRG5",
7331 SPR_NOACCESS
, SPR_NOACCESS
,
7332 &spr_read_generic
, &spr_write_generic
,
7334 spr_register(env
, SPR_USPRG5
, "USPRG5",
7335 &spr_read_ureg
, SPR_NOACCESS
,
7336 &spr_read_ureg
, SPR_NOACCESS
,
7338 spr_register(env
, SPR_SPRG6
, "SPRG6",
7339 SPR_NOACCESS
, SPR_NOACCESS
,
7340 &spr_read_generic
, &spr_write_generic
,
7342 spr_register(env
, SPR_USPRG6
, "USPRG6",
7343 &spr_read_ureg
, SPR_NOACCESS
,
7344 &spr_read_ureg
, SPR_NOACCESS
,
7346 spr_register(env
, SPR_SPRG7
, "SPRG7",
7347 SPR_NOACCESS
, SPR_NOACCESS
,
7348 &spr_read_generic
, &spr_write_generic
,
7350 spr_register(env
, SPR_USPRG7
, "USPRG7",
7351 &spr_read_ureg
, SPR_NOACCESS
,
7352 &spr_read_ureg
, SPR_NOACCESS
,
7354 /* Memory management */
7357 gen_74xx_soft_tlb(env
, 128, 2);
7358 init_excp_7450(env
);
7359 env
->dcache_line_size
= 32;
7360 env
->icache_line_size
= 32;
7361 /* Allocate hardware IRQ controller */
7362 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7365 POWERPC_FAMILY(e600
)(ObjectClass
*oc
, void *data
)
7367 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7368 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7370 dc
->desc
= "PowerPC e600";
7371 pcc
->init_proc
= init_proc_e600
;
7372 pcc
->check_pow
= check_pow_hid0_74xx
;
7373 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7374 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7375 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7377 PPC_CACHE
| PPC_CACHE_ICBI
|
7378 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7379 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7380 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7381 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7382 PPC_SEGMENT
| PPC_EXTERN
|
7384 pcc
->insns_flags2
= PPC_NONE
;
7385 pcc
->msr_mask
= (1ull << MSR_VR
) |
7402 pcc
->mmu_model
= POWERPC_MMU_32B
;
7403 #if defined(CONFIG_SOFTMMU)
7404 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
7406 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7407 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7408 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7409 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7410 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7411 POWERPC_FLAG_BUS_CLK
;
7414 #if defined(TARGET_PPC64)
7415 #if defined(CONFIG_USER_ONLY)
7416 #define POWERPC970_HID5_INIT 0x00000080
7418 #define POWERPC970_HID5_INIT 0x00000000
7421 static void gen_fscr_facility_check(DisasContext
*ctx
, int facility_sprn
,
7422 int bit
, int sprn
, int cause
)
7424 TCGv_i32 t1
= tcg_const_i32(bit
);
7425 TCGv_i32 t2
= tcg_const_i32(sprn
);
7426 TCGv_i32 t3
= tcg_const_i32(cause
);
7428 gen_helper_fscr_facility_check(cpu_env
, t1
, t2
, t3
);
7430 tcg_temp_free_i32(t3
);
7431 tcg_temp_free_i32(t2
);
7432 tcg_temp_free_i32(t1
);
7435 static void gen_msr_facility_check(DisasContext
*ctx
, int facility_sprn
,
7436 int bit
, int sprn
, int cause
)
7438 TCGv_i32 t1
= tcg_const_i32(bit
);
7439 TCGv_i32 t2
= tcg_const_i32(sprn
);
7440 TCGv_i32 t3
= tcg_const_i32(cause
);
7442 gen_helper_msr_facility_check(cpu_env
, t1
, t2
, t3
);
7444 tcg_temp_free_i32(t3
);
7445 tcg_temp_free_i32(t2
);
7446 tcg_temp_free_i32(t1
);
7449 static void spr_read_prev_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
7451 TCGv spr_up
= tcg_temp_new();
7452 TCGv spr
= tcg_temp_new();
7454 gen_load_spr(spr
, sprn
- 1);
7455 tcg_gen_shri_tl(spr_up
, spr
, 32);
7456 tcg_gen_ext32u_tl(cpu_gpr
[gprn
], spr_up
);
7459 tcg_temp_free(spr_up
);
7462 static void spr_write_prev_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
7464 TCGv spr
= tcg_temp_new();
7466 gen_load_spr(spr
, sprn
- 1);
7467 tcg_gen_deposit_tl(spr
, spr
, cpu_gpr
[gprn
], 32, 32);
7468 gen_store_spr(sprn
- 1, spr
);
7473 static int check_pow_970(CPUPPCState
*env
)
7475 if (env
->spr
[SPR_HID0
] & (HID0_DEEPNAP
| HID0_DOZE
| HID0_NAP
)) {
7482 static void gen_spr_970_hid(CPUPPCState
*env
)
7484 /* Hardware implementation registers */
7485 /* XXX : not implemented */
7486 spr_register(env
, SPR_HID0
, "HID0",
7487 SPR_NOACCESS
, SPR_NOACCESS
,
7488 &spr_read_generic
, &spr_write_clear
,
7490 spr_register(env
, SPR_HID1
, "HID1",
7491 SPR_NOACCESS
, SPR_NOACCESS
,
7492 &spr_read_generic
, &spr_write_generic
,
7494 spr_register(env
, SPR_970_HID5
, "HID5",
7495 SPR_NOACCESS
, SPR_NOACCESS
,
7496 &spr_read_generic
, &spr_write_generic
,
7497 POWERPC970_HID5_INIT
);
7500 static void gen_spr_970_hior(CPUPPCState
*env
)
7502 spr_register(env
, SPR_HIOR
, "SPR_HIOR",
7503 SPR_NOACCESS
, SPR_NOACCESS
,
7504 &spr_read_hior
, &spr_write_hior
,
7508 static void gen_spr_book3s_ctrl(CPUPPCState
*env
)
7510 spr_register(env
, SPR_CTRL
, "SPR_CTRL",
7511 SPR_NOACCESS
, SPR_NOACCESS
,
7512 SPR_NOACCESS
, &spr_write_generic
,
7514 spr_register(env
, SPR_UCTRL
, "SPR_UCTRL",
7515 &spr_read_ureg
, SPR_NOACCESS
,
7516 &spr_read_ureg
, SPR_NOACCESS
,
7520 static void gen_spr_book3s_altivec(CPUPPCState
*env
)
7522 if (!(env
->insns_flags
& PPC_ALTIVEC
)) {
7526 spr_register_kvm(env
, SPR_VRSAVE
, "VRSAVE",
7527 &spr_read_generic
, &spr_write_generic
,
7528 &spr_read_generic
, &spr_write_generic
,
7529 KVM_REG_PPC_VRSAVE
, 0x00000000);
7531 /* Can't find information on what this should be on reset. This
7532 * value is the one used by 74xx processors. */
7533 vscr_init(env
, 0x00010000);
7536 static void gen_spr_book3s_dbg(CPUPPCState
*env
)
7539 * TODO: different specs define different scopes for these,
7540 * will have to address this:
7541 * 970: super/write and super/read
7542 * powerisa 2.03..2.04: hypv/write and super/read.
7543 * powerisa 2.05 and newer: hypv/write and hypv/read.
7545 spr_register_kvm(env
, SPR_DABR
, "DABR",
7546 SPR_NOACCESS
, SPR_NOACCESS
,
7547 &spr_read_generic
, &spr_write_generic
,
7548 KVM_REG_PPC_DABR
, 0x00000000);
7549 spr_register_kvm(env
, SPR_DABRX
, "DABRX",
7550 SPR_NOACCESS
, SPR_NOACCESS
,
7551 &spr_read_generic
, &spr_write_generic
,
7552 KVM_REG_PPC_DABRX
, 0x00000000);
7555 static void gen_spr_book3s_207_dbg(CPUPPCState
*env
)
7557 spr_register_kvm_hv(env
, SPR_DAWR
, "DAWR",
7558 SPR_NOACCESS
, SPR_NOACCESS
,
7559 SPR_NOACCESS
, SPR_NOACCESS
,
7560 &spr_read_generic
, &spr_write_generic
,
7561 KVM_REG_PPC_DAWR
, 0x00000000);
7562 spr_register_kvm_hv(env
, SPR_DAWRX
, "DAWRX",
7563 SPR_NOACCESS
, SPR_NOACCESS
,
7564 SPR_NOACCESS
, SPR_NOACCESS
,
7565 &spr_read_generic
, &spr_write_generic
,
7566 KVM_REG_PPC_DAWRX
, 0x00000000);
7567 spr_register_kvm_hv(env
, SPR_CIABR
, "CIABR",
7568 SPR_NOACCESS
, SPR_NOACCESS
,
7569 SPR_NOACCESS
, SPR_NOACCESS
,
7570 &spr_read_generic
, &spr_write_generic
,
7571 KVM_REG_PPC_CIABR
, 0x00000000);
7574 static void gen_spr_970_dbg(CPUPPCState
*env
)
7577 spr_register(env
, SPR_IABR
, "IABR",
7578 SPR_NOACCESS
, SPR_NOACCESS
,
7579 &spr_read_generic
, &spr_write_generic
,
7583 static void gen_spr_book3s_pmu_sup(CPUPPCState
*env
)
7585 spr_register_kvm(env
, SPR_POWER_MMCR0
, "MMCR0",
7586 SPR_NOACCESS
, SPR_NOACCESS
,
7587 &spr_read_generic
, &spr_write_generic
,
7588 KVM_REG_PPC_MMCR0
, 0x00000000);
7589 spr_register_kvm(env
, SPR_POWER_MMCR1
, "MMCR1",
7590 SPR_NOACCESS
, SPR_NOACCESS
,
7591 &spr_read_generic
, &spr_write_generic
,
7592 KVM_REG_PPC_MMCR1
, 0x00000000);
7593 spr_register_kvm(env
, SPR_POWER_MMCRA
, "MMCRA",
7594 SPR_NOACCESS
, SPR_NOACCESS
,
7595 &spr_read_generic
, &spr_write_generic
,
7596 KVM_REG_PPC_MMCRA
, 0x00000000);
7597 spr_register_kvm(env
, SPR_POWER_PMC1
, "PMC1",
7598 SPR_NOACCESS
, SPR_NOACCESS
,
7599 &spr_read_generic
, &spr_write_generic
,
7600 KVM_REG_PPC_PMC1
, 0x00000000);
7601 spr_register_kvm(env
, SPR_POWER_PMC2
, "PMC2",
7602 SPR_NOACCESS
, SPR_NOACCESS
,
7603 &spr_read_generic
, &spr_write_generic
,
7604 KVM_REG_PPC_PMC2
, 0x00000000);
7605 spr_register_kvm(env
, SPR_POWER_PMC3
, "PMC3",
7606 SPR_NOACCESS
, SPR_NOACCESS
,
7607 &spr_read_generic
, &spr_write_generic
,
7608 KVM_REG_PPC_PMC3
, 0x00000000);
7609 spr_register_kvm(env
, SPR_POWER_PMC4
, "PMC4",
7610 SPR_NOACCESS
, SPR_NOACCESS
,
7611 &spr_read_generic
, &spr_write_generic
,
7612 KVM_REG_PPC_PMC4
, 0x00000000);
7613 spr_register_kvm(env
, SPR_POWER_PMC5
, "PMC5",
7614 SPR_NOACCESS
, SPR_NOACCESS
,
7615 &spr_read_generic
, &spr_write_generic
,
7616 KVM_REG_PPC_PMC5
, 0x00000000);
7617 spr_register_kvm(env
, SPR_POWER_PMC6
, "PMC6",
7618 SPR_NOACCESS
, SPR_NOACCESS
,
7619 &spr_read_generic
, &spr_write_generic
,
7620 KVM_REG_PPC_PMC6
, 0x00000000);
7621 spr_register_kvm(env
, SPR_POWER_SIAR
, "SIAR",
7622 SPR_NOACCESS
, SPR_NOACCESS
,
7623 &spr_read_generic
, &spr_write_generic
,
7624 KVM_REG_PPC_SIAR
, 0x00000000);
7625 spr_register_kvm(env
, SPR_POWER_SDAR
, "SDAR",
7626 SPR_NOACCESS
, SPR_NOACCESS
,
7627 &spr_read_generic
, &spr_write_generic
,
7628 KVM_REG_PPC_SDAR
, 0x00000000);
7631 static void gen_spr_book3s_pmu_user(CPUPPCState
*env
)
7633 spr_register(env
, SPR_POWER_UMMCR0
, "UMMCR0",
7634 &spr_read_ureg
, SPR_NOACCESS
,
7635 &spr_read_ureg
, &spr_write_ureg
,
7637 spr_register(env
, SPR_POWER_UMMCR1
, "UMMCR1",
7638 &spr_read_ureg
, SPR_NOACCESS
,
7639 &spr_read_ureg
, &spr_write_ureg
,
7641 spr_register(env
, SPR_POWER_UMMCRA
, "UMMCRA",
7642 &spr_read_ureg
, SPR_NOACCESS
,
7643 &spr_read_ureg
, &spr_write_ureg
,
7645 spr_register(env
, SPR_POWER_UPMC1
, "UPMC1",
7646 &spr_read_ureg
, SPR_NOACCESS
,
7647 &spr_read_ureg
, &spr_write_ureg
,
7649 spr_register(env
, SPR_POWER_UPMC2
, "UPMC2",
7650 &spr_read_ureg
, SPR_NOACCESS
,
7651 &spr_read_ureg
, &spr_write_ureg
,
7653 spr_register(env
, SPR_POWER_UPMC3
, "UPMC3",
7654 &spr_read_ureg
, SPR_NOACCESS
,
7655 &spr_read_ureg
, &spr_write_ureg
,
7657 spr_register(env
, SPR_POWER_UPMC4
, "UPMC4",
7658 &spr_read_ureg
, SPR_NOACCESS
,
7659 &spr_read_ureg
, &spr_write_ureg
,
7661 spr_register(env
, SPR_POWER_UPMC5
, "UPMC5",
7662 &spr_read_ureg
, SPR_NOACCESS
,
7663 &spr_read_ureg
, &spr_write_ureg
,
7665 spr_register(env
, SPR_POWER_UPMC6
, "UPMC6",
7666 &spr_read_ureg
, SPR_NOACCESS
,
7667 &spr_read_ureg
, &spr_write_ureg
,
7669 spr_register(env
, SPR_POWER_USIAR
, "USIAR",
7670 &spr_read_ureg
, SPR_NOACCESS
,
7671 &spr_read_ureg
, &spr_write_ureg
,
7673 spr_register(env
, SPR_POWER_USDAR
, "USDAR",
7674 &spr_read_ureg
, SPR_NOACCESS
,
7675 &spr_read_ureg
, &spr_write_ureg
,
7679 static void gen_spr_970_pmu_sup(CPUPPCState
*env
)
7681 spr_register_kvm(env
, SPR_970_PMC7
, "PMC7",
7682 SPR_NOACCESS
, SPR_NOACCESS
,
7683 &spr_read_generic
, &spr_write_generic
,
7684 KVM_REG_PPC_PMC7
, 0x00000000);
7685 spr_register_kvm(env
, SPR_970_PMC8
, "PMC8",
7686 SPR_NOACCESS
, SPR_NOACCESS
,
7687 &spr_read_generic
, &spr_write_generic
,
7688 KVM_REG_PPC_PMC8
, 0x00000000);
7691 static void gen_spr_970_pmu_user(CPUPPCState
*env
)
7693 spr_register(env
, SPR_970_UPMC7
, "UPMC7",
7694 &spr_read_ureg
, SPR_NOACCESS
,
7695 &spr_read_ureg
, &spr_write_ureg
,
7697 spr_register(env
, SPR_970_UPMC8
, "UPMC8",
7698 &spr_read_ureg
, SPR_NOACCESS
,
7699 &spr_read_ureg
, &spr_write_ureg
,
7703 static void gen_spr_power8_pmu_sup(CPUPPCState
*env
)
7705 spr_register_kvm(env
, SPR_POWER_MMCR2
, "MMCR2",
7706 SPR_NOACCESS
, SPR_NOACCESS
,
7707 &spr_read_generic
, &spr_write_generic
,
7708 KVM_REG_PPC_MMCR2
, 0x00000000);
7709 spr_register_kvm(env
, SPR_POWER_MMCRS
, "MMCRS",
7710 SPR_NOACCESS
, SPR_NOACCESS
,
7711 &spr_read_generic
, &spr_write_generic
,
7712 KVM_REG_PPC_MMCRS
, 0x00000000);
7713 spr_register_kvm(env
, SPR_POWER_SIER
, "SIER",
7714 SPR_NOACCESS
, SPR_NOACCESS
,
7715 &spr_read_generic
, &spr_write_generic
,
7716 KVM_REG_PPC_SIER
, 0x00000000);
7717 spr_register_kvm(env
, SPR_POWER_SPMC1
, "SPMC1",
7718 SPR_NOACCESS
, SPR_NOACCESS
,
7719 &spr_read_generic
, &spr_write_generic
,
7720 KVM_REG_PPC_SPMC1
, 0x00000000);
7721 spr_register_kvm(env
, SPR_POWER_SPMC2
, "SPMC2",
7722 SPR_NOACCESS
, SPR_NOACCESS
,
7723 &spr_read_generic
, &spr_write_generic
,
7724 KVM_REG_PPC_SPMC2
, 0x00000000);
7725 spr_register_kvm(env
, SPR_TACR
, "TACR",
7726 SPR_NOACCESS
, SPR_NOACCESS
,
7727 &spr_read_generic
, &spr_write_generic
,
7728 KVM_REG_PPC_TACR
, 0x00000000);
7729 spr_register_kvm(env
, SPR_TCSCR
, "TCSCR",
7730 SPR_NOACCESS
, SPR_NOACCESS
,
7731 &spr_read_generic
, &spr_write_generic
,
7732 KVM_REG_PPC_TCSCR
, 0x00000000);
7733 spr_register_kvm(env
, SPR_CSIGR
, "CSIGR",
7734 SPR_NOACCESS
, SPR_NOACCESS
,
7735 &spr_read_generic
, &spr_write_generic
,
7736 KVM_REG_PPC_CSIGR
, 0x00000000);
7739 static void gen_spr_power8_pmu_user(CPUPPCState
*env
)
7741 spr_register(env
, SPR_POWER_UMMCR2
, "UMMCR2",
7742 &spr_read_ureg
, SPR_NOACCESS
,
7743 &spr_read_ureg
, &spr_write_ureg
,
7745 spr_register(env
, SPR_POWER_USIER
, "USIER",
7746 &spr_read_generic
, SPR_NOACCESS
,
7747 &spr_read_generic
, &spr_write_generic
,
7751 static void gen_spr_power5p_ear(CPUPPCState
*env
)
7753 /* External access control */
7754 spr_register(env
, SPR_EAR
, "EAR",
7755 SPR_NOACCESS
, SPR_NOACCESS
,
7756 &spr_read_generic
, &spr_write_generic
,
7760 #if !defined(CONFIG_USER_ONLY)
7761 static void spr_write_hmer(DisasContext
*ctx
, int sprn
, int gprn
)
7763 TCGv hmer
= tcg_temp_new();
7765 gen_load_spr(hmer
, sprn
);
7766 tcg_gen_and_tl(hmer
, cpu_gpr
[gprn
], hmer
);
7767 gen_store_spr(sprn
, hmer
);
7768 spr_store_dump_spr(sprn
);
7769 tcg_temp_free(hmer
);
7772 static void spr_write_lpcr(DisasContext
*ctx
, int sprn
, int gprn
)
7774 gen_helper_store_lpcr(cpu_env
, cpu_gpr
[gprn
]);
7777 static void spr_write_970_hid4(DisasContext
*ctx
, int sprn
, int gprn
)
7779 #if defined(TARGET_PPC64)
7780 spr_write_generic(ctx
, sprn
, gprn
);
7781 gen_helper_store_lpcr(cpu_env
, cpu_gpr
[gprn
]);
7785 #endif /* !defined(CONFIG_USER_ONLY) */
7787 static void gen_spr_970_lpar(CPUPPCState
*env
)
7789 #if !defined(CONFIG_USER_ONLY)
7790 /* Logical partitionning */
7791 /* PPC970: HID4 is effectively the LPCR */
7792 spr_register(env
, SPR_970_HID4
, "HID4",
7793 SPR_NOACCESS
, SPR_NOACCESS
,
7794 &spr_read_generic
, &spr_write_970_hid4
,
7799 static void gen_spr_power5p_lpar(CPUPPCState
*env
)
7801 #if !defined(CONFIG_USER_ONLY)
7802 /* Logical partitionning */
7803 spr_register_kvm_hv(env
, SPR_LPCR
, "LPCR",
7804 SPR_NOACCESS
, SPR_NOACCESS
,
7805 SPR_NOACCESS
, SPR_NOACCESS
,
7806 &spr_read_generic
, &spr_write_lpcr
,
7807 KVM_REG_PPC_LPCR
, LPCR_LPES0
| LPCR_LPES1
);
7808 spr_register_hv(env
, SPR_HDEC
, "HDEC",
7809 SPR_NOACCESS
, SPR_NOACCESS
,
7810 SPR_NOACCESS
, SPR_NOACCESS
,
7811 &spr_read_hdecr
, &spr_write_hdecr
, 0);
7815 static void gen_spr_book3s_ids(CPUPPCState
*env
)
7817 /* FIXME: Will need to deal with thread vs core only SPRs */
7819 /* Processor identification */
7820 spr_register_hv(env
, SPR_PIR
, "PIR",
7821 SPR_NOACCESS
, SPR_NOACCESS
,
7822 &spr_read_generic
, SPR_NOACCESS
,
7823 &spr_read_generic
, NULL
,
7825 spr_register_hv(env
, SPR_HID0
, "HID0",
7826 SPR_NOACCESS
, SPR_NOACCESS
,
7827 SPR_NOACCESS
, SPR_NOACCESS
,
7828 &spr_read_generic
, &spr_write_generic
,
7830 spr_register_hv(env
, SPR_TSCR
, "TSCR",
7831 SPR_NOACCESS
, SPR_NOACCESS
,
7832 SPR_NOACCESS
, SPR_NOACCESS
,
7833 &spr_read_generic
, &spr_write_generic
,
7835 spr_register_hv(env
, SPR_HMER
, "HMER",
7836 SPR_NOACCESS
, SPR_NOACCESS
,
7837 SPR_NOACCESS
, SPR_NOACCESS
,
7838 &spr_read_generic
, &spr_write_hmer
,
7840 spr_register_hv(env
, SPR_HMEER
, "HMEER",
7841 SPR_NOACCESS
, SPR_NOACCESS
,
7842 SPR_NOACCESS
, SPR_NOACCESS
,
7843 &spr_read_generic
, &spr_write_generic
,
7845 spr_register_hv(env
, SPR_TFMR
, "TFMR",
7846 SPR_NOACCESS
, SPR_NOACCESS
,
7847 SPR_NOACCESS
, SPR_NOACCESS
,
7848 &spr_read_generic
, &spr_write_generic
,
7850 spr_register_hv(env
, SPR_LPIDR
, "LPIDR",
7851 SPR_NOACCESS
, SPR_NOACCESS
,
7852 SPR_NOACCESS
, SPR_NOACCESS
,
7853 &spr_read_generic
, &spr_write_generic
,
7855 spr_register_hv(env
, SPR_HFSCR
, "HFSCR",
7856 SPR_NOACCESS
, SPR_NOACCESS
,
7857 SPR_NOACCESS
, SPR_NOACCESS
,
7858 &spr_read_generic
, &spr_write_generic
,
7860 spr_register_hv(env
, SPR_MMCRC
, "MMCRC",
7861 SPR_NOACCESS
, SPR_NOACCESS
,
7862 SPR_NOACCESS
, SPR_NOACCESS
,
7863 &spr_read_generic
, &spr_write_generic
,
7865 spr_register_hv(env
, SPR_MMCRH
, "MMCRH",
7866 SPR_NOACCESS
, SPR_NOACCESS
,
7867 SPR_NOACCESS
, SPR_NOACCESS
,
7868 &spr_read_generic
, &spr_write_generic
,
7870 spr_register_hv(env
, SPR_HSPRG0
, "HSPRG0",
7871 SPR_NOACCESS
, SPR_NOACCESS
,
7872 SPR_NOACCESS
, SPR_NOACCESS
,
7873 &spr_read_generic
, &spr_write_generic
,
7875 spr_register_hv(env
, SPR_HSPRG1
, "HSPRG1",
7876 SPR_NOACCESS
, SPR_NOACCESS
,
7877 SPR_NOACCESS
, SPR_NOACCESS
,
7878 &spr_read_generic
, &spr_write_generic
,
7880 spr_register_hv(env
, SPR_HSRR0
, "HSRR0",
7881 SPR_NOACCESS
, SPR_NOACCESS
,
7882 SPR_NOACCESS
, SPR_NOACCESS
,
7883 &spr_read_generic
, &spr_write_generic
,
7885 spr_register_hv(env
, SPR_HSRR1
, "HSRR1",
7886 SPR_NOACCESS
, SPR_NOACCESS
,
7887 SPR_NOACCESS
, SPR_NOACCESS
,
7888 &spr_read_generic
, &spr_write_generic
,
7890 spr_register_hv(env
, SPR_HDAR
, "HDAR",
7891 SPR_NOACCESS
, SPR_NOACCESS
,
7892 SPR_NOACCESS
, SPR_NOACCESS
,
7893 &spr_read_generic
, &spr_write_generic
,
7895 spr_register_hv(env
, SPR_HDSISR
, "HDSISR",
7896 SPR_NOACCESS
, SPR_NOACCESS
,
7897 SPR_NOACCESS
, SPR_NOACCESS
,
7898 &spr_read_generic
, &spr_write_generic
,
7900 spr_register_hv(env
, SPR_RMOR
, "RMOR",
7901 SPR_NOACCESS
, SPR_NOACCESS
,
7902 SPR_NOACCESS
, SPR_NOACCESS
,
7903 &spr_read_generic
, &spr_write_generic
,
7905 spr_register_hv(env
, SPR_HRMOR
, "HRMOR",
7906 SPR_NOACCESS
, SPR_NOACCESS
,
7907 SPR_NOACCESS
, SPR_NOACCESS
,
7908 &spr_read_generic
, &spr_write_generic
,
7912 static void gen_spr_power8_ids(CPUPPCState
*env
)
7914 /* Thread identification */
7915 spr_register(env
, SPR_TIR
, "TIR",
7916 SPR_NOACCESS
, SPR_NOACCESS
,
7917 &spr_read_generic
, SPR_NOACCESS
,
7921 static void gen_spr_book3s_purr(CPUPPCState
*env
)
7923 #if !defined(CONFIG_USER_ONLY)
7924 /* PURR & SPURR: Hack - treat these as aliases for the TB for now */
7925 spr_register_kvm(env
, SPR_PURR
, "PURR",
7926 &spr_read_purr
, SPR_NOACCESS
,
7927 &spr_read_purr
, SPR_NOACCESS
,
7928 KVM_REG_PPC_PURR
, 0x00000000);
7929 spr_register_kvm(env
, SPR_SPURR
, "SPURR",
7930 &spr_read_purr
, SPR_NOACCESS
,
7931 &spr_read_purr
, SPR_NOACCESS
,
7932 KVM_REG_PPC_SPURR
, 0x00000000);
7936 static void gen_spr_power6_dbg(CPUPPCState
*env
)
7938 #if !defined(CONFIG_USER_ONLY)
7939 spr_register(env
, SPR_CFAR
, "SPR_CFAR",
7940 SPR_NOACCESS
, SPR_NOACCESS
,
7941 &spr_read_cfar
, &spr_write_cfar
,
7946 static void gen_spr_power5p_common(CPUPPCState
*env
)
7948 spr_register_kvm(env
, SPR_PPR
, "PPR",
7949 &spr_read_generic
, &spr_write_generic
,
7950 &spr_read_generic
, &spr_write_generic
,
7951 KVM_REG_PPC_PPR
, 0x00000000);
7954 static void gen_spr_power6_common(CPUPPCState
*env
)
7956 #if !defined(CONFIG_USER_ONLY)
7957 spr_register_kvm(env
, SPR_DSCR
, "SPR_DSCR",
7958 SPR_NOACCESS
, SPR_NOACCESS
,
7959 &spr_read_generic
, &spr_write_generic
,
7960 KVM_REG_PPC_DSCR
, 0x00000000);
7963 * Register PCR to report POWERPC_EXCP_PRIV_REG instead of
7964 * POWERPC_EXCP_INVAL_SPR in userspace. Permit hypervisor access.
7966 spr_register_hv(env
, SPR_PCR
, "PCR",
7967 SPR_NOACCESS
, SPR_NOACCESS
,
7968 SPR_NOACCESS
, SPR_NOACCESS
,
7969 &spr_read_generic
, &spr_write_pcr
,
7973 static void spr_read_tar(DisasContext
*ctx
, int gprn
, int sprn
)
7975 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_TAR
, sprn
, FSCR_IC_TAR
);
7976 spr_read_generic(ctx
, gprn
, sprn
);
7979 static void spr_write_tar(DisasContext
*ctx
, int sprn
, int gprn
)
7981 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_TAR
, sprn
, FSCR_IC_TAR
);
7982 spr_write_generic(ctx
, sprn
, gprn
);
7985 static void gen_spr_power8_tce_address_control(CPUPPCState
*env
)
7987 spr_register_kvm(env
, SPR_TAR
, "TAR",
7988 &spr_read_tar
, &spr_write_tar
,
7989 &spr_read_generic
, &spr_write_generic
,
7990 KVM_REG_PPC_TAR
, 0x00000000);
7993 static void spr_read_tm(DisasContext
*ctx
, int gprn
, int sprn
)
7995 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
7996 spr_read_generic(ctx
, gprn
, sprn
);
7999 static void spr_write_tm(DisasContext
*ctx
, int sprn
, int gprn
)
8001 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8002 spr_write_generic(ctx
, sprn
, gprn
);
8005 static void spr_read_tm_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
8007 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8008 spr_read_prev_upper32(ctx
, gprn
, sprn
);
8011 static void spr_write_tm_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
8013 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8014 spr_write_prev_upper32(ctx
, sprn
, gprn
);
8017 static void gen_spr_power8_tm(CPUPPCState
*env
)
8019 spr_register_kvm(env
, SPR_TFHAR
, "TFHAR",
8020 &spr_read_tm
, &spr_write_tm
,
8021 &spr_read_tm
, &spr_write_tm
,
8022 KVM_REG_PPC_TFHAR
, 0x00000000);
8023 spr_register_kvm(env
, SPR_TFIAR
, "TFIAR",
8024 &spr_read_tm
, &spr_write_tm
,
8025 &spr_read_tm
, &spr_write_tm
,
8026 KVM_REG_PPC_TFIAR
, 0x00000000);
8027 spr_register_kvm(env
, SPR_TEXASR
, "TEXASR",
8028 &spr_read_tm
, &spr_write_tm
,
8029 &spr_read_tm
, &spr_write_tm
,
8030 KVM_REG_PPC_TEXASR
, 0x00000000);
8031 spr_register(env
, SPR_TEXASRU
, "TEXASRU",
8032 &spr_read_tm_upper32
, &spr_write_tm_upper32
,
8033 &spr_read_tm_upper32
, &spr_write_tm_upper32
,
8037 static void spr_read_ebb(DisasContext
*ctx
, int gprn
, int sprn
)
8039 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8040 spr_read_generic(ctx
, gprn
, sprn
);
8043 static void spr_write_ebb(DisasContext
*ctx
, int sprn
, int gprn
)
8045 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8046 spr_write_generic(ctx
, sprn
, gprn
);
8049 static void spr_read_ebb_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
8051 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8052 spr_read_prev_upper32(ctx
, gprn
, sprn
);
8055 static void spr_write_ebb_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
8057 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8058 spr_write_prev_upper32(ctx
, sprn
, gprn
);
8061 static void gen_spr_power8_ebb(CPUPPCState
*env
)
8063 spr_register(env
, SPR_BESCRS
, "BESCRS",
8064 &spr_read_ebb
, &spr_write_ebb
,
8065 &spr_read_generic
, &spr_write_generic
,
8067 spr_register(env
, SPR_BESCRSU
, "BESCRSU",
8068 &spr_read_ebb_upper32
, &spr_write_ebb_upper32
,
8069 &spr_read_prev_upper32
, &spr_write_prev_upper32
,
8071 spr_register(env
, SPR_BESCRR
, "BESCRR",
8072 &spr_read_ebb
, &spr_write_ebb
,
8073 &spr_read_generic
, &spr_write_generic
,
8075 spr_register(env
, SPR_BESCRRU
, "BESCRRU",
8076 &spr_read_ebb_upper32
, &spr_write_ebb_upper32
,
8077 &spr_read_prev_upper32
, &spr_write_prev_upper32
,
8079 spr_register_kvm(env
, SPR_EBBHR
, "EBBHR",
8080 &spr_read_ebb
, &spr_write_ebb
,
8081 &spr_read_generic
, &spr_write_generic
,
8082 KVM_REG_PPC_EBBHR
, 0x00000000);
8083 spr_register_kvm(env
, SPR_EBBRR
, "EBBRR",
8084 &spr_read_ebb
, &spr_write_ebb
,
8085 &spr_read_generic
, &spr_write_generic
,
8086 KVM_REG_PPC_EBBRR
, 0x00000000);
8087 spr_register_kvm(env
, SPR_BESCR
, "BESCR",
8088 &spr_read_ebb
, &spr_write_ebb
,
8089 &spr_read_generic
, &spr_write_generic
,
8090 KVM_REG_PPC_BESCR
, 0x00000000);
8093 /* Virtual Time Base */
8094 static void gen_spr_vtb(CPUPPCState
*env
)
8096 spr_register_kvm(env
, SPR_VTB
, "VTB",
8097 SPR_NOACCESS
, SPR_NOACCESS
,
8098 &spr_read_tbl
, SPR_NOACCESS
,
8099 KVM_REG_PPC_VTB
, 0x00000000);
8102 static void gen_spr_power8_fscr(CPUPPCState
*env
)
8104 #if defined(CONFIG_USER_ONLY)
8105 target_ulong initval
= 1ULL << FSCR_TAR
;
8107 target_ulong initval
= 0;
8109 spr_register_kvm(env
, SPR_FSCR
, "FSCR",
8110 SPR_NOACCESS
, SPR_NOACCESS
,
8111 &spr_read_generic
, &spr_write_generic
,
8112 KVM_REG_PPC_FSCR
, initval
);
8115 static void gen_spr_power8_pspb(CPUPPCState
*env
)
8117 spr_register_kvm(env
, SPR_PSPB
, "PSPB",
8118 SPR_NOACCESS
, SPR_NOACCESS
,
8119 &spr_read_generic
, &spr_write_generic32
,
8120 KVM_REG_PPC_PSPB
, 0);
8123 static void gen_spr_power8_ic(CPUPPCState
*env
)
8125 #if !defined(CONFIG_USER_ONLY)
8126 spr_register_hv(env
, SPR_IC
, "IC",
8127 SPR_NOACCESS
, SPR_NOACCESS
,
8128 &spr_read_generic
, SPR_NOACCESS
,
8129 &spr_read_generic
, &spr_write_generic
,
8134 static void gen_spr_power8_book4(CPUPPCState
*env
)
8136 /* Add a number of P8 book4 registers */
8137 #if !defined(CONFIG_USER_ONLY)
8138 spr_register_kvm(env
, SPR_ACOP
, "ACOP",
8139 SPR_NOACCESS
, SPR_NOACCESS
,
8140 &spr_read_generic
, &spr_write_generic
,
8141 KVM_REG_PPC_ACOP
, 0);
8142 spr_register_kvm(env
, SPR_BOOKS_PID
, "PID",
8143 SPR_NOACCESS
, SPR_NOACCESS
,
8144 &spr_read_generic
, &spr_write_pidr
,
8145 KVM_REG_PPC_PID
, 0);
8146 spr_register_kvm(env
, SPR_WORT
, "WORT",
8147 SPR_NOACCESS
, SPR_NOACCESS
,
8148 &spr_read_generic
, &spr_write_generic
,
8149 KVM_REG_PPC_WORT
, 0);
8153 static void gen_spr_power7_book4(CPUPPCState
*env
)
8155 /* Add a number of P7 book4 registers */
8156 #if !defined(CONFIG_USER_ONLY)
8157 spr_register_kvm(env
, SPR_ACOP
, "ACOP",
8158 SPR_NOACCESS
, SPR_NOACCESS
,
8159 &spr_read_generic
, &spr_write_generic
,
8160 KVM_REG_PPC_ACOP
, 0);
8161 spr_register_kvm(env
, SPR_BOOKS_PID
, "PID",
8162 SPR_NOACCESS
, SPR_NOACCESS
,
8163 &spr_read_generic
, &spr_write_generic
,
8164 KVM_REG_PPC_PID
, 0);
8168 static void gen_spr_power8_rpr(CPUPPCState
*env
)
8170 #if !defined(CONFIG_USER_ONLY)
8171 spr_register_hv(env
, SPR_RPR
, "RPR",
8172 SPR_NOACCESS
, SPR_NOACCESS
,
8173 SPR_NOACCESS
, SPR_NOACCESS
,
8174 &spr_read_generic
, &spr_write_generic
,
8175 0x00000103070F1F3F);
8179 static void gen_spr_power9_mmu(CPUPPCState
*env
)
8181 #if !defined(CONFIG_USER_ONLY)
8182 /* Partition Table Control */
8183 spr_register_hv(env
, SPR_PTCR
, "PTCR",
8184 SPR_NOACCESS
, SPR_NOACCESS
,
8185 SPR_NOACCESS
, SPR_NOACCESS
,
8186 &spr_read_generic
, &spr_write_ptcr
,
8191 static void init_proc_book3s_common(CPUPPCState
*env
)
8193 gen_spr_ne_601(env
);
8195 gen_spr_usprg3(env
);
8196 gen_spr_book3s_altivec(env
);
8197 gen_spr_book3s_pmu_sup(env
);
8198 gen_spr_book3s_pmu_user(env
);
8199 gen_spr_book3s_ctrl(env
);
8202 static void init_proc_970(CPUPPCState
*env
)
8204 /* Common Registers */
8205 init_proc_book3s_common(env
);
8207 gen_spr_book3s_dbg(env
);
8209 /* 970 Specific Registers */
8210 gen_spr_970_hid(env
);
8211 gen_spr_970_hior(env
);
8213 gen_spr_970_pmu_sup(env
);
8214 gen_spr_970_pmu_user(env
);
8215 gen_spr_970_lpar(env
);
8216 gen_spr_970_dbg(env
);
8219 env
->dcache_line_size
= 128;
8220 env
->icache_line_size
= 128;
8222 /* Allocate hardware IRQ controller */
8224 ppc970_irq_init(ppc_env_get_cpu(env
));
8227 POWERPC_FAMILY(970)(ObjectClass
*oc
, void *data
)
8229 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8230 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8232 dc
->desc
= "PowerPC 970";
8233 pcc
->init_proc
= init_proc_970
;
8234 pcc
->check_pow
= check_pow_970
;
8235 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
8236 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8237 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8239 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8240 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8241 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8242 PPC_64B
| PPC_ALTIVEC
|
8243 PPC_SEGMENT_64B
| PPC_SLBI
;
8244 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
8245 pcc
->msr_mask
= (1ull << MSR_SF
) |
8260 pcc
->mmu_model
= POWERPC_MMU_64B
;
8261 #if defined(CONFIG_SOFTMMU)
8262 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8263 pcc
->hash64_opts
= &ppc_hash64_opts_basic
;
8265 pcc
->excp_model
= POWERPC_EXCP_970
;
8266 pcc
->bus_model
= PPC_FLAGS_INPUT_970
;
8267 pcc
->bfd_mach
= bfd_mach_ppc64
;
8268 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8269 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8270 POWERPC_FLAG_BUS_CLK
;
8271 pcc
->l1_dcache_size
= 0x8000;
8272 pcc
->l1_icache_size
= 0x10000;
8275 static void init_proc_power5plus(CPUPPCState
*env
)
8277 /* Common Registers */
8278 init_proc_book3s_common(env
);
8280 gen_spr_book3s_dbg(env
);
8282 /* POWER5+ Specific Registers */
8283 gen_spr_970_hid(env
);
8284 gen_spr_970_hior(env
);
8286 gen_spr_970_pmu_sup(env
);
8287 gen_spr_970_pmu_user(env
);
8288 gen_spr_power5p_common(env
);
8289 gen_spr_power5p_lpar(env
);
8290 gen_spr_power5p_ear(env
);
8293 env
->dcache_line_size
= 128;
8294 env
->icache_line_size
= 128;
8296 /* Allocate hardware IRQ controller */
8298 ppc970_irq_init(ppc_env_get_cpu(env
));
8301 POWERPC_FAMILY(POWER5P
)(ObjectClass
*oc
, void *data
)
8303 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8304 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8306 dc
->fw_name
= "PowerPC,POWER5";
8307 dc
->desc
= "POWER5+";
8308 pcc
->init_proc
= init_proc_power5plus
;
8309 pcc
->check_pow
= check_pow_970
;
8310 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
8311 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8312 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8314 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8315 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8316 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8318 PPC_SEGMENT_64B
| PPC_SLBI
;
8319 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
8320 pcc
->msr_mask
= (1ull << MSR_SF
) |
8335 pcc
->mmu_model
= POWERPC_MMU_2_03
;
8336 #if defined(CONFIG_SOFTMMU)
8337 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8338 pcc
->hash64_opts
= &ppc_hash64_opts_basic
;
8340 pcc
->excp_model
= POWERPC_EXCP_970
;
8341 pcc
->bus_model
= PPC_FLAGS_INPUT_970
;
8342 pcc
->bfd_mach
= bfd_mach_ppc64
;
8343 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8344 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8345 POWERPC_FLAG_BUS_CLK
;
8346 pcc
->l1_dcache_size
= 0x8000;
8347 pcc
->l1_icache_size
= 0x10000;
8351 * The CPU used to have a "compat" property which set the
8352 * compatibility mode PVR. However, this was conceptually broken - it
8353 * only makes sense on the pseries machine type (otherwise the guest
8354 * owns the PCR and can control the compatibility mode itself). It's
8355 * been replaced with the 'max-cpu-compat' property on the pseries
8356 * machine type. For backwards compatibility, pseries specially
8357 * parses the -cpu parameter and converts old compat= parameters into
8358 * the appropriate machine parameters. This stub implementation of
8359 * the parameter catches any uses on explicitly created CPUs.
8361 static void getset_compat_deprecated(Object
*obj
, Visitor
*v
, const char *name
,
8362 void *opaque
, Error
**errp
)
8366 if (!qtest_enabled()) {
8367 error_report("CPU 'compat' property is deprecated and has no effect; "
8368 "use max-cpu-compat machine property instead");
8370 visit_type_null(v
, name
, &null
, NULL
);
8371 qobject_unref(null
);
8374 static const PropertyInfo ppc_compat_deprecated_propinfo
= {
8376 .description
= "compatibility mode (deprecated)",
8377 .get
= getset_compat_deprecated
,
8378 .set
= getset_compat_deprecated
,
8380 static Property powerpc_servercpu_properties
[] = {
8383 .info
= &ppc_compat_deprecated_propinfo
,
8385 DEFINE_PROP_END_OF_LIST(),
8388 static void init_proc_POWER7(CPUPPCState
*env
)
8390 /* Common Registers */
8391 init_proc_book3s_common(env
);
8393 gen_spr_book3s_dbg(env
);
8395 /* POWER7 Specific Registers */
8396 gen_spr_book3s_ids(env
);
8398 gen_spr_book3s_purr(env
);
8399 gen_spr_power5p_common(env
);
8400 gen_spr_power5p_lpar(env
);
8401 gen_spr_power5p_ear(env
);
8402 gen_spr_power6_common(env
);
8403 gen_spr_power6_dbg(env
);
8404 gen_spr_power7_book4(env
);
8407 env
->dcache_line_size
= 128;
8408 env
->icache_line_size
= 128;
8410 /* Allocate hardware IRQ controller */
8411 init_excp_POWER7(env
);
8412 ppcPOWER7_irq_init(ppc_env_get_cpu(env
));
8415 static bool ppc_pvr_match_power7(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8417 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER7P_BASE
) {
8420 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER7_BASE
) {
8426 static bool cpu_has_work_POWER7(CPUState
*cs
)
8428 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8429 CPUPPCState
*env
= &cpu
->env
;
8432 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8435 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8436 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE0
)) {
8439 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8440 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE1
)) {
8443 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
)) &&
8444 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE2
)) {
8447 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HMI
)) &&
8448 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE2
)) {
8451 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8456 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8460 POWERPC_FAMILY(POWER7
)(ObjectClass
*oc
, void *data
)
8462 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8463 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8464 CPUClass
*cc
= CPU_CLASS(oc
);
8466 dc
->fw_name
= "PowerPC,POWER7";
8467 dc
->desc
= "POWER7";
8468 dc
->props
= powerpc_servercpu_properties
;
8469 pcc
->pvr_match
= ppc_pvr_match_power7
;
8470 pcc
->pcr_mask
= PCR_VEC_DIS
| PCR_VSX_DIS
| PCR_COMPAT_2_05
;
8471 pcc
->pcr_supported
= PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8472 pcc
->init_proc
= init_proc_POWER7
;
8473 pcc
->check_pow
= check_pow_nocheck
;
8474 cc
->has_work
= cpu_has_work_POWER7
;
8475 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8476 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8477 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8478 PPC_FLOAT_FRSQRTES
|
8481 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8482 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8483 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8484 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
8485 PPC_SEGMENT_64B
| PPC_SLBI
|
8486 PPC_POPCNTB
| PPC_POPCNTWD
|
8488 pcc
->insns_flags2
= PPC2_VSX
| PPC2_DFP
| PPC2_DBRX
| PPC2_ISA205
|
8489 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8490 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8491 PPC2_FP_TST_ISA206
| PPC2_FP_CVT_S64
|
8493 pcc
->msr_mask
= (1ull << MSR_SF
) |
8509 pcc
->mmu_model
= POWERPC_MMU_2_06
;
8510 #if defined(CONFIG_SOFTMMU)
8511 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8512 pcc
->hash64_opts
= &ppc_hash64_opts_POWER7
;
8514 pcc
->excp_model
= POWERPC_EXCP_POWER7
;
8515 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8516 pcc
->bfd_mach
= bfd_mach_ppc64
;
8517 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8518 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8519 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8521 pcc
->l1_dcache_size
= 0x8000;
8522 pcc
->l1_icache_size
= 0x8000;
8523 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8524 pcc
->lpcr_pm
= LPCR_P7_PECE0
| LPCR_P7_PECE1
| LPCR_P7_PECE2
;
8527 static void init_proc_POWER8(CPUPPCState
*env
)
8529 /* Common Registers */
8530 init_proc_book3s_common(env
);
8532 gen_spr_book3s_207_dbg(env
);
8534 /* POWER8 Specific Registers */
8535 gen_spr_book3s_ids(env
);
8538 gen_spr_book3s_purr(env
);
8539 gen_spr_power5p_common(env
);
8540 gen_spr_power5p_lpar(env
);
8541 gen_spr_power5p_ear(env
);
8542 gen_spr_power6_common(env
);
8543 gen_spr_power6_dbg(env
);
8544 gen_spr_power8_tce_address_control(env
);
8545 gen_spr_power8_ids(env
);
8546 gen_spr_power8_ebb(env
);
8547 gen_spr_power8_fscr(env
);
8548 gen_spr_power8_pmu_sup(env
);
8549 gen_spr_power8_pmu_user(env
);
8550 gen_spr_power8_tm(env
);
8551 gen_spr_power8_pspb(env
);
8553 gen_spr_power8_ic(env
);
8554 gen_spr_power8_book4(env
);
8555 gen_spr_power8_rpr(env
);
8558 env
->dcache_line_size
= 128;
8559 env
->icache_line_size
= 128;
8561 /* Allocate hardware IRQ controller */
8562 init_excp_POWER8(env
);
8563 ppcPOWER7_irq_init(ppc_env_get_cpu(env
));
8566 static bool ppc_pvr_match_power8(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8568 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8NVL_BASE
) {
8571 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8E_BASE
) {
8574 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8_BASE
) {
8580 static bool cpu_has_work_POWER8(CPUState
*cs
)
8582 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8583 CPUPPCState
*env
= &cpu
->env
;
8586 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8589 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8590 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE2
)) {
8593 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8594 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE3
)) {
8597 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
)) &&
8598 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE4
)) {
8601 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HMI
)) &&
8602 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE4
)) {
8605 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DOORBELL
)) &&
8606 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE0
)) {
8609 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HDOORBELL
)) &&
8610 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE1
)) {
8613 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8618 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8622 POWERPC_FAMILY(POWER8
)(ObjectClass
*oc
, void *data
)
8624 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8625 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8626 CPUClass
*cc
= CPU_CLASS(oc
);
8628 dc
->fw_name
= "PowerPC,POWER8";
8629 dc
->desc
= "POWER8";
8630 dc
->props
= powerpc_servercpu_properties
;
8631 pcc
->pvr_match
= ppc_pvr_match_power8
;
8632 pcc
->pcr_mask
= PCR_TM_DIS
| PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8633 pcc
->pcr_supported
= PCR_COMPAT_2_07
| PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8634 pcc
->init_proc
= init_proc_POWER8
;
8635 pcc
->check_pow
= check_pow_nocheck
;
8636 cc
->has_work
= cpu_has_work_POWER8
;
8637 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8638 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8639 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8640 PPC_FLOAT_FRSQRTES
|
8643 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8644 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8645 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8646 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
8647 PPC_SEGMENT_64B
| PPC_SLBI
|
8648 PPC_POPCNTB
| PPC_POPCNTWD
|
8650 pcc
->insns_flags2
= PPC2_VSX
| PPC2_VSX207
| PPC2_DFP
| PPC2_DBRX
|
8651 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8652 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8653 PPC2_FP_TST_ISA206
| PPC2_BCTAR_ISA207
|
8654 PPC2_LSQ_ISA207
| PPC2_ALTIVEC_207
|
8655 PPC2_ISA205
| PPC2_ISA207S
| PPC2_FP_CVT_S64
|
8656 PPC2_TM
| PPC2_PM_ISA206
;
8657 pcc
->msr_mask
= (1ull << MSR_SF
) |
8677 pcc
->mmu_model
= POWERPC_MMU_2_07
;
8678 #if defined(CONFIG_SOFTMMU)
8679 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8680 pcc
->hash64_opts
= &ppc_hash64_opts_POWER7
;
8682 pcc
->excp_model
= POWERPC_EXCP_POWER8
;
8683 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8684 pcc
->bfd_mach
= bfd_mach_ppc64
;
8685 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8686 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8687 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8688 POWERPC_FLAG_VSX
| POWERPC_FLAG_TM
;
8689 pcc
->l1_dcache_size
= 0x8000;
8690 pcc
->l1_icache_size
= 0x8000;
8691 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8692 pcc
->lpcr_pm
= LPCR_P8_PECE0
| LPCR_P8_PECE1
| LPCR_P8_PECE2
|
8693 LPCR_P8_PECE3
| LPCR_P8_PECE4
;
8696 #ifdef CONFIG_SOFTMMU
8698 * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
8699 * Encoded as array of int_32s in the form:
8700 * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
8702 * y -> radix mode supported page size (encoded as a shift)
8704 static struct ppc_radix_page_info POWER9_radix_page_info
= {
8707 0x0000000c, /* 4K - enc: 0x0 */
8708 0xa0000010, /* 64K - enc: 0x5 */
8709 0x20000015, /* 2M - enc: 0x1 */
8710 0x4000001e /* 1G - enc: 0x2 */
8713 #endif /* CONFIG_SOFTMMU */
8715 static void init_proc_POWER9(CPUPPCState
*env
)
8717 /* Common Registers */
8718 init_proc_book3s_common(env
);
8719 gen_spr_book3s_207_dbg(env
);
8721 /* POWER8 Specific Registers */
8722 gen_spr_book3s_ids(env
);
8725 gen_spr_book3s_purr(env
);
8726 gen_spr_power5p_common(env
);
8727 gen_spr_power5p_lpar(env
);
8728 gen_spr_power5p_ear(env
);
8729 gen_spr_power6_common(env
);
8730 gen_spr_power6_dbg(env
);
8731 gen_spr_power8_tce_address_control(env
);
8732 gen_spr_power8_ids(env
);
8733 gen_spr_power8_ebb(env
);
8734 gen_spr_power8_fscr(env
);
8735 gen_spr_power8_pmu_sup(env
);
8736 gen_spr_power8_pmu_user(env
);
8737 gen_spr_power8_tm(env
);
8738 gen_spr_power8_pspb(env
);
8740 gen_spr_power8_ic(env
);
8741 gen_spr_power8_book4(env
);
8742 gen_spr_power8_rpr(env
);
8743 gen_spr_power9_mmu(env
);
8745 /* POWER9 Specific registers */
8746 spr_register_kvm(env
, SPR_TIDR
, "TIDR", NULL
, NULL
,
8747 spr_read_generic
, spr_write_generic
,
8748 KVM_REG_PPC_TIDR
, 0);
8750 /* FIXME: Filter fields properly based on privilege level */
8751 spr_register_kvm_hv(env
, SPR_PSSCR
, "PSSCR", NULL
, NULL
, NULL
, NULL
,
8752 spr_read_generic
, spr_write_generic
,
8753 KVM_REG_PPC_PSSCR
, 0);
8756 env
->dcache_line_size
= 128;
8757 env
->icache_line_size
= 128;
8759 /* Allocate hardware IRQ controller */
8760 init_excp_POWER8(env
);
8761 ppcPOWER7_irq_init(ppc_env_get_cpu(env
));
8764 static bool ppc_pvr_match_power9(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8766 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER9_BASE
) {
8772 static bool cpu_has_work_POWER9(CPUState
*cs
)
8774 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8775 CPUPPCState
*env
= &cpu
->env
;
8778 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8781 /* External Exception */
8782 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8783 (env
->spr
[SPR_LPCR
] & LPCR_EEE
)) {
8786 /* Decrementer Exception */
8787 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8788 (env
->spr
[SPR_LPCR
] & LPCR_DEE
)) {
8791 /* Machine Check or Hypervisor Maintenance Exception */
8792 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
|
8793 1u << PPC_INTERRUPT_HMI
)) && (env
->spr
[SPR_LPCR
] & LPCR_OEE
)) {
8796 /* Privileged Doorbell Exception */
8797 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DOORBELL
)) &&
8798 (env
->spr
[SPR_LPCR
] & LPCR_PDEE
)) {
8801 /* Hypervisor Doorbell Exception */
8802 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HDOORBELL
)) &&
8803 (env
->spr
[SPR_LPCR
] & LPCR_HDEE
)) {
8806 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8811 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8815 POWERPC_FAMILY(POWER9
)(ObjectClass
*oc
, void *data
)
8817 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8818 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8819 CPUClass
*cc
= CPU_CLASS(oc
);
8821 dc
->fw_name
= "PowerPC,POWER9";
8822 dc
->desc
= "POWER9";
8823 dc
->props
= powerpc_servercpu_properties
;
8824 pcc
->pvr_match
= ppc_pvr_match_power9
;
8825 pcc
->pcr_mask
= PCR_COMPAT_2_05
| PCR_COMPAT_2_06
| PCR_COMPAT_2_07
;
8826 pcc
->pcr_supported
= PCR_COMPAT_3_00
| PCR_COMPAT_2_07
| PCR_COMPAT_2_06
|
8828 pcc
->init_proc
= init_proc_POWER9
;
8829 pcc
->check_pow
= check_pow_nocheck
;
8830 cc
->has_work
= cpu_has_work_POWER9
;
8831 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8832 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8833 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8834 PPC_FLOAT_FRSQRTES
|
8837 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8838 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8840 PPC_64B
| PPC_64BX
| PPC_ALTIVEC
|
8841 PPC_SEGMENT_64B
| PPC_SLBI
|
8842 PPC_POPCNTB
| PPC_POPCNTWD
|
8844 pcc
->insns_flags2
= PPC2_VSX
| PPC2_VSX207
| PPC2_DFP
| PPC2_DBRX
|
8845 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8846 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8847 PPC2_FP_TST_ISA206
| PPC2_BCTAR_ISA207
|
8848 PPC2_LSQ_ISA207
| PPC2_ALTIVEC_207
|
8849 PPC2_ISA205
| PPC2_ISA207S
| PPC2_FP_CVT_S64
|
8850 PPC2_TM
| PPC2_PM_ISA206
| PPC2_ISA300
| PPC2_PRCNTL
;
8851 pcc
->msr_mask
= (1ull << MSR_SF
) |
8868 pcc
->mmu_model
= POWERPC_MMU_3_00
;
8869 #if defined(CONFIG_SOFTMMU)
8870 pcc
->handle_mmu_fault
= ppc64_v3_handle_mmu_fault
;
8871 /* segment page size remain the same */
8872 pcc
->hash64_opts
= &ppc_hash64_opts_POWER7
;
8873 pcc
->radix_page_info
= &POWER9_radix_page_info
;
8875 pcc
->excp_model
= POWERPC_EXCP_POWER8
;
8876 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8877 pcc
->bfd_mach
= bfd_mach_ppc64
;
8878 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8879 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8880 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8881 POWERPC_FLAG_VSX
| POWERPC_FLAG_TM
;
8882 pcc
->l1_dcache_size
= 0x8000;
8883 pcc
->l1_icache_size
= 0x8000;
8884 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8885 pcc
->lpcr_pm
= LPCR_PDEE
| LPCR_HDEE
| LPCR_EEE
| LPCR_DEE
| LPCR_OEE
;
8888 #if !defined(CONFIG_USER_ONLY)
8889 void cpu_ppc_set_vhyp(PowerPCCPU
*cpu
, PPCVirtualHypervisor
*vhyp
)
8891 CPUPPCState
*env
= &cpu
->env
;
8896 * With a virtual hypervisor mode we never allow the CPU to go
8897 * hypervisor mode itself
8899 env
->msr_mask
&= ~MSR_HVB
;
8902 #endif /* !defined(CONFIG_USER_ONLY) */
8904 #endif /* defined(TARGET_PPC64) */
8906 /*****************************************************************************/
8907 /* Generic CPU instantiation routine */
8908 static void init_ppc_proc(PowerPCCPU
*cpu
)
8910 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
8911 CPUPPCState
*env
= &cpu
->env
;
8912 #if !defined(CONFIG_USER_ONLY)
8915 env
->irq_inputs
= NULL
;
8916 /* Set all exception vectors to an invalid address */
8917 for (i
= 0; i
< POWERPC_EXCP_NB
; i
++)
8918 env
->excp_vectors
[i
] = (target_ulong
)(-1ULL);
8919 env
->ivor_mask
= 0x00000000;
8920 env
->ivpr_mask
= 0x00000000;
8921 /* Default MMU definitions */
8925 env
->tlb_type
= TLB_NONE
;
8927 /* Register SPR common to all PowerPC implementations */
8928 gen_spr_generic(env
);
8929 spr_register(env
, SPR_PVR
, "PVR",
8930 /* Linux permits userspace to read PVR */
8931 #if defined(CONFIG_LINUX_USER)
8937 &spr_read_generic
, SPR_NOACCESS
,
8939 /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
8940 if (pcc
->svr
!= POWERPC_SVR_NONE
) {
8941 if (pcc
->svr
& POWERPC_SVR_E500
) {
8942 spr_register(env
, SPR_E500_SVR
, "SVR",
8943 SPR_NOACCESS
, SPR_NOACCESS
,
8944 &spr_read_generic
, SPR_NOACCESS
,
8945 pcc
->svr
& ~POWERPC_SVR_E500
);
8947 spr_register(env
, SPR_SVR
, "SVR",
8948 SPR_NOACCESS
, SPR_NOACCESS
,
8949 &spr_read_generic
, SPR_NOACCESS
,
8953 /* PowerPC implementation specific initialisations (SPRs, timers, ...) */
8954 (*pcc
->init_proc
)(env
);
8956 /* MSR bits & flags consistency checks */
8957 if (env
->msr_mask
& (1 << 25)) {
8958 switch (env
->flags
& (POWERPC_FLAG_SPE
| POWERPC_FLAG_VRE
)) {
8959 case POWERPC_FLAG_SPE
:
8960 case POWERPC_FLAG_VRE
:
8963 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
8964 "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n");
8967 } else if (env
->flags
& (POWERPC_FLAG_SPE
| POWERPC_FLAG_VRE
)) {
8968 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
8969 "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n");
8972 if (env
->msr_mask
& (1 << 17)) {
8973 switch (env
->flags
& (POWERPC_FLAG_TGPR
| POWERPC_FLAG_CE
)) {
8974 case POWERPC_FLAG_TGPR
:
8975 case POWERPC_FLAG_CE
:
8978 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
8979 "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n");
8982 } else if (env
->flags
& (POWERPC_FLAG_TGPR
| POWERPC_FLAG_CE
)) {
8983 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
8984 "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n");
8987 if (env
->msr_mask
& (1 << 10)) {
8988 switch (env
->flags
& (POWERPC_FLAG_SE
| POWERPC_FLAG_DWE
|
8989 POWERPC_FLAG_UBLE
)) {
8990 case POWERPC_FLAG_SE
:
8991 case POWERPC_FLAG_DWE
:
8992 case POWERPC_FLAG_UBLE
:
8995 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
8996 "Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE or "
8997 "POWERPC_FLAG_UBLE\n");
9000 } else if (env
->flags
& (POWERPC_FLAG_SE
| POWERPC_FLAG_DWE
|
9001 POWERPC_FLAG_UBLE
)) {
9002 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9003 "Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE nor "
9004 "POWERPC_FLAG_UBLE\n");
9007 if (env
->msr_mask
& (1 << 9)) {
9008 switch (env
->flags
& (POWERPC_FLAG_BE
| POWERPC_FLAG_DE
)) {
9009 case POWERPC_FLAG_BE
:
9010 case POWERPC_FLAG_DE
:
9013 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9014 "Should define POWERPC_FLAG_BE or POWERPC_FLAG_DE\n");
9017 } else if (env
->flags
& (POWERPC_FLAG_BE
| POWERPC_FLAG_DE
)) {
9018 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9019 "Should not define POWERPC_FLAG_BE nor POWERPC_FLAG_DE\n");
9022 if (env
->msr_mask
& (1 << 2)) {
9023 switch (env
->flags
& (POWERPC_FLAG_PX
| POWERPC_FLAG_PMM
)) {
9024 case POWERPC_FLAG_PX
:
9025 case POWERPC_FLAG_PMM
:
9028 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9029 "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n");
9032 } else if (env
->flags
& (POWERPC_FLAG_PX
| POWERPC_FLAG_PMM
)) {
9033 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9034 "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
9037 if ((env
->flags
& (POWERPC_FLAG_RTC_CLK
| POWERPC_FLAG_BUS_CLK
)) == 0) {
9038 fprintf(stderr
, "PowerPC flags inconsistency\n"
9039 "Should define the time-base and decrementer clock source\n");
9042 /* Allocate TLBs buffer when needed */
9043 #if !defined(CONFIG_USER_ONLY)
9044 if (env
->nb_tlb
!= 0) {
9045 int nb_tlb
= env
->nb_tlb
;
9046 if (env
->id_tlbs
!= 0)
9048 switch (env
->tlb_type
) {
9050 env
->tlb
.tlb6
= g_malloc0(nb_tlb
* sizeof(ppc6xx_tlb_t
));
9053 env
->tlb
.tlbe
= g_malloc0(nb_tlb
* sizeof(ppcemb_tlb_t
));
9056 env
->tlb
.tlbm
= g_malloc0(nb_tlb
* sizeof(ppcmas_tlb_t
));
9059 /* Pre-compute some useful values */
9060 env
->tlb_per_way
= env
->nb_tlb
/ env
->nb_ways
;
9062 if (env
->irq_inputs
== NULL
) {
9063 warn_report("no internal IRQ controller registered."
9064 " Attempt QEMU to crash very soon !");
9067 if (env
->check_pow
== NULL
) {
9068 warn_report("no power management check handler registered."
9069 " Attempt QEMU to crash very soon !");
9073 #if defined(PPC_DUMP_CPU)
9074 static void dump_ppc_sprs(CPUPPCState
*env
)
9077 #if !defined(CONFIG_USER_ONLY)
9083 printf("Special purpose registers:\n");
9084 for (i
= 0; i
< 32; i
++) {
9085 for (j
= 0; j
< 32; j
++) {
9087 spr
= &env
->spr_cb
[n
];
9088 uw
= spr
->uea_write
!= NULL
&& spr
->uea_write
!= SPR_NOACCESS
;
9089 ur
= spr
->uea_read
!= NULL
&& spr
->uea_read
!= SPR_NOACCESS
;
9090 #if !defined(CONFIG_USER_ONLY)
9091 sw
= spr
->oea_write
!= NULL
&& spr
->oea_write
!= SPR_NOACCESS
;
9092 sr
= spr
->oea_read
!= NULL
&& spr
->oea_read
!= SPR_NOACCESS
;
9093 if (sw
|| sr
|| uw
|| ur
) {
9094 printf("SPR: %4d (%03x) %-8s s%c%c u%c%c\n",
9095 (i
<< 5) | j
, (i
<< 5) | j
, spr
->name
,
9096 sw
? 'w' : '-', sr
? 'r' : '-',
9097 uw
? 'w' : '-', ur
? 'r' : '-');
9101 printf("SPR: %4d (%03x) %-8s u%c%c\n",
9102 (i
<< 5) | j
, (i
<< 5) | j
, spr
->name
,
9103 uw
? 'w' : '-', ur
? 'r' : '-');
9113 /*****************************************************************************/
9117 PPC_DIRECT
= 0, /* Opcode routine */
9118 PPC_INDIRECT
= 1, /* Indirect opcode table */
9121 #define PPC_OPCODE_MASK 0x3
9123 static inline int is_indirect_opcode(void *handler
)
9125 return ((uintptr_t)handler
& PPC_OPCODE_MASK
) == PPC_INDIRECT
;
9128 static inline opc_handler_t
**ind_table(void *handler
)
9130 return (opc_handler_t
**)((uintptr_t)handler
& ~PPC_OPCODE_MASK
);
9133 /* Instruction table creation */
9134 /* Opcodes tables creation */
9135 static void fill_new_table(opc_handler_t
**table
, int len
)
9139 for (i
= 0; i
< len
; i
++)
9140 table
[i
] = &invalid_handler
;
9143 static int create_new_table(opc_handler_t
**table
, unsigned char idx
)
9145 opc_handler_t
**tmp
;
9147 tmp
= g_new(opc_handler_t
*, PPC_CPU_INDIRECT_OPCODES_LEN
);
9148 fill_new_table(tmp
, PPC_CPU_INDIRECT_OPCODES_LEN
);
9149 table
[idx
] = (opc_handler_t
*)((uintptr_t)tmp
| PPC_INDIRECT
);
9154 static int insert_in_table(opc_handler_t
**table
, unsigned char idx
,
9155 opc_handler_t
*handler
)
9157 if (table
[idx
] != &invalid_handler
)
9159 table
[idx
] = handler
;
9164 static int register_direct_insn(opc_handler_t
**ppc_opcodes
,
9165 unsigned char idx
, opc_handler_t
*handler
)
9167 if (insert_in_table(ppc_opcodes
, idx
, handler
) < 0) {
9168 printf("*** ERROR: opcode %02x already assigned in main "
9169 "opcode table\n", idx
);
9170 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9171 printf(" Registered handler '%s' - new handler '%s'\n",
9172 ppc_opcodes
[idx
]->oname
, handler
->oname
);
9180 static int register_ind_in_table(opc_handler_t
**table
,
9181 unsigned char idx1
, unsigned char idx2
,
9182 opc_handler_t
*handler
)
9184 if (table
[idx1
] == &invalid_handler
) {
9185 if (create_new_table(table
, idx1
) < 0) {
9186 printf("*** ERROR: unable to create indirect table "
9187 "idx=%02x\n", idx1
);
9191 if (!is_indirect_opcode(table
[idx1
])) {
9192 printf("*** ERROR: idx %02x already assigned to a direct "
9194 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9195 printf(" Registered handler '%s' - new handler '%s'\n",
9196 ind_table(table
[idx1
])[idx2
]->oname
, handler
->oname
);
9201 if (handler
!= NULL
&&
9202 insert_in_table(ind_table(table
[idx1
]), idx2
, handler
) < 0) {
9203 printf("*** ERROR: opcode %02x already assigned in "
9204 "opcode table %02x\n", idx2
, idx1
);
9205 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9206 printf(" Registered handler '%s' - new handler '%s'\n",
9207 ind_table(table
[idx1
])[idx2
]->oname
, handler
->oname
);
9215 static int register_ind_insn(opc_handler_t
**ppc_opcodes
,
9216 unsigned char idx1
, unsigned char idx2
,
9217 opc_handler_t
*handler
)
9219 return register_ind_in_table(ppc_opcodes
, idx1
, idx2
, handler
);
9222 static int register_dblind_insn(opc_handler_t
**ppc_opcodes
,
9223 unsigned char idx1
, unsigned char idx2
,
9224 unsigned char idx3
, opc_handler_t
*handler
)
9226 if (register_ind_in_table(ppc_opcodes
, idx1
, idx2
, NULL
) < 0) {
9227 printf("*** ERROR: unable to join indirect table idx "
9228 "[%02x-%02x]\n", idx1
, idx2
);
9231 if (register_ind_in_table(ind_table(ppc_opcodes
[idx1
]), idx2
, idx3
,
9233 printf("*** ERROR: unable to insert opcode "
9234 "[%02x-%02x-%02x]\n", idx1
, idx2
, idx3
);
9241 static int register_trplind_insn(opc_handler_t
**ppc_opcodes
,
9242 unsigned char idx1
, unsigned char idx2
,
9243 unsigned char idx3
, unsigned char idx4
,
9244 opc_handler_t
*handler
)
9246 opc_handler_t
**table
;
9248 if (register_ind_in_table(ppc_opcodes
, idx1
, idx2
, NULL
) < 0) {
9249 printf("*** ERROR: unable to join indirect table idx "
9250 "[%02x-%02x]\n", idx1
, idx2
);
9253 table
= ind_table(ppc_opcodes
[idx1
]);
9254 if (register_ind_in_table(table
, idx2
, idx3
, NULL
) < 0) {
9255 printf("*** ERROR: unable to join 2nd-level indirect table idx "
9256 "[%02x-%02x-%02x]\n", idx1
, idx2
, idx3
);
9259 table
= ind_table(table
[idx2
]);
9260 if (register_ind_in_table(table
, idx3
, idx4
, handler
) < 0) {
9261 printf("*** ERROR: unable to insert opcode "
9262 "[%02x-%02x-%02x-%02x]\n", idx1
, idx2
, idx3
, idx4
);
9267 static int register_insn(opc_handler_t
**ppc_opcodes
, opcode_t
*insn
)
9269 if (insn
->opc2
!= 0xFF) {
9270 if (insn
->opc3
!= 0xFF) {
9271 if (insn
->opc4
!= 0xFF) {
9272 if (register_trplind_insn(ppc_opcodes
, insn
->opc1
, insn
->opc2
,
9273 insn
->opc3
, insn
->opc4
,
9274 &insn
->handler
) < 0) {
9278 if (register_dblind_insn(ppc_opcodes
, insn
->opc1
, insn
->opc2
,
9279 insn
->opc3
, &insn
->handler
) < 0)
9283 if (register_ind_insn(ppc_opcodes
, insn
->opc1
,
9284 insn
->opc2
, &insn
->handler
) < 0)
9288 if (register_direct_insn(ppc_opcodes
, insn
->opc1
, &insn
->handler
) < 0)
9295 static int test_opcode_table(opc_handler_t
**table
, int len
)
9299 for (i
= 0, count
= 0; i
< len
; i
++) {
9300 /* Consistency fixup */
9301 if (table
[i
] == NULL
)
9302 table
[i
] = &invalid_handler
;
9303 if (table
[i
] != &invalid_handler
) {
9304 if (is_indirect_opcode(table
[i
])) {
9305 tmp
= test_opcode_table(ind_table(table
[i
]),
9306 PPC_CPU_INDIRECT_OPCODES_LEN
);
9309 table
[i
] = &invalid_handler
;
9322 static void fix_opcode_tables(opc_handler_t
**ppc_opcodes
)
9324 if (test_opcode_table(ppc_opcodes
, PPC_CPU_OPCODES_LEN
) == 0)
9325 printf("*** WARNING: no opcode defined !\n");
9328 /*****************************************************************************/
9329 static void create_ppc_opcodes(PowerPCCPU
*cpu
, Error
**errp
)
9331 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9332 CPUPPCState
*env
= &cpu
->env
;
9335 fill_new_table(env
->opcodes
, PPC_CPU_OPCODES_LEN
);
9336 for (opc
= opcodes
; opc
< &opcodes
[ARRAY_SIZE(opcodes
)]; opc
++) {
9337 if (((opc
->handler
.type
& pcc
->insns_flags
) != 0) ||
9338 ((opc
->handler
.type2
& pcc
->insns_flags2
) != 0)) {
9339 if (register_insn(env
->opcodes
, opc
) < 0) {
9340 error_setg(errp
, "ERROR initializing PowerPC instruction "
9341 "0x%02x 0x%02x 0x%02x", opc
->opc1
, opc
->opc2
,
9347 fix_opcode_tables(env
->opcodes
);
9352 #if defined(PPC_DUMP_CPU)
9353 static void dump_ppc_insns(CPUPPCState
*env
)
9355 opc_handler_t
**table
, *handler
;
9357 uint8_t opc1
, opc2
, opc3
, opc4
;
9359 printf("Instructions set:\n");
9360 /* opc1 is 6 bits long */
9361 for (opc1
= 0x00; opc1
< PPC_CPU_OPCODES_LEN
; opc1
++) {
9362 table
= env
->opcodes
;
9363 handler
= table
[opc1
];
9364 if (is_indirect_opcode(handler
)) {
9365 /* opc2 is 5 bits long */
9366 for (opc2
= 0; opc2
< PPC_CPU_INDIRECT_OPCODES_LEN
; opc2
++) {
9367 table
= env
->opcodes
;
9368 handler
= env
->opcodes
[opc1
];
9369 table
= ind_table(handler
);
9370 handler
= table
[opc2
];
9371 if (is_indirect_opcode(handler
)) {
9372 table
= ind_table(handler
);
9373 /* opc3 is 5 bits long */
9374 for (opc3
= 0; opc3
< PPC_CPU_INDIRECT_OPCODES_LEN
;
9376 handler
= table
[opc3
];
9377 if (is_indirect_opcode(handler
)) {
9378 table
= ind_table(handler
);
9379 /* opc4 is 5 bits long */
9380 for (opc4
= 0; opc4
< PPC_CPU_INDIRECT_OPCODES_LEN
;
9382 handler
= table
[opc4
];
9383 if (handler
->handler
!= &gen_invalid
) {
9384 printf("INSN: %02x %02x %02x %02x -- "
9385 "(%02d %04d %02d) : %s\n",
9386 opc1
, opc2
, opc3
, opc4
,
9387 opc1
, (opc3
<< 5) | opc2
, opc4
,
9392 if (handler
->handler
!= &gen_invalid
) {
9393 /* Special hack to properly dump SPE insns */
9394 p
= strchr(handler
->oname
, '_');
9396 printf("INSN: %02x %02x %02x (%02d %04d) : "
9398 opc1
, opc2
, opc3
, opc1
,
9403 if ((p
- handler
->oname
) != strlen(q
)
9404 || (memcmp(handler
->oname
, q
, strlen(q
))
9406 /* First instruction */
9407 printf("INSN: %02x %02x %02x"
9408 "(%02d %04d) : %.*s\n",
9409 opc1
, opc2
<< 1, opc3
, opc1
,
9410 (opc3
<< 6) | (opc2
<< 1),
9411 (int)(p
- handler
->oname
),
9414 if (strcmp(p
+ 1, q
) != 0) {
9415 /* Second instruction */
9416 printf("INSN: %02x %02x %02x "
9417 "(%02d %04d) : %s\n", opc1
,
9418 (opc2
<< 1) | 1, opc3
, opc1
,
9419 (opc3
<< 6) | (opc2
<< 1) | 1,
9427 if (handler
->handler
!= &gen_invalid
) {
9428 printf("INSN: %02x %02x -- (%02d %04d) : %s\n",
9429 opc1
, opc2
, opc1
, opc2
, handler
->oname
);
9434 if (handler
->handler
!= &gen_invalid
) {
9435 printf("INSN: %02x -- -- (%02d ----) : %s\n",
9436 opc1
, opc1
, handler
->oname
);
9443 static bool avr_need_swap(CPUPPCState
*env
)
9445 #ifdef HOST_WORDS_BIGENDIAN
9452 static int gdb_get_float_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9455 stfq_p(mem_buf
, env
->fpr
[n
]);
9456 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9460 stl_p(mem_buf
, env
->fpscr
);
9461 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9467 static int gdb_set_float_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9470 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9471 env
->fpr
[n
] = ldfq_p(mem_buf
);
9475 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9476 helper_store_fpscr(env
, ldl_p(mem_buf
), 0xffffffff);
9482 static int gdb_get_avr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9485 if (!avr_need_swap(env
)) {
9486 stq_p(mem_buf
, env
->avr
[n
].u64
[0]);
9487 stq_p(mem_buf
+8, env
->avr
[n
].u64
[1]);
9489 stq_p(mem_buf
, env
->avr
[n
].u64
[1]);
9490 stq_p(mem_buf
+8, env
->avr
[n
].u64
[0]);
9492 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9493 ppc_maybe_bswap_register(env
, mem_buf
+ 8, 8);
9497 stl_p(mem_buf
, env
->vscr
);
9498 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9502 stl_p(mem_buf
, (uint32_t)env
->spr
[SPR_VRSAVE
]);
9503 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9509 static int gdb_set_avr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9512 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9513 ppc_maybe_bswap_register(env
, mem_buf
+ 8, 8);
9514 if (!avr_need_swap(env
)) {
9515 env
->avr
[n
].u64
[0] = ldq_p(mem_buf
);
9516 env
->avr
[n
].u64
[1] = ldq_p(mem_buf
+8);
9518 env
->avr
[n
].u64
[1] = ldq_p(mem_buf
);
9519 env
->avr
[n
].u64
[0] = ldq_p(mem_buf
+8);
9524 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9525 env
->vscr
= ldl_p(mem_buf
);
9529 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9530 env
->spr
[SPR_VRSAVE
] = (target_ulong
)ldl_p(mem_buf
);
9536 static int gdb_get_spe_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9539 #if defined(TARGET_PPC64)
9540 stl_p(mem_buf
, env
->gpr
[n
] >> 32);
9541 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9543 stl_p(mem_buf
, env
->gprh
[n
]);
9548 stq_p(mem_buf
, env
->spe_acc
);
9549 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9553 stl_p(mem_buf
, env
->spe_fscr
);
9554 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9560 static int gdb_set_spe_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9563 #if defined(TARGET_PPC64)
9564 target_ulong lo
= (uint32_t)env
->gpr
[n
];
9567 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9569 hi
= (target_ulong
)ldl_p(mem_buf
) << 32;
9570 env
->gpr
[n
] = lo
| hi
;
9572 env
->gprh
[n
] = ldl_p(mem_buf
);
9577 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9578 env
->spe_acc
= ldq_p(mem_buf
);
9582 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9583 env
->spe_fscr
= ldl_p(mem_buf
);
9589 static int gdb_get_vsx_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9592 stq_p(mem_buf
, env
->vsr
[n
]);
9593 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9599 static int gdb_set_vsx_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9602 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9603 env
->vsr
[n
] = ldq_p(mem_buf
);
9609 static int ppc_fixup_cpu(PowerPCCPU
*cpu
)
9611 CPUPPCState
*env
= &cpu
->env
;
9613 /* TCG doesn't (yet) emulate some groups of instructions that
9614 * are implemented on some otherwise supported CPUs (e.g. VSX
9615 * and decimal floating point instructions on POWER7). We
9616 * remove unsupported instruction groups from the cpu state's
9617 * instruction masks and hope the guest can cope. For at
9618 * least the pseries machine, the unavailability of these
9619 * instructions can be advertised to the guest via the device
9621 if ((env
->insns_flags
& ~PPC_TCG_INSNS
)
9622 || (env
->insns_flags2
& ~PPC_TCG_INSNS2
)) {
9623 warn_report("Disabling some instructions which are not "
9624 "emulated by TCG (0x%" PRIx64
", 0x%" PRIx64
")",
9625 env
->insns_flags
& ~PPC_TCG_INSNS
,
9626 env
->insns_flags2
& ~PPC_TCG_INSNS2
);
9628 env
->insns_flags
&= PPC_TCG_INSNS
;
9629 env
->insns_flags2
&= PPC_TCG_INSNS2
;
9633 static inline bool ppc_cpu_is_valid(PowerPCCPUClass
*pcc
)
9635 #ifdef TARGET_PPCEMB
9636 return pcc
->mmu_model
== POWERPC_MMU_BOOKE
||
9637 pcc
->mmu_model
== POWERPC_MMU_SOFT_4xx
||
9638 pcc
->mmu_model
== POWERPC_MMU_SOFT_4xx_Z
;
9644 static void ppc_cpu_realize(DeviceState
*dev
, Error
**errp
)
9646 CPUState
*cs
= CPU(dev
);
9647 PowerPCCPU
*cpu
= POWERPC_CPU(dev
);
9648 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9649 Error
*local_err
= NULL
;
9651 cpu_exec_realizefn(cs
, &local_err
);
9652 if (local_err
!= NULL
) {
9653 error_propagate(errp
, local_err
);
9656 if (cpu
->vcpu_id
== UNASSIGNED_CPU_INDEX
) {
9657 cpu
->vcpu_id
= cs
->cpu_index
;
9660 if (tcg_enabled()) {
9661 if (ppc_fixup_cpu(cpu
) != 0) {
9662 error_setg(errp
, "Unable to emulate selected CPU with TCG");
9667 assert(ppc_cpu_is_valid(pcc
));
9669 create_ppc_opcodes(cpu
, &local_err
);
9670 if (local_err
!= NULL
) {
9671 error_propagate(errp
, local_err
);
9676 if (pcc
->insns_flags
& PPC_FLOAT
) {
9677 gdb_register_coprocessor(cs
, gdb_get_float_reg
, gdb_set_float_reg
,
9678 33, "power-fpu.xml", 0);
9680 if (pcc
->insns_flags
& PPC_ALTIVEC
) {
9681 gdb_register_coprocessor(cs
, gdb_get_avr_reg
, gdb_set_avr_reg
,
9682 34, "power-altivec.xml", 0);
9684 if (pcc
->insns_flags
& PPC_SPE
) {
9685 gdb_register_coprocessor(cs
, gdb_get_spe_reg
, gdb_set_spe_reg
,
9686 34, "power-spe.xml", 0);
9688 if (pcc
->insns_flags2
& PPC2_VSX
) {
9689 gdb_register_coprocessor(cs
, gdb_get_vsx_reg
, gdb_set_vsx_reg
,
9690 32, "power-vsx.xml", 0);
9695 pcc
->parent_realize(dev
, errp
);
9697 #if defined(PPC_DUMP_CPU)
9699 CPUPPCState
*env
= &cpu
->env
;
9700 const char *mmu_model
, *excp_model
, *bus_model
;
9701 switch (env
->mmu_model
) {
9702 case POWERPC_MMU_32B
:
9703 mmu_model
= "PowerPC 32";
9705 case POWERPC_MMU_SOFT_6xx
:
9706 mmu_model
= "PowerPC 6xx/7xx with software driven TLBs";
9708 case POWERPC_MMU_SOFT_74xx
:
9709 mmu_model
= "PowerPC 74xx with software driven TLBs";
9711 case POWERPC_MMU_SOFT_4xx
:
9712 mmu_model
= "PowerPC 4xx with software driven TLBs";
9714 case POWERPC_MMU_SOFT_4xx_Z
:
9715 mmu_model
= "PowerPC 4xx with software driven TLBs "
9716 "and zones protections";
9718 case POWERPC_MMU_REAL
:
9719 mmu_model
= "PowerPC real mode only";
9721 case POWERPC_MMU_MPC8xx
:
9722 mmu_model
= "PowerPC MPC8xx";
9724 case POWERPC_MMU_BOOKE
:
9725 mmu_model
= "PowerPC BookE";
9727 case POWERPC_MMU_BOOKE206
:
9728 mmu_model
= "PowerPC BookE 2.06";
9730 case POWERPC_MMU_601
:
9731 mmu_model
= "PowerPC 601";
9733 #if defined(TARGET_PPC64)
9734 case POWERPC_MMU_64B
:
9735 mmu_model
= "PowerPC 64";
9739 mmu_model
= "Unknown or invalid";
9742 switch (env
->excp_model
) {
9743 case POWERPC_EXCP_STD
:
9744 excp_model
= "PowerPC";
9746 case POWERPC_EXCP_40x
:
9747 excp_model
= "PowerPC 40x";
9749 case POWERPC_EXCP_601
:
9750 excp_model
= "PowerPC 601";
9752 case POWERPC_EXCP_602
:
9753 excp_model
= "PowerPC 602";
9755 case POWERPC_EXCP_603
:
9756 excp_model
= "PowerPC 603";
9758 case POWERPC_EXCP_603E
:
9759 excp_model
= "PowerPC 603e";
9761 case POWERPC_EXCP_604
:
9762 excp_model
= "PowerPC 604";
9764 case POWERPC_EXCP_7x0
:
9765 excp_model
= "PowerPC 740/750";
9767 case POWERPC_EXCP_7x5
:
9768 excp_model
= "PowerPC 745/755";
9770 case POWERPC_EXCP_74xx
:
9771 excp_model
= "PowerPC 74xx";
9773 case POWERPC_EXCP_BOOKE
:
9774 excp_model
= "PowerPC BookE";
9776 #if defined(TARGET_PPC64)
9777 case POWERPC_EXCP_970
:
9778 excp_model
= "PowerPC 970";
9782 excp_model
= "Unknown or invalid";
9785 switch (env
->bus_model
) {
9786 case PPC_FLAGS_INPUT_6xx
:
9787 bus_model
= "PowerPC 6xx";
9789 case PPC_FLAGS_INPUT_BookE
:
9790 bus_model
= "PowerPC BookE";
9792 case PPC_FLAGS_INPUT_405
:
9793 bus_model
= "PowerPC 405";
9795 case PPC_FLAGS_INPUT_401
:
9796 bus_model
= "PowerPC 401/403";
9798 case PPC_FLAGS_INPUT_RCPU
:
9799 bus_model
= "RCPU / MPC8xx";
9801 #if defined(TARGET_PPC64)
9802 case PPC_FLAGS_INPUT_970
:
9803 bus_model
= "PowerPC 970";
9807 bus_model
= "Unknown or invalid";
9810 printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64
"\n"
9811 " MMU model : %s\n",
9812 object_class_get_name(OBJECT_CLASS(pcc
)),
9813 pcc
->pvr
, pcc
->msr_mask
, mmu_model
);
9814 #if !defined(CONFIG_USER_ONLY)
9815 if (env
->tlb
.tlb6
) {
9816 printf(" %d %s TLB in %d ways\n",
9817 env
->nb_tlb
, env
->id_tlbs
? "splitted" : "merged",
9821 printf(" Exceptions model : %s\n"
9822 " Bus model : %s\n",
9823 excp_model
, bus_model
);
9824 printf(" MSR features :\n");
9825 if (env
->flags
& POWERPC_FLAG_SPE
)
9826 printf(" signal processing engine enable"
9828 else if (env
->flags
& POWERPC_FLAG_VRE
)
9829 printf(" vector processor enable\n");
9830 if (env
->flags
& POWERPC_FLAG_TGPR
)
9831 printf(" temporary GPRs\n");
9832 else if (env
->flags
& POWERPC_FLAG_CE
)
9833 printf(" critical input enable\n");
9834 if (env
->flags
& POWERPC_FLAG_SE
)
9835 printf(" single-step trace mode\n");
9836 else if (env
->flags
& POWERPC_FLAG_DWE
)
9837 printf(" debug wait enable\n");
9838 else if (env
->flags
& POWERPC_FLAG_UBLE
)
9839 printf(" user BTB lock enable\n");
9840 if (env
->flags
& POWERPC_FLAG_BE
)
9841 printf(" branch-step trace mode\n");
9842 else if (env
->flags
& POWERPC_FLAG_DE
)
9843 printf(" debug interrupt enable\n");
9844 if (env
->flags
& POWERPC_FLAG_PX
)
9845 printf(" inclusive protection\n");
9846 else if (env
->flags
& POWERPC_FLAG_PMM
)
9847 printf(" performance monitor mark\n");
9848 if (env
->flags
== POWERPC_FLAG_NONE
)
9850 printf(" Time-base/decrementer clock source: %s\n",
9851 env
->flags
& POWERPC_FLAG_RTC_CLK
? "RTC clock" : "bus clock");
9852 dump_ppc_insns(env
);
9860 cpu_exec_unrealizefn(cs
);
9863 static void ppc_cpu_unrealize(DeviceState
*dev
, Error
**errp
)
9865 PowerPCCPU
*cpu
= POWERPC_CPU(dev
);
9866 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9867 CPUPPCState
*env
= &cpu
->env
;
9868 Error
*local_err
= NULL
;
9869 opc_handler_t
**table
, **table_2
;
9872 pcc
->parent_unrealize(dev
, &local_err
);
9873 if (local_err
!= NULL
) {
9874 error_propagate(errp
, local_err
);
9878 for (i
= 0; i
< PPC_CPU_OPCODES_LEN
; i
++) {
9879 if (env
->opcodes
[i
] == &invalid_handler
) {
9882 if (is_indirect_opcode(env
->opcodes
[i
])) {
9883 table
= ind_table(env
->opcodes
[i
]);
9884 for (j
= 0; j
< PPC_CPU_INDIRECT_OPCODES_LEN
; j
++) {
9885 if (table
[j
] == &invalid_handler
) {
9888 if (is_indirect_opcode(table
[j
])) {
9889 table_2
= ind_table(table
[j
]);
9890 for (k
= 0; k
< PPC_CPU_INDIRECT_OPCODES_LEN
; k
++) {
9891 if (table_2
[k
] != &invalid_handler
&&
9892 is_indirect_opcode(table_2
[k
])) {
9893 g_free((opc_handler_t
*)((uintptr_t)table_2
[k
] &
9897 g_free((opc_handler_t
*)((uintptr_t)table
[j
] &
9901 g_free((opc_handler_t
*)((uintptr_t)env
->opcodes
[i
] &
9907 static gint
ppc_cpu_compare_class_pvr(gconstpointer a
, gconstpointer b
)
9909 ObjectClass
*oc
= (ObjectClass
*)a
;
9910 uint32_t pvr
= *(uint32_t *)b
;
9911 PowerPCCPUClass
*pcc
= (PowerPCCPUClass
*)a
;
9913 /* -cpu host does a PVR lookup during construction */
9914 if (unlikely(strcmp(object_class_get_name(oc
),
9915 TYPE_HOST_POWERPC_CPU
) == 0)) {
9919 if (!ppc_cpu_is_valid(pcc
)) {
9923 return pcc
->pvr
== pvr
? 0 : -1;
9926 PowerPCCPUClass
*ppc_cpu_class_by_pvr(uint32_t pvr
)
9928 GSList
*list
, *item
;
9929 PowerPCCPUClass
*pcc
= NULL
;
9931 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
9932 item
= g_slist_find_custom(list
, &pvr
, ppc_cpu_compare_class_pvr
);
9934 pcc
= POWERPC_CPU_CLASS(item
->data
);
9941 static gint
ppc_cpu_compare_class_pvr_mask(gconstpointer a
, gconstpointer b
)
9943 ObjectClass
*oc
= (ObjectClass
*)a
;
9944 uint32_t pvr
= *(uint32_t *)b
;
9945 PowerPCCPUClass
*pcc
= (PowerPCCPUClass
*)a
;
9947 /* -cpu host does a PVR lookup during construction */
9948 if (unlikely(strcmp(object_class_get_name(oc
),
9949 TYPE_HOST_POWERPC_CPU
) == 0)) {
9953 if (!ppc_cpu_is_valid(pcc
)) {
9957 if (pcc
->pvr_match(pcc
, pvr
)) {
9964 PowerPCCPUClass
*ppc_cpu_class_by_pvr_mask(uint32_t pvr
)
9966 GSList
*list
, *item
;
9967 PowerPCCPUClass
*pcc
= NULL
;
9969 list
= object_class_get_list(TYPE_POWERPC_CPU
, true);
9970 item
= g_slist_find_custom(list
, &pvr
, ppc_cpu_compare_class_pvr_mask
);
9972 pcc
= POWERPC_CPU_CLASS(item
->data
);
9979 static const char *ppc_cpu_lookup_alias(const char *alias
)
9983 for (ai
= 0; ppc_cpu_aliases
[ai
].alias
!= NULL
; ai
++) {
9984 if (strcmp(ppc_cpu_aliases
[ai
].alias
, alias
) == 0) {
9985 return ppc_cpu_aliases
[ai
].model
;
9992 static ObjectClass
*ppc_cpu_class_by_name(const char *name
)
9994 char *cpu_model
, *typename
;
9999 /* Lookup by PVR if cpu_model is valid 8 digit hex number
10000 * (excl: 0x prefix if present)
10002 if (!qemu_strtoul(name
, &p
, 16, &pvr
)) {
10003 int len
= p
- name
;
10004 len
= (len
== 10) && (name
[1] == 'x') ? len
- 2 : len
;
10005 if ((len
== 8) && (*p
== '\0')) {
10006 return OBJECT_CLASS(ppc_cpu_class_by_pvr(pvr
));
10010 cpu_model
= g_ascii_strdown(name
, -1);
10011 p
= ppc_cpu_lookup_alias(cpu_model
);
10014 cpu_model
= g_strdup(p
);
10017 typename
= g_strdup_printf("%s" POWERPC_CPU_TYPE_SUFFIX
, cpu_model
);
10018 oc
= object_class_by_name(typename
);
10022 if (oc
&& ppc_cpu_is_valid(POWERPC_CPU_CLASS(oc
))) {
10029 static void ppc_cpu_parse_featurestr(const char *type
, char *features
,
10032 Object
*machine
= qdev_get_machine();
10033 const PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(object_class_by_name(type
));
10039 if (object_property_find(machine
, "max-cpu-compat", NULL
)) {
10042 char *s
= features
;
10043 Error
*local_err
= NULL
;
10044 char *compat_str
= NULL
;
10047 * Backwards compatibility hack:
10049 * CPUs had a "compat=" property which didn't make sense for
10050 * anything except pseries. It was replaced by "max-cpu-compat"
10051 * machine option. This supports old command lines like
10052 * -cpu POWER8,compat=power7
10053 * By stripping the compat option and applying it to the machine
10054 * before passing it on to the cpu level parser.
10056 inpieces
= g_strsplit(features
, ",", 0);
10058 for (i
= 0; inpieces
[i
]; i
++) {
10059 if (g_str_has_prefix(inpieces
[i
], "compat=")) {
10060 compat_str
= inpieces
[i
];
10063 if ((i
!= 0) && (s
!= features
)) {
10064 s
= g_stpcpy(s
, ",");
10066 s
= g_stpcpy(s
, inpieces
[i
]);
10070 char *v
= compat_str
+ strlen("compat=");
10071 object_property_set_str(machine
, v
, "max-cpu-compat", &local_err
);
10073 g_strfreev(inpieces
);
10075 error_propagate(errp
, local_err
);
10080 /* do property processing with generic handler */
10081 pcc
->parent_parse_features(type
, features
, errp
);
10084 PowerPCCPUClass
*ppc_cpu_get_family_class(PowerPCCPUClass
*pcc
)
10086 ObjectClass
*oc
= OBJECT_CLASS(pcc
);
10088 while (oc
&& !object_class_is_abstract(oc
)) {
10089 oc
= object_class_get_parent(oc
);
10093 return POWERPC_CPU_CLASS(oc
);
10096 /* Sort by PVR, ordering special case "host" last. */
10097 static gint
ppc_cpu_list_compare(gconstpointer a
, gconstpointer b
)
10099 ObjectClass
*oc_a
= (ObjectClass
*)a
;
10100 ObjectClass
*oc_b
= (ObjectClass
*)b
;
10101 PowerPCCPUClass
*pcc_a
= POWERPC_CPU_CLASS(oc_a
);
10102 PowerPCCPUClass
*pcc_b
= POWERPC_CPU_CLASS(oc_b
);
10103 const char *name_a
= object_class_get_name(oc_a
);
10104 const char *name_b
= object_class_get_name(oc_b
);
10106 if (strcmp(name_a
, TYPE_HOST_POWERPC_CPU
) == 0) {
10108 } else if (strcmp(name_b
, TYPE_HOST_POWERPC_CPU
) == 0) {
10111 /* Avoid an integer overflow during subtraction */
10112 if (pcc_a
->pvr
< pcc_b
->pvr
) {
10114 } else if (pcc_a
->pvr
> pcc_b
->pvr
) {
10122 static void ppc_cpu_list_entry(gpointer data
, gpointer user_data
)
10124 ObjectClass
*oc
= data
;
10125 CPUListState
*s
= user_data
;
10126 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10127 DeviceClass
*family
= DEVICE_CLASS(ppc_cpu_get_family_class(pcc
));
10128 const char *typename
= object_class_get_name(oc
);
10132 if (!ppc_cpu_is_valid(pcc
)) {
10135 if (unlikely(strcmp(typename
, TYPE_HOST_POWERPC_CPU
) == 0)) {
10139 name
= g_strndup(typename
,
10140 strlen(typename
) - strlen(POWERPC_CPU_TYPE_SUFFIX
));
10141 (*s
->cpu_fprintf
)(s
->file
, "PowerPC %-16s PVR %08x\n",
10143 for (i
= 0; ppc_cpu_aliases
[i
].alias
!= NULL
; i
++) {
10144 PowerPCCPUAlias
*alias
= &ppc_cpu_aliases
[i
];
10145 ObjectClass
*alias_oc
= ppc_cpu_class_by_name(alias
->model
);
10147 if (alias_oc
!= oc
) {
10151 * If running with KVM, we might update the family alias later, so
10152 * avoid printing the wrong alias here and use "preferred" instead
10154 if (strcmp(alias
->alias
, family
->desc
) == 0) {
10155 (*s
->cpu_fprintf
)(s
->file
,
10156 "PowerPC %-16s (alias for preferred %s CPU)\n",
10157 alias
->alias
, family
->desc
);
10159 (*s
->cpu_fprintf
)(s
->file
, "PowerPC %-16s (alias for %s)\n",
10160 alias
->alias
, name
);
10166 void ppc_cpu_list(FILE *f
, fprintf_function cpu_fprintf
)
10170 .cpu_fprintf
= cpu_fprintf
,
10174 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10175 list
= g_slist_sort(list
, ppc_cpu_list_compare
);
10176 g_slist_foreach(list
, ppc_cpu_list_entry
, &s
);
10177 g_slist_free(list
);
10180 cpu_fprintf(f
, "\n");
10181 cpu_fprintf(f
, "PowerPC %-16s\n", "host");
10185 static void ppc_cpu_defs_entry(gpointer data
, gpointer user_data
)
10187 ObjectClass
*oc
= data
;
10188 CpuDefinitionInfoList
**first
= user_data
;
10189 const char *typename
;
10190 CpuDefinitionInfoList
*entry
;
10191 CpuDefinitionInfo
*info
;
10192 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10194 if (!ppc_cpu_is_valid(pcc
)) {
10198 typename
= object_class_get_name(oc
);
10199 info
= g_malloc0(sizeof(*info
));
10200 info
->name
= g_strndup(typename
,
10201 strlen(typename
) - strlen(POWERPC_CPU_TYPE_SUFFIX
));
10203 entry
= g_malloc0(sizeof(*entry
));
10204 entry
->value
= info
;
10205 entry
->next
= *first
;
10209 CpuDefinitionInfoList
*arch_query_cpu_definitions(Error
**errp
)
10211 CpuDefinitionInfoList
*cpu_list
= NULL
;
10215 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10216 g_slist_foreach(list
, ppc_cpu_defs_entry
, &cpu_list
);
10217 g_slist_free(list
);
10219 for (i
= 0; ppc_cpu_aliases
[i
].alias
!= NULL
; i
++) {
10220 PowerPCCPUAlias
*alias
= &ppc_cpu_aliases
[i
];
10222 CpuDefinitionInfoList
*entry
;
10223 CpuDefinitionInfo
*info
;
10225 oc
= ppc_cpu_class_by_name(alias
->model
);
10230 info
= g_malloc0(sizeof(*info
));
10231 info
->name
= g_strdup(alias
->alias
);
10232 info
->q_typename
= g_strdup(object_class_get_name(oc
));
10234 entry
= g_malloc0(sizeof(*entry
));
10235 entry
->value
= info
;
10236 entry
->next
= cpu_list
;
10243 static void ppc_cpu_set_pc(CPUState
*cs
, vaddr value
)
10245 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10247 cpu
->env
.nip
= value
;
10250 static bool ppc_cpu_has_work(CPUState
*cs
)
10252 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10253 CPUPPCState
*env
= &cpu
->env
;
10255 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
10258 /* CPUClass::reset() */
10259 static void ppc_cpu_reset(CPUState
*s
)
10261 PowerPCCPU
*cpu
= POWERPC_CPU(s
);
10262 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10263 CPUPPCState
*env
= &cpu
->env
;
10267 pcc
->parent_reset(s
);
10269 msr
= (target_ulong
)0;
10270 msr
|= (target_ulong
)MSR_HVB
;
10271 msr
|= (target_ulong
)0 << MSR_AP
; /* TO BE CHECKED */
10272 msr
|= (target_ulong
)0 << MSR_SA
; /* TO BE CHECKED */
10273 msr
|= (target_ulong
)1 << MSR_EP
;
10274 #if defined(DO_SINGLE_STEP) && 0
10275 /* Single step trace mode */
10276 msr
|= (target_ulong
)1 << MSR_SE
;
10277 msr
|= (target_ulong
)1 << MSR_BE
;
10279 #if defined(CONFIG_USER_ONLY)
10280 msr
|= (target_ulong
)1 << MSR_FP
; /* Allow floating point usage */
10281 msr
|= (target_ulong
)1 << MSR_VR
; /* Allow altivec usage */
10282 msr
|= (target_ulong
)1 << MSR_VSX
; /* Allow VSX usage */
10283 msr
|= (target_ulong
)1 << MSR_SPE
; /* Allow SPE usage */
10284 msr
|= (target_ulong
)1 << MSR_PR
;
10285 #if defined(TARGET_PPC64)
10286 msr
|= (target_ulong
)1 << MSR_TM
; /* Transactional memory */
10288 #if !defined(TARGET_WORDS_BIGENDIAN)
10289 msr
|= (target_ulong
)1 << MSR_LE
; /* Little-endian user mode */
10290 if (!((env
->msr_mask
>> MSR_LE
) & 1)) {
10291 fprintf(stderr
, "Selected CPU does not support little-endian.\n");
10297 #if defined(TARGET_PPC64)
10298 if (env
->mmu_model
& POWERPC_MMU_64
) {
10299 msr
|= (1ULL << MSR_SF
);
10303 hreg_store_msr(env
, msr
, 1);
10305 #if !defined(CONFIG_USER_ONLY)
10306 env
->nip
= env
->hreset_vector
| env
->excp_prefix
;
10307 if (env
->mmu_model
!= POWERPC_MMU_REAL
) {
10308 ppc_tlb_invalidate_all(env
);
10312 hreg_compute_hflags(env
);
10313 env
->reserve_addr
= (target_ulong
)-1ULL;
10314 /* Be sure no exception or interrupt is pending */
10315 env
->pending_interrupts
= 0;
10316 s
->exception_index
= POWERPC_EXCP_NONE
;
10317 env
->error_code
= 0;
10319 for (i
= 0; i
< ARRAY_SIZE(env
->spr_cb
); i
++) {
10320 ppc_spr_t
*spr
= &env
->spr_cb
[i
];
10325 env
->spr
[i
] = spr
->default_value
;
10329 #ifndef CONFIG_USER_ONLY
10330 static bool ppc_cpu_is_big_endian(CPUState
*cs
)
10332 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10333 CPUPPCState
*env
= &cpu
->env
;
10335 cpu_synchronize_state(cs
);
10341 static void ppc_cpu_instance_init(Object
*obj
)
10343 CPUState
*cs
= CPU(obj
);
10344 PowerPCCPU
*cpu
= POWERPC_CPU(obj
);
10345 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10346 CPUPPCState
*env
= &cpu
->env
;
10349 cpu
->vcpu_id
= UNASSIGNED_CPU_INDEX
;
10351 env
->msr_mask
= pcc
->msr_mask
;
10352 env
->mmu_model
= pcc
->mmu_model
;
10353 env
->excp_model
= pcc
->excp_model
;
10354 env
->bus_model
= pcc
->bus_model
;
10355 env
->insns_flags
= pcc
->insns_flags
;
10356 env
->insns_flags2
= pcc
->insns_flags2
;
10357 env
->flags
= pcc
->flags
;
10358 env
->bfd_mach
= pcc
->bfd_mach
;
10359 env
->check_pow
= pcc
->check_pow
;
10361 /* Mark HV mode as supported if the CPU has an MSR_HV bit
10362 * in the msr_mask. The mask can later be cleared by PAPR
10363 * mode but the hv mode support will remain, thus enforcing
10364 * that we cannot use priv. instructions in guest in PAPR
10365 * mode. For 970 we currently simply don't set HV in msr_mask
10366 * thus simulating an "Apple mode" 970. If we ever want to
10367 * support 970 HV mode, we'll have to add a processor attribute
10370 #if !defined(CONFIG_USER_ONLY)
10371 env
->has_hv_mode
= !!(env
->msr_mask
& MSR_HVB
);
10374 ppc_hash64_init(cpu
);
10377 static void ppc_cpu_instance_finalize(Object
*obj
)
10379 PowerPCCPU
*cpu
= POWERPC_CPU(obj
);
10381 ppc_hash64_finalize(cpu
);
10384 static bool ppc_pvr_match_default(PowerPCCPUClass
*pcc
, uint32_t pvr
)
10386 return pcc
->pvr
== pvr
;
10389 static gchar
*ppc_gdb_arch_name(CPUState
*cs
)
10391 #if defined(TARGET_PPC64)
10392 return g_strdup("powerpc:common64");
10394 return g_strdup("powerpc:common");
10398 static void ppc_disas_set_info(CPUState
*cs
, disassemble_info
*info
)
10400 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10401 CPUPPCState
*env
= &cpu
->env
;
10403 if ((env
->hflags
>> MSR_LE
) & 1) {
10404 info
->endian
= BFD_ENDIAN_LITTLE
;
10406 info
->mach
= env
->bfd_mach
;
10407 if (!env
->bfd_mach
) {
10408 #ifdef TARGET_PPC64
10409 info
->mach
= bfd_mach_ppc64
;
10411 info
->mach
= bfd_mach_ppc
;
10414 info
->disassembler_options
= (char *)"any";
10415 info
->print_insn
= print_insn_ppc
;
10417 info
->cap_arch
= CS_ARCH_PPC
;
10418 #ifdef TARGET_PPC64
10419 info
->cap_mode
= CS_MODE_64
;
10423 static Property ppc_cpu_properties
[] = {
10424 DEFINE_PROP_BOOL("pre-2.8-migration", PowerPCCPU
, pre_2_8_migration
, false),
10425 DEFINE_PROP_BOOL("pre-2.10-migration", PowerPCCPU
, pre_2_10_migration
,
10427 DEFINE_PROP_BOOL("pre-3.0-migration", PowerPCCPU
, pre_3_0_migration
,
10429 DEFINE_PROP_END_OF_LIST(),
10432 static void ppc_cpu_class_init(ObjectClass
*oc
, void *data
)
10434 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10435 CPUClass
*cc
= CPU_CLASS(oc
);
10436 DeviceClass
*dc
= DEVICE_CLASS(oc
);
10438 device_class_set_parent_realize(dc
, ppc_cpu_realize
,
10439 &pcc
->parent_realize
);
10440 device_class_set_parent_unrealize(dc
, ppc_cpu_unrealize
,
10441 &pcc
->parent_unrealize
);
10442 pcc
->pvr_match
= ppc_pvr_match_default
;
10443 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_always
;
10444 dc
->props
= ppc_cpu_properties
;
10446 pcc
->parent_reset
= cc
->reset
;
10447 cc
->reset
= ppc_cpu_reset
;
10449 cc
->class_by_name
= ppc_cpu_class_by_name
;
10450 pcc
->parent_parse_features
= cc
->parse_features
;
10451 cc
->parse_features
= ppc_cpu_parse_featurestr
;
10452 cc
->has_work
= ppc_cpu_has_work
;
10453 cc
->do_interrupt
= ppc_cpu_do_interrupt
;
10454 cc
->cpu_exec_interrupt
= ppc_cpu_exec_interrupt
;
10455 cc
->dump_state
= ppc_cpu_dump_state
;
10456 cc
->dump_statistics
= ppc_cpu_dump_statistics
;
10457 cc
->set_pc
= ppc_cpu_set_pc
;
10458 cc
->gdb_read_register
= ppc_cpu_gdb_read_register
;
10459 cc
->gdb_write_register
= ppc_cpu_gdb_write_register
;
10460 cc
->do_unaligned_access
= ppc_cpu_do_unaligned_access
;
10461 #ifdef CONFIG_USER_ONLY
10462 cc
->handle_mmu_fault
= ppc_cpu_handle_mmu_fault
;
10464 cc
->get_phys_page_debug
= ppc_cpu_get_phys_page_debug
;
10465 cc
->vmsd
= &vmstate_ppc_cpu
;
10467 #if defined(CONFIG_SOFTMMU)
10468 cc
->write_elf64_note
= ppc64_cpu_write_elf64_note
;
10469 cc
->write_elf32_note
= ppc32_cpu_write_elf32_note
;
10472 cc
->gdb_num_core_regs
= 71;
10474 #ifdef USE_APPLE_GDB
10475 cc
->gdb_read_register
= ppc_cpu_gdb_read_register_apple
;
10476 cc
->gdb_write_register
= ppc_cpu_gdb_write_register_apple
;
10477 cc
->gdb_num_core_regs
= 71 + 32;
10480 cc
->gdb_arch_name
= ppc_gdb_arch_name
;
10481 #if defined(TARGET_PPC64)
10482 cc
->gdb_core_xml_file
= "power64-core.xml";
10484 cc
->gdb_core_xml_file
= "power-core.xml";
10486 #ifndef CONFIG_USER_ONLY
10487 cc
->virtio_is_big_endian
= ppc_cpu_is_big_endian
;
10490 cc
->tcg_initialize
= ppc_translate_init
;
10492 cc
->disas_set_info
= ppc_disas_set_info
;
10494 dc
->fw_name
= "PowerPC,UNKNOWN";
10497 static const TypeInfo ppc_cpu_type_info
= {
10498 .name
= TYPE_POWERPC_CPU
,
10499 .parent
= TYPE_CPU
,
10500 .instance_size
= sizeof(PowerPCCPU
),
10501 .instance_init
= ppc_cpu_instance_init
,
10502 .instance_finalize
= ppc_cpu_instance_finalize
,
10504 .class_size
= sizeof(PowerPCCPUClass
),
10505 .class_init
= ppc_cpu_class_init
,
10508 static const TypeInfo ppc_vhyp_type_info
= {
10509 .name
= TYPE_PPC_VIRTUAL_HYPERVISOR
,
10510 .parent
= TYPE_INTERFACE
,
10511 .class_size
= sizeof(PPCVirtualHypervisorClass
),
10514 static void ppc_cpu_register_types(void)
10516 type_register_static(&ppc_cpu_type_info
);
10517 type_register_static(&ppc_vhyp_type_info
);
10520 type_init(ppc_cpu_register_types
)