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_store_spr(sprn
, cpu_gpr
[gprn
]);
502 gen_helper_store_40x_dbcr0(cpu_env
, cpu_gpr
[gprn
]);
503 /* We must stop translation as we may have rebooted */
504 gen_stop_exception(ctx
);
507 static void spr_write_40x_sler(DisasContext
*ctx
, int sprn
, int gprn
)
509 gen_helper_store_40x_sler(cpu_env
, cpu_gpr
[gprn
]);
512 static void spr_write_booke_tcr(DisasContext
*ctx
, int sprn
, int gprn
)
514 gen_helper_store_booke_tcr(cpu_env
, cpu_gpr
[gprn
]);
517 static void spr_write_booke_tsr(DisasContext
*ctx
, int sprn
, int gprn
)
519 gen_helper_store_booke_tsr(cpu_env
, cpu_gpr
[gprn
]);
523 /* PowerPC 403 specific registers */
524 /* PBL1 / PBU1 / PBL2 / PBU2 */
525 #if !defined(CONFIG_USER_ONLY)
526 static void spr_read_403_pbr(DisasContext
*ctx
, int gprn
, int sprn
)
528 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, pb
[sprn
- SPR_403_PBL1
]));
531 static void spr_write_403_pbr(DisasContext
*ctx
, int sprn
, int gprn
)
533 TCGv_i32 t0
= tcg_const_i32(sprn
- SPR_403_PBL1
);
534 gen_helper_store_403_pbr(cpu_env
, t0
, cpu_gpr
[gprn
]);
535 tcg_temp_free_i32(t0
);
538 static void spr_write_pir(DisasContext
*ctx
, int sprn
, int gprn
)
540 TCGv t0
= tcg_temp_new();
541 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], 0xF);
542 gen_store_spr(SPR_PIR
, t0
);
547 /* SPE specific registers */
548 static void spr_read_spefscr(DisasContext
*ctx
, int gprn
, int sprn
)
550 TCGv_i32 t0
= tcg_temp_new_i32();
551 tcg_gen_ld_i32(t0
, cpu_env
, offsetof(CPUPPCState
, spe_fscr
));
552 tcg_gen_extu_i32_tl(cpu_gpr
[gprn
], t0
);
553 tcg_temp_free_i32(t0
);
556 static void spr_write_spefscr(DisasContext
*ctx
, int sprn
, int gprn
)
558 TCGv_i32 t0
= tcg_temp_new_i32();
559 tcg_gen_trunc_tl_i32(t0
, cpu_gpr
[gprn
]);
560 tcg_gen_st_i32(t0
, cpu_env
, offsetof(CPUPPCState
, spe_fscr
));
561 tcg_temp_free_i32(t0
);
564 #if !defined(CONFIG_USER_ONLY)
565 /* Callback used to write the exception vector base */
566 static void spr_write_excp_prefix(DisasContext
*ctx
, int sprn
, int gprn
)
568 TCGv t0
= tcg_temp_new();
569 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUPPCState
, ivpr_mask
));
570 tcg_gen_and_tl(t0
, t0
, cpu_gpr
[gprn
]);
571 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_prefix
));
572 gen_store_spr(sprn
, t0
);
576 static void spr_write_excp_vector(DisasContext
*ctx
, int sprn
, int gprn
)
580 if (sprn
>= SPR_BOOKE_IVOR0
&& sprn
<= SPR_BOOKE_IVOR15
) {
581 sprn_offs
= sprn
- SPR_BOOKE_IVOR0
;
582 } else if (sprn
>= SPR_BOOKE_IVOR32
&& sprn
<= SPR_BOOKE_IVOR37
) {
583 sprn_offs
= sprn
- SPR_BOOKE_IVOR32
+ 32;
584 } else if (sprn
>= SPR_BOOKE_IVOR38
&& sprn
<= SPR_BOOKE_IVOR42
) {
585 sprn_offs
= sprn
- SPR_BOOKE_IVOR38
+ 38;
587 printf("Trying to write an unknown exception vector %d %03x\n",
589 gen_inval_exception(ctx
, POWERPC_EXCP_PRIV_REG
);
593 TCGv t0
= tcg_temp_new();
594 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUPPCState
, ivor_mask
));
595 tcg_gen_and_tl(t0
, t0
, cpu_gpr
[gprn
]);
596 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_vectors
[sprn_offs
]));
597 gen_store_spr(sprn
, t0
);
602 static inline void vscr_init(CPUPPCState
*env
, uint32_t val
)
605 /* Altivec always uses round-to-nearest */
606 set_float_rounding_mode(float_round_nearest_even
, &env
->vec_status
);
607 set_flush_to_zero(vscr_nj
, &env
->vec_status
);
610 #ifdef CONFIG_USER_ONLY
611 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
612 oea_read, oea_write, one_reg_id, initial_value) \
613 _spr_register(env, num, name, uea_read, uea_write, initial_value)
614 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
615 oea_read, oea_write, hea_read, hea_write, \
616 one_reg_id, initial_value) \
617 _spr_register(env, num, name, uea_read, uea_write, initial_value)
619 #if !defined(CONFIG_KVM)
620 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
621 oea_read, oea_write, one_reg_id, initial_value) \
622 _spr_register(env, num, name, uea_read, uea_write, \
623 oea_read, oea_write, oea_read, oea_write, initial_value)
624 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
625 oea_read, oea_write, hea_read, hea_write, \
626 one_reg_id, initial_value) \
627 _spr_register(env, num, name, uea_read, uea_write, \
628 oea_read, oea_write, hea_read, hea_write, initial_value)
630 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
631 oea_read, oea_write, one_reg_id, initial_value) \
632 _spr_register(env, num, name, uea_read, uea_write, \
633 oea_read, oea_write, oea_read, oea_write, \
634 one_reg_id, initial_value)
635 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
636 oea_read, oea_write, hea_read, hea_write, \
637 one_reg_id, initial_value) \
638 _spr_register(env, num, name, uea_read, uea_write, \
639 oea_read, oea_write, hea_read, hea_write, \
640 one_reg_id, initial_value)
644 #define spr_register(env, num, name, uea_read, uea_write, \
645 oea_read, oea_write, initial_value) \
646 spr_register_kvm(env, num, name, uea_read, uea_write, \
647 oea_read, oea_write, 0, initial_value)
649 #define spr_register_hv(env, num, name, uea_read, uea_write, \
650 oea_read, oea_write, hea_read, hea_write, \
652 spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
653 oea_read, oea_write, hea_read, hea_write, \
656 static inline void _spr_register(CPUPPCState
*env
, int num
,
658 void (*uea_read
)(DisasContext
*ctx
, int gprn
, int sprn
),
659 void (*uea_write
)(DisasContext
*ctx
, int sprn
, int gprn
),
660 #if !defined(CONFIG_USER_ONLY)
662 void (*oea_read
)(DisasContext
*ctx
, int gprn
, int sprn
),
663 void (*oea_write
)(DisasContext
*ctx
, int sprn
, int gprn
),
664 void (*hea_read
)(DisasContext
*opaque
, int gprn
, int sprn
),
665 void (*hea_write
)(DisasContext
*opaque
, int sprn
, int gprn
),
667 #if defined(CONFIG_KVM)
670 target_ulong initial_value
)
674 spr
= &env
->spr_cb
[num
];
675 if (spr
->name
!= NULL
||env
-> spr
[num
] != 0x00000000 ||
676 #if !defined(CONFIG_USER_ONLY)
677 spr
->oea_read
!= NULL
|| spr
->oea_write
!= NULL
||
679 spr
->uea_read
!= NULL
|| spr
->uea_write
!= NULL
) {
680 printf("Error: Trying to register SPR %d (%03x) twice !\n", num
, num
);
683 #if defined(PPC_DEBUG_SPR)
684 printf("*** register spr %d (%03x) %s val " TARGET_FMT_lx
"\n", num
, num
,
685 name
, initial_value
);
688 spr
->uea_read
= uea_read
;
689 spr
->uea_write
= uea_write
;
690 #if !defined(CONFIG_USER_ONLY)
691 spr
->oea_read
= oea_read
;
692 spr
->oea_write
= oea_write
;
693 spr
->hea_read
= hea_read
;
694 spr
->hea_write
= hea_write
;
696 #if defined(CONFIG_KVM)
697 spr
->one_reg_id
= one_reg_id
,
699 env
->spr
[num
] = spr
->default_value
= initial_value
;
702 /* Generic PowerPC SPRs */
703 static void gen_spr_generic(CPUPPCState
*env
)
705 /* Integer processing */
706 spr_register(env
, SPR_XER
, "XER",
707 &spr_read_xer
, &spr_write_xer
,
708 &spr_read_xer
, &spr_write_xer
,
711 spr_register(env
, SPR_LR
, "LR",
712 &spr_read_lr
, &spr_write_lr
,
713 &spr_read_lr
, &spr_write_lr
,
715 spr_register(env
, SPR_CTR
, "CTR",
716 &spr_read_ctr
, &spr_write_ctr
,
717 &spr_read_ctr
, &spr_write_ctr
,
719 /* Interrupt processing */
720 spr_register(env
, SPR_SRR0
, "SRR0",
721 SPR_NOACCESS
, SPR_NOACCESS
,
722 &spr_read_generic
, &spr_write_generic
,
724 spr_register(env
, SPR_SRR1
, "SRR1",
725 SPR_NOACCESS
, SPR_NOACCESS
,
726 &spr_read_generic
, &spr_write_generic
,
728 /* Processor control */
729 spr_register(env
, SPR_SPRG0
, "SPRG0",
730 SPR_NOACCESS
, SPR_NOACCESS
,
731 &spr_read_generic
, &spr_write_generic
,
733 spr_register(env
, SPR_SPRG1
, "SPRG1",
734 SPR_NOACCESS
, SPR_NOACCESS
,
735 &spr_read_generic
, &spr_write_generic
,
737 spr_register(env
, SPR_SPRG2
, "SPRG2",
738 SPR_NOACCESS
, SPR_NOACCESS
,
739 &spr_read_generic
, &spr_write_generic
,
741 spr_register(env
, SPR_SPRG3
, "SPRG3",
742 SPR_NOACCESS
, SPR_NOACCESS
,
743 &spr_read_generic
, &spr_write_generic
,
747 /* SPR common to all non-embedded PowerPC, including 601 */
748 static void gen_spr_ne_601(CPUPPCState
*env
)
750 /* Exception processing */
751 spr_register_kvm(env
, SPR_DSISR
, "DSISR",
752 SPR_NOACCESS
, SPR_NOACCESS
,
753 &spr_read_generic
, &spr_write_generic
,
754 KVM_REG_PPC_DSISR
, 0x00000000);
755 spr_register_kvm(env
, SPR_DAR
, "DAR",
756 SPR_NOACCESS
, SPR_NOACCESS
,
757 &spr_read_generic
, &spr_write_generic
,
758 KVM_REG_PPC_DAR
, 0x00000000);
760 spr_register(env
, SPR_DECR
, "DECR",
761 SPR_NOACCESS
, SPR_NOACCESS
,
762 &spr_read_decr
, &spr_write_decr
,
766 /* Storage Description Register 1 */
767 static void gen_spr_sdr1(CPUPPCState
*env
)
769 #ifndef CONFIG_USER_ONLY
770 if (env
->has_hv_mode
) {
771 /* SDR1 is a hypervisor resource on CPUs which have a
773 spr_register_hv(env
, SPR_SDR1
, "SDR1",
774 SPR_NOACCESS
, SPR_NOACCESS
,
775 SPR_NOACCESS
, SPR_NOACCESS
,
776 &spr_read_generic
, &spr_write_sdr1
,
779 spr_register(env
, SPR_SDR1
, "SDR1",
780 SPR_NOACCESS
, SPR_NOACCESS
,
781 &spr_read_generic
, &spr_write_sdr1
,
788 static void gen_low_BATs(CPUPPCState
*env
)
790 #if !defined(CONFIG_USER_ONLY)
791 spr_register(env
, SPR_IBAT0U
, "IBAT0U",
792 SPR_NOACCESS
, SPR_NOACCESS
,
793 &spr_read_ibat
, &spr_write_ibatu
,
795 spr_register(env
, SPR_IBAT0L
, "IBAT0L",
796 SPR_NOACCESS
, SPR_NOACCESS
,
797 &spr_read_ibat
, &spr_write_ibatl
,
799 spr_register(env
, SPR_IBAT1U
, "IBAT1U",
800 SPR_NOACCESS
, SPR_NOACCESS
,
801 &spr_read_ibat
, &spr_write_ibatu
,
803 spr_register(env
, SPR_IBAT1L
, "IBAT1L",
804 SPR_NOACCESS
, SPR_NOACCESS
,
805 &spr_read_ibat
, &spr_write_ibatl
,
807 spr_register(env
, SPR_IBAT2U
, "IBAT2U",
808 SPR_NOACCESS
, SPR_NOACCESS
,
809 &spr_read_ibat
, &spr_write_ibatu
,
811 spr_register(env
, SPR_IBAT2L
, "IBAT2L",
812 SPR_NOACCESS
, SPR_NOACCESS
,
813 &spr_read_ibat
, &spr_write_ibatl
,
815 spr_register(env
, SPR_IBAT3U
, "IBAT3U",
816 SPR_NOACCESS
, SPR_NOACCESS
,
817 &spr_read_ibat
, &spr_write_ibatu
,
819 spr_register(env
, SPR_IBAT3L
, "IBAT3L",
820 SPR_NOACCESS
, SPR_NOACCESS
,
821 &spr_read_ibat
, &spr_write_ibatl
,
823 spr_register(env
, SPR_DBAT0U
, "DBAT0U",
824 SPR_NOACCESS
, SPR_NOACCESS
,
825 &spr_read_dbat
, &spr_write_dbatu
,
827 spr_register(env
, SPR_DBAT0L
, "DBAT0L",
828 SPR_NOACCESS
, SPR_NOACCESS
,
829 &spr_read_dbat
, &spr_write_dbatl
,
831 spr_register(env
, SPR_DBAT1U
, "DBAT1U",
832 SPR_NOACCESS
, SPR_NOACCESS
,
833 &spr_read_dbat
, &spr_write_dbatu
,
835 spr_register(env
, SPR_DBAT1L
, "DBAT1L",
836 SPR_NOACCESS
, SPR_NOACCESS
,
837 &spr_read_dbat
, &spr_write_dbatl
,
839 spr_register(env
, SPR_DBAT2U
, "DBAT2U",
840 SPR_NOACCESS
, SPR_NOACCESS
,
841 &spr_read_dbat
, &spr_write_dbatu
,
843 spr_register(env
, SPR_DBAT2L
, "DBAT2L",
844 SPR_NOACCESS
, SPR_NOACCESS
,
845 &spr_read_dbat
, &spr_write_dbatl
,
847 spr_register(env
, SPR_DBAT3U
, "DBAT3U",
848 SPR_NOACCESS
, SPR_NOACCESS
,
849 &spr_read_dbat
, &spr_write_dbatu
,
851 spr_register(env
, SPR_DBAT3L
, "DBAT3L",
852 SPR_NOACCESS
, SPR_NOACCESS
,
853 &spr_read_dbat
, &spr_write_dbatl
,
860 static void gen_high_BATs(CPUPPCState
*env
)
862 #if !defined(CONFIG_USER_ONLY)
863 spr_register(env
, SPR_IBAT4U
, "IBAT4U",
864 SPR_NOACCESS
, SPR_NOACCESS
,
865 &spr_read_ibat_h
, &spr_write_ibatu_h
,
867 spr_register(env
, SPR_IBAT4L
, "IBAT4L",
868 SPR_NOACCESS
, SPR_NOACCESS
,
869 &spr_read_ibat_h
, &spr_write_ibatl_h
,
871 spr_register(env
, SPR_IBAT5U
, "IBAT5U",
872 SPR_NOACCESS
, SPR_NOACCESS
,
873 &spr_read_ibat_h
, &spr_write_ibatu_h
,
875 spr_register(env
, SPR_IBAT5L
, "IBAT5L",
876 SPR_NOACCESS
, SPR_NOACCESS
,
877 &spr_read_ibat_h
, &spr_write_ibatl_h
,
879 spr_register(env
, SPR_IBAT6U
, "IBAT6U",
880 SPR_NOACCESS
, SPR_NOACCESS
,
881 &spr_read_ibat_h
, &spr_write_ibatu_h
,
883 spr_register(env
, SPR_IBAT6L
, "IBAT6L",
884 SPR_NOACCESS
, SPR_NOACCESS
,
885 &spr_read_ibat_h
, &spr_write_ibatl_h
,
887 spr_register(env
, SPR_IBAT7U
, "IBAT7U",
888 SPR_NOACCESS
, SPR_NOACCESS
,
889 &spr_read_ibat_h
, &spr_write_ibatu_h
,
891 spr_register(env
, SPR_IBAT7L
, "IBAT7L",
892 SPR_NOACCESS
, SPR_NOACCESS
,
893 &spr_read_ibat_h
, &spr_write_ibatl_h
,
895 spr_register(env
, SPR_DBAT4U
, "DBAT4U",
896 SPR_NOACCESS
, SPR_NOACCESS
,
897 &spr_read_dbat_h
, &spr_write_dbatu_h
,
899 spr_register(env
, SPR_DBAT4L
, "DBAT4L",
900 SPR_NOACCESS
, SPR_NOACCESS
,
901 &spr_read_dbat_h
, &spr_write_dbatl_h
,
903 spr_register(env
, SPR_DBAT5U
, "DBAT5U",
904 SPR_NOACCESS
, SPR_NOACCESS
,
905 &spr_read_dbat_h
, &spr_write_dbatu_h
,
907 spr_register(env
, SPR_DBAT5L
, "DBAT5L",
908 SPR_NOACCESS
, SPR_NOACCESS
,
909 &spr_read_dbat_h
, &spr_write_dbatl_h
,
911 spr_register(env
, SPR_DBAT6U
, "DBAT6U",
912 SPR_NOACCESS
, SPR_NOACCESS
,
913 &spr_read_dbat_h
, &spr_write_dbatu_h
,
915 spr_register(env
, SPR_DBAT6L
, "DBAT6L",
916 SPR_NOACCESS
, SPR_NOACCESS
,
917 &spr_read_dbat_h
, &spr_write_dbatl_h
,
919 spr_register(env
, SPR_DBAT7U
, "DBAT7U",
920 SPR_NOACCESS
, SPR_NOACCESS
,
921 &spr_read_dbat_h
, &spr_write_dbatu_h
,
923 spr_register(env
, SPR_DBAT7L
, "DBAT7L",
924 SPR_NOACCESS
, SPR_NOACCESS
,
925 &spr_read_dbat_h
, &spr_write_dbatl_h
,
931 /* Generic PowerPC time base */
932 static void gen_tbl(CPUPPCState
*env
)
934 spr_register(env
, SPR_VTBL
, "TBL",
935 &spr_read_tbl
, SPR_NOACCESS
,
936 &spr_read_tbl
, SPR_NOACCESS
,
938 spr_register(env
, SPR_TBL
, "TBL",
939 &spr_read_tbl
, SPR_NOACCESS
,
940 &spr_read_tbl
, &spr_write_tbl
,
942 spr_register(env
, SPR_VTBU
, "TBU",
943 &spr_read_tbu
, SPR_NOACCESS
,
944 &spr_read_tbu
, SPR_NOACCESS
,
946 spr_register(env
, SPR_TBU
, "TBU",
947 &spr_read_tbu
, SPR_NOACCESS
,
948 &spr_read_tbu
, &spr_write_tbu
,
952 /* Softare table search registers */
953 static void gen_6xx_7xx_soft_tlb(CPUPPCState
*env
, int nb_tlbs
, int nb_ways
)
955 #if !defined(CONFIG_USER_ONLY)
956 env
->nb_tlb
= nb_tlbs
;
957 env
->nb_ways
= nb_ways
;
959 env
->tlb_type
= TLB_6XX
;
960 spr_register(env
, SPR_DMISS
, "DMISS",
961 SPR_NOACCESS
, SPR_NOACCESS
,
962 &spr_read_generic
, SPR_NOACCESS
,
964 spr_register(env
, SPR_DCMP
, "DCMP",
965 SPR_NOACCESS
, SPR_NOACCESS
,
966 &spr_read_generic
, SPR_NOACCESS
,
968 spr_register(env
, SPR_HASH1
, "HASH1",
969 SPR_NOACCESS
, SPR_NOACCESS
,
970 &spr_read_generic
, SPR_NOACCESS
,
972 spr_register(env
, SPR_HASH2
, "HASH2",
973 SPR_NOACCESS
, SPR_NOACCESS
,
974 &spr_read_generic
, SPR_NOACCESS
,
976 spr_register(env
, SPR_IMISS
, "IMISS",
977 SPR_NOACCESS
, SPR_NOACCESS
,
978 &spr_read_generic
, SPR_NOACCESS
,
980 spr_register(env
, SPR_ICMP
, "ICMP",
981 SPR_NOACCESS
, SPR_NOACCESS
,
982 &spr_read_generic
, SPR_NOACCESS
,
984 spr_register(env
, SPR_RPA
, "RPA",
985 SPR_NOACCESS
, SPR_NOACCESS
,
986 &spr_read_generic
, &spr_write_generic
,
991 /* SPR common to MPC755 and G2 */
992 static void gen_spr_G2_755(CPUPPCState
*env
)
995 spr_register(env
, SPR_SPRG4
, "SPRG4",
996 SPR_NOACCESS
, SPR_NOACCESS
,
997 &spr_read_generic
, &spr_write_generic
,
999 spr_register(env
, SPR_SPRG5
, "SPRG5",
1000 SPR_NOACCESS
, SPR_NOACCESS
,
1001 &spr_read_generic
, &spr_write_generic
,
1003 spr_register(env
, SPR_SPRG6
, "SPRG6",
1004 SPR_NOACCESS
, SPR_NOACCESS
,
1005 &spr_read_generic
, &spr_write_generic
,
1007 spr_register(env
, SPR_SPRG7
, "SPRG7",
1008 SPR_NOACCESS
, SPR_NOACCESS
,
1009 &spr_read_generic
, &spr_write_generic
,
1013 /* SPR common to all 7xx PowerPC implementations */
1014 static void gen_spr_7xx(CPUPPCState
*env
)
1017 /* XXX : not implemented */
1018 spr_register_kvm(env
, SPR_DABR
, "DABR",
1019 SPR_NOACCESS
, SPR_NOACCESS
,
1020 &spr_read_generic
, &spr_write_generic
,
1021 KVM_REG_PPC_DABR
, 0x00000000);
1022 /* XXX : not implemented */
1023 spr_register(env
, SPR_IABR
, "IABR",
1024 SPR_NOACCESS
, SPR_NOACCESS
,
1025 &spr_read_generic
, &spr_write_generic
,
1027 /* Cache management */
1028 /* XXX : not implemented */
1029 spr_register(env
, SPR_ICTC
, "ICTC",
1030 SPR_NOACCESS
, SPR_NOACCESS
,
1031 &spr_read_generic
, &spr_write_generic
,
1033 /* Performance monitors */
1034 /* XXX : not implemented */
1035 spr_register(env
, SPR_7XX_MMCR0
, "MMCR0",
1036 SPR_NOACCESS
, SPR_NOACCESS
,
1037 &spr_read_generic
, &spr_write_generic
,
1039 /* XXX : not implemented */
1040 spr_register(env
, SPR_7XX_MMCR1
, "MMCR1",
1041 SPR_NOACCESS
, SPR_NOACCESS
,
1042 &spr_read_generic
, &spr_write_generic
,
1044 /* XXX : not implemented */
1045 spr_register(env
, SPR_7XX_PMC1
, "PMC1",
1046 SPR_NOACCESS
, SPR_NOACCESS
,
1047 &spr_read_generic
, &spr_write_generic
,
1049 /* XXX : not implemented */
1050 spr_register(env
, SPR_7XX_PMC2
, "PMC2",
1051 SPR_NOACCESS
, SPR_NOACCESS
,
1052 &spr_read_generic
, &spr_write_generic
,
1054 /* XXX : not implemented */
1055 spr_register(env
, SPR_7XX_PMC3
, "PMC3",
1056 SPR_NOACCESS
, SPR_NOACCESS
,
1057 &spr_read_generic
, &spr_write_generic
,
1059 /* XXX : not implemented */
1060 spr_register(env
, SPR_7XX_PMC4
, "PMC4",
1061 SPR_NOACCESS
, SPR_NOACCESS
,
1062 &spr_read_generic
, &spr_write_generic
,
1064 /* XXX : not implemented */
1065 spr_register(env
, SPR_7XX_SIAR
, "SIAR",
1066 SPR_NOACCESS
, SPR_NOACCESS
,
1067 &spr_read_generic
, SPR_NOACCESS
,
1069 /* XXX : not implemented */
1070 spr_register(env
, SPR_7XX_UMMCR0
, "UMMCR0",
1071 &spr_read_ureg
, SPR_NOACCESS
,
1072 &spr_read_ureg
, SPR_NOACCESS
,
1074 /* XXX : not implemented */
1075 spr_register(env
, SPR_7XX_UMMCR1
, "UMMCR1",
1076 &spr_read_ureg
, SPR_NOACCESS
,
1077 &spr_read_ureg
, SPR_NOACCESS
,
1079 /* XXX : not implemented */
1080 spr_register(env
, SPR_7XX_UPMC1
, "UPMC1",
1081 &spr_read_ureg
, SPR_NOACCESS
,
1082 &spr_read_ureg
, SPR_NOACCESS
,
1084 /* XXX : not implemented */
1085 spr_register(env
, SPR_7XX_UPMC2
, "UPMC2",
1086 &spr_read_ureg
, SPR_NOACCESS
,
1087 &spr_read_ureg
, SPR_NOACCESS
,
1089 /* XXX : not implemented */
1090 spr_register(env
, SPR_7XX_UPMC3
, "UPMC3",
1091 &spr_read_ureg
, SPR_NOACCESS
,
1092 &spr_read_ureg
, SPR_NOACCESS
,
1094 /* XXX : not implemented */
1095 spr_register(env
, SPR_7XX_UPMC4
, "UPMC4",
1096 &spr_read_ureg
, SPR_NOACCESS
,
1097 &spr_read_ureg
, SPR_NOACCESS
,
1099 /* XXX : not implemented */
1100 spr_register(env
, SPR_7XX_USIAR
, "USIAR",
1101 &spr_read_ureg
, SPR_NOACCESS
,
1102 &spr_read_ureg
, SPR_NOACCESS
,
1104 /* External access control */
1105 /* XXX : not implemented */
1106 spr_register(env
, SPR_EAR
, "EAR",
1107 SPR_NOACCESS
, SPR_NOACCESS
,
1108 &spr_read_generic
, &spr_write_generic
,
1113 #ifndef CONFIG_USER_ONLY
1114 static void spr_write_amr(DisasContext
*ctx
, int sprn
, int gprn
)
1116 TCGv t0
= tcg_temp_new();
1117 TCGv t1
= tcg_temp_new();
1118 TCGv t2
= tcg_temp_new();
1120 /* Note, the HV=1 PR=0 case is handled earlier by simply using
1121 * spr_write_generic for HV mode in the SPR table
1124 /* Build insertion mask into t1 based on context */
1126 gen_load_spr(t1
, SPR_UAMOR
);
1128 gen_load_spr(t1
, SPR_AMOR
);
1131 /* Mask new bits into t2 */
1132 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1134 /* Load AMR and clear new bits in t0 */
1135 gen_load_spr(t0
, SPR_AMR
);
1136 tcg_gen_andc_tl(t0
, t0
, t1
);
1138 /* Or'in new bits and write it out */
1139 tcg_gen_or_tl(t0
, t0
, t2
);
1140 gen_store_spr(SPR_AMR
, t0
);
1141 spr_store_dump_spr(SPR_AMR
);
1148 static void spr_write_uamor(DisasContext
*ctx
, int sprn
, int gprn
)
1150 TCGv t0
= tcg_temp_new();
1151 TCGv t1
= tcg_temp_new();
1152 TCGv t2
= tcg_temp_new();
1154 /* Note, the HV=1 case is handled earlier by simply using
1155 * spr_write_generic for HV mode in the SPR table
1158 /* Build insertion mask into t1 based on context */
1159 gen_load_spr(t1
, SPR_AMOR
);
1161 /* Mask new bits into t2 */
1162 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1164 /* Load AMR and clear new bits in t0 */
1165 gen_load_spr(t0
, SPR_UAMOR
);
1166 tcg_gen_andc_tl(t0
, t0
, t1
);
1168 /* Or'in new bits and write it out */
1169 tcg_gen_or_tl(t0
, t0
, t2
);
1170 gen_store_spr(SPR_UAMOR
, t0
);
1171 spr_store_dump_spr(SPR_UAMOR
);
1178 static void spr_write_iamr(DisasContext
*ctx
, int sprn
, int gprn
)
1180 TCGv t0
= tcg_temp_new();
1181 TCGv t1
= tcg_temp_new();
1182 TCGv t2
= tcg_temp_new();
1184 /* Note, the HV=1 case is handled earlier by simply using
1185 * spr_write_generic for HV mode in the SPR table
1188 /* Build insertion mask into t1 based on context */
1189 gen_load_spr(t1
, SPR_AMOR
);
1191 /* Mask new bits into t2 */
1192 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1194 /* Load AMR and clear new bits in t0 */
1195 gen_load_spr(t0
, SPR_IAMR
);
1196 tcg_gen_andc_tl(t0
, t0
, t1
);
1198 /* Or'in new bits and write it out */
1199 tcg_gen_or_tl(t0
, t0
, t2
);
1200 gen_store_spr(SPR_IAMR
, t0
);
1201 spr_store_dump_spr(SPR_IAMR
);
1207 #endif /* CONFIG_USER_ONLY */
1209 static void gen_spr_amr(CPUPPCState
*env
)
1211 #ifndef CONFIG_USER_ONLY
1212 /* Virtual Page Class Key protection */
1213 /* The AMR is accessible either via SPR 13 or SPR 29. 13 is
1214 * userspace accessible, 29 is privileged. So we only need to set
1215 * the kvm ONE_REG id on one of them, we use 29 */
1216 spr_register(env
, SPR_UAMR
, "UAMR",
1217 &spr_read_generic
, &spr_write_amr
,
1218 &spr_read_generic
, &spr_write_amr
,
1220 spr_register_kvm_hv(env
, SPR_AMR
, "AMR",
1221 SPR_NOACCESS
, SPR_NOACCESS
,
1222 &spr_read_generic
, &spr_write_amr
,
1223 &spr_read_generic
, &spr_write_generic
,
1224 KVM_REG_PPC_AMR
, 0);
1225 spr_register_kvm_hv(env
, SPR_UAMOR
, "UAMOR",
1226 SPR_NOACCESS
, SPR_NOACCESS
,
1227 &spr_read_generic
, &spr_write_uamor
,
1228 &spr_read_generic
, &spr_write_generic
,
1229 KVM_REG_PPC_UAMOR
, 0);
1230 spr_register_hv(env
, SPR_AMOR
, "AMOR",
1231 SPR_NOACCESS
, SPR_NOACCESS
,
1232 SPR_NOACCESS
, SPR_NOACCESS
,
1233 &spr_read_generic
, &spr_write_generic
,
1235 #endif /* !CONFIG_USER_ONLY */
1238 static void gen_spr_iamr(CPUPPCState
*env
)
1240 #ifndef CONFIG_USER_ONLY
1241 spr_register_kvm_hv(env
, SPR_IAMR
, "IAMR",
1242 SPR_NOACCESS
, SPR_NOACCESS
,
1243 &spr_read_generic
, &spr_write_iamr
,
1244 &spr_read_generic
, &spr_write_generic
,
1245 KVM_REG_PPC_IAMR
, 0);
1246 #endif /* !CONFIG_USER_ONLY */
1248 #endif /* TARGET_PPC64 */
1250 #ifndef CONFIG_USER_ONLY
1251 static void spr_read_thrm(DisasContext
*ctx
, int gprn
, int sprn
)
1253 gen_helper_fixup_thrm(cpu_env
);
1254 gen_load_spr(cpu_gpr
[gprn
], sprn
);
1255 spr_load_dump_spr(sprn
);
1257 #endif /* !CONFIG_USER_ONLY */
1259 static void gen_spr_thrm(CPUPPCState
*env
)
1261 /* Thermal management */
1262 /* XXX : not implemented */
1263 spr_register(env
, SPR_THRM1
, "THRM1",
1264 SPR_NOACCESS
, SPR_NOACCESS
,
1265 &spr_read_thrm
, &spr_write_generic
,
1267 /* XXX : not implemented */
1268 spr_register(env
, SPR_THRM2
, "THRM2",
1269 SPR_NOACCESS
, SPR_NOACCESS
,
1270 &spr_read_thrm
, &spr_write_generic
,
1272 /* XXX : not implemented */
1273 spr_register(env
, SPR_THRM3
, "THRM3",
1274 SPR_NOACCESS
, SPR_NOACCESS
,
1275 &spr_read_thrm
, &spr_write_generic
,
1279 /* SPR specific to PowerPC 604 implementation */
1280 static void gen_spr_604(CPUPPCState
*env
)
1282 /* Processor identification */
1283 spr_register(env
, SPR_PIR
, "PIR",
1284 SPR_NOACCESS
, SPR_NOACCESS
,
1285 &spr_read_generic
, &spr_write_pir
,
1288 /* XXX : not implemented */
1289 spr_register(env
, SPR_IABR
, "IABR",
1290 SPR_NOACCESS
, SPR_NOACCESS
,
1291 &spr_read_generic
, &spr_write_generic
,
1293 /* XXX : not implemented */
1294 spr_register_kvm(env
, SPR_DABR
, "DABR",
1295 SPR_NOACCESS
, SPR_NOACCESS
,
1296 &spr_read_generic
, &spr_write_generic
,
1297 KVM_REG_PPC_DABR
, 0x00000000);
1298 /* Performance counters */
1299 /* XXX : not implemented */
1300 spr_register(env
, SPR_7XX_MMCR0
, "MMCR0",
1301 SPR_NOACCESS
, SPR_NOACCESS
,
1302 &spr_read_generic
, &spr_write_generic
,
1304 /* XXX : not implemented */
1305 spr_register(env
, SPR_7XX_PMC1
, "PMC1",
1306 SPR_NOACCESS
, SPR_NOACCESS
,
1307 &spr_read_generic
, &spr_write_generic
,
1309 /* XXX : not implemented */
1310 spr_register(env
, SPR_7XX_PMC2
, "PMC2",
1311 SPR_NOACCESS
, SPR_NOACCESS
,
1312 &spr_read_generic
, &spr_write_generic
,
1314 /* XXX : not implemented */
1315 spr_register(env
, SPR_7XX_SIAR
, "SIAR",
1316 SPR_NOACCESS
, SPR_NOACCESS
,
1317 &spr_read_generic
, SPR_NOACCESS
,
1319 /* XXX : not implemented */
1320 spr_register(env
, SPR_SDA
, "SDA",
1321 SPR_NOACCESS
, SPR_NOACCESS
,
1322 &spr_read_generic
, SPR_NOACCESS
,
1324 /* External access control */
1325 /* XXX : not implemented */
1326 spr_register(env
, SPR_EAR
, "EAR",
1327 SPR_NOACCESS
, SPR_NOACCESS
,
1328 &spr_read_generic
, &spr_write_generic
,
1332 /* SPR specific to PowerPC 603 implementation */
1333 static void gen_spr_603(CPUPPCState
*env
)
1335 /* External access control */
1336 /* XXX : not implemented */
1337 spr_register(env
, SPR_EAR
, "EAR",
1338 SPR_NOACCESS
, SPR_NOACCESS
,
1339 &spr_read_generic
, &spr_write_generic
,
1342 /* XXX : not implemented */
1343 spr_register(env
, SPR_IABR
, "IABR",
1344 SPR_NOACCESS
, SPR_NOACCESS
,
1345 &spr_read_generic
, &spr_write_generic
,
1350 /* SPR specific to PowerPC G2 implementation */
1351 static void gen_spr_G2(CPUPPCState
*env
)
1353 /* Memory base address */
1355 /* XXX : not implemented */
1356 spr_register(env
, SPR_MBAR
, "MBAR",
1357 SPR_NOACCESS
, SPR_NOACCESS
,
1358 &spr_read_generic
, &spr_write_generic
,
1360 /* Exception processing */
1361 spr_register(env
, SPR_BOOKE_CSRR0
, "CSRR0",
1362 SPR_NOACCESS
, SPR_NOACCESS
,
1363 &spr_read_generic
, &spr_write_generic
,
1365 spr_register(env
, SPR_BOOKE_CSRR1
, "CSRR1",
1366 SPR_NOACCESS
, SPR_NOACCESS
,
1367 &spr_read_generic
, &spr_write_generic
,
1370 /* XXX : not implemented */
1371 spr_register(env
, SPR_DABR
, "DABR",
1372 SPR_NOACCESS
, SPR_NOACCESS
,
1373 &spr_read_generic
, &spr_write_generic
,
1375 /* XXX : not implemented */
1376 spr_register(env
, SPR_DABR2
, "DABR2",
1377 SPR_NOACCESS
, SPR_NOACCESS
,
1378 &spr_read_generic
, &spr_write_generic
,
1380 /* XXX : not implemented */
1381 spr_register(env
, SPR_IABR
, "IABR",
1382 SPR_NOACCESS
, SPR_NOACCESS
,
1383 &spr_read_generic
, &spr_write_generic
,
1385 /* XXX : not implemented */
1386 spr_register(env
, SPR_IABR2
, "IABR2",
1387 SPR_NOACCESS
, SPR_NOACCESS
,
1388 &spr_read_generic
, &spr_write_generic
,
1390 /* XXX : not implemented */
1391 spr_register(env
, SPR_IBCR
, "IBCR",
1392 SPR_NOACCESS
, SPR_NOACCESS
,
1393 &spr_read_generic
, &spr_write_generic
,
1395 /* XXX : not implemented */
1396 spr_register(env
, SPR_DBCR
, "DBCR",
1397 SPR_NOACCESS
, SPR_NOACCESS
,
1398 &spr_read_generic
, &spr_write_generic
,
1402 /* SPR specific to PowerPC 602 implementation */
1403 static void gen_spr_602(CPUPPCState
*env
)
1406 /* XXX : not implemented */
1407 spr_register(env
, SPR_SER
, "SER",
1408 SPR_NOACCESS
, SPR_NOACCESS
,
1409 &spr_read_generic
, &spr_write_generic
,
1411 /* XXX : not implemented */
1412 spr_register(env
, SPR_SEBR
, "SEBR",
1413 SPR_NOACCESS
, SPR_NOACCESS
,
1414 &spr_read_generic
, &spr_write_generic
,
1416 /* XXX : not implemented */
1417 spr_register(env
, SPR_ESASRR
, "ESASRR",
1418 SPR_NOACCESS
, SPR_NOACCESS
,
1419 &spr_read_generic
, &spr_write_generic
,
1421 /* Floating point status */
1422 /* XXX : not implemented */
1423 spr_register(env
, SPR_SP
, "SP",
1424 SPR_NOACCESS
, SPR_NOACCESS
,
1425 &spr_read_generic
, &spr_write_generic
,
1427 /* XXX : not implemented */
1428 spr_register(env
, SPR_LT
, "LT",
1429 SPR_NOACCESS
, SPR_NOACCESS
,
1430 &spr_read_generic
, &spr_write_generic
,
1432 /* Watchdog timer */
1433 /* XXX : not implemented */
1434 spr_register(env
, SPR_TCR
, "TCR",
1435 SPR_NOACCESS
, SPR_NOACCESS
,
1436 &spr_read_generic
, &spr_write_generic
,
1438 /* Interrupt base */
1439 spr_register(env
, SPR_IBR
, "IBR",
1440 SPR_NOACCESS
, SPR_NOACCESS
,
1441 &spr_read_generic
, &spr_write_generic
,
1443 /* XXX : not implemented */
1444 spr_register(env
, SPR_IABR
, "IABR",
1445 SPR_NOACCESS
, SPR_NOACCESS
,
1446 &spr_read_generic
, &spr_write_generic
,
1450 /* SPR specific to PowerPC 601 implementation */
1451 static void gen_spr_601(CPUPPCState
*env
)
1453 /* Multiplication/division register */
1455 spr_register(env
, SPR_MQ
, "MQ",
1456 &spr_read_generic
, &spr_write_generic
,
1457 &spr_read_generic
, &spr_write_generic
,
1460 spr_register(env
, SPR_601_RTCU
, "RTCU",
1461 SPR_NOACCESS
, SPR_NOACCESS
,
1462 SPR_NOACCESS
, &spr_write_601_rtcu
,
1464 spr_register(env
, SPR_601_VRTCU
, "RTCU",
1465 &spr_read_601_rtcu
, SPR_NOACCESS
,
1466 &spr_read_601_rtcu
, SPR_NOACCESS
,
1468 spr_register(env
, SPR_601_RTCL
, "RTCL",
1469 SPR_NOACCESS
, SPR_NOACCESS
,
1470 SPR_NOACCESS
, &spr_write_601_rtcl
,
1472 spr_register(env
, SPR_601_VRTCL
, "RTCL",
1473 &spr_read_601_rtcl
, SPR_NOACCESS
,
1474 &spr_read_601_rtcl
, SPR_NOACCESS
,
1478 spr_register(env
, SPR_601_UDECR
, "UDECR",
1479 &spr_read_decr
, SPR_NOACCESS
,
1480 &spr_read_decr
, SPR_NOACCESS
,
1483 /* External access control */
1484 /* XXX : not implemented */
1485 spr_register(env
, SPR_EAR
, "EAR",
1486 SPR_NOACCESS
, SPR_NOACCESS
,
1487 &spr_read_generic
, &spr_write_generic
,
1489 /* Memory management */
1490 #if !defined(CONFIG_USER_ONLY)
1491 spr_register(env
, SPR_IBAT0U
, "IBAT0U",
1492 SPR_NOACCESS
, SPR_NOACCESS
,
1493 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1495 spr_register(env
, SPR_IBAT0L
, "IBAT0L",
1496 SPR_NOACCESS
, SPR_NOACCESS
,
1497 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1499 spr_register(env
, SPR_IBAT1U
, "IBAT1U",
1500 SPR_NOACCESS
, SPR_NOACCESS
,
1501 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1503 spr_register(env
, SPR_IBAT1L
, "IBAT1L",
1504 SPR_NOACCESS
, SPR_NOACCESS
,
1505 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1507 spr_register(env
, SPR_IBAT2U
, "IBAT2U",
1508 SPR_NOACCESS
, SPR_NOACCESS
,
1509 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1511 spr_register(env
, SPR_IBAT2L
, "IBAT2L",
1512 SPR_NOACCESS
, SPR_NOACCESS
,
1513 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1515 spr_register(env
, SPR_IBAT3U
, "IBAT3U",
1516 SPR_NOACCESS
, SPR_NOACCESS
,
1517 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1519 spr_register(env
, SPR_IBAT3L
, "IBAT3L",
1520 SPR_NOACCESS
, SPR_NOACCESS
,
1521 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1527 static void gen_spr_74xx(CPUPPCState
*env
)
1529 /* Processor identification */
1530 spr_register(env
, SPR_PIR
, "PIR",
1531 SPR_NOACCESS
, SPR_NOACCESS
,
1532 &spr_read_generic
, &spr_write_pir
,
1534 /* XXX : not implemented */
1535 spr_register(env
, SPR_74XX_MMCR2
, "MMCR2",
1536 SPR_NOACCESS
, SPR_NOACCESS
,
1537 &spr_read_generic
, &spr_write_generic
,
1539 /* XXX : not implemented */
1540 spr_register(env
, SPR_74XX_UMMCR2
, "UMMCR2",
1541 &spr_read_ureg
, SPR_NOACCESS
,
1542 &spr_read_ureg
, SPR_NOACCESS
,
1544 /* XXX: not implemented */
1545 spr_register(env
, SPR_BAMR
, "BAMR",
1546 SPR_NOACCESS
, SPR_NOACCESS
,
1547 &spr_read_generic
, &spr_write_generic
,
1549 /* XXX : not implemented */
1550 spr_register(env
, SPR_MSSCR0
, "MSSCR0",
1551 SPR_NOACCESS
, SPR_NOACCESS
,
1552 &spr_read_generic
, &spr_write_generic
,
1554 /* Hardware implementation registers */
1555 /* XXX : not implemented */
1556 spr_register(env
, SPR_HID0
, "HID0",
1557 SPR_NOACCESS
, SPR_NOACCESS
,
1558 &spr_read_generic
, &spr_write_generic
,
1560 /* XXX : not implemented */
1561 spr_register(env
, SPR_HID1
, "HID1",
1562 SPR_NOACCESS
, SPR_NOACCESS
,
1563 &spr_read_generic
, &spr_write_generic
,
1566 spr_register(env
, SPR_VRSAVE
, "VRSAVE",
1567 &spr_read_generic
, &spr_write_generic
,
1568 &spr_read_generic
, &spr_write_generic
,
1570 /* XXX : not implemented */
1571 spr_register(env
, SPR_L2CR
, "L2CR",
1572 SPR_NOACCESS
, SPR_NOACCESS
,
1573 &spr_read_generic
, spr_access_nop
,
1575 /* Not strictly an SPR */
1576 vscr_init(env
, 0x00010000);
1579 static void gen_l3_ctrl(CPUPPCState
*env
)
1582 /* XXX : not implemented */
1583 spr_register(env
, SPR_L3CR
, "L3CR",
1584 SPR_NOACCESS
, SPR_NOACCESS
,
1585 &spr_read_generic
, &spr_write_generic
,
1588 /* XXX : not implemented */
1589 spr_register(env
, SPR_L3ITCR0
, "L3ITCR0",
1590 SPR_NOACCESS
, SPR_NOACCESS
,
1591 &spr_read_generic
, &spr_write_generic
,
1594 /* XXX : not implemented */
1595 spr_register(env
, SPR_L3PM
, "L3PM",
1596 SPR_NOACCESS
, SPR_NOACCESS
,
1597 &spr_read_generic
, &spr_write_generic
,
1601 static void gen_74xx_soft_tlb(CPUPPCState
*env
, int nb_tlbs
, int nb_ways
)
1603 #if !defined(CONFIG_USER_ONLY)
1604 env
->nb_tlb
= nb_tlbs
;
1605 env
->nb_ways
= nb_ways
;
1607 env
->tlb_type
= TLB_6XX
;
1608 /* XXX : not implemented */
1609 spr_register(env
, SPR_PTEHI
, "PTEHI",
1610 SPR_NOACCESS
, SPR_NOACCESS
,
1611 &spr_read_generic
, &spr_write_generic
,
1613 /* XXX : not implemented */
1614 spr_register(env
, SPR_PTELO
, "PTELO",
1615 SPR_NOACCESS
, SPR_NOACCESS
,
1616 &spr_read_generic
, &spr_write_generic
,
1618 /* XXX : not implemented */
1619 spr_register(env
, SPR_TLBMISS
, "TLBMISS",
1620 SPR_NOACCESS
, SPR_NOACCESS
,
1621 &spr_read_generic
, &spr_write_generic
,
1626 #if !defined(CONFIG_USER_ONLY)
1627 static void spr_write_e500_l1csr0(DisasContext
*ctx
, int sprn
, int gprn
)
1629 TCGv t0
= tcg_temp_new();
1631 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], L1CSR0_DCE
| L1CSR0_CPE
);
1632 gen_store_spr(sprn
, t0
);
1636 static void spr_write_e500_l1csr1(DisasContext
*ctx
, int sprn
, int gprn
)
1638 TCGv t0
= tcg_temp_new();
1640 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], L1CSR1_ICE
| L1CSR1_CPE
);
1641 gen_store_spr(sprn
, t0
);
1645 static void spr_write_booke206_mmucsr0(DisasContext
*ctx
, int sprn
, int gprn
)
1647 gen_helper_booke206_tlbflush(cpu_env
, cpu_gpr
[gprn
]);
1650 static void spr_write_booke_pid(DisasContext
*ctx
, int sprn
, int gprn
)
1652 TCGv_i32 t0
= tcg_const_i32(sprn
);
1653 gen_helper_booke_setpid(cpu_env
, t0
, cpu_gpr
[gprn
]);
1654 tcg_temp_free_i32(t0
);
1656 static void spr_write_eplc(DisasContext
*ctx
, int sprn
, int gprn
)
1658 gen_helper_booke_set_eplc(cpu_env
, cpu_gpr
[gprn
]);
1660 static void spr_write_epsc(DisasContext
*ctx
, int sprn
, int gprn
)
1662 gen_helper_booke_set_epsc(cpu_env
, cpu_gpr
[gprn
]);
1667 static void gen_spr_usprg3(CPUPPCState
*env
)
1669 spr_register(env
, SPR_USPRG3
, "USPRG3",
1670 &spr_read_ureg
, SPR_NOACCESS
,
1671 &spr_read_ureg
, SPR_NOACCESS
,
1675 static void gen_spr_usprgh(CPUPPCState
*env
)
1677 spr_register(env
, SPR_USPRG4
, "USPRG4",
1678 &spr_read_ureg
, SPR_NOACCESS
,
1679 &spr_read_ureg
, SPR_NOACCESS
,
1681 spr_register(env
, SPR_USPRG5
, "USPRG5",
1682 &spr_read_ureg
, SPR_NOACCESS
,
1683 &spr_read_ureg
, SPR_NOACCESS
,
1685 spr_register(env
, SPR_USPRG6
, "USPRG6",
1686 &spr_read_ureg
, SPR_NOACCESS
,
1687 &spr_read_ureg
, SPR_NOACCESS
,
1689 spr_register(env
, SPR_USPRG7
, "USPRG7",
1690 &spr_read_ureg
, SPR_NOACCESS
,
1691 &spr_read_ureg
, SPR_NOACCESS
,
1695 /* PowerPC BookE SPR */
1696 static void gen_spr_BookE(CPUPPCState
*env
, uint64_t ivor_mask
)
1698 const char *ivor_names
[64] = {
1699 "IVOR0", "IVOR1", "IVOR2", "IVOR3",
1700 "IVOR4", "IVOR5", "IVOR6", "IVOR7",
1701 "IVOR8", "IVOR9", "IVOR10", "IVOR11",
1702 "IVOR12", "IVOR13", "IVOR14", "IVOR15",
1703 "IVOR16", "IVOR17", "IVOR18", "IVOR19",
1704 "IVOR20", "IVOR21", "IVOR22", "IVOR23",
1705 "IVOR24", "IVOR25", "IVOR26", "IVOR27",
1706 "IVOR28", "IVOR29", "IVOR30", "IVOR31",
1707 "IVOR32", "IVOR33", "IVOR34", "IVOR35",
1708 "IVOR36", "IVOR37", "IVOR38", "IVOR39",
1709 "IVOR40", "IVOR41", "IVOR42", "IVOR43",
1710 "IVOR44", "IVOR45", "IVOR46", "IVOR47",
1711 "IVOR48", "IVOR49", "IVOR50", "IVOR51",
1712 "IVOR52", "IVOR53", "IVOR54", "IVOR55",
1713 "IVOR56", "IVOR57", "IVOR58", "IVOR59",
1714 "IVOR60", "IVOR61", "IVOR62", "IVOR63",
1716 #define SPR_BOOKE_IVORxx (-1)
1717 int ivor_sprn
[64] = {
1718 SPR_BOOKE_IVOR0
, SPR_BOOKE_IVOR1
, SPR_BOOKE_IVOR2
, SPR_BOOKE_IVOR3
,
1719 SPR_BOOKE_IVOR4
, SPR_BOOKE_IVOR5
, SPR_BOOKE_IVOR6
, SPR_BOOKE_IVOR7
,
1720 SPR_BOOKE_IVOR8
, SPR_BOOKE_IVOR9
, SPR_BOOKE_IVOR10
, SPR_BOOKE_IVOR11
,
1721 SPR_BOOKE_IVOR12
, SPR_BOOKE_IVOR13
, SPR_BOOKE_IVOR14
, SPR_BOOKE_IVOR15
,
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
,
1724 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1725 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1726 SPR_BOOKE_IVOR32
, SPR_BOOKE_IVOR33
, SPR_BOOKE_IVOR34
, SPR_BOOKE_IVOR35
,
1727 SPR_BOOKE_IVOR36
, SPR_BOOKE_IVOR37
, SPR_BOOKE_IVOR38
, SPR_BOOKE_IVOR39
,
1728 SPR_BOOKE_IVOR40
, SPR_BOOKE_IVOR41
, SPR_BOOKE_IVOR42
, SPR_BOOKE_IVORxx
,
1729 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1730 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1731 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1732 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1733 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1737 /* Interrupt processing */
1738 spr_register(env
, SPR_BOOKE_CSRR0
, "CSRR0",
1739 SPR_NOACCESS
, SPR_NOACCESS
,
1740 &spr_read_generic
, &spr_write_generic
,
1742 spr_register(env
, SPR_BOOKE_CSRR1
, "CSRR1",
1743 SPR_NOACCESS
, SPR_NOACCESS
,
1744 &spr_read_generic
, &spr_write_generic
,
1747 /* XXX : not implemented */
1748 spr_register(env
, SPR_BOOKE_IAC1
, "IAC1",
1749 SPR_NOACCESS
, SPR_NOACCESS
,
1750 &spr_read_generic
, &spr_write_generic
,
1752 /* XXX : not implemented */
1753 spr_register(env
, SPR_BOOKE_IAC2
, "IAC2",
1754 SPR_NOACCESS
, SPR_NOACCESS
,
1755 &spr_read_generic
, &spr_write_generic
,
1757 /* XXX : not implemented */
1758 spr_register(env
, SPR_BOOKE_DAC1
, "DAC1",
1759 SPR_NOACCESS
, SPR_NOACCESS
,
1760 &spr_read_generic
, &spr_write_generic
,
1762 /* XXX : not implemented */
1763 spr_register(env
, SPR_BOOKE_DAC2
, "DAC2",
1764 SPR_NOACCESS
, SPR_NOACCESS
,
1765 &spr_read_generic
, &spr_write_generic
,
1767 /* XXX : not implemented */
1768 spr_register(env
, SPR_BOOKE_DBCR0
, "DBCR0",
1769 SPR_NOACCESS
, SPR_NOACCESS
,
1770 &spr_read_generic
, &spr_write_40x_dbcr0
,
1772 /* XXX : not implemented */
1773 spr_register(env
, SPR_BOOKE_DBCR1
, "DBCR1",
1774 SPR_NOACCESS
, SPR_NOACCESS
,
1775 &spr_read_generic
, &spr_write_generic
,
1777 /* XXX : not implemented */
1778 spr_register(env
, SPR_BOOKE_DBCR2
, "DBCR2",
1779 SPR_NOACCESS
, SPR_NOACCESS
,
1780 &spr_read_generic
, &spr_write_generic
,
1782 spr_register(env
, SPR_BOOKE_DSRR0
, "DSRR0",
1783 SPR_NOACCESS
, SPR_NOACCESS
,
1784 &spr_read_generic
, &spr_write_generic
,
1786 spr_register(env
, SPR_BOOKE_DSRR1
, "DSRR1",
1787 SPR_NOACCESS
, SPR_NOACCESS
,
1788 &spr_read_generic
, &spr_write_generic
,
1790 /* XXX : not implemented */
1791 spr_register(env
, SPR_BOOKE_DBSR
, "DBSR",
1792 SPR_NOACCESS
, SPR_NOACCESS
,
1793 &spr_read_generic
, &spr_write_clear
,
1795 spr_register(env
, SPR_BOOKE_DEAR
, "DEAR",
1796 SPR_NOACCESS
, SPR_NOACCESS
,
1797 &spr_read_generic
, &spr_write_generic
,
1799 spr_register(env
, SPR_BOOKE_ESR
, "ESR",
1800 SPR_NOACCESS
, SPR_NOACCESS
,
1801 &spr_read_generic
, &spr_write_generic
,
1803 spr_register(env
, SPR_BOOKE_IVPR
, "IVPR",
1804 SPR_NOACCESS
, SPR_NOACCESS
,
1805 &spr_read_generic
, &spr_write_excp_prefix
,
1807 /* Exception vectors */
1808 for (i
= 0; i
< 64; i
++) {
1809 if (ivor_mask
& (1ULL << i
)) {
1810 if (ivor_sprn
[i
] == SPR_BOOKE_IVORxx
) {
1811 fprintf(stderr
, "ERROR: IVOR %d SPR is not defined\n", i
);
1814 spr_register(env
, ivor_sprn
[i
], ivor_names
[i
],
1815 SPR_NOACCESS
, SPR_NOACCESS
,
1816 &spr_read_generic
, &spr_write_excp_vector
,
1820 spr_register(env
, SPR_BOOKE_PID
, "PID",
1821 SPR_NOACCESS
, SPR_NOACCESS
,
1822 &spr_read_generic
, &spr_write_booke_pid
,
1824 spr_register(env
, SPR_BOOKE_TCR
, "TCR",
1825 SPR_NOACCESS
, SPR_NOACCESS
,
1826 &spr_read_generic
, &spr_write_booke_tcr
,
1828 spr_register(env
, SPR_BOOKE_TSR
, "TSR",
1829 SPR_NOACCESS
, SPR_NOACCESS
,
1830 &spr_read_generic
, &spr_write_booke_tsr
,
1833 spr_register(env
, SPR_DECR
, "DECR",
1834 SPR_NOACCESS
, SPR_NOACCESS
,
1835 &spr_read_decr
, &spr_write_decr
,
1837 spr_register(env
, SPR_BOOKE_DECAR
, "DECAR",
1838 SPR_NOACCESS
, SPR_NOACCESS
,
1839 SPR_NOACCESS
, &spr_write_generic
,
1842 spr_register(env
, SPR_USPRG0
, "USPRG0",
1843 &spr_read_generic
, &spr_write_generic
,
1844 &spr_read_generic
, &spr_write_generic
,
1846 spr_register(env
, SPR_SPRG4
, "SPRG4",
1847 SPR_NOACCESS
, SPR_NOACCESS
,
1848 &spr_read_generic
, &spr_write_generic
,
1850 spr_register(env
, SPR_SPRG5
, "SPRG5",
1851 SPR_NOACCESS
, SPR_NOACCESS
,
1852 &spr_read_generic
, &spr_write_generic
,
1854 spr_register(env
, SPR_SPRG6
, "SPRG6",
1855 SPR_NOACCESS
, SPR_NOACCESS
,
1856 &spr_read_generic
, &spr_write_generic
,
1858 spr_register(env
, SPR_SPRG7
, "SPRG7",
1859 SPR_NOACCESS
, SPR_NOACCESS
,
1860 &spr_read_generic
, &spr_write_generic
,
1862 spr_register(env
, SPR_BOOKE_SPRG8
, "SPRG8",
1863 SPR_NOACCESS
, SPR_NOACCESS
,
1864 &spr_read_generic
, &spr_write_generic
,
1866 spr_register(env
, SPR_BOOKE_SPRG9
, "SPRG9",
1867 SPR_NOACCESS
, SPR_NOACCESS
,
1868 &spr_read_generic
, &spr_write_generic
,
1872 static inline uint32_t gen_tlbncfg(uint32_t assoc
, uint32_t minsize
,
1873 uint32_t maxsize
, uint32_t flags
,
1876 return (assoc
<< TLBnCFG_ASSOC_SHIFT
) |
1877 (minsize
<< TLBnCFG_MINSIZE_SHIFT
) |
1878 (maxsize
<< TLBnCFG_MAXSIZE_SHIFT
) |
1882 /* BookE 2.06 storage control registers */
1883 static void gen_spr_BookE206(CPUPPCState
*env
, uint32_t mas_mask
,
1884 uint32_t *tlbncfg
, uint32_t mmucfg
)
1886 #if !defined(CONFIG_USER_ONLY)
1887 const char *mas_names
[8] = {
1888 "MAS0", "MAS1", "MAS2", "MAS3", "MAS4", "MAS5", "MAS6", "MAS7",
1891 SPR_BOOKE_MAS0
, SPR_BOOKE_MAS1
, SPR_BOOKE_MAS2
, SPR_BOOKE_MAS3
,
1892 SPR_BOOKE_MAS4
, SPR_BOOKE_MAS5
, SPR_BOOKE_MAS6
, SPR_BOOKE_MAS7
,
1896 /* TLB assist registers */
1897 /* XXX : not implemented */
1898 for (i
= 0; i
< 8; i
++) {
1899 void (*uea_write
)(DisasContext
*ctx
, int sprn
, int gprn
) = &spr_write_generic32
;
1900 if (i
== 2 && (mas_mask
& (1 << i
)) && (env
->insns_flags
& PPC_64B
)) {
1901 uea_write
= &spr_write_generic
;
1903 if (mas_mask
& (1 << i
)) {
1904 spr_register(env
, mas_sprn
[i
], mas_names
[i
],
1905 SPR_NOACCESS
, SPR_NOACCESS
,
1906 &spr_read_generic
, uea_write
,
1910 if (env
->nb_pids
> 1) {
1911 /* XXX : not implemented */
1912 spr_register(env
, SPR_BOOKE_PID1
, "PID1",
1913 SPR_NOACCESS
, SPR_NOACCESS
,
1914 &spr_read_generic
, &spr_write_booke_pid
,
1917 if (env
->nb_pids
> 2) {
1918 /* XXX : not implemented */
1919 spr_register(env
, SPR_BOOKE_PID2
, "PID2",
1920 SPR_NOACCESS
, SPR_NOACCESS
,
1921 &spr_read_generic
, &spr_write_booke_pid
,
1925 spr_register(env
, SPR_BOOKE_EPLC
, "EPLC",
1926 SPR_NOACCESS
, SPR_NOACCESS
,
1927 &spr_read_generic
, &spr_write_eplc
,
1929 spr_register(env
, SPR_BOOKE_EPSC
, "EPSC",
1930 SPR_NOACCESS
, SPR_NOACCESS
,
1931 &spr_read_generic
, &spr_write_epsc
,
1934 /* XXX : not implemented */
1935 spr_register(env
, SPR_MMUCFG
, "MMUCFG",
1936 SPR_NOACCESS
, SPR_NOACCESS
,
1937 &spr_read_generic
, SPR_NOACCESS
,
1939 switch (env
->nb_ways
) {
1941 spr_register(env
, SPR_BOOKE_TLB3CFG
, "TLB3CFG",
1942 SPR_NOACCESS
, SPR_NOACCESS
,
1943 &spr_read_generic
, SPR_NOACCESS
,
1947 spr_register(env
, SPR_BOOKE_TLB2CFG
, "TLB2CFG",
1948 SPR_NOACCESS
, SPR_NOACCESS
,
1949 &spr_read_generic
, SPR_NOACCESS
,
1953 spr_register(env
, SPR_BOOKE_TLB1CFG
, "TLB1CFG",
1954 SPR_NOACCESS
, SPR_NOACCESS
,
1955 &spr_read_generic
, SPR_NOACCESS
,
1959 spr_register(env
, SPR_BOOKE_TLB0CFG
, "TLB0CFG",
1960 SPR_NOACCESS
, SPR_NOACCESS
,
1961 &spr_read_generic
, SPR_NOACCESS
,
1970 gen_spr_usprgh(env
);
1973 /* SPR specific to PowerPC 440 implementation */
1974 static void gen_spr_440(CPUPPCState
*env
)
1977 /* XXX : not implemented */
1978 spr_register(env
, SPR_440_DNV0
, "DNV0",
1979 SPR_NOACCESS
, SPR_NOACCESS
,
1980 &spr_read_generic
, &spr_write_generic
,
1982 /* XXX : not implemented */
1983 spr_register(env
, SPR_440_DNV1
, "DNV1",
1984 SPR_NOACCESS
, SPR_NOACCESS
,
1985 &spr_read_generic
, &spr_write_generic
,
1987 /* XXX : not implemented */
1988 spr_register(env
, SPR_440_DNV2
, "DNV2",
1989 SPR_NOACCESS
, SPR_NOACCESS
,
1990 &spr_read_generic
, &spr_write_generic
,
1992 /* XXX : not implemented */
1993 spr_register(env
, SPR_440_DNV3
, "DNV3",
1994 SPR_NOACCESS
, SPR_NOACCESS
,
1995 &spr_read_generic
, &spr_write_generic
,
1997 /* XXX : not implemented */
1998 spr_register(env
, SPR_440_DTV0
, "DTV0",
1999 SPR_NOACCESS
, SPR_NOACCESS
,
2000 &spr_read_generic
, &spr_write_generic
,
2002 /* XXX : not implemented */
2003 spr_register(env
, SPR_440_DTV1
, "DTV1",
2004 SPR_NOACCESS
, SPR_NOACCESS
,
2005 &spr_read_generic
, &spr_write_generic
,
2007 /* XXX : not implemented */
2008 spr_register(env
, SPR_440_DTV2
, "DTV2",
2009 SPR_NOACCESS
, SPR_NOACCESS
,
2010 &spr_read_generic
, &spr_write_generic
,
2012 /* XXX : not implemented */
2013 spr_register(env
, SPR_440_DTV3
, "DTV3",
2014 SPR_NOACCESS
, SPR_NOACCESS
,
2015 &spr_read_generic
, &spr_write_generic
,
2017 /* XXX : not implemented */
2018 spr_register(env
, SPR_440_DVLIM
, "DVLIM",
2019 SPR_NOACCESS
, SPR_NOACCESS
,
2020 &spr_read_generic
, &spr_write_generic
,
2022 /* XXX : not implemented */
2023 spr_register(env
, SPR_440_INV0
, "INV0",
2024 SPR_NOACCESS
, SPR_NOACCESS
,
2025 &spr_read_generic
, &spr_write_generic
,
2027 /* XXX : not implemented */
2028 spr_register(env
, SPR_440_INV1
, "INV1",
2029 SPR_NOACCESS
, SPR_NOACCESS
,
2030 &spr_read_generic
, &spr_write_generic
,
2032 /* XXX : not implemented */
2033 spr_register(env
, SPR_440_INV2
, "INV2",
2034 SPR_NOACCESS
, SPR_NOACCESS
,
2035 &spr_read_generic
, &spr_write_generic
,
2037 /* XXX : not implemented */
2038 spr_register(env
, SPR_440_INV3
, "INV3",
2039 SPR_NOACCESS
, SPR_NOACCESS
,
2040 &spr_read_generic
, &spr_write_generic
,
2042 /* XXX : not implemented */
2043 spr_register(env
, SPR_440_ITV0
, "ITV0",
2044 SPR_NOACCESS
, SPR_NOACCESS
,
2045 &spr_read_generic
, &spr_write_generic
,
2047 /* XXX : not implemented */
2048 spr_register(env
, SPR_440_ITV1
, "ITV1",
2049 SPR_NOACCESS
, SPR_NOACCESS
,
2050 &spr_read_generic
, &spr_write_generic
,
2052 /* XXX : not implemented */
2053 spr_register(env
, SPR_440_ITV2
, "ITV2",
2054 SPR_NOACCESS
, SPR_NOACCESS
,
2055 &spr_read_generic
, &spr_write_generic
,
2057 /* XXX : not implemented */
2058 spr_register(env
, SPR_440_ITV3
, "ITV3",
2059 SPR_NOACCESS
, SPR_NOACCESS
,
2060 &spr_read_generic
, &spr_write_generic
,
2062 /* XXX : not implemented */
2063 spr_register(env
, SPR_440_IVLIM
, "IVLIM",
2064 SPR_NOACCESS
, SPR_NOACCESS
,
2065 &spr_read_generic
, &spr_write_generic
,
2068 /* XXX : not implemented */
2069 spr_register(env
, SPR_BOOKE_DCDBTRH
, "DCDBTRH",
2070 SPR_NOACCESS
, SPR_NOACCESS
,
2071 &spr_read_generic
, SPR_NOACCESS
,
2073 /* XXX : not implemented */
2074 spr_register(env
, SPR_BOOKE_DCDBTRL
, "DCDBTRL",
2075 SPR_NOACCESS
, SPR_NOACCESS
,
2076 &spr_read_generic
, SPR_NOACCESS
,
2078 /* XXX : not implemented */
2079 spr_register(env
, SPR_BOOKE_ICDBDR
, "ICDBDR",
2080 SPR_NOACCESS
, SPR_NOACCESS
,
2081 &spr_read_generic
, SPR_NOACCESS
,
2083 /* XXX : not implemented */
2084 spr_register(env
, SPR_BOOKE_ICDBTRH
, "ICDBTRH",
2085 SPR_NOACCESS
, SPR_NOACCESS
,
2086 &spr_read_generic
, SPR_NOACCESS
,
2088 /* XXX : not implemented */
2089 spr_register(env
, SPR_BOOKE_ICDBTRL
, "ICDBTRL",
2090 SPR_NOACCESS
, SPR_NOACCESS
,
2091 &spr_read_generic
, SPR_NOACCESS
,
2093 /* XXX : not implemented */
2094 spr_register(env
, SPR_440_DBDR
, "DBDR",
2095 SPR_NOACCESS
, SPR_NOACCESS
,
2096 &spr_read_generic
, &spr_write_generic
,
2098 /* Processor control */
2099 spr_register(env
, SPR_4xx_CCR0
, "CCR0",
2100 SPR_NOACCESS
, SPR_NOACCESS
,
2101 &spr_read_generic
, &spr_write_generic
,
2103 spr_register(env
, SPR_440_RSTCFG
, "RSTCFG",
2104 SPR_NOACCESS
, SPR_NOACCESS
,
2105 &spr_read_generic
, SPR_NOACCESS
,
2107 /* Storage control */
2108 spr_register(env
, SPR_440_MMUCR
, "MMUCR",
2109 SPR_NOACCESS
, SPR_NOACCESS
,
2110 &spr_read_generic
, &spr_write_generic
,
2114 /* SPR shared between PowerPC 40x implementations */
2115 static void gen_spr_40x(CPUPPCState
*env
)
2118 /* not emulated, as QEMU do not emulate caches */
2119 spr_register(env
, SPR_40x_DCCR
, "DCCR",
2120 SPR_NOACCESS
, SPR_NOACCESS
,
2121 &spr_read_generic
, &spr_write_generic
,
2123 /* not emulated, as QEMU do not emulate caches */
2124 spr_register(env
, SPR_40x_ICCR
, "ICCR",
2125 SPR_NOACCESS
, SPR_NOACCESS
,
2126 &spr_read_generic
, &spr_write_generic
,
2128 /* not emulated, as QEMU do not emulate caches */
2129 spr_register(env
, SPR_BOOKE_ICDBDR
, "ICDBDR",
2130 SPR_NOACCESS
, SPR_NOACCESS
,
2131 &spr_read_generic
, SPR_NOACCESS
,
2134 spr_register(env
, SPR_40x_DEAR
, "DEAR",
2135 SPR_NOACCESS
, SPR_NOACCESS
,
2136 &spr_read_generic
, &spr_write_generic
,
2138 spr_register(env
, SPR_40x_ESR
, "ESR",
2139 SPR_NOACCESS
, SPR_NOACCESS
,
2140 &spr_read_generic
, &spr_write_generic
,
2142 spr_register(env
, SPR_40x_EVPR
, "EVPR",
2143 SPR_NOACCESS
, SPR_NOACCESS
,
2144 &spr_read_generic
, &spr_write_excp_prefix
,
2146 spr_register(env
, SPR_40x_SRR2
, "SRR2",
2147 &spr_read_generic
, &spr_write_generic
,
2148 &spr_read_generic
, &spr_write_generic
,
2150 spr_register(env
, SPR_40x_SRR3
, "SRR3",
2151 &spr_read_generic
, &spr_write_generic
,
2152 &spr_read_generic
, &spr_write_generic
,
2155 spr_register(env
, SPR_40x_PIT
, "PIT",
2156 SPR_NOACCESS
, SPR_NOACCESS
,
2157 &spr_read_40x_pit
, &spr_write_40x_pit
,
2159 spr_register(env
, SPR_40x_TCR
, "TCR",
2160 SPR_NOACCESS
, SPR_NOACCESS
,
2161 &spr_read_generic
, &spr_write_booke_tcr
,
2163 spr_register(env
, SPR_40x_TSR
, "TSR",
2164 SPR_NOACCESS
, SPR_NOACCESS
,
2165 &spr_read_generic
, &spr_write_booke_tsr
,
2169 /* SPR specific to PowerPC 405 implementation */
2170 static void gen_spr_405(CPUPPCState
*env
)
2173 spr_register(env
, SPR_40x_PID
, "PID",
2174 SPR_NOACCESS
, SPR_NOACCESS
,
2175 &spr_read_generic
, &spr_write_generic
,
2177 spr_register(env
, SPR_4xx_CCR0
, "CCR0",
2178 SPR_NOACCESS
, SPR_NOACCESS
,
2179 &spr_read_generic
, &spr_write_generic
,
2181 /* Debug interface */
2182 /* XXX : not implemented */
2183 spr_register(env
, SPR_40x_DBCR0
, "DBCR0",
2184 SPR_NOACCESS
, SPR_NOACCESS
,
2185 &spr_read_generic
, &spr_write_40x_dbcr0
,
2187 /* XXX : not implemented */
2188 spr_register(env
, SPR_405_DBCR1
, "DBCR1",
2189 SPR_NOACCESS
, SPR_NOACCESS
,
2190 &spr_read_generic
, &spr_write_generic
,
2192 /* XXX : not implemented */
2193 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2194 SPR_NOACCESS
, SPR_NOACCESS
,
2195 &spr_read_generic
, &spr_write_clear
,
2196 /* Last reset was system reset */
2198 /* XXX : not implemented */
2199 spr_register(env
, SPR_40x_DAC1
, "DAC1",
2200 SPR_NOACCESS
, SPR_NOACCESS
,
2201 &spr_read_generic
, &spr_write_generic
,
2203 spr_register(env
, SPR_40x_DAC2
, "DAC2",
2204 SPR_NOACCESS
, SPR_NOACCESS
,
2205 &spr_read_generic
, &spr_write_generic
,
2207 /* XXX : not implemented */
2208 spr_register(env
, SPR_405_DVC1
, "DVC1",
2209 SPR_NOACCESS
, SPR_NOACCESS
,
2210 &spr_read_generic
, &spr_write_generic
,
2212 /* XXX : not implemented */
2213 spr_register(env
, SPR_405_DVC2
, "DVC2",
2214 SPR_NOACCESS
, SPR_NOACCESS
,
2215 &spr_read_generic
, &spr_write_generic
,
2217 /* XXX : not implemented */
2218 spr_register(env
, SPR_40x_IAC1
, "IAC1",
2219 SPR_NOACCESS
, SPR_NOACCESS
,
2220 &spr_read_generic
, &spr_write_generic
,
2222 spr_register(env
, SPR_40x_IAC2
, "IAC2",
2223 SPR_NOACCESS
, SPR_NOACCESS
,
2224 &spr_read_generic
, &spr_write_generic
,
2226 /* XXX : not implemented */
2227 spr_register(env
, SPR_405_IAC3
, "IAC3",
2228 SPR_NOACCESS
, SPR_NOACCESS
,
2229 &spr_read_generic
, &spr_write_generic
,
2231 /* XXX : not implemented */
2232 spr_register(env
, SPR_405_IAC4
, "IAC4",
2233 SPR_NOACCESS
, SPR_NOACCESS
,
2234 &spr_read_generic
, &spr_write_generic
,
2236 /* Storage control */
2237 /* XXX: TODO: not implemented */
2238 spr_register(env
, SPR_405_SLER
, "SLER",
2239 SPR_NOACCESS
, SPR_NOACCESS
,
2240 &spr_read_generic
, &spr_write_40x_sler
,
2242 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2243 SPR_NOACCESS
, SPR_NOACCESS
,
2244 &spr_read_generic
, &spr_write_generic
,
2246 /* XXX : not implemented */
2247 spr_register(env
, SPR_405_SU0R
, "SU0R",
2248 SPR_NOACCESS
, SPR_NOACCESS
,
2249 &spr_read_generic
, &spr_write_generic
,
2252 spr_register(env
, SPR_USPRG0
, "USPRG0",
2253 &spr_read_ureg
, SPR_NOACCESS
,
2254 &spr_read_ureg
, SPR_NOACCESS
,
2256 spr_register(env
, SPR_SPRG4
, "SPRG4",
2257 SPR_NOACCESS
, SPR_NOACCESS
,
2258 &spr_read_generic
, &spr_write_generic
,
2260 spr_register(env
, SPR_SPRG5
, "SPRG5",
2261 SPR_NOACCESS
, SPR_NOACCESS
,
2262 spr_read_generic
, &spr_write_generic
,
2264 spr_register(env
, SPR_SPRG6
, "SPRG6",
2265 SPR_NOACCESS
, SPR_NOACCESS
,
2266 spr_read_generic
, &spr_write_generic
,
2268 spr_register(env
, SPR_SPRG7
, "SPRG7",
2269 SPR_NOACCESS
, SPR_NOACCESS
,
2270 spr_read_generic
, &spr_write_generic
,
2272 gen_spr_usprgh(env
);
2275 /* SPR shared between PowerPC 401 & 403 implementations */
2276 static void gen_spr_401_403(CPUPPCState
*env
)
2279 spr_register(env
, SPR_403_VTBL
, "TBL",
2280 &spr_read_tbl
, SPR_NOACCESS
,
2281 &spr_read_tbl
, SPR_NOACCESS
,
2283 spr_register(env
, SPR_403_TBL
, "TBL",
2284 SPR_NOACCESS
, SPR_NOACCESS
,
2285 SPR_NOACCESS
, &spr_write_tbl
,
2287 spr_register(env
, SPR_403_VTBU
, "TBU",
2288 &spr_read_tbu
, SPR_NOACCESS
,
2289 &spr_read_tbu
, SPR_NOACCESS
,
2291 spr_register(env
, SPR_403_TBU
, "TBU",
2292 SPR_NOACCESS
, SPR_NOACCESS
,
2293 SPR_NOACCESS
, &spr_write_tbu
,
2296 /* not emulated, as QEMU do not emulate caches */
2297 spr_register(env
, SPR_403_CDBCR
, "CDBCR",
2298 SPR_NOACCESS
, SPR_NOACCESS
,
2299 &spr_read_generic
, &spr_write_generic
,
2303 /* SPR specific to PowerPC 401 implementation */
2304 static void gen_spr_401(CPUPPCState
*env
)
2306 /* Debug interface */
2307 /* XXX : not implemented */
2308 spr_register(env
, SPR_40x_DBCR0
, "DBCR",
2309 SPR_NOACCESS
, SPR_NOACCESS
,
2310 &spr_read_generic
, &spr_write_40x_dbcr0
,
2312 /* XXX : not implemented */
2313 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2314 SPR_NOACCESS
, SPR_NOACCESS
,
2315 &spr_read_generic
, &spr_write_clear
,
2316 /* Last reset was system reset */
2318 /* XXX : not implemented */
2319 spr_register(env
, SPR_40x_DAC1
, "DAC",
2320 SPR_NOACCESS
, SPR_NOACCESS
,
2321 &spr_read_generic
, &spr_write_generic
,
2323 /* XXX : not implemented */
2324 spr_register(env
, SPR_40x_IAC1
, "IAC",
2325 SPR_NOACCESS
, SPR_NOACCESS
,
2326 &spr_read_generic
, &spr_write_generic
,
2328 /* Storage control */
2329 /* XXX: TODO: not implemented */
2330 spr_register(env
, SPR_405_SLER
, "SLER",
2331 SPR_NOACCESS
, SPR_NOACCESS
,
2332 &spr_read_generic
, &spr_write_40x_sler
,
2334 /* not emulated, as QEMU never does speculative access */
2335 spr_register(env
, SPR_40x_SGR
, "SGR",
2336 SPR_NOACCESS
, SPR_NOACCESS
,
2337 &spr_read_generic
, &spr_write_generic
,
2339 /* not emulated, as QEMU do not emulate caches */
2340 spr_register(env
, SPR_40x_DCWR
, "DCWR",
2341 SPR_NOACCESS
, SPR_NOACCESS
,
2342 &spr_read_generic
, &spr_write_generic
,
2346 static void gen_spr_401x2(CPUPPCState
*env
)
2349 spr_register(env
, SPR_40x_PID
, "PID",
2350 SPR_NOACCESS
, SPR_NOACCESS
,
2351 &spr_read_generic
, &spr_write_generic
,
2353 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2354 SPR_NOACCESS
, SPR_NOACCESS
,
2355 &spr_read_generic
, &spr_write_generic
,
2359 /* SPR specific to PowerPC 403 implementation */
2360 static void gen_spr_403(CPUPPCState
*env
)
2362 /* Debug interface */
2363 /* XXX : not implemented */
2364 spr_register(env
, SPR_40x_DBCR0
, "DBCR0",
2365 SPR_NOACCESS
, SPR_NOACCESS
,
2366 &spr_read_generic
, &spr_write_40x_dbcr0
,
2368 /* XXX : not implemented */
2369 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2370 SPR_NOACCESS
, SPR_NOACCESS
,
2371 &spr_read_generic
, &spr_write_clear
,
2372 /* Last reset was system reset */
2374 /* XXX : not implemented */
2375 spr_register(env
, SPR_40x_DAC1
, "DAC1",
2376 SPR_NOACCESS
, SPR_NOACCESS
,
2377 &spr_read_generic
, &spr_write_generic
,
2379 /* XXX : not implemented */
2380 spr_register(env
, SPR_40x_DAC2
, "DAC2",
2381 SPR_NOACCESS
, SPR_NOACCESS
,
2382 &spr_read_generic
, &spr_write_generic
,
2384 /* XXX : not implemented */
2385 spr_register(env
, SPR_40x_IAC1
, "IAC1",
2386 SPR_NOACCESS
, SPR_NOACCESS
,
2387 &spr_read_generic
, &spr_write_generic
,
2389 /* XXX : not implemented */
2390 spr_register(env
, SPR_40x_IAC2
, "IAC2",
2391 SPR_NOACCESS
, SPR_NOACCESS
,
2392 &spr_read_generic
, &spr_write_generic
,
2396 static void gen_spr_403_real(CPUPPCState
*env
)
2398 spr_register(env
, SPR_403_PBL1
, "PBL1",
2399 SPR_NOACCESS
, SPR_NOACCESS
,
2400 &spr_read_403_pbr
, &spr_write_403_pbr
,
2402 spr_register(env
, SPR_403_PBU1
, "PBU1",
2403 SPR_NOACCESS
, SPR_NOACCESS
,
2404 &spr_read_403_pbr
, &spr_write_403_pbr
,
2406 spr_register(env
, SPR_403_PBL2
, "PBL2",
2407 SPR_NOACCESS
, SPR_NOACCESS
,
2408 &spr_read_403_pbr
, &spr_write_403_pbr
,
2410 spr_register(env
, SPR_403_PBU2
, "PBU2",
2411 SPR_NOACCESS
, SPR_NOACCESS
,
2412 &spr_read_403_pbr
, &spr_write_403_pbr
,
2416 static void gen_spr_403_mmu(CPUPPCState
*env
)
2419 spr_register(env
, SPR_40x_PID
, "PID",
2420 SPR_NOACCESS
, SPR_NOACCESS
,
2421 &spr_read_generic
, &spr_write_generic
,
2423 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2424 SPR_NOACCESS
, SPR_NOACCESS
,
2425 &spr_read_generic
, &spr_write_generic
,
2429 /* SPR specific to PowerPC compression coprocessor extension */
2430 static void gen_spr_compress(CPUPPCState
*env
)
2432 /* XXX : not implemented */
2433 spr_register(env
, SPR_401_SKR
, "SKR",
2434 SPR_NOACCESS
, SPR_NOACCESS
,
2435 &spr_read_generic
, &spr_write_generic
,
2439 static void gen_spr_5xx_8xx(CPUPPCState
*env
)
2441 /* Exception processing */
2442 spr_register_kvm(env
, SPR_DSISR
, "DSISR",
2443 SPR_NOACCESS
, SPR_NOACCESS
,
2444 &spr_read_generic
, &spr_write_generic
,
2445 KVM_REG_PPC_DSISR
, 0x00000000);
2446 spr_register_kvm(env
, SPR_DAR
, "DAR",
2447 SPR_NOACCESS
, SPR_NOACCESS
,
2448 &spr_read_generic
, &spr_write_generic
,
2449 KVM_REG_PPC_DAR
, 0x00000000);
2451 spr_register(env
, SPR_DECR
, "DECR",
2452 SPR_NOACCESS
, SPR_NOACCESS
,
2453 &spr_read_decr
, &spr_write_decr
,
2455 /* XXX : not implemented */
2456 spr_register(env
, SPR_MPC_EIE
, "EIE",
2457 SPR_NOACCESS
, SPR_NOACCESS
,
2458 &spr_read_generic
, &spr_write_generic
,
2460 /* XXX : not implemented */
2461 spr_register(env
, SPR_MPC_EID
, "EID",
2462 SPR_NOACCESS
, SPR_NOACCESS
,
2463 &spr_read_generic
, &spr_write_generic
,
2465 /* XXX : not implemented */
2466 spr_register(env
, SPR_MPC_NRI
, "NRI",
2467 SPR_NOACCESS
, SPR_NOACCESS
,
2468 &spr_read_generic
, &spr_write_generic
,
2470 /* XXX : not implemented */
2471 spr_register(env
, SPR_MPC_CMPA
, "CMPA",
2472 SPR_NOACCESS
, SPR_NOACCESS
,
2473 &spr_read_generic
, &spr_write_generic
,
2475 /* XXX : not implemented */
2476 spr_register(env
, SPR_MPC_CMPB
, "CMPB",
2477 SPR_NOACCESS
, SPR_NOACCESS
,
2478 &spr_read_generic
, &spr_write_generic
,
2480 /* XXX : not implemented */
2481 spr_register(env
, SPR_MPC_CMPC
, "CMPC",
2482 SPR_NOACCESS
, SPR_NOACCESS
,
2483 &spr_read_generic
, &spr_write_generic
,
2485 /* XXX : not implemented */
2486 spr_register(env
, SPR_MPC_CMPD
, "CMPD",
2487 SPR_NOACCESS
, SPR_NOACCESS
,
2488 &spr_read_generic
, &spr_write_generic
,
2490 /* XXX : not implemented */
2491 spr_register(env
, SPR_MPC_ECR
, "ECR",
2492 SPR_NOACCESS
, SPR_NOACCESS
,
2493 &spr_read_generic
, &spr_write_generic
,
2495 /* XXX : not implemented */
2496 spr_register(env
, SPR_MPC_DER
, "DER",
2497 SPR_NOACCESS
, SPR_NOACCESS
,
2498 &spr_read_generic
, &spr_write_generic
,
2500 /* XXX : not implemented */
2501 spr_register(env
, SPR_MPC_COUNTA
, "COUNTA",
2502 SPR_NOACCESS
, SPR_NOACCESS
,
2503 &spr_read_generic
, &spr_write_generic
,
2505 /* XXX : not implemented */
2506 spr_register(env
, SPR_MPC_COUNTB
, "COUNTB",
2507 SPR_NOACCESS
, SPR_NOACCESS
,
2508 &spr_read_generic
, &spr_write_generic
,
2510 /* XXX : not implemented */
2511 spr_register(env
, SPR_MPC_CMPE
, "CMPE",
2512 SPR_NOACCESS
, SPR_NOACCESS
,
2513 &spr_read_generic
, &spr_write_generic
,
2515 /* XXX : not implemented */
2516 spr_register(env
, SPR_MPC_CMPF
, "CMPF",
2517 SPR_NOACCESS
, SPR_NOACCESS
,
2518 &spr_read_generic
, &spr_write_generic
,
2520 /* XXX : not implemented */
2521 spr_register(env
, SPR_MPC_CMPG
, "CMPG",
2522 SPR_NOACCESS
, SPR_NOACCESS
,
2523 &spr_read_generic
, &spr_write_generic
,
2525 /* XXX : not implemented */
2526 spr_register(env
, SPR_MPC_CMPH
, "CMPH",
2527 SPR_NOACCESS
, SPR_NOACCESS
,
2528 &spr_read_generic
, &spr_write_generic
,
2530 /* XXX : not implemented */
2531 spr_register(env
, SPR_MPC_LCTRL1
, "LCTRL1",
2532 SPR_NOACCESS
, SPR_NOACCESS
,
2533 &spr_read_generic
, &spr_write_generic
,
2535 /* XXX : not implemented */
2536 spr_register(env
, SPR_MPC_LCTRL2
, "LCTRL2",
2537 SPR_NOACCESS
, SPR_NOACCESS
,
2538 &spr_read_generic
, &spr_write_generic
,
2540 /* XXX : not implemented */
2541 spr_register(env
, SPR_MPC_BAR
, "BAR",
2542 SPR_NOACCESS
, SPR_NOACCESS
,
2543 &spr_read_generic
, &spr_write_generic
,
2545 /* XXX : not implemented */
2546 spr_register(env
, SPR_MPC_DPDR
, "DPDR",
2547 SPR_NOACCESS
, SPR_NOACCESS
,
2548 &spr_read_generic
, &spr_write_generic
,
2550 /* XXX : not implemented */
2551 spr_register(env
, SPR_MPC_IMMR
, "IMMR",
2552 SPR_NOACCESS
, SPR_NOACCESS
,
2553 &spr_read_generic
, &spr_write_generic
,
2557 static void gen_spr_5xx(CPUPPCState
*env
)
2559 /* XXX : not implemented */
2560 spr_register(env
, SPR_RCPU_MI_GRA
, "MI_GRA",
2561 SPR_NOACCESS
, SPR_NOACCESS
,
2562 &spr_read_generic
, &spr_write_generic
,
2564 /* XXX : not implemented */
2565 spr_register(env
, SPR_RCPU_L2U_GRA
, "L2U_GRA",
2566 SPR_NOACCESS
, SPR_NOACCESS
,
2567 &spr_read_generic
, &spr_write_generic
,
2569 /* XXX : not implemented */
2570 spr_register(env
, SPR_RPCU_BBCMCR
, "L2U_BBCMCR",
2571 SPR_NOACCESS
, SPR_NOACCESS
,
2572 &spr_read_generic
, &spr_write_generic
,
2574 /* XXX : not implemented */
2575 spr_register(env
, SPR_RCPU_L2U_MCR
, "L2U_MCR",
2576 SPR_NOACCESS
, SPR_NOACCESS
,
2577 &spr_read_generic
, &spr_write_generic
,
2579 /* XXX : not implemented */
2580 spr_register(env
, SPR_RCPU_MI_RBA0
, "MI_RBA0",
2581 SPR_NOACCESS
, SPR_NOACCESS
,
2582 &spr_read_generic
, &spr_write_generic
,
2584 /* XXX : not implemented */
2585 spr_register(env
, SPR_RCPU_MI_RBA1
, "MI_RBA1",
2586 SPR_NOACCESS
, SPR_NOACCESS
,
2587 &spr_read_generic
, &spr_write_generic
,
2589 /* XXX : not implemented */
2590 spr_register(env
, SPR_RCPU_MI_RBA2
, "MI_RBA2",
2591 SPR_NOACCESS
, SPR_NOACCESS
,
2592 &spr_read_generic
, &spr_write_generic
,
2594 /* XXX : not implemented */
2595 spr_register(env
, SPR_RCPU_MI_RBA3
, "MI_RBA3",
2596 SPR_NOACCESS
, SPR_NOACCESS
,
2597 &spr_read_generic
, &spr_write_generic
,
2599 /* XXX : not implemented */
2600 spr_register(env
, SPR_RCPU_L2U_RBA0
, "L2U_RBA0",
2601 SPR_NOACCESS
, SPR_NOACCESS
,
2602 &spr_read_generic
, &spr_write_generic
,
2604 /* XXX : not implemented */
2605 spr_register(env
, SPR_RCPU_L2U_RBA1
, "L2U_RBA1",
2606 SPR_NOACCESS
, SPR_NOACCESS
,
2607 &spr_read_generic
, &spr_write_generic
,
2609 /* XXX : not implemented */
2610 spr_register(env
, SPR_RCPU_L2U_RBA2
, "L2U_RBA2",
2611 SPR_NOACCESS
, SPR_NOACCESS
,
2612 &spr_read_generic
, &spr_write_generic
,
2614 /* XXX : not implemented */
2615 spr_register(env
, SPR_RCPU_L2U_RBA3
, "L2U_RBA3",
2616 SPR_NOACCESS
, SPR_NOACCESS
,
2617 &spr_read_generic
, &spr_write_generic
,
2619 /* XXX : not implemented */
2620 spr_register(env
, SPR_RCPU_MI_RA0
, "MI_RA0",
2621 SPR_NOACCESS
, SPR_NOACCESS
,
2622 &spr_read_generic
, &spr_write_generic
,
2624 /* XXX : not implemented */
2625 spr_register(env
, SPR_RCPU_MI_RA1
, "MI_RA1",
2626 SPR_NOACCESS
, SPR_NOACCESS
,
2627 &spr_read_generic
, &spr_write_generic
,
2629 /* XXX : not implemented */
2630 spr_register(env
, SPR_RCPU_MI_RA2
, "MI_RA2",
2631 SPR_NOACCESS
, SPR_NOACCESS
,
2632 &spr_read_generic
, &spr_write_generic
,
2634 /* XXX : not implemented */
2635 spr_register(env
, SPR_RCPU_MI_RA3
, "MI_RA3",
2636 SPR_NOACCESS
, SPR_NOACCESS
,
2637 &spr_read_generic
, &spr_write_generic
,
2639 /* XXX : not implemented */
2640 spr_register(env
, SPR_RCPU_L2U_RA0
, "L2U_RA0",
2641 SPR_NOACCESS
, SPR_NOACCESS
,
2642 &spr_read_generic
, &spr_write_generic
,
2644 /* XXX : not implemented */
2645 spr_register(env
, SPR_RCPU_L2U_RA1
, "L2U_RA1",
2646 SPR_NOACCESS
, SPR_NOACCESS
,
2647 &spr_read_generic
, &spr_write_generic
,
2649 /* XXX : not implemented */
2650 spr_register(env
, SPR_RCPU_L2U_RA2
, "L2U_RA2",
2651 SPR_NOACCESS
, SPR_NOACCESS
,
2652 &spr_read_generic
, &spr_write_generic
,
2654 /* XXX : not implemented */
2655 spr_register(env
, SPR_RCPU_L2U_RA3
, "L2U_RA3",
2656 SPR_NOACCESS
, SPR_NOACCESS
,
2657 &spr_read_generic
, &spr_write_generic
,
2659 /* XXX : not implemented */
2660 spr_register(env
, SPR_RCPU_FPECR
, "FPECR",
2661 SPR_NOACCESS
, SPR_NOACCESS
,
2662 &spr_read_generic
, &spr_write_generic
,
2666 static void gen_spr_8xx(CPUPPCState
*env
)
2668 /* XXX : not implemented */
2669 spr_register(env
, SPR_MPC_IC_CST
, "IC_CST",
2670 SPR_NOACCESS
, SPR_NOACCESS
,
2671 &spr_read_generic
, &spr_write_generic
,
2673 /* XXX : not implemented */
2674 spr_register(env
, SPR_MPC_IC_ADR
, "IC_ADR",
2675 SPR_NOACCESS
, SPR_NOACCESS
,
2676 &spr_read_generic
, &spr_write_generic
,
2678 /* XXX : not implemented */
2679 spr_register(env
, SPR_MPC_IC_DAT
, "IC_DAT",
2680 SPR_NOACCESS
, SPR_NOACCESS
,
2681 &spr_read_generic
, &spr_write_generic
,
2683 /* XXX : not implemented */
2684 spr_register(env
, SPR_MPC_DC_CST
, "DC_CST",
2685 SPR_NOACCESS
, SPR_NOACCESS
,
2686 &spr_read_generic
, &spr_write_generic
,
2688 /* XXX : not implemented */
2689 spr_register(env
, SPR_MPC_DC_ADR
, "DC_ADR",
2690 SPR_NOACCESS
, SPR_NOACCESS
,
2691 &spr_read_generic
, &spr_write_generic
,
2693 /* XXX : not implemented */
2694 spr_register(env
, SPR_MPC_DC_DAT
, "DC_DAT",
2695 SPR_NOACCESS
, SPR_NOACCESS
,
2696 &spr_read_generic
, &spr_write_generic
,
2698 /* XXX : not implemented */
2699 spr_register(env
, SPR_MPC_MI_CTR
, "MI_CTR",
2700 SPR_NOACCESS
, SPR_NOACCESS
,
2701 &spr_read_generic
, &spr_write_generic
,
2703 /* XXX : not implemented */
2704 spr_register(env
, SPR_MPC_MI_AP
, "MI_AP",
2705 SPR_NOACCESS
, SPR_NOACCESS
,
2706 &spr_read_generic
, &spr_write_generic
,
2708 /* XXX : not implemented */
2709 spr_register(env
, SPR_MPC_MI_EPN
, "MI_EPN",
2710 SPR_NOACCESS
, SPR_NOACCESS
,
2711 &spr_read_generic
, &spr_write_generic
,
2713 /* XXX : not implemented */
2714 spr_register(env
, SPR_MPC_MI_TWC
, "MI_TWC",
2715 SPR_NOACCESS
, SPR_NOACCESS
,
2716 &spr_read_generic
, &spr_write_generic
,
2718 /* XXX : not implemented */
2719 spr_register(env
, SPR_MPC_MI_RPN
, "MI_RPN",
2720 SPR_NOACCESS
, SPR_NOACCESS
,
2721 &spr_read_generic
, &spr_write_generic
,
2723 /* XXX : not implemented */
2724 spr_register(env
, SPR_MPC_MI_DBCAM
, "MI_DBCAM",
2725 SPR_NOACCESS
, SPR_NOACCESS
,
2726 &spr_read_generic
, &spr_write_generic
,
2728 /* XXX : not implemented */
2729 spr_register(env
, SPR_MPC_MI_DBRAM0
, "MI_DBRAM0",
2730 SPR_NOACCESS
, SPR_NOACCESS
,
2731 &spr_read_generic
, &spr_write_generic
,
2733 /* XXX : not implemented */
2734 spr_register(env
, SPR_MPC_MI_DBRAM1
, "MI_DBRAM1",
2735 SPR_NOACCESS
, SPR_NOACCESS
,
2736 &spr_read_generic
, &spr_write_generic
,
2738 /* XXX : not implemented */
2739 spr_register(env
, SPR_MPC_MD_CTR
, "MD_CTR",
2740 SPR_NOACCESS
, SPR_NOACCESS
,
2741 &spr_read_generic
, &spr_write_generic
,
2743 /* XXX : not implemented */
2744 spr_register(env
, SPR_MPC_MD_CASID
, "MD_CASID",
2745 SPR_NOACCESS
, SPR_NOACCESS
,
2746 &spr_read_generic
, &spr_write_generic
,
2748 /* XXX : not implemented */
2749 spr_register(env
, SPR_MPC_MD_AP
, "MD_AP",
2750 SPR_NOACCESS
, SPR_NOACCESS
,
2751 &spr_read_generic
, &spr_write_generic
,
2753 /* XXX : not implemented */
2754 spr_register(env
, SPR_MPC_MD_EPN
, "MD_EPN",
2755 SPR_NOACCESS
, SPR_NOACCESS
,
2756 &spr_read_generic
, &spr_write_generic
,
2758 /* XXX : not implemented */
2759 spr_register(env
, SPR_MPC_MD_TWB
, "MD_TWB",
2760 SPR_NOACCESS
, SPR_NOACCESS
,
2761 &spr_read_generic
, &spr_write_generic
,
2763 /* XXX : not implemented */
2764 spr_register(env
, SPR_MPC_MD_TWC
, "MD_TWC",
2765 SPR_NOACCESS
, SPR_NOACCESS
,
2766 &spr_read_generic
, &spr_write_generic
,
2768 /* XXX : not implemented */
2769 spr_register(env
, SPR_MPC_MD_RPN
, "MD_RPN",
2770 SPR_NOACCESS
, SPR_NOACCESS
,
2771 &spr_read_generic
, &spr_write_generic
,
2773 /* XXX : not implemented */
2774 spr_register(env
, SPR_MPC_MD_TW
, "MD_TW",
2775 SPR_NOACCESS
, SPR_NOACCESS
,
2776 &spr_read_generic
, &spr_write_generic
,
2778 /* XXX : not implemented */
2779 spr_register(env
, SPR_MPC_MD_DBCAM
, "MD_DBCAM",
2780 SPR_NOACCESS
, SPR_NOACCESS
,
2781 &spr_read_generic
, &spr_write_generic
,
2783 /* XXX : not implemented */
2784 spr_register(env
, SPR_MPC_MD_DBRAM0
, "MD_DBRAM0",
2785 SPR_NOACCESS
, SPR_NOACCESS
,
2786 &spr_read_generic
, &spr_write_generic
,
2788 /* XXX : not implemented */
2789 spr_register(env
, SPR_MPC_MD_DBRAM1
, "MD_DBRAM1",
2790 SPR_NOACCESS
, SPR_NOACCESS
,
2791 &spr_read_generic
, &spr_write_generic
,
2797 * AMR => SPR 29 (Power 2.04)
2798 * CTRL => SPR 136 (Power 2.04)
2799 * CTRL => SPR 152 (Power 2.04)
2800 * SCOMC => SPR 276 (64 bits ?)
2801 * SCOMD => SPR 277 (64 bits ?)
2802 * TBU40 => SPR 286 (Power 2.04 hypv)
2803 * HSPRG0 => SPR 304 (Power 2.04 hypv)
2804 * HSPRG1 => SPR 305 (Power 2.04 hypv)
2805 * HDSISR => SPR 306 (Power 2.04 hypv)
2806 * HDAR => SPR 307 (Power 2.04 hypv)
2807 * PURR => SPR 309 (Power 2.04 hypv)
2808 * HDEC => SPR 310 (Power 2.04 hypv)
2809 * HIOR => SPR 311 (hypv)
2810 * RMOR => SPR 312 (970)
2811 * HRMOR => SPR 313 (Power 2.04 hypv)
2812 * HSRR0 => SPR 314 (Power 2.04 hypv)
2813 * HSRR1 => SPR 315 (Power 2.04 hypv)
2814 * LPIDR => SPR 317 (970)
2815 * EPR => SPR 702 (Power 2.04 emb)
2816 * perf => 768-783 (Power 2.04)
2817 * perf => 784-799 (Power 2.04)
2818 * PPR => SPR 896 (Power 2.04)
2819 * DABRX => 1015 (Power 2.04 hypv)
2820 * FPECR => SPR 1022 (?)
2821 * ... and more (thermal management, performance counters, ...)
2824 /*****************************************************************************/
2825 /* Exception vectors models */
2826 static void init_excp_4xx_real(CPUPPCState
*env
)
2828 #if !defined(CONFIG_USER_ONLY)
2829 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000100;
2830 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2831 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2832 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2833 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2834 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2835 env
->excp_vectors
[POWERPC_EXCP_PIT
] = 0x00001000;
2836 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00001010;
2837 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001020;
2838 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00002000;
2839 env
->ivor_mask
= 0x0000FFF0UL
;
2840 env
->ivpr_mask
= 0xFFFF0000UL
;
2841 /* Hardware reset vector */
2842 env
->hreset_vector
= 0xFFFFFFFCUL
;
2846 static void init_excp_4xx_softmmu(CPUPPCState
*env
)
2848 #if !defined(CONFIG_USER_ONLY)
2849 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000100;
2850 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2851 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2852 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2853 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2854 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2855 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2856 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2857 env
->excp_vectors
[POWERPC_EXCP_PIT
] = 0x00001000;
2858 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00001010;
2859 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001020;
2860 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00001100;
2861 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00001200;
2862 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00002000;
2863 env
->ivor_mask
= 0x0000FFF0UL
;
2864 env
->ivpr_mask
= 0xFFFF0000UL
;
2865 /* Hardware reset vector */
2866 env
->hreset_vector
= 0xFFFFFFFCUL
;
2870 static void init_excp_MPC5xx(CPUPPCState
*env
)
2872 #if !defined(CONFIG_USER_ONLY)
2873 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2874 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2875 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2876 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2877 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2878 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000900;
2879 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2880 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2881 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2882 env
->excp_vectors
[POWERPC_EXCP_FPA
] = 0x00000E00;
2883 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001000;
2884 env
->excp_vectors
[POWERPC_EXCP_DABR
] = 0x00001C00;
2885 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001C00;
2886 env
->excp_vectors
[POWERPC_EXCP_MEXTBR
] = 0x00001E00;
2887 env
->excp_vectors
[POWERPC_EXCP_NMEXTBR
] = 0x00001F00;
2888 env
->ivor_mask
= 0x0000FFF0UL
;
2889 env
->ivpr_mask
= 0xFFFF0000UL
;
2890 /* Hardware reset vector */
2891 env
->hreset_vector
= 0x00000100UL
;
2895 static void init_excp_MPC8xx(CPUPPCState
*env
)
2897 #if !defined(CONFIG_USER_ONLY)
2898 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2899 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2900 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2901 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2902 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2903 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2904 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2905 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000900;
2906 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2907 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2908 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2909 env
->excp_vectors
[POWERPC_EXCP_FPA
] = 0x00000E00;
2910 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001000;
2911 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00001100;
2912 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00001200;
2913 env
->excp_vectors
[POWERPC_EXCP_ITLBE
] = 0x00001300;
2914 env
->excp_vectors
[POWERPC_EXCP_DTLBE
] = 0x00001400;
2915 env
->excp_vectors
[POWERPC_EXCP_DABR
] = 0x00001C00;
2916 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001C00;
2917 env
->excp_vectors
[POWERPC_EXCP_MEXTBR
] = 0x00001E00;
2918 env
->excp_vectors
[POWERPC_EXCP_NMEXTBR
] = 0x00001F00;
2919 env
->ivor_mask
= 0x0000FFF0UL
;
2920 env
->ivpr_mask
= 0xFFFF0000UL
;
2921 /* Hardware reset vector */
2922 env
->hreset_vector
= 0x00000100UL
;
2926 static void init_excp_G2(CPUPPCState
*env
)
2928 #if !defined(CONFIG_USER_ONLY)
2929 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2930 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2931 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2932 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2933 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2934 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2935 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2936 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
2937 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2938 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000A00;
2939 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2940 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2941 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
2942 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
2943 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
2944 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
2945 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
2946 /* Hardware reset vector */
2947 env
->hreset_vector
= 0x00000100UL
;
2951 static void init_excp_e200(CPUPPCState
*env
, target_ulong ivpr_mask
)
2953 #if !defined(CONFIG_USER_ONLY)
2954 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000FFC;
2955 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000000;
2956 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000000;
2957 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000000;
2958 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000000;
2959 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000000;
2960 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000000;
2961 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000000;
2962 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000000;
2963 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000000;
2964 env
->excp_vectors
[POWERPC_EXCP_APU
] = 0x00000000;
2965 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000000;
2966 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00000000;
2967 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00000000;
2968 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00000000;
2969 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00000000;
2970 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00000000;
2971 env
->excp_vectors
[POWERPC_EXCP_SPEU
] = 0x00000000;
2972 env
->excp_vectors
[POWERPC_EXCP_EFPDI
] = 0x00000000;
2973 env
->excp_vectors
[POWERPC_EXCP_EFPRI
] = 0x00000000;
2974 env
->ivor_mask
= 0x0000FFF7UL
;
2975 env
->ivpr_mask
= ivpr_mask
;
2976 /* Hardware reset vector */
2977 env
->hreset_vector
= 0xFFFFFFFCUL
;
2981 static void init_excp_BookE(CPUPPCState
*env
)
2983 #if !defined(CONFIG_USER_ONLY)
2984 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000000;
2985 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000000;
2986 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000000;
2987 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000000;
2988 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000000;
2989 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000000;
2990 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000000;
2991 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000000;
2992 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000000;
2993 env
->excp_vectors
[POWERPC_EXCP_APU
] = 0x00000000;
2994 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000000;
2995 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00000000;
2996 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00000000;
2997 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00000000;
2998 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00000000;
2999 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00000000;
3000 env
->ivor_mask
= 0x0000FFF0UL
;
3001 env
->ivpr_mask
= 0xFFFF0000UL
;
3002 /* Hardware reset vector */
3003 env
->hreset_vector
= 0xFFFFFFFCUL
;
3007 static void init_excp_601(CPUPPCState
*env
)
3009 #if !defined(CONFIG_USER_ONLY)
3010 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3011 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3012 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3013 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3014 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3015 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3016 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3017 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3018 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3019 env
->excp_vectors
[POWERPC_EXCP_IO
] = 0x00000A00;
3020 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3021 env
->excp_vectors
[POWERPC_EXCP_RUNM
] = 0x00002000;
3022 /* Hardware reset vector */
3023 env
->hreset_vector
= 0x00000100UL
;
3027 static void init_excp_602(CPUPPCState
*env
)
3029 #if !defined(CONFIG_USER_ONLY)
3030 /* XXX: exception prefix has a special behavior on 602 */
3031 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3032 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3033 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3034 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3035 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3036 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3037 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3038 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3039 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3040 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3041 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3042 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3043 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3044 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3045 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3046 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3047 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001500;
3048 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001600;
3049 /* Hardware reset vector */
3050 env
->hreset_vector
= 0x00000100UL
;
3054 static void init_excp_603(CPUPPCState
*env
)
3056 #if !defined(CONFIG_USER_ONLY)
3057 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3058 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3059 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3060 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3061 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3062 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3063 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3064 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3065 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3066 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3067 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3068 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3069 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3070 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3071 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3072 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3073 /* Hardware reset vector */
3074 env
->hreset_vector
= 0x00000100UL
;
3078 static void init_excp_604(CPUPPCState
*env
)
3080 #if !defined(CONFIG_USER_ONLY)
3081 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3082 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3083 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3084 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3085 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3086 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3087 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3088 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3089 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3090 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3091 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3092 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3093 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3094 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3095 /* Hardware reset vector */
3096 env
->hreset_vector
= 0x00000100UL
;
3100 static void init_excp_7x0(CPUPPCState
*env
)
3102 #if !defined(CONFIG_USER_ONLY)
3103 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3104 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3105 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3106 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3107 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3108 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3109 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3110 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3111 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3112 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3113 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3114 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3115 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3116 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3117 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3118 /* Hardware reset vector */
3119 env
->hreset_vector
= 0x00000100UL
;
3123 static void init_excp_750cl(CPUPPCState
*env
)
3125 #if !defined(CONFIG_USER_ONLY)
3126 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3127 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3128 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3129 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3130 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3131 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3132 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3133 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3134 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3135 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3136 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3137 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3138 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3139 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3140 /* Hardware reset vector */
3141 env
->hreset_vector
= 0x00000100UL
;
3145 static void init_excp_750cx(CPUPPCState
*env
)
3147 #if !defined(CONFIG_USER_ONLY)
3148 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3149 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3150 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3151 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3152 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3153 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3154 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3155 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3156 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3157 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3158 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3159 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3160 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3161 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3162 /* Hardware reset vector */
3163 env
->hreset_vector
= 0x00000100UL
;
3167 /* XXX: Check if this is correct */
3168 static void init_excp_7x5(CPUPPCState
*env
)
3170 #if !defined(CONFIG_USER_ONLY)
3171 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3172 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3173 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3174 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3175 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3176 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3177 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3178 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3179 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3180 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3181 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3182 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3183 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3184 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3185 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3186 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3187 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3188 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3189 /* Hardware reset vector */
3190 env
->hreset_vector
= 0x00000100UL
;
3194 static void init_excp_7400(CPUPPCState
*env
)
3196 #if !defined(CONFIG_USER_ONLY)
3197 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3198 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3199 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3200 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3201 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3202 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3203 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3204 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3205 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3206 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3207 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3208 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3209 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3210 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3211 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3212 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001600;
3213 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3214 /* Hardware reset vector */
3215 env
->hreset_vector
= 0x00000100UL
;
3219 static void init_excp_7450(CPUPPCState
*env
)
3221 #if !defined(CONFIG_USER_ONLY)
3222 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3223 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3224 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3225 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3226 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3227 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3228 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3229 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3230 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3231 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3232 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3233 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3234 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3235 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3236 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3237 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3238 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3239 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3240 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001600;
3241 /* Hardware reset vector */
3242 env
->hreset_vector
= 0x00000100UL
;
3246 #if defined(TARGET_PPC64)
3247 static void init_excp_970(CPUPPCState
*env
)
3249 #if !defined(CONFIG_USER_ONLY)
3250 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3251 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3252 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3253 env
->excp_vectors
[POWERPC_EXCP_DSEG
] = 0x00000380;
3254 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3255 env
->excp_vectors
[POWERPC_EXCP_ISEG
] = 0x00000480;
3256 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3257 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3258 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3259 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3260 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3261 env
->excp_vectors
[POWERPC_EXCP_HDECR
] = 0x00000980;
3262 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3263 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3264 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3265 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3266 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3267 env
->excp_vectors
[POWERPC_EXCP_MAINT
] = 0x00001600;
3268 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001700;
3269 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001800;
3270 /* Hardware reset vector */
3271 env
->hreset_vector
= 0x0000000000000100ULL
;
3275 static void init_excp_POWER7(CPUPPCState
*env
)
3277 #if !defined(CONFIG_USER_ONLY)
3278 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3279 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3280 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3281 env
->excp_vectors
[POWERPC_EXCP_DSEG
] = 0x00000380;
3282 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3283 env
->excp_vectors
[POWERPC_EXCP_ISEG
] = 0x00000480;
3284 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3285 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3286 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3287 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3288 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3289 env
->excp_vectors
[POWERPC_EXCP_HDECR
] = 0x00000980;
3290 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3291 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3292 env
->excp_vectors
[POWERPC_EXCP_HDSI
] = 0x00000E00;
3293 env
->excp_vectors
[POWERPC_EXCP_HISI
] = 0x00000E20;
3294 env
->excp_vectors
[POWERPC_EXCP_HV_EMU
] = 0x00000E40;
3295 env
->excp_vectors
[POWERPC_EXCP_HV_MAINT
] = 0x00000E60;
3296 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3297 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3298 env
->excp_vectors
[POWERPC_EXCP_VSXU
] = 0x00000F40;
3299 /* Hardware reset vector */
3300 env
->hreset_vector
= 0x0000000000000100ULL
;
3304 static void init_excp_POWER8(CPUPPCState
*env
)
3306 init_excp_POWER7(env
);
3308 #if !defined(CONFIG_USER_ONLY)
3309 env
->excp_vectors
[POWERPC_EXCP_SDOOR
] = 0x00000A00;
3310 env
->excp_vectors
[POWERPC_EXCP_FU
] = 0x00000F60;
3311 env
->excp_vectors
[POWERPC_EXCP_HV_FU
] = 0x00000F80;
3312 env
->excp_vectors
[POWERPC_EXCP_SDOOR_HV
] = 0x00000E80;
3318 /*****************************************************************************/
3319 /* Power management enable checks */
3320 static int check_pow_none(CPUPPCState
*env
)
3325 static int check_pow_nocheck(CPUPPCState
*env
)
3330 static int check_pow_hid0(CPUPPCState
*env
)
3332 if (env
->spr
[SPR_HID0
] & 0x00E00000)
3338 static int check_pow_hid0_74xx(CPUPPCState
*env
)
3340 if (env
->spr
[SPR_HID0
] & 0x00600000)
3346 static bool ppc_cpu_interrupts_big_endian_always(PowerPCCPU
*cpu
)
3352 static bool ppc_cpu_interrupts_big_endian_lpcr(PowerPCCPU
*cpu
)
3354 return !(cpu
->env
.spr
[SPR_LPCR
] & LPCR_ILE
);
3358 /*****************************************************************************/
3359 /* PowerPC implementations definitions */
3361 #define POWERPC_FAMILY(_name) \
3363 glue(glue(ppc_, _name), _cpu_family_class_init)(ObjectClass *, void *); \
3365 static const TypeInfo \
3366 glue(glue(ppc_, _name), _cpu_family_type_info) = { \
3367 .name = stringify(_name) "-family-" TYPE_POWERPC_CPU, \
3368 .parent = TYPE_POWERPC_CPU, \
3370 .class_init = glue(glue(ppc_, _name), _cpu_family_class_init), \
3373 static void glue(glue(ppc_, _name), _cpu_family_register_types)(void) \
3375 type_register_static( \
3376 &glue(glue(ppc_, _name), _cpu_family_type_info)); \
3379 type_init(glue(glue(ppc_, _name), _cpu_family_register_types)) \
3381 static void glue(glue(ppc_, _name), _cpu_family_class_init)
3383 static void init_proc_401(CPUPPCState
*env
)
3386 gen_spr_401_403(env
);
3388 init_excp_4xx_real(env
);
3389 env
->dcache_line_size
= 32;
3390 env
->icache_line_size
= 32;
3391 /* Allocate hardware IRQ controller */
3392 ppc40x_irq_init(ppc_env_get_cpu(env
));
3394 SET_FIT_PERIOD(12, 16, 20, 24);
3395 SET_WDT_PERIOD(16, 20, 24, 28);
3398 POWERPC_FAMILY(401)(ObjectClass
*oc
, void *data
)
3400 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3401 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3403 dc
->desc
= "PowerPC 401";
3404 pcc
->init_proc
= init_proc_401
;
3405 pcc
->check_pow
= check_pow_nocheck
;
3406 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3407 PPC_WRTEE
| PPC_DCR
|
3408 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3410 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3411 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3412 pcc
->msr_mask
= (1ull << MSR_KEY
) |
3421 pcc
->mmu_model
= POWERPC_MMU_REAL
;
3422 pcc
->excp_model
= POWERPC_EXCP_40x
;
3423 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3424 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3425 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3426 POWERPC_FLAG_BUS_CLK
;
3429 static void init_proc_401x2(CPUPPCState
*env
)
3432 gen_spr_401_403(env
);
3434 gen_spr_compress(env
);
3435 /* Memory management */
3436 #if !defined(CONFIG_USER_ONLY)
3440 env
->tlb_type
= TLB_EMB
;
3442 init_excp_4xx_softmmu(env
);
3443 env
->dcache_line_size
= 32;
3444 env
->icache_line_size
= 32;
3445 /* Allocate hardware IRQ controller */
3446 ppc40x_irq_init(ppc_env_get_cpu(env
));
3448 SET_FIT_PERIOD(12, 16, 20, 24);
3449 SET_WDT_PERIOD(16, 20, 24, 28);
3452 POWERPC_FAMILY(401x2
)(ObjectClass
*oc
, void *data
)
3454 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3455 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3457 dc
->desc
= "PowerPC 401x2";
3458 pcc
->init_proc
= init_proc_401x2
;
3459 pcc
->check_pow
= check_pow_nocheck
;
3460 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3461 PPC_DCR
| PPC_WRTEE
|
3462 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3463 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3464 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3465 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3466 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3467 pcc
->msr_mask
= (1ull << 20) |
3479 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3480 pcc
->excp_model
= POWERPC_EXCP_40x
;
3481 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3482 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3483 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3484 POWERPC_FLAG_BUS_CLK
;
3487 static void init_proc_401x3(CPUPPCState
*env
)
3490 gen_spr_401_403(env
);
3493 gen_spr_compress(env
);
3494 init_excp_4xx_softmmu(env
);
3495 env
->dcache_line_size
= 32;
3496 env
->icache_line_size
= 32;
3497 /* Allocate hardware IRQ controller */
3498 ppc40x_irq_init(ppc_env_get_cpu(env
));
3500 SET_FIT_PERIOD(12, 16, 20, 24);
3501 SET_WDT_PERIOD(16, 20, 24, 28);
3504 POWERPC_FAMILY(401x3
)(ObjectClass
*oc
, void *data
)
3506 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3507 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3509 dc
->desc
= "PowerPC 401x3";
3510 pcc
->init_proc
= init_proc_401x3
;
3511 pcc
->check_pow
= check_pow_nocheck
;
3512 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3513 PPC_DCR
| PPC_WRTEE
|
3514 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3515 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3516 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3517 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3518 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3519 pcc
->msr_mask
= (1ull << 20) |
3532 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3533 pcc
->excp_model
= POWERPC_EXCP_40x
;
3534 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3535 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3536 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3537 POWERPC_FLAG_BUS_CLK
;
3540 static void init_proc_IOP480(CPUPPCState
*env
)
3543 gen_spr_401_403(env
);
3545 gen_spr_compress(env
);
3546 /* Memory management */
3547 #if !defined(CONFIG_USER_ONLY)
3551 env
->tlb_type
= TLB_EMB
;
3553 init_excp_4xx_softmmu(env
);
3554 env
->dcache_line_size
= 32;
3555 env
->icache_line_size
= 32;
3556 /* Allocate hardware IRQ controller */
3557 ppc40x_irq_init(ppc_env_get_cpu(env
));
3559 SET_FIT_PERIOD(8, 12, 16, 20);
3560 SET_WDT_PERIOD(16, 20, 24, 28);
3563 POWERPC_FAMILY(IOP480
)(ObjectClass
*oc
, void *data
)
3565 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3566 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3568 dc
->desc
= "IOP480";
3569 pcc
->init_proc
= init_proc_IOP480
;
3570 pcc
->check_pow
= check_pow_nocheck
;
3571 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3572 PPC_DCR
| PPC_WRTEE
|
3573 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3574 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3575 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3576 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3577 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3578 pcc
->msr_mask
= (1ull << 20) |
3590 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3591 pcc
->excp_model
= POWERPC_EXCP_40x
;
3592 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3593 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3594 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3595 POWERPC_FLAG_BUS_CLK
;
3598 static void init_proc_403(CPUPPCState
*env
)
3601 gen_spr_401_403(env
);
3603 gen_spr_403_real(env
);
3604 init_excp_4xx_real(env
);
3605 env
->dcache_line_size
= 32;
3606 env
->icache_line_size
= 32;
3607 /* Allocate hardware IRQ controller */
3608 ppc40x_irq_init(ppc_env_get_cpu(env
));
3610 SET_FIT_PERIOD(8, 12, 16, 20);
3611 SET_WDT_PERIOD(16, 20, 24, 28);
3614 POWERPC_FAMILY(403)(ObjectClass
*oc
, void *data
)
3616 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3617 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3619 dc
->desc
= "PowerPC 403";
3620 pcc
->init_proc
= init_proc_403
;
3621 pcc
->check_pow
= check_pow_nocheck
;
3622 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3623 PPC_DCR
| PPC_WRTEE
|
3624 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3626 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3627 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3628 pcc
->msr_mask
= (1ull << MSR_POW
) |
3637 pcc
->mmu_model
= POWERPC_MMU_REAL
;
3638 pcc
->excp_model
= POWERPC_EXCP_40x
;
3639 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3640 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3641 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_PX
|
3642 POWERPC_FLAG_BUS_CLK
;
3645 static void init_proc_403GCX(CPUPPCState
*env
)
3648 gen_spr_401_403(env
);
3650 gen_spr_403_real(env
);
3651 gen_spr_403_mmu(env
);
3652 /* Bus access control */
3653 /* not emulated, as QEMU never does speculative access */
3654 spr_register(env
, SPR_40x_SGR
, "SGR",
3655 SPR_NOACCESS
, SPR_NOACCESS
,
3656 &spr_read_generic
, &spr_write_generic
,
3658 /* not emulated, as QEMU do not emulate caches */
3659 spr_register(env
, SPR_40x_DCWR
, "DCWR",
3660 SPR_NOACCESS
, SPR_NOACCESS
,
3661 &spr_read_generic
, &spr_write_generic
,
3663 /* Memory management */
3664 #if !defined(CONFIG_USER_ONLY)
3668 env
->tlb_type
= TLB_EMB
;
3670 init_excp_4xx_softmmu(env
);
3671 env
->dcache_line_size
= 32;
3672 env
->icache_line_size
= 32;
3673 /* Allocate hardware IRQ controller */
3674 ppc40x_irq_init(ppc_env_get_cpu(env
));
3676 SET_FIT_PERIOD(8, 12, 16, 20);
3677 SET_WDT_PERIOD(16, 20, 24, 28);
3680 POWERPC_FAMILY(403GCX
)(ObjectClass
*oc
, void *data
)
3682 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3683 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3685 dc
->desc
= "PowerPC 403 GCX";
3686 pcc
->init_proc
= init_proc_403GCX
;
3687 pcc
->check_pow
= check_pow_nocheck
;
3688 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3689 PPC_DCR
| PPC_WRTEE
|
3690 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3692 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3693 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3694 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3695 pcc
->msr_mask
= (1ull << MSR_POW
) |
3704 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3705 pcc
->excp_model
= POWERPC_EXCP_40x
;
3706 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3707 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3708 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_PX
|
3709 POWERPC_FLAG_BUS_CLK
;
3712 static void init_proc_405(CPUPPCState
*env
)
3718 /* Bus access control */
3719 /* not emulated, as QEMU never does speculative access */
3720 spr_register(env
, SPR_40x_SGR
, "SGR",
3721 SPR_NOACCESS
, SPR_NOACCESS
,
3722 &spr_read_generic
, &spr_write_generic
,
3724 /* not emulated, as QEMU do not emulate caches */
3725 spr_register(env
, SPR_40x_DCWR
, "DCWR",
3726 SPR_NOACCESS
, SPR_NOACCESS
,
3727 &spr_read_generic
, &spr_write_generic
,
3729 /* Memory management */
3730 #if !defined(CONFIG_USER_ONLY)
3734 env
->tlb_type
= TLB_EMB
;
3736 init_excp_4xx_softmmu(env
);
3737 env
->dcache_line_size
= 32;
3738 env
->icache_line_size
= 32;
3739 /* Allocate hardware IRQ controller */
3740 ppc40x_irq_init(ppc_env_get_cpu(env
));
3742 SET_FIT_PERIOD(8, 12, 16, 20);
3743 SET_WDT_PERIOD(16, 20, 24, 28);
3746 POWERPC_FAMILY(405)(ObjectClass
*oc
, void *data
)
3748 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3749 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3751 dc
->desc
= "PowerPC 405";
3752 pcc
->init_proc
= init_proc_405
;
3753 pcc
->check_pow
= check_pow_nocheck
;
3754 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3755 PPC_DCR
| PPC_WRTEE
|
3756 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3757 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3758 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3759 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3760 PPC_4xx_COMMON
| PPC_405_MAC
| PPC_40x_EXCP
;
3761 pcc
->msr_mask
= (1ull << MSR_POW
) |
3770 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx
;
3771 pcc
->excp_model
= POWERPC_EXCP_40x
;
3772 pcc
->bus_model
= PPC_FLAGS_INPUT_405
;
3773 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3774 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3775 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3778 static void init_proc_440EP(CPUPPCState
*env
)
3782 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3784 gen_spr_usprgh(env
);
3785 /* Processor identification */
3786 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3787 SPR_NOACCESS
, SPR_NOACCESS
,
3788 &spr_read_generic
, &spr_write_pir
,
3790 /* XXX : not implemented */
3791 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
3792 SPR_NOACCESS
, SPR_NOACCESS
,
3793 &spr_read_generic
, &spr_write_generic
,
3795 /* XXX : not implemented */
3796 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
3797 SPR_NOACCESS
, SPR_NOACCESS
,
3798 &spr_read_generic
, &spr_write_generic
,
3800 /* XXX : not implemented */
3801 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
3802 SPR_NOACCESS
, SPR_NOACCESS
,
3803 &spr_read_generic
, &spr_write_generic
,
3805 /* XXX : not implemented */
3806 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
3807 SPR_NOACCESS
, SPR_NOACCESS
,
3808 &spr_read_generic
, &spr_write_generic
,
3810 /* XXX : not implemented */
3811 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
3812 SPR_NOACCESS
, SPR_NOACCESS
,
3813 &spr_read_generic
, &spr_write_generic
,
3815 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
3816 SPR_NOACCESS
, SPR_NOACCESS
,
3817 &spr_read_generic
, &spr_write_generic
,
3819 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
3820 SPR_NOACCESS
, SPR_NOACCESS
,
3821 &spr_read_generic
, &spr_write_generic
,
3823 /* XXX : not implemented */
3824 spr_register(env
, SPR_440_CCR1
, "CCR1",
3825 SPR_NOACCESS
, SPR_NOACCESS
,
3826 &spr_read_generic
, &spr_write_generic
,
3828 /* Memory management */
3829 #if !defined(CONFIG_USER_ONLY)
3833 env
->tlb_type
= TLB_EMB
;
3835 init_excp_BookE(env
);
3836 env
->dcache_line_size
= 32;
3837 env
->icache_line_size
= 32;
3838 ppc40x_irq_init(ppc_env_get_cpu(env
));
3840 SET_FIT_PERIOD(12, 16, 20, 24);
3841 SET_WDT_PERIOD(20, 24, 28, 32);
3844 POWERPC_FAMILY(440EP
)(ObjectClass
*oc
, void *data
)
3846 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3847 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3849 dc
->desc
= "PowerPC 440 EP";
3850 pcc
->init_proc
= init_proc_440EP
;
3851 pcc
->check_pow
= check_pow_nocheck
;
3852 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3853 PPC_FLOAT
| PPC_FLOAT_FRES
| PPC_FLOAT_FSEL
|
3854 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
3856 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
3857 PPC_CACHE
| PPC_CACHE_ICBI
|
3858 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3859 PPC_MEM_TLBSYNC
| PPC_MFTB
|
3860 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3862 pcc
->msr_mask
= (1ull << MSR_POW
) |
3874 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3875 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3876 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3877 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3878 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3879 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3882 POWERPC_FAMILY(460EX
)(ObjectClass
*oc
, void *data
)
3884 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3885 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3887 dc
->desc
= "PowerPC 460 EX";
3888 pcc
->init_proc
= init_proc_440EP
;
3889 pcc
->check_pow
= check_pow_nocheck
;
3890 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3891 PPC_FLOAT
| PPC_FLOAT_FRES
| PPC_FLOAT_FSEL
|
3892 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
3894 PPC_DCR
| PPC_DCRX
| PPC_WRTEE
| PPC_RFMCI
|
3895 PPC_CACHE
| PPC_CACHE_ICBI
|
3896 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3897 PPC_MEM_TLBSYNC
| PPC_MFTB
|
3898 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3900 pcc
->msr_mask
= (1ull << MSR_POW
) |
3912 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3913 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3914 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3915 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3916 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3917 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3920 static void init_proc_440GP(CPUPPCState
*env
)
3924 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3926 gen_spr_usprgh(env
);
3927 /* Processor identification */
3928 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3929 SPR_NOACCESS
, SPR_NOACCESS
,
3930 &spr_read_generic
, &spr_write_pir
,
3932 /* XXX : not implemented */
3933 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
3934 SPR_NOACCESS
, SPR_NOACCESS
,
3935 &spr_read_generic
, &spr_write_generic
,
3937 /* XXX : not implemented */
3938 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
3939 SPR_NOACCESS
, SPR_NOACCESS
,
3940 &spr_read_generic
, &spr_write_generic
,
3942 /* XXX : not implemented */
3943 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
3944 SPR_NOACCESS
, SPR_NOACCESS
,
3945 &spr_read_generic
, &spr_write_generic
,
3947 /* XXX : not implemented */
3948 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
3949 SPR_NOACCESS
, SPR_NOACCESS
,
3950 &spr_read_generic
, &spr_write_generic
,
3952 /* Memory management */
3953 #if !defined(CONFIG_USER_ONLY)
3957 env
->tlb_type
= TLB_EMB
;
3959 init_excp_BookE(env
);
3960 env
->dcache_line_size
= 32;
3961 env
->icache_line_size
= 32;
3962 /* XXX: TODO: allocate internal IRQ controller */
3964 SET_FIT_PERIOD(12, 16, 20, 24);
3965 SET_WDT_PERIOD(20, 24, 28, 32);
3968 POWERPC_FAMILY(440GP
)(ObjectClass
*oc
, void *data
)
3970 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3971 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3973 dc
->desc
= "PowerPC 440 GP";
3974 pcc
->init_proc
= init_proc_440GP
;
3975 pcc
->check_pow
= check_pow_nocheck
;
3976 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3977 PPC_DCR
| PPC_DCRX
| PPC_WRTEE
| PPC_MFAPIDI
|
3978 PPC_CACHE
| PPC_CACHE_ICBI
|
3979 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3980 PPC_MEM_TLBSYNC
| PPC_TLBIVA
| PPC_MFTB
|
3981 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3983 pcc
->msr_mask
= (1ull << MSR_POW
) |
3995 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3996 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3997 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3998 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3999 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4000 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4003 static void init_proc_440x4(CPUPPCState
*env
)
4007 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
4009 gen_spr_usprgh(env
);
4010 /* Processor identification */
4011 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4012 SPR_NOACCESS
, SPR_NOACCESS
,
4013 &spr_read_generic
, &spr_write_pir
,
4015 /* XXX : not implemented */
4016 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4017 SPR_NOACCESS
, SPR_NOACCESS
,
4018 &spr_read_generic
, &spr_write_generic
,
4020 /* XXX : not implemented */
4021 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4022 SPR_NOACCESS
, SPR_NOACCESS
,
4023 &spr_read_generic
, &spr_write_generic
,
4025 /* XXX : not implemented */
4026 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
4027 SPR_NOACCESS
, SPR_NOACCESS
,
4028 &spr_read_generic
, &spr_write_generic
,
4030 /* XXX : not implemented */
4031 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
4032 SPR_NOACCESS
, SPR_NOACCESS
,
4033 &spr_read_generic
, &spr_write_generic
,
4035 /* Memory management */
4036 #if !defined(CONFIG_USER_ONLY)
4040 env
->tlb_type
= TLB_EMB
;
4042 init_excp_BookE(env
);
4043 env
->dcache_line_size
= 32;
4044 env
->icache_line_size
= 32;
4045 /* XXX: TODO: allocate internal IRQ controller */
4047 SET_FIT_PERIOD(12, 16, 20, 24);
4048 SET_WDT_PERIOD(20, 24, 28, 32);
4051 POWERPC_FAMILY(440x4
)(ObjectClass
*oc
, void *data
)
4053 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4054 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4056 dc
->desc
= "PowerPC 440x4";
4057 pcc
->init_proc
= init_proc_440x4
;
4058 pcc
->check_pow
= check_pow_nocheck
;
4059 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4060 PPC_DCR
| PPC_WRTEE
|
4061 PPC_CACHE
| PPC_CACHE_ICBI
|
4062 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4063 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4064 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4066 pcc
->msr_mask
= (1ull << MSR_POW
) |
4078 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4079 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4080 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4081 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4082 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4083 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4086 static void init_proc_440x5(CPUPPCState
*env
)
4090 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
4092 gen_spr_usprgh(env
);
4093 /* Processor identification */
4094 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4095 SPR_NOACCESS
, SPR_NOACCESS
,
4096 &spr_read_generic
, &spr_write_pir
,
4098 /* XXX : not implemented */
4099 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4100 SPR_NOACCESS
, SPR_NOACCESS
,
4101 &spr_read_generic
, &spr_write_generic
,
4103 /* XXX : not implemented */
4104 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4105 SPR_NOACCESS
, SPR_NOACCESS
,
4106 &spr_read_generic
, &spr_write_generic
,
4108 /* XXX : not implemented */
4109 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
4110 SPR_NOACCESS
, SPR_NOACCESS
,
4111 &spr_read_generic
, &spr_write_generic
,
4113 /* XXX : not implemented */
4114 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
4115 SPR_NOACCESS
, SPR_NOACCESS
,
4116 &spr_read_generic
, &spr_write_generic
,
4118 /* XXX : not implemented */
4119 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
4120 SPR_NOACCESS
, SPR_NOACCESS
,
4121 &spr_read_generic
, &spr_write_generic
,
4123 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
4124 SPR_NOACCESS
, SPR_NOACCESS
,
4125 &spr_read_generic
, &spr_write_generic
,
4127 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
4128 SPR_NOACCESS
, SPR_NOACCESS
,
4129 &spr_read_generic
, &spr_write_generic
,
4131 /* XXX : not implemented */
4132 spr_register(env
, SPR_440_CCR1
, "CCR1",
4133 SPR_NOACCESS
, SPR_NOACCESS
,
4134 &spr_read_generic
, &spr_write_generic
,
4136 /* Memory management */
4137 #if !defined(CONFIG_USER_ONLY)
4141 env
->tlb_type
= TLB_EMB
;
4143 init_excp_BookE(env
);
4144 env
->dcache_line_size
= 32;
4145 env
->icache_line_size
= 32;
4146 ppc40x_irq_init(ppc_env_get_cpu(env
));
4148 SET_FIT_PERIOD(12, 16, 20, 24);
4149 SET_WDT_PERIOD(20, 24, 28, 32);
4152 POWERPC_FAMILY(440x5
)(ObjectClass
*oc
, void *data
)
4154 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4155 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4157 dc
->desc
= "PowerPC 440x5";
4158 pcc
->init_proc
= init_proc_440x5
;
4159 pcc
->check_pow
= check_pow_nocheck
;
4160 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4161 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
4162 PPC_CACHE
| PPC_CACHE_ICBI
|
4163 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4164 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4165 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4167 pcc
->msr_mask
= (1ull << MSR_POW
) |
4179 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4180 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4181 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4182 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4183 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4184 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4187 POWERPC_FAMILY(440x5wDFPU
)(ObjectClass
*oc
, void *data
)
4189 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4190 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4192 dc
->desc
= "PowerPC 440x5 with double precision FPU";
4193 pcc
->init_proc
= init_proc_440x5
;
4194 pcc
->check_pow
= check_pow_nocheck
;
4195 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4196 PPC_FLOAT
| PPC_FLOAT_FSQRT
|
4198 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
4199 PPC_CACHE
| PPC_CACHE_ICBI
|
4200 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4201 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4202 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4204 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
4205 pcc
->msr_mask
= (1ull << MSR_POW
) |
4217 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4218 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4219 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4220 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4221 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4222 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4225 static void init_proc_MPC5xx(CPUPPCState
*env
)
4229 gen_spr_5xx_8xx(env
);
4231 init_excp_MPC5xx(env
);
4232 env
->dcache_line_size
= 32;
4233 env
->icache_line_size
= 32;
4234 /* XXX: TODO: allocate internal IRQ controller */
4237 POWERPC_FAMILY(MPC5xx
)(ObjectClass
*oc
, void *data
)
4239 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4240 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4242 dc
->desc
= "Freescale 5xx cores (aka RCPU)";
4243 pcc
->init_proc
= init_proc_MPC5xx
;
4244 pcc
->check_pow
= check_pow_none
;
4245 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4246 PPC_MEM_EIEIO
| PPC_MEM_SYNC
|
4247 PPC_CACHE_ICBI
| PPC_FLOAT
| PPC_FLOAT_STFIWX
|
4249 pcc
->msr_mask
= (1ull << MSR_ILE
) |
4261 pcc
->mmu_model
= POWERPC_MMU_REAL
;
4262 pcc
->excp_model
= POWERPC_EXCP_603
;
4263 pcc
->bus_model
= PPC_FLAGS_INPUT_RCPU
;
4264 pcc
->bfd_mach
= bfd_mach_ppc_505
;
4265 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
4266 POWERPC_FLAG_BUS_CLK
;
4269 static void init_proc_MPC8xx(CPUPPCState
*env
)
4273 gen_spr_5xx_8xx(env
);
4275 init_excp_MPC8xx(env
);
4276 env
->dcache_line_size
= 32;
4277 env
->icache_line_size
= 32;
4278 /* XXX: TODO: allocate internal IRQ controller */
4281 POWERPC_FAMILY(MPC8xx
)(ObjectClass
*oc
, void *data
)
4283 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4284 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4286 dc
->desc
= "Freescale 8xx cores (aka PowerQUICC)";
4287 pcc
->init_proc
= init_proc_MPC8xx
;
4288 pcc
->check_pow
= check_pow_none
;
4289 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4290 PPC_MEM_EIEIO
| PPC_MEM_SYNC
|
4291 PPC_CACHE_ICBI
| PPC_MFTB
;
4292 pcc
->msr_mask
= (1ull << MSR_ILE
) |
4304 pcc
->mmu_model
= POWERPC_MMU_MPC8xx
;
4305 pcc
->excp_model
= POWERPC_EXCP_603
;
4306 pcc
->bus_model
= PPC_FLAGS_INPUT_RCPU
;
4307 pcc
->bfd_mach
= bfd_mach_ppc_860
;
4308 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
4309 POWERPC_FLAG_BUS_CLK
;
4312 /* Freescale 82xx cores (aka PowerQUICC-II) */
4314 static void init_proc_G2(CPUPPCState
*env
)
4316 gen_spr_ne_601(env
);
4318 gen_spr_G2_755(env
);
4322 /* External access control */
4323 /* XXX : not implemented */
4324 spr_register(env
, SPR_EAR
, "EAR",
4325 SPR_NOACCESS
, SPR_NOACCESS
,
4326 &spr_read_generic
, &spr_write_generic
,
4328 /* Hardware implementation register */
4329 /* XXX : not implemented */
4330 spr_register(env
, SPR_HID0
, "HID0",
4331 SPR_NOACCESS
, SPR_NOACCESS
,
4332 &spr_read_generic
, &spr_write_generic
,
4334 /* XXX : not implemented */
4335 spr_register(env
, SPR_HID1
, "HID1",
4336 SPR_NOACCESS
, SPR_NOACCESS
,
4337 &spr_read_generic
, &spr_write_generic
,
4339 /* XXX : not implemented */
4340 spr_register(env
, SPR_HID2
, "HID2",
4341 SPR_NOACCESS
, SPR_NOACCESS
,
4342 &spr_read_generic
, &spr_write_generic
,
4344 /* Memory management */
4347 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4349 env
->dcache_line_size
= 32;
4350 env
->icache_line_size
= 32;
4351 /* Allocate hardware IRQ controller */
4352 ppc6xx_irq_init(ppc_env_get_cpu(env
));
4355 POWERPC_FAMILY(G2
)(ObjectClass
*oc
, void *data
)
4357 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4358 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4360 dc
->desc
= "PowerPC G2";
4361 pcc
->init_proc
= init_proc_G2
;
4362 pcc
->check_pow
= check_pow_hid0
;
4363 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4364 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4366 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4367 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4368 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4369 PPC_SEGMENT
| PPC_EXTERN
;
4370 pcc
->msr_mask
= (1ull << MSR_POW
) |
4371 (1ull << MSR_TGPR
) |
4385 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4386 pcc
->excp_model
= POWERPC_EXCP_G2
;
4387 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4388 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
4389 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4390 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4393 static void init_proc_G2LE(CPUPPCState
*env
)
4395 gen_spr_ne_601(env
);
4397 gen_spr_G2_755(env
);
4401 /* External access control */
4402 /* XXX : not implemented */
4403 spr_register(env
, SPR_EAR
, "EAR",
4404 SPR_NOACCESS
, SPR_NOACCESS
,
4405 &spr_read_generic
, &spr_write_generic
,
4407 /* Hardware implementation register */
4408 /* XXX : not implemented */
4409 spr_register(env
, SPR_HID0
, "HID0",
4410 SPR_NOACCESS
, SPR_NOACCESS
,
4411 &spr_read_generic
, &spr_write_generic
,
4413 /* XXX : not implemented */
4414 spr_register(env
, SPR_HID1
, "HID1",
4415 SPR_NOACCESS
, SPR_NOACCESS
,
4416 &spr_read_generic
, &spr_write_generic
,
4418 /* XXX : not implemented */
4419 spr_register(env
, SPR_HID2
, "HID2",
4420 SPR_NOACCESS
, SPR_NOACCESS
,
4421 &spr_read_generic
, &spr_write_generic
,
4424 /* Memory management */
4427 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4429 env
->dcache_line_size
= 32;
4430 env
->icache_line_size
= 32;
4431 /* Allocate hardware IRQ controller */
4432 ppc6xx_irq_init(ppc_env_get_cpu(env
));
4435 POWERPC_FAMILY(G2LE
)(ObjectClass
*oc
, void *data
)
4437 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4438 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4440 dc
->desc
= "PowerPC G2LE";
4441 pcc
->init_proc
= init_proc_G2LE
;
4442 pcc
->check_pow
= check_pow_hid0
;
4443 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4444 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4446 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4447 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4448 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4449 PPC_SEGMENT
| PPC_EXTERN
;
4450 pcc
->msr_mask
= (1ull << MSR_POW
) |
4451 (1ull << MSR_TGPR
) |
4467 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4468 pcc
->excp_model
= POWERPC_EXCP_G2
;
4469 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4470 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
4471 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4472 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4475 static void init_proc_e200(CPUPPCState
*env
)
4479 gen_spr_BookE(env
, 0x000000070000FFFFULL
);
4480 /* XXX : not implemented */
4481 spr_register(env
, SPR_BOOKE_SPEFSCR
, "SPEFSCR",
4482 &spr_read_spefscr
, &spr_write_spefscr
,
4483 &spr_read_spefscr
, &spr_write_spefscr
,
4485 /* Memory management */
4486 gen_spr_BookE206(env
, 0x0000005D, NULL
, 0);
4487 /* XXX : not implemented */
4488 spr_register(env
, SPR_HID0
, "HID0",
4489 SPR_NOACCESS
, SPR_NOACCESS
,
4490 &spr_read_generic
, &spr_write_generic
,
4492 /* XXX : not implemented */
4493 spr_register(env
, SPR_HID1
, "HID1",
4494 SPR_NOACCESS
, SPR_NOACCESS
,
4495 &spr_read_generic
, &spr_write_generic
,
4497 /* XXX : not implemented */
4498 spr_register(env
, SPR_Exxx_ALTCTXCR
, "ALTCTXCR",
4499 SPR_NOACCESS
, SPR_NOACCESS
,
4500 &spr_read_generic
, &spr_write_generic
,
4502 /* XXX : not implemented */
4503 spr_register(env
, SPR_Exxx_BUCSR
, "BUCSR",
4504 SPR_NOACCESS
, SPR_NOACCESS
,
4505 &spr_read_generic
, &spr_write_generic
,
4507 /* XXX : not implemented */
4508 spr_register(env
, SPR_Exxx_CTXCR
, "CTXCR",
4509 SPR_NOACCESS
, SPR_NOACCESS
,
4510 &spr_read_generic
, &spr_write_generic
,
4512 /* XXX : not implemented */
4513 spr_register(env
, SPR_Exxx_DBCNT
, "DBCNT",
4514 SPR_NOACCESS
, SPR_NOACCESS
,
4515 &spr_read_generic
, &spr_write_generic
,
4517 /* XXX : not implemented */
4518 spr_register(env
, SPR_Exxx_DBCR3
, "DBCR3",
4519 SPR_NOACCESS
, SPR_NOACCESS
,
4520 &spr_read_generic
, &spr_write_generic
,
4522 /* XXX : not implemented */
4523 spr_register(env
, SPR_Exxx_L1CFG0
, "L1CFG0",
4524 &spr_read_generic
, SPR_NOACCESS
,
4525 &spr_read_generic
, SPR_NOACCESS
,
4527 /* XXX : not implemented */
4528 spr_register(env
, SPR_Exxx_L1CSR0
, "L1CSR0",
4529 SPR_NOACCESS
, SPR_NOACCESS
,
4530 &spr_read_generic
, &spr_write_generic
,
4532 /* XXX : not implemented */
4533 spr_register(env
, SPR_Exxx_L1FINV0
, "L1FINV0",
4534 SPR_NOACCESS
, SPR_NOACCESS
,
4535 &spr_read_generic
, &spr_write_generic
,
4537 /* XXX : not implemented */
4538 spr_register(env
, SPR_BOOKE_TLB0CFG
, "TLB0CFG",
4539 SPR_NOACCESS
, SPR_NOACCESS
,
4540 &spr_read_generic
, &spr_write_generic
,
4542 /* XXX : not implemented */
4543 spr_register(env
, SPR_BOOKE_TLB1CFG
, "TLB1CFG",
4544 SPR_NOACCESS
, SPR_NOACCESS
,
4545 &spr_read_generic
, &spr_write_generic
,
4547 /* XXX : not implemented */
4548 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4549 SPR_NOACCESS
, SPR_NOACCESS
,
4550 &spr_read_generic
, &spr_write_generic
,
4552 /* XXX : not implemented */
4553 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4554 SPR_NOACCESS
, SPR_NOACCESS
,
4555 &spr_read_generic
, &spr_write_generic
,
4557 /* XXX : not implemented */
4558 spr_register(env
, SPR_MMUCSR0
, "MMUCSR0",
4559 SPR_NOACCESS
, SPR_NOACCESS
,
4560 &spr_read_generic
, &spr_write_generic
,
4561 0x00000000); /* TOFIX */
4562 spr_register(env
, SPR_BOOKE_DSRR0
, "DSRR0",
4563 SPR_NOACCESS
, SPR_NOACCESS
,
4564 &spr_read_generic
, &spr_write_generic
,
4566 spr_register(env
, SPR_BOOKE_DSRR1
, "DSRR1",
4567 SPR_NOACCESS
, SPR_NOACCESS
,
4568 &spr_read_generic
, &spr_write_generic
,
4570 #if !defined(CONFIG_USER_ONLY)
4574 env
->tlb_type
= TLB_EMB
;
4576 init_excp_e200(env
, 0xFFFF0000UL
);
4577 env
->dcache_line_size
= 32;
4578 env
->icache_line_size
= 32;
4579 /* XXX: TODO: allocate internal IRQ controller */
4582 POWERPC_FAMILY(e200
)(ObjectClass
*oc
, void *data
)
4584 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4585 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4587 dc
->desc
= "e200 core";
4588 pcc
->init_proc
= init_proc_e200
;
4589 pcc
->check_pow
= check_pow_hid0
;
4590 /* XXX: unimplemented instructions:
4597 * all SPE multiply-accumulate instructions
4599 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
4600 PPC_SPE
| PPC_SPE_SINGLE
|
4601 PPC_WRTEE
| PPC_RFDI
|
4602 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
4603 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4604 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
|
4606 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
4620 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
4621 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4622 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4623 pcc
->bfd_mach
= bfd_mach_ppc_860
;
4624 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
4625 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
4626 POWERPC_FLAG_BUS_CLK
;
4629 static void init_proc_e300(CPUPPCState
*env
)
4631 gen_spr_ne_601(env
);
4636 /* hardware implementation registers */
4637 /* XXX : not implemented */
4638 spr_register(env
, SPR_HID0
, "HID0",
4639 SPR_NOACCESS
, SPR_NOACCESS
,
4640 &spr_read_generic
, &spr_write_generic
,
4642 /* XXX : not implemented */
4643 spr_register(env
, SPR_HID1
, "HID1",
4644 SPR_NOACCESS
, SPR_NOACCESS
,
4645 &spr_read_generic
, &spr_write_generic
,
4647 /* XXX : not implemented */
4648 spr_register(env
, SPR_HID2
, "HID2",
4649 SPR_NOACCESS
, SPR_NOACCESS
,
4650 &spr_read_generic
, &spr_write_generic
,
4653 /* XXX : not implemented */
4654 spr_register(env
, SPR_DABR
, "DABR",
4655 SPR_NOACCESS
, SPR_NOACCESS
,
4656 &spr_read_generic
, &spr_write_generic
,
4658 /* XXX : not implemented */
4659 spr_register(env
, SPR_DABR2
, "DABR2",
4660 SPR_NOACCESS
, SPR_NOACCESS
,
4661 &spr_read_generic
, &spr_write_generic
,
4663 /* XXX : not implemented */
4664 spr_register(env
, SPR_IABR2
, "IABR2",
4665 SPR_NOACCESS
, SPR_NOACCESS
,
4666 &spr_read_generic
, &spr_write_generic
,
4668 /* XXX : not implemented */
4669 spr_register(env
, SPR_IBCR
, "IBCR",
4670 SPR_NOACCESS
, SPR_NOACCESS
,
4671 &spr_read_generic
, &spr_write_generic
,
4673 /* XXX : not implemented */
4674 spr_register(env
, SPR_DBCR
, "DBCR",
4675 SPR_NOACCESS
, SPR_NOACCESS
,
4676 &spr_read_generic
, &spr_write_generic
,
4678 /* Memory management */
4681 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4683 env
->dcache_line_size
= 32;
4684 env
->icache_line_size
= 32;
4685 /* Allocate hardware IRQ controller */
4686 ppc6xx_irq_init(ppc_env_get_cpu(env
));
4689 POWERPC_FAMILY(e300
)(ObjectClass
*oc
, void *data
)
4691 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4692 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4694 dc
->desc
= "e300 core";
4695 pcc
->init_proc
= init_proc_e300
;
4696 pcc
->check_pow
= check_pow_hid0
;
4697 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4698 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4700 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4701 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4702 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4703 PPC_SEGMENT
| PPC_EXTERN
;
4704 pcc
->msr_mask
= (1ull << MSR_POW
) |
4705 (1ull << MSR_TGPR
) |
4721 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4722 pcc
->excp_model
= POWERPC_EXCP_603
;
4723 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4724 pcc
->bfd_mach
= bfd_mach_ppc_603
;
4725 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4726 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4729 #if !defined(CONFIG_USER_ONLY)
4730 static void spr_write_mas73(DisasContext
*ctx
, int sprn
, int gprn
)
4732 TCGv val
= tcg_temp_new();
4733 tcg_gen_ext32u_tl(val
, cpu_gpr
[gprn
]);
4734 gen_store_spr(SPR_BOOKE_MAS3
, val
);
4735 tcg_gen_shri_tl(val
, cpu_gpr
[gprn
], 32);
4736 gen_store_spr(SPR_BOOKE_MAS7
, val
);
4740 static void spr_read_mas73(DisasContext
*ctx
, int gprn
, int sprn
)
4742 TCGv mas7
= tcg_temp_new();
4743 TCGv mas3
= tcg_temp_new();
4744 gen_load_spr(mas7
, SPR_BOOKE_MAS7
);
4745 tcg_gen_shli_tl(mas7
, mas7
, 32);
4746 gen_load_spr(mas3
, SPR_BOOKE_MAS3
);
4747 tcg_gen_or_tl(cpu_gpr
[gprn
], mas3
, mas7
);
4748 tcg_temp_free(mas3
);
4749 tcg_temp_free(mas7
);
4754 enum fsl_e500_version
{
4762 static void init_proc_e500(CPUPPCState
*env
, int version
)
4764 PowerPCCPU
*cpu
= ppc_env_get_cpu(env
);
4765 uint32_t tlbncfg
[2];
4767 uint64_t ivpr_mask
= 0xFFFF0000ULL
;
4768 uint32_t l1cfg0
= 0x3800 /* 8 ways */
4769 | 0x0020; /* 32 kb */
4770 uint32_t l1cfg1
= 0x3800 /* 8 ways */
4771 | 0x0020; /* 32 kb */
4772 uint32_t mmucfg
= 0;
4773 #if !defined(CONFIG_USER_ONLY)
4780 * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't
4781 * complain when accessing them.
4782 * gen_spr_BookE(env, 0x0000000F0000FD7FULL);
4788 ivor_mask
= 0x0000000F0000FFFFULL
;
4792 ivor_mask
= 0x000003FE0000FFFFULL
;
4795 ivor_mask
= 0x000003FF0000FFFFULL
;
4798 gen_spr_BookE(env
, ivor_mask
);
4799 gen_spr_usprg3(env
);
4800 /* Processor identification */
4801 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4802 SPR_NOACCESS
, SPR_NOACCESS
,
4803 &spr_read_generic
, &spr_write_pir
,
4805 /* XXX : not implemented */
4806 spr_register(env
, SPR_BOOKE_SPEFSCR
, "SPEFSCR",
4807 &spr_read_spefscr
, &spr_write_spefscr
,
4808 &spr_read_spefscr
, &spr_write_spefscr
,
4810 #if !defined(CONFIG_USER_ONLY)
4811 /* Memory management */
4817 tlbncfg
[0] = gen_tlbncfg(2, 1, 1, 0, 256);
4818 tlbncfg
[1] = gen_tlbncfg(16, 1, 9, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 16);
4821 tlbncfg
[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4822 tlbncfg
[1] = gen_tlbncfg(16, 1, 12, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 16);
4826 tlbncfg
[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4827 tlbncfg
[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 64);
4832 tlbncfg
[0] = 0x08052400;
4833 tlbncfg
[1] = 0x40028040;
4836 cpu_abort(CPU(cpu
), "Unknown CPU: " TARGET_FMT_lx
"\n", env
->spr
[SPR_PVR
]);
4843 env
->dcache_line_size
= 32;
4844 env
->icache_line_size
= 32;
4848 env
->dcache_line_size
= 64;
4849 env
->icache_line_size
= 64;
4850 l1cfg0
|= 0x1000000; /* 64 byte cache block size */
4851 l1cfg1
|= 0x1000000; /* 64 byte cache block size */
4854 env
->dcache_line_size
= 32;
4855 env
->icache_line_size
= 32;
4856 l1cfg0
|= 0x0F83820;
4857 l1cfg1
|= 0x0B83820;
4860 cpu_abort(CPU(cpu
), "Unknown CPU: " TARGET_FMT_lx
"\n", env
->spr
[SPR_PVR
]);
4862 gen_spr_BookE206(env
, 0x000000DF, tlbncfg
, mmucfg
);
4863 /* XXX : not implemented */
4864 spr_register(env
, SPR_HID0
, "HID0",
4865 SPR_NOACCESS
, SPR_NOACCESS
,
4866 &spr_read_generic
, &spr_write_generic
,
4868 /* XXX : not implemented */
4869 spr_register(env
, SPR_HID1
, "HID1",
4870 SPR_NOACCESS
, SPR_NOACCESS
,
4871 &spr_read_generic
, &spr_write_generic
,
4873 /* XXX : not implemented */
4874 spr_register(env
, SPR_Exxx_BBEAR
, "BBEAR",
4875 SPR_NOACCESS
, SPR_NOACCESS
,
4876 &spr_read_generic
, &spr_write_generic
,
4878 /* XXX : not implemented */
4879 spr_register(env
, SPR_Exxx_BBTAR
, "BBTAR",
4880 SPR_NOACCESS
, SPR_NOACCESS
,
4881 &spr_read_generic
, &spr_write_generic
,
4883 /* XXX : not implemented */
4884 spr_register(env
, SPR_Exxx_MCAR
, "MCAR",
4885 SPR_NOACCESS
, SPR_NOACCESS
,
4886 &spr_read_generic
, &spr_write_generic
,
4888 /* XXX : not implemented */
4889 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
4890 SPR_NOACCESS
, SPR_NOACCESS
,
4891 &spr_read_generic
, &spr_write_generic
,
4893 /* XXX : not implemented */
4894 spr_register(env
, SPR_Exxx_NPIDR
, "NPIDR",
4895 SPR_NOACCESS
, SPR_NOACCESS
,
4896 &spr_read_generic
, &spr_write_generic
,
4898 /* XXX : not implemented */
4899 spr_register(env
, SPR_Exxx_BUCSR
, "BUCSR",
4900 SPR_NOACCESS
, SPR_NOACCESS
,
4901 &spr_read_generic
, &spr_write_generic
,
4903 /* XXX : not implemented */
4904 spr_register(env
, SPR_Exxx_L1CFG0
, "L1CFG0",
4905 &spr_read_generic
, SPR_NOACCESS
,
4906 &spr_read_generic
, SPR_NOACCESS
,
4908 spr_register(env
, SPR_Exxx_L1CFG1
, "L1CFG1",
4909 &spr_read_generic
, SPR_NOACCESS
,
4910 &spr_read_generic
, SPR_NOACCESS
,
4912 spr_register(env
, SPR_Exxx_L1CSR0
, "L1CSR0",
4913 SPR_NOACCESS
, SPR_NOACCESS
,
4914 &spr_read_generic
, &spr_write_e500_l1csr0
,
4916 spr_register(env
, SPR_Exxx_L1CSR1
, "L1CSR1",
4917 SPR_NOACCESS
, SPR_NOACCESS
,
4918 &spr_read_generic
, &spr_write_e500_l1csr1
,
4920 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
4921 SPR_NOACCESS
, SPR_NOACCESS
,
4922 &spr_read_generic
, &spr_write_generic
,
4924 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
4925 SPR_NOACCESS
, SPR_NOACCESS
,
4926 &spr_read_generic
, &spr_write_generic
,
4928 spr_register(env
, SPR_MMUCSR0
, "MMUCSR0",
4929 SPR_NOACCESS
, SPR_NOACCESS
,
4930 &spr_read_generic
, &spr_write_booke206_mmucsr0
,
4932 spr_register(env
, SPR_BOOKE_EPR
, "EPR",
4933 SPR_NOACCESS
, SPR_NOACCESS
,
4934 &spr_read_generic
, SPR_NOACCESS
,
4936 /* XXX better abstract into Emb.xxx features */
4937 if ((version
== fsl_e5500
) || (version
== fsl_e6500
)) {
4938 spr_register(env
, SPR_BOOKE_EPCR
, "EPCR",
4939 SPR_NOACCESS
, SPR_NOACCESS
,
4940 &spr_read_generic
, &spr_write_generic
,
4942 spr_register(env
, SPR_BOOKE_MAS7_MAS3
, "MAS7_MAS3",
4943 SPR_NOACCESS
, SPR_NOACCESS
,
4944 &spr_read_mas73
, &spr_write_mas73
,
4946 ivpr_mask
= (target_ulong
)~0xFFFFULL
;
4949 if (version
== fsl_e6500
) {
4950 spr_register(env
, SPR_BOOKE_SPRG8
, "SPRG8",
4951 SPR_NOACCESS
, SPR_NOACCESS
,
4952 &spr_read_generic
, &spr_write_generic
,
4954 spr_register(env
, SPR_BOOKE_SPRG9
, "SPRG9",
4955 SPR_NOACCESS
, SPR_NOACCESS
,
4956 &spr_read_generic
, &spr_write_generic
,
4958 /* Thread identification */
4959 spr_register(env
, SPR_TIR
, "TIR",
4960 SPR_NOACCESS
, SPR_NOACCESS
,
4961 &spr_read_generic
, SPR_NOACCESS
,
4963 spr_register(env
, SPR_BOOKE_TLB0PS
, "TLB0PS",
4964 SPR_NOACCESS
, SPR_NOACCESS
,
4965 &spr_read_generic
, SPR_NOACCESS
,
4967 spr_register(env
, SPR_BOOKE_TLB1PS
, "TLB1PS",
4968 SPR_NOACCESS
, SPR_NOACCESS
,
4969 &spr_read_generic
, SPR_NOACCESS
,
4973 #if !defined(CONFIG_USER_ONLY)
4975 env
->tlb_type
= TLB_MAS
;
4976 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
4977 env
->nb_tlb
+= booke206_tlb_size(env
, i
);
4981 init_excp_e200(env
, ivpr_mask
);
4982 /* Allocate hardware IRQ controller */
4983 ppce500_irq_init(ppc_env_get_cpu(env
));
4986 static void init_proc_e500v1(CPUPPCState
*env
)
4988 init_proc_e500(env
, fsl_e500v1
);
4991 POWERPC_FAMILY(e500v1
)(ObjectClass
*oc
, void *data
)
4993 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4994 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4996 dc
->desc
= "e500v1 core";
4997 pcc
->init_proc
= init_proc_e500v1
;
4998 pcc
->check_pow
= check_pow_hid0
;
4999 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
5000 PPC_SPE
| PPC_SPE_SINGLE
|
5001 PPC_WRTEE
| PPC_RFDI
|
5002 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5003 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5004 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5005 pcc
->insns_flags2
= PPC2_BOOKE206
;
5006 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
5020 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5021 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5022 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5023 pcc
->bfd_mach
= bfd_mach_ppc_860
;
5024 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
5025 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
5026 POWERPC_FLAG_BUS_CLK
;
5029 static void init_proc_e500v2(CPUPPCState
*env
)
5031 init_proc_e500(env
, fsl_e500v2
);
5034 POWERPC_FAMILY(e500v2
)(ObjectClass
*oc
, void *data
)
5036 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5037 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5039 dc
->desc
= "e500v2 core";
5040 pcc
->init_proc
= init_proc_e500v2
;
5041 pcc
->check_pow
= check_pow_hid0
;
5042 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
5043 PPC_SPE
| PPC_SPE_SINGLE
| PPC_SPE_DOUBLE
|
5044 PPC_WRTEE
| PPC_RFDI
|
5045 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5046 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5047 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5048 pcc
->insns_flags2
= PPC2_BOOKE206
;
5049 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
5063 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5064 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5065 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5066 pcc
->bfd_mach
= bfd_mach_ppc_860
;
5067 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
5068 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
5069 POWERPC_FLAG_BUS_CLK
;
5072 static void init_proc_e500mc(CPUPPCState
*env
)
5074 init_proc_e500(env
, fsl_e500mc
);
5077 POWERPC_FAMILY(e500mc
)(ObjectClass
*oc
, void *data
)
5079 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5080 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5082 dc
->desc
= "e500mc core";
5083 pcc
->init_proc
= init_proc_e500mc
;
5084 pcc
->check_pow
= check_pow_none
;
5085 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5086 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5087 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5088 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5089 PPC_FLOAT
| PPC_FLOAT_FRES
|
5090 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5091 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5092 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5093 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
;
5094 pcc
->msr_mask
= (1ull << MSR_GS
) |
5095 (1ull << MSR_UCLE
) |
5108 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5109 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5110 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5111 /* FIXME: figure out the correct flag for e500mc */
5112 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5113 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5114 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5118 static void init_proc_e5500(CPUPPCState
*env
)
5120 init_proc_e500(env
, fsl_e5500
);
5123 POWERPC_FAMILY(e5500
)(ObjectClass
*oc
, void *data
)
5125 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5126 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5128 dc
->desc
= "e5500 core";
5129 pcc
->init_proc
= init_proc_e5500
;
5130 pcc
->check_pow
= check_pow_none
;
5131 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5132 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5133 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5134 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5135 PPC_FLOAT
| PPC_FLOAT_FRES
|
5136 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5137 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5138 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
|
5139 PPC_64B
| PPC_POPCNTB
| PPC_POPCNTWD
;
5140 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
| PPC2_PERM_ISA206
| \
5142 pcc
->msr_mask
= (1ull << MSR_CM
) |
5144 (1ull << MSR_UCLE
) |
5157 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5158 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5159 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5160 /* FIXME: figure out the correct flag for e5500 */
5161 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5162 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5163 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5166 static void init_proc_e6500(CPUPPCState
*env
)
5168 init_proc_e500(env
, fsl_e6500
);
5171 POWERPC_FAMILY(e6500
)(ObjectClass
*oc
, void *data
)
5173 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5174 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5176 dc
->desc
= "e6500 core";
5177 pcc
->init_proc
= init_proc_e6500
;
5178 pcc
->check_pow
= check_pow_none
;
5179 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5180 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5181 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5182 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5183 PPC_FLOAT
| PPC_FLOAT_FRES
|
5184 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5185 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5186 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
|
5187 PPC_64B
| PPC_POPCNTB
| PPC_POPCNTWD
| PPC_ALTIVEC
;
5188 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
| PPC2_PERM_ISA206
| \
5189 PPC2_FP_CVT_S64
| PPC2_ATOMIC_ISA206
;
5190 pcc
->msr_mask
= (1ull << MSR_CM
) |
5192 (1ull << MSR_UCLE
) |
5206 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5207 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5208 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5209 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5210 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5211 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_VRE
;
5216 /* Non-embedded PowerPC */
5218 #define POWERPC_MSRR_601 (0x0000000000001040ULL)
5220 static void init_proc_601(CPUPPCState
*env
)
5222 gen_spr_ne_601(env
);
5225 /* Hardware implementation registers */
5226 /* XXX : not implemented */
5227 spr_register(env
, SPR_HID0
, "HID0",
5228 SPR_NOACCESS
, SPR_NOACCESS
,
5229 &spr_read_generic
, &spr_write_hid0_601
,
5231 /* XXX : not implemented */
5232 spr_register(env
, SPR_HID1
, "HID1",
5233 SPR_NOACCESS
, SPR_NOACCESS
,
5234 &spr_read_generic
, &spr_write_generic
,
5236 /* XXX : not implemented */
5237 spr_register(env
, SPR_601_HID2
, "HID2",
5238 SPR_NOACCESS
, SPR_NOACCESS
,
5239 &spr_read_generic
, &spr_write_generic
,
5241 /* XXX : not implemented */
5242 spr_register(env
, SPR_601_HID5
, "HID5",
5243 SPR_NOACCESS
, SPR_NOACCESS
,
5244 &spr_read_generic
, &spr_write_generic
,
5246 /* Memory management */
5248 /* XXX: beware that dcache line size is 64
5249 * but dcbz uses 32 bytes "sectors"
5250 * XXX: this breaks clcs instruction !
5252 env
->dcache_line_size
= 32;
5253 env
->icache_line_size
= 64;
5254 /* Allocate hardware IRQ controller */
5255 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5258 POWERPC_FAMILY(601)(ObjectClass
*oc
, void *data
)
5260 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5261 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5263 dc
->desc
= "PowerPC 601";
5264 pcc
->init_proc
= init_proc_601
;
5265 pcc
->check_pow
= check_pow_none
;
5266 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_POWER_BR
|
5268 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5269 PPC_MEM_SYNC
| PPC_MEM_EIEIO
| PPC_MEM_TLBIE
|
5270 PPC_SEGMENT
| PPC_EXTERN
;
5271 pcc
->msr_mask
= (1ull << MSR_EE
) |
5281 pcc
->mmu_model
= POWERPC_MMU_601
;
5282 #if defined(CONFIG_SOFTMMU)
5283 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5285 pcc
->excp_model
= POWERPC_EXCP_601
;
5286 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5287 pcc
->bfd_mach
= bfd_mach_ppc_601
;
5288 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_RTC_CLK
;
5291 #define POWERPC_MSRR_601v (0x0000000000001040ULL)
5293 static void init_proc_601v(CPUPPCState
*env
)
5296 /* XXX : not implemented */
5297 spr_register(env
, SPR_601_HID15
, "HID15",
5298 SPR_NOACCESS
, SPR_NOACCESS
,
5299 &spr_read_generic
, &spr_write_generic
,
5303 POWERPC_FAMILY(601v
)(ObjectClass
*oc
, void *data
)
5305 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5306 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5308 dc
->desc
= "PowerPC 601v";
5309 pcc
->init_proc
= init_proc_601v
;
5310 pcc
->check_pow
= check_pow_none
;
5311 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_POWER_BR
|
5313 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5314 PPC_MEM_SYNC
| PPC_MEM_EIEIO
| PPC_MEM_TLBIE
|
5315 PPC_SEGMENT
| PPC_EXTERN
;
5316 pcc
->msr_mask
= (1ull << MSR_EE
) |
5326 pcc
->mmu_model
= POWERPC_MMU_601
;
5327 #if defined(CONFIG_SOFTMMU)
5328 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5330 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5331 pcc
->bfd_mach
= bfd_mach_ppc_601
;
5332 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_RTC_CLK
;
5335 static void init_proc_602(CPUPPCState
*env
)
5337 gen_spr_ne_601(env
);
5342 /* hardware implementation registers */
5343 /* XXX : not implemented */
5344 spr_register(env
, SPR_HID0
, "HID0",
5345 SPR_NOACCESS
, SPR_NOACCESS
,
5346 &spr_read_generic
, &spr_write_generic
,
5348 /* XXX : not implemented */
5349 spr_register(env
, SPR_HID1
, "HID1",
5350 SPR_NOACCESS
, SPR_NOACCESS
,
5351 &spr_read_generic
, &spr_write_generic
,
5353 /* Memory management */
5355 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5357 env
->dcache_line_size
= 32;
5358 env
->icache_line_size
= 32;
5359 /* Allocate hardware IRQ controller */
5360 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5363 POWERPC_FAMILY(602)(ObjectClass
*oc
, void *data
)
5365 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5366 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5368 dc
->desc
= "PowerPC 602";
5369 pcc
->init_proc
= init_proc_602
;
5370 pcc
->check_pow
= check_pow_hid0
;
5371 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5372 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5373 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5374 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5375 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5376 PPC_MEM_TLBIE
| PPC_6xx_TLB
| PPC_MEM_TLBSYNC
|
5377 PPC_SEGMENT
| PPC_602_SPEC
;
5378 pcc
->msr_mask
= (1ull << MSR_VSX
) |
5381 (1ull << MSR_TGPR
) |
5396 /* XXX: 602 MMU is quite specific. Should add a special case */
5397 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5398 pcc
->excp_model
= POWERPC_EXCP_602
;
5399 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5400 pcc
->bfd_mach
= bfd_mach_ppc_602
;
5401 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5402 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5405 static void init_proc_603(CPUPPCState
*env
)
5407 gen_spr_ne_601(env
);
5412 /* hardware implementation registers */
5413 /* XXX : not implemented */
5414 spr_register(env
, SPR_HID0
, "HID0",
5415 SPR_NOACCESS
, SPR_NOACCESS
,
5416 &spr_read_generic
, &spr_write_generic
,
5418 /* XXX : not implemented */
5419 spr_register(env
, SPR_HID1
, "HID1",
5420 SPR_NOACCESS
, SPR_NOACCESS
,
5421 &spr_read_generic
, &spr_write_generic
,
5423 /* Memory management */
5425 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5427 env
->dcache_line_size
= 32;
5428 env
->icache_line_size
= 32;
5429 /* Allocate hardware IRQ controller */
5430 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5433 POWERPC_FAMILY(603)(ObjectClass
*oc
, void *data
)
5435 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5436 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5438 dc
->desc
= "PowerPC 603";
5439 pcc
->init_proc
= init_proc_603
;
5440 pcc
->check_pow
= check_pow_hid0
;
5441 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5442 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5443 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5444 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5445 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5446 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
5447 PPC_SEGMENT
| PPC_EXTERN
;
5448 pcc
->msr_mask
= (1ull << MSR_POW
) |
5449 (1ull << MSR_TGPR
) |
5464 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5465 pcc
->excp_model
= POWERPC_EXCP_603
;
5466 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5467 pcc
->bfd_mach
= bfd_mach_ppc_603
;
5468 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5469 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5472 static void init_proc_603E(CPUPPCState
*env
)
5474 gen_spr_ne_601(env
);
5479 /* hardware implementation registers */
5480 /* XXX : not implemented */
5481 spr_register(env
, SPR_HID0
, "HID0",
5482 SPR_NOACCESS
, SPR_NOACCESS
,
5483 &spr_read_generic
, &spr_write_generic
,
5485 /* XXX : not implemented */
5486 spr_register(env
, SPR_HID1
, "HID1",
5487 SPR_NOACCESS
, SPR_NOACCESS
,
5488 &spr_read_generic
, &spr_write_generic
,
5490 /* Memory management */
5492 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5494 env
->dcache_line_size
= 32;
5495 env
->icache_line_size
= 32;
5496 /* Allocate hardware IRQ controller */
5497 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5500 POWERPC_FAMILY(603E
)(ObjectClass
*oc
, void *data
)
5502 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5503 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5505 dc
->desc
= "PowerPC 603e";
5506 pcc
->init_proc
= init_proc_603E
;
5507 pcc
->check_pow
= check_pow_hid0
;
5508 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5509 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5510 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5511 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5512 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5513 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
5514 PPC_SEGMENT
| PPC_EXTERN
;
5515 pcc
->msr_mask
= (1ull << MSR_POW
) |
5516 (1ull << MSR_TGPR
) |
5531 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5532 pcc
->excp_model
= POWERPC_EXCP_603E
;
5533 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5534 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
5535 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5536 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5539 static void init_proc_604(CPUPPCState
*env
)
5541 gen_spr_ne_601(env
);
5546 /* Hardware implementation registers */
5547 /* XXX : not implemented */
5548 spr_register(env
, SPR_HID0
, "HID0",
5549 SPR_NOACCESS
, SPR_NOACCESS
,
5550 &spr_read_generic
, &spr_write_generic
,
5552 /* Memory management */
5555 env
->dcache_line_size
= 32;
5556 env
->icache_line_size
= 32;
5557 /* Allocate hardware IRQ controller */
5558 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5561 POWERPC_FAMILY(604)(ObjectClass
*oc
, void *data
)
5563 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5564 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5566 dc
->desc
= "PowerPC 604";
5567 pcc
->init_proc
= init_proc_604
;
5568 pcc
->check_pow
= check_pow_nocheck
;
5569 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5570 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5571 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5572 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5573 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5574 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5575 PPC_SEGMENT
| PPC_EXTERN
;
5576 pcc
->msr_mask
= (1ull << MSR_POW
) |
5592 pcc
->mmu_model
= POWERPC_MMU_32B
;
5593 #if defined(CONFIG_SOFTMMU)
5594 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5596 pcc
->excp_model
= POWERPC_EXCP_604
;
5597 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5598 pcc
->bfd_mach
= bfd_mach_ppc_604
;
5599 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5600 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5603 static void init_proc_604E(CPUPPCState
*env
)
5605 gen_spr_ne_601(env
);
5608 /* XXX : not implemented */
5609 spr_register(env
, SPR_7XX_MMCR1
, "MMCR1",
5610 SPR_NOACCESS
, SPR_NOACCESS
,
5611 &spr_read_generic
, &spr_write_generic
,
5613 /* XXX : not implemented */
5614 spr_register(env
, SPR_7XX_PMC3
, "PMC3",
5615 SPR_NOACCESS
, SPR_NOACCESS
,
5616 &spr_read_generic
, &spr_write_generic
,
5618 /* XXX : not implemented */
5619 spr_register(env
, SPR_7XX_PMC4
, "PMC4",
5620 SPR_NOACCESS
, SPR_NOACCESS
,
5621 &spr_read_generic
, &spr_write_generic
,
5625 /* Hardware implementation registers */
5626 /* XXX : not implemented */
5627 spr_register(env
, SPR_HID0
, "HID0",
5628 SPR_NOACCESS
, SPR_NOACCESS
,
5629 &spr_read_generic
, &spr_write_generic
,
5631 /* XXX : not implemented */
5632 spr_register(env
, SPR_HID1
, "HID1",
5633 SPR_NOACCESS
, SPR_NOACCESS
,
5634 &spr_read_generic
, &spr_write_generic
,
5636 /* Memory management */
5639 env
->dcache_line_size
= 32;
5640 env
->icache_line_size
= 32;
5641 /* Allocate hardware IRQ controller */
5642 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5645 POWERPC_FAMILY(604E
)(ObjectClass
*oc
, void *data
)
5647 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5648 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5650 dc
->desc
= "PowerPC 604E";
5651 pcc
->init_proc
= init_proc_604E
;
5652 pcc
->check_pow
= check_pow_nocheck
;
5653 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5654 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5655 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5656 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5657 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5658 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5659 PPC_SEGMENT
| PPC_EXTERN
;
5660 pcc
->msr_mask
= (1ull << MSR_POW
) |
5676 pcc
->mmu_model
= POWERPC_MMU_32B
;
5677 #if defined(CONFIG_SOFTMMU)
5678 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5680 pcc
->excp_model
= POWERPC_EXCP_604
;
5681 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5682 pcc
->bfd_mach
= bfd_mach_ppc_604
;
5683 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5684 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5687 static void init_proc_740(CPUPPCState
*env
)
5689 gen_spr_ne_601(env
);
5694 /* Thermal management */
5696 /* Hardware implementation registers */
5697 /* XXX : not implemented */
5698 spr_register(env
, SPR_HID0
, "HID0",
5699 SPR_NOACCESS
, SPR_NOACCESS
,
5700 &spr_read_generic
, &spr_write_generic
,
5702 /* XXX : not implemented */
5703 spr_register(env
, SPR_HID1
, "HID1",
5704 SPR_NOACCESS
, SPR_NOACCESS
,
5705 &spr_read_generic
, &spr_write_generic
,
5707 /* Memory management */
5710 env
->dcache_line_size
= 32;
5711 env
->icache_line_size
= 32;
5712 /* Allocate hardware IRQ controller */
5713 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5716 POWERPC_FAMILY(740)(ObjectClass
*oc
, void *data
)
5718 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5719 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5721 dc
->desc
= "PowerPC 740";
5722 pcc
->init_proc
= init_proc_740
;
5723 pcc
->check_pow
= check_pow_hid0
;
5724 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5725 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5726 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5727 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5728 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5729 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5730 PPC_SEGMENT
| PPC_EXTERN
;
5731 pcc
->msr_mask
= (1ull << MSR_POW
) |
5747 pcc
->mmu_model
= POWERPC_MMU_32B
;
5748 #if defined(CONFIG_SOFTMMU)
5749 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5751 pcc
->excp_model
= POWERPC_EXCP_7x0
;
5752 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5753 pcc
->bfd_mach
= bfd_mach_ppc_750
;
5754 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5755 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5758 static void init_proc_750(CPUPPCState
*env
)
5760 gen_spr_ne_601(env
);
5763 /* XXX : not implemented */
5764 spr_register(env
, SPR_L2CR
, "L2CR",
5765 SPR_NOACCESS
, SPR_NOACCESS
,
5766 &spr_read_generic
, spr_access_nop
,
5770 /* Thermal management */
5772 /* Hardware implementation registers */
5773 /* XXX : not implemented */
5774 spr_register(env
, SPR_HID0
, "HID0",
5775 SPR_NOACCESS
, SPR_NOACCESS
,
5776 &spr_read_generic
, &spr_write_generic
,
5778 /* XXX : not implemented */
5779 spr_register(env
, SPR_HID1
, "HID1",
5780 SPR_NOACCESS
, SPR_NOACCESS
,
5781 &spr_read_generic
, &spr_write_generic
,
5783 /* Memory management */
5785 /* XXX: high BATs are also present but are known to be bugged on
5789 env
->dcache_line_size
= 32;
5790 env
->icache_line_size
= 32;
5791 /* Allocate hardware IRQ controller */
5792 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5795 POWERPC_FAMILY(750)(ObjectClass
*oc
, void *data
)
5797 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5798 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5800 dc
->desc
= "PowerPC 750";
5801 pcc
->init_proc
= init_proc_750
;
5802 pcc
->check_pow
= check_pow_hid0
;
5803 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5804 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5805 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5806 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5807 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5808 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5809 PPC_SEGMENT
| PPC_EXTERN
;
5810 pcc
->msr_mask
= (1ull << MSR_POW
) |
5826 pcc
->mmu_model
= POWERPC_MMU_32B
;
5827 #if defined(CONFIG_SOFTMMU)
5828 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5830 pcc
->excp_model
= POWERPC_EXCP_7x0
;
5831 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5832 pcc
->bfd_mach
= bfd_mach_ppc_750
;
5833 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5834 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5837 static void init_proc_750cl(CPUPPCState
*env
)
5839 gen_spr_ne_601(env
);
5842 /* XXX : not implemented */
5843 spr_register(env
, SPR_L2CR
, "L2CR",
5844 SPR_NOACCESS
, SPR_NOACCESS
,
5845 &spr_read_generic
, spr_access_nop
,
5849 /* Thermal management */
5850 /* Those registers are fake on 750CL */
5851 spr_register(env
, SPR_THRM1
, "THRM1",
5852 SPR_NOACCESS
, SPR_NOACCESS
,
5853 &spr_read_generic
, &spr_write_generic
,
5855 spr_register(env
, SPR_THRM2
, "THRM2",
5856 SPR_NOACCESS
, SPR_NOACCESS
,
5857 &spr_read_generic
, &spr_write_generic
,
5859 spr_register(env
, SPR_THRM3
, "THRM3",
5860 SPR_NOACCESS
, SPR_NOACCESS
,
5861 &spr_read_generic
, &spr_write_generic
,
5863 /* XXX: not implemented */
5864 spr_register(env
, SPR_750_TDCL
, "TDCL",
5865 SPR_NOACCESS
, SPR_NOACCESS
,
5866 &spr_read_generic
, &spr_write_generic
,
5868 spr_register(env
, SPR_750_TDCH
, "TDCH",
5869 SPR_NOACCESS
, SPR_NOACCESS
,
5870 &spr_read_generic
, &spr_write_generic
,
5873 /* XXX : not implemented */
5874 spr_register(env
, SPR_750_WPAR
, "WPAR",
5875 SPR_NOACCESS
, SPR_NOACCESS
,
5876 &spr_read_generic
, &spr_write_generic
,
5878 spr_register(env
, SPR_750_DMAL
, "DMAL",
5879 SPR_NOACCESS
, SPR_NOACCESS
,
5880 &spr_read_generic
, &spr_write_generic
,
5882 spr_register(env
, SPR_750_DMAU
, "DMAU",
5883 SPR_NOACCESS
, SPR_NOACCESS
,
5884 &spr_read_generic
, &spr_write_generic
,
5886 /* Hardware implementation registers */
5887 /* XXX : not implemented */
5888 spr_register(env
, SPR_HID0
, "HID0",
5889 SPR_NOACCESS
, SPR_NOACCESS
,
5890 &spr_read_generic
, &spr_write_generic
,
5892 /* XXX : not implemented */
5893 spr_register(env
, SPR_HID1
, "HID1",
5894 SPR_NOACCESS
, SPR_NOACCESS
,
5895 &spr_read_generic
, &spr_write_generic
,
5897 /* XXX : not implemented */
5898 spr_register(env
, SPR_750CL_HID2
, "HID2",
5899 SPR_NOACCESS
, SPR_NOACCESS
,
5900 &spr_read_generic
, &spr_write_generic
,
5902 /* XXX : not implemented */
5903 spr_register(env
, SPR_750CL_HID4
, "HID4",
5904 SPR_NOACCESS
, SPR_NOACCESS
,
5905 &spr_read_generic
, &spr_write_generic
,
5907 /* Quantization registers */
5908 /* XXX : not implemented */
5909 spr_register(env
, SPR_750_GQR0
, "GQR0",
5910 SPR_NOACCESS
, SPR_NOACCESS
,
5911 &spr_read_generic
, &spr_write_generic
,
5913 /* XXX : not implemented */
5914 spr_register(env
, SPR_750_GQR1
, "GQR1",
5915 SPR_NOACCESS
, SPR_NOACCESS
,
5916 &spr_read_generic
, &spr_write_generic
,
5918 /* XXX : not implemented */
5919 spr_register(env
, SPR_750_GQR2
, "GQR2",
5920 SPR_NOACCESS
, SPR_NOACCESS
,
5921 &spr_read_generic
, &spr_write_generic
,
5923 /* XXX : not implemented */
5924 spr_register(env
, SPR_750_GQR3
, "GQR3",
5925 SPR_NOACCESS
, SPR_NOACCESS
,
5926 &spr_read_generic
, &spr_write_generic
,
5928 /* XXX : not implemented */
5929 spr_register(env
, SPR_750_GQR4
, "GQR4",
5930 SPR_NOACCESS
, SPR_NOACCESS
,
5931 &spr_read_generic
, &spr_write_generic
,
5933 /* XXX : not implemented */
5934 spr_register(env
, SPR_750_GQR5
, "GQR5",
5935 SPR_NOACCESS
, SPR_NOACCESS
,
5936 &spr_read_generic
, &spr_write_generic
,
5938 /* XXX : not implemented */
5939 spr_register(env
, SPR_750_GQR6
, "GQR6",
5940 SPR_NOACCESS
, SPR_NOACCESS
,
5941 &spr_read_generic
, &spr_write_generic
,
5943 /* XXX : not implemented */
5944 spr_register(env
, SPR_750_GQR7
, "GQR7",
5945 SPR_NOACCESS
, SPR_NOACCESS
,
5946 &spr_read_generic
, &spr_write_generic
,
5948 /* Memory management */
5950 /* PowerPC 750cl has 8 DBATs and 8 IBATs */
5952 init_excp_750cl(env
);
5953 env
->dcache_line_size
= 32;
5954 env
->icache_line_size
= 32;
5955 /* Allocate hardware IRQ controller */
5956 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5959 POWERPC_FAMILY(750cl
)(ObjectClass
*oc
, void *data
)
5961 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5962 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5964 dc
->desc
= "PowerPC 750 CL";
5965 pcc
->init_proc
= init_proc_750cl
;
5966 pcc
->check_pow
= check_pow_hid0
;
5967 /* XXX: not implemented:
5968 * cache lock instructions:
5970 * floating point paired instructions
6005 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6006 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6007 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6008 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6009 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6010 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6011 PPC_SEGMENT
| PPC_EXTERN
;
6012 pcc
->msr_mask
= (1ull << MSR_POW
) |
6028 pcc
->mmu_model
= POWERPC_MMU_32B
;
6029 #if defined(CONFIG_SOFTMMU)
6030 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6032 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6033 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6034 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6035 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6036 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6039 static void init_proc_750cx(CPUPPCState
*env
)
6041 gen_spr_ne_601(env
);
6044 /* XXX : not implemented */
6045 spr_register(env
, SPR_L2CR
, "L2CR",
6046 SPR_NOACCESS
, SPR_NOACCESS
,
6047 &spr_read_generic
, spr_access_nop
,
6051 /* Thermal management */
6053 /* This register is not implemented but is present for compatibility */
6054 spr_register(env
, SPR_SDA
, "SDA",
6055 SPR_NOACCESS
, SPR_NOACCESS
,
6056 &spr_read_generic
, &spr_write_generic
,
6058 /* Hardware implementation registers */
6059 /* XXX : not implemented */
6060 spr_register(env
, SPR_HID0
, "HID0",
6061 SPR_NOACCESS
, SPR_NOACCESS
,
6062 &spr_read_generic
, &spr_write_generic
,
6064 /* XXX : not implemented */
6065 spr_register(env
, SPR_HID1
, "HID1",
6066 SPR_NOACCESS
, SPR_NOACCESS
,
6067 &spr_read_generic
, &spr_write_generic
,
6069 /* Memory management */
6071 /* PowerPC 750cx has 8 DBATs and 8 IBATs */
6073 init_excp_750cx(env
);
6074 env
->dcache_line_size
= 32;
6075 env
->icache_line_size
= 32;
6076 /* Allocate hardware IRQ controller */
6077 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6080 POWERPC_FAMILY(750cx
)(ObjectClass
*oc
, void *data
)
6082 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6083 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6085 dc
->desc
= "PowerPC 750CX";
6086 pcc
->init_proc
= init_proc_750cx
;
6087 pcc
->check_pow
= check_pow_hid0
;
6088 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6089 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6090 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6091 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6092 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6093 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6094 PPC_SEGMENT
| PPC_EXTERN
;
6095 pcc
->msr_mask
= (1ull << MSR_POW
) |
6111 pcc
->mmu_model
= POWERPC_MMU_32B
;
6112 #if defined(CONFIG_SOFTMMU)
6113 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6115 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6116 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6117 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6118 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6119 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6122 static void init_proc_750fx(CPUPPCState
*env
)
6124 gen_spr_ne_601(env
);
6127 /* XXX : not implemented */
6128 spr_register(env
, SPR_L2CR
, "L2CR",
6129 SPR_NOACCESS
, SPR_NOACCESS
,
6130 &spr_read_generic
, spr_access_nop
,
6134 /* Thermal management */
6136 /* XXX : not implemented */
6137 spr_register(env
, SPR_750_THRM4
, "THRM4",
6138 SPR_NOACCESS
, SPR_NOACCESS
,
6139 &spr_read_generic
, &spr_write_generic
,
6141 /* Hardware implementation registers */
6142 /* XXX : not implemented */
6143 spr_register(env
, SPR_HID0
, "HID0",
6144 SPR_NOACCESS
, SPR_NOACCESS
,
6145 &spr_read_generic
, &spr_write_generic
,
6147 /* XXX : not implemented */
6148 spr_register(env
, SPR_HID1
, "HID1",
6149 SPR_NOACCESS
, SPR_NOACCESS
,
6150 &spr_read_generic
, &spr_write_generic
,
6152 /* XXX : not implemented */
6153 spr_register(env
, SPR_750FX_HID2
, "HID2",
6154 SPR_NOACCESS
, SPR_NOACCESS
,
6155 &spr_read_generic
, &spr_write_generic
,
6157 /* Memory management */
6159 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6162 env
->dcache_line_size
= 32;
6163 env
->icache_line_size
= 32;
6164 /* Allocate hardware IRQ controller */
6165 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6168 POWERPC_FAMILY(750fx
)(ObjectClass
*oc
, void *data
)
6170 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6171 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6173 dc
->desc
= "PowerPC 750FX";
6174 pcc
->init_proc
= init_proc_750fx
;
6175 pcc
->check_pow
= check_pow_hid0
;
6176 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6177 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6178 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6179 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6180 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6181 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6182 PPC_SEGMENT
| PPC_EXTERN
;
6183 pcc
->msr_mask
= (1ull << MSR_POW
) |
6199 pcc
->mmu_model
= POWERPC_MMU_32B
;
6200 #if defined(CONFIG_SOFTMMU)
6201 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6203 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6204 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6205 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6206 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6207 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6210 static void init_proc_750gx(CPUPPCState
*env
)
6212 gen_spr_ne_601(env
);
6215 /* XXX : not implemented (XXX: different from 750fx) */
6216 spr_register(env
, SPR_L2CR
, "L2CR",
6217 SPR_NOACCESS
, SPR_NOACCESS
,
6218 &spr_read_generic
, spr_access_nop
,
6222 /* Thermal management */
6224 /* XXX : not implemented */
6225 spr_register(env
, SPR_750_THRM4
, "THRM4",
6226 SPR_NOACCESS
, SPR_NOACCESS
,
6227 &spr_read_generic
, &spr_write_generic
,
6229 /* Hardware implementation registers */
6230 /* XXX : not implemented (XXX: different from 750fx) */
6231 spr_register(env
, SPR_HID0
, "HID0",
6232 SPR_NOACCESS
, SPR_NOACCESS
,
6233 &spr_read_generic
, &spr_write_generic
,
6235 /* XXX : not implemented */
6236 spr_register(env
, SPR_HID1
, "HID1",
6237 SPR_NOACCESS
, SPR_NOACCESS
,
6238 &spr_read_generic
, &spr_write_generic
,
6240 /* XXX : not implemented (XXX: different from 750fx) */
6241 spr_register(env
, SPR_750FX_HID2
, "HID2",
6242 SPR_NOACCESS
, SPR_NOACCESS
,
6243 &spr_read_generic
, &spr_write_generic
,
6245 /* Memory management */
6247 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6250 env
->dcache_line_size
= 32;
6251 env
->icache_line_size
= 32;
6252 /* Allocate hardware IRQ controller */
6253 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6256 POWERPC_FAMILY(750gx
)(ObjectClass
*oc
, void *data
)
6258 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6259 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6261 dc
->desc
= "PowerPC 750GX";
6262 pcc
->init_proc
= init_proc_750gx
;
6263 pcc
->check_pow
= check_pow_hid0
;
6264 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6265 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6266 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6267 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6268 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6269 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6270 PPC_SEGMENT
| PPC_EXTERN
;
6271 pcc
->msr_mask
= (1ull << MSR_POW
) |
6287 pcc
->mmu_model
= POWERPC_MMU_32B
;
6288 #if defined(CONFIG_SOFTMMU)
6289 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6291 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6292 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6293 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6294 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6295 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6298 static void init_proc_745(CPUPPCState
*env
)
6300 gen_spr_ne_601(env
);
6303 gen_spr_G2_755(env
);
6306 /* Thermal management */
6308 /* Hardware implementation registers */
6309 /* XXX : not implemented */
6310 spr_register(env
, SPR_HID0
, "HID0",
6311 SPR_NOACCESS
, SPR_NOACCESS
,
6312 &spr_read_generic
, &spr_write_generic
,
6314 /* XXX : not implemented */
6315 spr_register(env
, SPR_HID1
, "HID1",
6316 SPR_NOACCESS
, SPR_NOACCESS
,
6317 &spr_read_generic
, &spr_write_generic
,
6319 /* XXX : not implemented */
6320 spr_register(env
, SPR_HID2
, "HID2",
6321 SPR_NOACCESS
, SPR_NOACCESS
,
6322 &spr_read_generic
, &spr_write_generic
,
6324 /* Memory management */
6327 gen_6xx_7xx_soft_tlb(env
, 64, 2);
6329 env
->dcache_line_size
= 32;
6330 env
->icache_line_size
= 32;
6331 /* Allocate hardware IRQ controller */
6332 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6335 POWERPC_FAMILY(745)(ObjectClass
*oc
, void *data
)
6337 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6338 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6340 dc
->desc
= "PowerPC 745";
6341 pcc
->init_proc
= init_proc_745
;
6342 pcc
->check_pow
= check_pow_hid0
;
6343 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6344 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6345 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6346 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6347 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6348 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
6349 PPC_SEGMENT
| PPC_EXTERN
;
6350 pcc
->msr_mask
= (1ull << MSR_POW
) |
6366 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
6367 pcc
->excp_model
= POWERPC_EXCP_7x5
;
6368 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6369 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6370 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6371 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6374 static void init_proc_755(CPUPPCState
*env
)
6376 gen_spr_ne_601(env
);
6379 gen_spr_G2_755(env
);
6382 /* L2 cache control */
6383 /* XXX : not implemented */
6384 spr_register(env
, SPR_L2CR
, "L2CR",
6385 SPR_NOACCESS
, SPR_NOACCESS
,
6386 &spr_read_generic
, spr_access_nop
,
6388 /* XXX : not implemented */
6389 spr_register(env
, SPR_L2PMCR
, "L2PMCR",
6390 SPR_NOACCESS
, SPR_NOACCESS
,
6391 &spr_read_generic
, &spr_write_generic
,
6393 /* Thermal management */
6395 /* Hardware implementation registers */
6396 /* XXX : not implemented */
6397 spr_register(env
, SPR_HID0
, "HID0",
6398 SPR_NOACCESS
, SPR_NOACCESS
,
6399 &spr_read_generic
, &spr_write_generic
,
6401 /* XXX : not implemented */
6402 spr_register(env
, SPR_HID1
, "HID1",
6403 SPR_NOACCESS
, SPR_NOACCESS
,
6404 &spr_read_generic
, &spr_write_generic
,
6406 /* XXX : not implemented */
6407 spr_register(env
, SPR_HID2
, "HID2",
6408 SPR_NOACCESS
, SPR_NOACCESS
,
6409 &spr_read_generic
, &spr_write_generic
,
6411 /* Memory management */
6414 gen_6xx_7xx_soft_tlb(env
, 64, 2);
6416 env
->dcache_line_size
= 32;
6417 env
->icache_line_size
= 32;
6418 /* Allocate hardware IRQ controller */
6419 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6422 POWERPC_FAMILY(755)(ObjectClass
*oc
, void *data
)
6424 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6425 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6427 dc
->desc
= "PowerPC 755";
6428 pcc
->init_proc
= init_proc_755
;
6429 pcc
->check_pow
= check_pow_hid0
;
6430 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6431 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6432 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6433 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6434 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6435 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
6436 PPC_SEGMENT
| PPC_EXTERN
;
6437 pcc
->msr_mask
= (1ull << MSR_POW
) |
6453 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
6454 pcc
->excp_model
= POWERPC_EXCP_7x5
;
6455 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6456 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6457 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6458 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6461 static void init_proc_7400(CPUPPCState
*env
)
6463 gen_spr_ne_601(env
);
6468 /* 74xx specific SPR */
6470 /* XXX : not implemented */
6471 spr_register(env
, SPR_UBAMR
, "UBAMR",
6472 &spr_read_ureg
, SPR_NOACCESS
,
6473 &spr_read_ureg
, SPR_NOACCESS
,
6475 /* XXX: this seems not implemented on all revisions. */
6476 /* XXX : not implemented */
6477 spr_register(env
, SPR_MSSCR1
, "MSSCR1",
6478 SPR_NOACCESS
, SPR_NOACCESS
,
6479 &spr_read_generic
, &spr_write_generic
,
6481 /* Thermal management */
6483 /* Memory management */
6485 init_excp_7400(env
);
6486 env
->dcache_line_size
= 32;
6487 env
->icache_line_size
= 32;
6488 /* Allocate hardware IRQ controller */
6489 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6492 POWERPC_FAMILY(7400)(ObjectClass
*oc
, void *data
)
6494 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6495 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6497 dc
->desc
= "PowerPC 7400 (aka G4)";
6498 pcc
->init_proc
= init_proc_7400
;
6499 pcc
->check_pow
= check_pow_hid0
;
6500 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6501 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6502 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6504 PPC_CACHE
| PPC_CACHE_ICBI
|
6505 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6506 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6507 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6509 PPC_SEGMENT
| PPC_EXTERN
|
6511 pcc
->msr_mask
= (1ull << MSR_VR
) |
6528 pcc
->mmu_model
= POWERPC_MMU_32B
;
6529 #if defined(CONFIG_SOFTMMU)
6530 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6532 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6533 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6534 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6535 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6536 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6537 POWERPC_FLAG_BUS_CLK
;
6540 static void init_proc_7410(CPUPPCState
*env
)
6542 gen_spr_ne_601(env
);
6547 /* 74xx specific SPR */
6549 /* XXX : not implemented */
6550 spr_register(env
, SPR_UBAMR
, "UBAMR",
6551 &spr_read_ureg
, SPR_NOACCESS
,
6552 &spr_read_ureg
, SPR_NOACCESS
,
6554 /* Thermal management */
6557 /* XXX : not implemented */
6558 spr_register(env
, SPR_L2PMCR
, "L2PMCR",
6559 SPR_NOACCESS
, SPR_NOACCESS
,
6560 &spr_read_generic
, &spr_write_generic
,
6563 /* XXX : not implemented */
6564 spr_register(env
, SPR_LDSTDB
, "LDSTDB",
6565 SPR_NOACCESS
, SPR_NOACCESS
,
6566 &spr_read_generic
, &spr_write_generic
,
6568 /* Memory management */
6570 init_excp_7400(env
);
6571 env
->dcache_line_size
= 32;
6572 env
->icache_line_size
= 32;
6573 /* Allocate hardware IRQ controller */
6574 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6577 POWERPC_FAMILY(7410)(ObjectClass
*oc
, void *data
)
6579 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6580 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6582 dc
->desc
= "PowerPC 7410 (aka G4)";
6583 pcc
->init_proc
= init_proc_7410
;
6584 pcc
->check_pow
= check_pow_hid0
;
6585 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6586 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6587 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6589 PPC_CACHE
| PPC_CACHE_ICBI
|
6590 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6591 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6592 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6594 PPC_SEGMENT
| PPC_EXTERN
|
6596 pcc
->msr_mask
= (1ull << MSR_VR
) |
6613 pcc
->mmu_model
= POWERPC_MMU_32B
;
6614 #if defined(CONFIG_SOFTMMU)
6615 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6617 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6618 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6619 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6620 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6621 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6622 POWERPC_FLAG_BUS_CLK
;
6625 static void init_proc_7440(CPUPPCState
*env
)
6627 gen_spr_ne_601(env
);
6632 /* 74xx specific SPR */
6634 /* XXX : not implemented */
6635 spr_register(env
, SPR_UBAMR
, "UBAMR",
6636 &spr_read_ureg
, SPR_NOACCESS
,
6637 &spr_read_ureg
, SPR_NOACCESS
,
6640 /* XXX : not implemented */
6641 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6642 SPR_NOACCESS
, SPR_NOACCESS
,
6643 &spr_read_generic
, &spr_write_generic
,
6646 /* XXX : not implemented */
6647 spr_register(env
, SPR_ICTRL
, "ICTRL",
6648 SPR_NOACCESS
, SPR_NOACCESS
,
6649 &spr_read_generic
, &spr_write_generic
,
6652 /* XXX : not implemented */
6653 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6654 SPR_NOACCESS
, SPR_NOACCESS
,
6655 &spr_read_generic
, &spr_write_generic
,
6658 /* XXX : not implemented */
6659 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6660 SPR_NOACCESS
, SPR_NOACCESS
,
6661 &spr_read_generic
, &spr_write_generic
,
6663 /* XXX : not implemented */
6664 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6665 &spr_read_ureg
, SPR_NOACCESS
,
6666 &spr_read_ureg
, SPR_NOACCESS
,
6668 /* XXX : not implemented */
6669 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6670 SPR_NOACCESS
, SPR_NOACCESS
,
6671 &spr_read_generic
, &spr_write_generic
,
6673 /* XXX : not implemented */
6674 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6675 &spr_read_ureg
, SPR_NOACCESS
,
6676 &spr_read_ureg
, SPR_NOACCESS
,
6678 /* Memory management */
6680 gen_74xx_soft_tlb(env
, 128, 2);
6681 init_excp_7450(env
);
6682 env
->dcache_line_size
= 32;
6683 env
->icache_line_size
= 32;
6684 /* Allocate hardware IRQ controller */
6685 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6688 POWERPC_FAMILY(7440)(ObjectClass
*oc
, void *data
)
6690 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6691 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6693 dc
->desc
= "PowerPC 7440 (aka G4)";
6694 pcc
->init_proc
= init_proc_7440
;
6695 pcc
->check_pow
= check_pow_hid0_74xx
;
6696 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6697 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6698 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6700 PPC_CACHE
| PPC_CACHE_ICBI
|
6701 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6702 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6703 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6704 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6705 PPC_SEGMENT
| PPC_EXTERN
|
6707 pcc
->msr_mask
= (1ull << MSR_VR
) |
6724 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6725 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6726 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6727 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6728 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6729 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6730 POWERPC_FLAG_BUS_CLK
;
6733 static void init_proc_7450(CPUPPCState
*env
)
6735 gen_spr_ne_601(env
);
6740 /* 74xx specific SPR */
6742 /* Level 3 cache control */
6745 /* XXX : not implemented */
6746 spr_register(env
, SPR_L3ITCR1
, "L3ITCR1",
6747 SPR_NOACCESS
, SPR_NOACCESS
,
6748 &spr_read_generic
, &spr_write_generic
,
6751 /* XXX : not implemented */
6752 spr_register(env
, SPR_L3ITCR2
, "L3ITCR2",
6753 SPR_NOACCESS
, SPR_NOACCESS
,
6754 &spr_read_generic
, &spr_write_generic
,
6757 /* XXX : not implemented */
6758 spr_register(env
, SPR_L3ITCR3
, "L3ITCR3",
6759 SPR_NOACCESS
, SPR_NOACCESS
,
6760 &spr_read_generic
, &spr_write_generic
,
6763 /* XXX : not implemented */
6764 spr_register(env
, SPR_L3OHCR
, "L3OHCR",
6765 SPR_NOACCESS
, SPR_NOACCESS
,
6766 &spr_read_generic
, &spr_write_generic
,
6768 /* XXX : not implemented */
6769 spr_register(env
, SPR_UBAMR
, "UBAMR",
6770 &spr_read_ureg
, SPR_NOACCESS
,
6771 &spr_read_ureg
, SPR_NOACCESS
,
6774 /* XXX : not implemented */
6775 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6776 SPR_NOACCESS
, SPR_NOACCESS
,
6777 &spr_read_generic
, &spr_write_generic
,
6780 /* XXX : not implemented */
6781 spr_register(env
, SPR_ICTRL
, "ICTRL",
6782 SPR_NOACCESS
, SPR_NOACCESS
,
6783 &spr_read_generic
, &spr_write_generic
,
6786 /* XXX : not implemented */
6787 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6788 SPR_NOACCESS
, SPR_NOACCESS
,
6789 &spr_read_generic
, &spr_write_generic
,
6792 /* XXX : not implemented */
6793 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6794 SPR_NOACCESS
, SPR_NOACCESS
,
6795 &spr_read_generic
, &spr_write_generic
,
6797 /* XXX : not implemented */
6798 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6799 &spr_read_ureg
, SPR_NOACCESS
,
6800 &spr_read_ureg
, SPR_NOACCESS
,
6802 /* XXX : not implemented */
6803 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6804 SPR_NOACCESS
, SPR_NOACCESS
,
6805 &spr_read_generic
, &spr_write_generic
,
6807 /* XXX : not implemented */
6808 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6809 &spr_read_ureg
, SPR_NOACCESS
,
6810 &spr_read_ureg
, SPR_NOACCESS
,
6812 /* Memory management */
6814 gen_74xx_soft_tlb(env
, 128, 2);
6815 init_excp_7450(env
);
6816 env
->dcache_line_size
= 32;
6817 env
->icache_line_size
= 32;
6818 /* Allocate hardware IRQ controller */
6819 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6822 POWERPC_FAMILY(7450)(ObjectClass
*oc
, void *data
)
6824 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6825 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6827 dc
->desc
= "PowerPC 7450 (aka G4)";
6828 pcc
->init_proc
= init_proc_7450
;
6829 pcc
->check_pow
= check_pow_hid0_74xx
;
6830 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6831 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6832 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6834 PPC_CACHE
| PPC_CACHE_ICBI
|
6835 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6836 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6837 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6838 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6839 PPC_SEGMENT
| PPC_EXTERN
|
6841 pcc
->msr_mask
= (1ull << MSR_VR
) |
6858 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6859 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6860 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6861 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6862 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6863 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6864 POWERPC_FLAG_BUS_CLK
;
6867 static void init_proc_7445(CPUPPCState
*env
)
6869 gen_spr_ne_601(env
);
6874 /* 74xx specific SPR */
6877 /* XXX : not implemented */
6878 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6879 SPR_NOACCESS
, SPR_NOACCESS
,
6880 &spr_read_generic
, &spr_write_generic
,
6883 /* XXX : not implemented */
6884 spr_register(env
, SPR_ICTRL
, "ICTRL",
6885 SPR_NOACCESS
, SPR_NOACCESS
,
6886 &spr_read_generic
, &spr_write_generic
,
6889 /* XXX : not implemented */
6890 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6891 SPR_NOACCESS
, SPR_NOACCESS
,
6892 &spr_read_generic
, &spr_write_generic
,
6895 /* XXX : not implemented */
6896 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6897 SPR_NOACCESS
, SPR_NOACCESS
,
6898 &spr_read_generic
, &spr_write_generic
,
6900 /* XXX : not implemented */
6901 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6902 &spr_read_ureg
, SPR_NOACCESS
,
6903 &spr_read_ureg
, SPR_NOACCESS
,
6905 /* XXX : not implemented */
6906 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6907 SPR_NOACCESS
, SPR_NOACCESS
,
6908 &spr_read_generic
, &spr_write_generic
,
6910 /* XXX : not implemented */
6911 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6912 &spr_read_ureg
, SPR_NOACCESS
,
6913 &spr_read_ureg
, SPR_NOACCESS
,
6916 spr_register(env
, SPR_SPRG4
, "SPRG4",
6917 SPR_NOACCESS
, SPR_NOACCESS
,
6918 &spr_read_generic
, &spr_write_generic
,
6920 spr_register(env
, SPR_USPRG4
, "USPRG4",
6921 &spr_read_ureg
, SPR_NOACCESS
,
6922 &spr_read_ureg
, SPR_NOACCESS
,
6924 spr_register(env
, SPR_SPRG5
, "SPRG5",
6925 SPR_NOACCESS
, SPR_NOACCESS
,
6926 &spr_read_generic
, &spr_write_generic
,
6928 spr_register(env
, SPR_USPRG5
, "USPRG5",
6929 &spr_read_ureg
, SPR_NOACCESS
,
6930 &spr_read_ureg
, SPR_NOACCESS
,
6932 spr_register(env
, SPR_SPRG6
, "SPRG6",
6933 SPR_NOACCESS
, SPR_NOACCESS
,
6934 &spr_read_generic
, &spr_write_generic
,
6936 spr_register(env
, SPR_USPRG6
, "USPRG6",
6937 &spr_read_ureg
, SPR_NOACCESS
,
6938 &spr_read_ureg
, SPR_NOACCESS
,
6940 spr_register(env
, SPR_SPRG7
, "SPRG7",
6941 SPR_NOACCESS
, SPR_NOACCESS
,
6942 &spr_read_generic
, &spr_write_generic
,
6944 spr_register(env
, SPR_USPRG7
, "USPRG7",
6945 &spr_read_ureg
, SPR_NOACCESS
,
6946 &spr_read_ureg
, SPR_NOACCESS
,
6948 /* Memory management */
6951 gen_74xx_soft_tlb(env
, 128, 2);
6952 init_excp_7450(env
);
6953 env
->dcache_line_size
= 32;
6954 env
->icache_line_size
= 32;
6955 /* Allocate hardware IRQ controller */
6956 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6959 POWERPC_FAMILY(7445)(ObjectClass
*oc
, void *data
)
6961 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6962 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6964 dc
->desc
= "PowerPC 7445 (aka G4)";
6965 pcc
->init_proc
= init_proc_7445
;
6966 pcc
->check_pow
= check_pow_hid0_74xx
;
6967 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6968 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6969 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6971 PPC_CACHE
| PPC_CACHE_ICBI
|
6972 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6973 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6974 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6975 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6976 PPC_SEGMENT
| PPC_EXTERN
|
6978 pcc
->msr_mask
= (1ull << MSR_VR
) |
6995 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6996 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6997 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6998 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6999 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7000 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7001 POWERPC_FLAG_BUS_CLK
;
7004 static void init_proc_7455(CPUPPCState
*env
)
7006 gen_spr_ne_601(env
);
7011 /* 74xx specific SPR */
7013 /* Level 3 cache control */
7016 /* XXX : not implemented */
7017 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7018 SPR_NOACCESS
, SPR_NOACCESS
,
7019 &spr_read_generic
, &spr_write_generic
,
7022 /* XXX : not implemented */
7023 spr_register(env
, SPR_ICTRL
, "ICTRL",
7024 SPR_NOACCESS
, SPR_NOACCESS
,
7025 &spr_read_generic
, &spr_write_generic
,
7028 /* XXX : not implemented */
7029 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7030 SPR_NOACCESS
, SPR_NOACCESS
,
7031 &spr_read_generic
, &spr_write_generic
,
7034 /* XXX : not implemented */
7035 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7036 SPR_NOACCESS
, SPR_NOACCESS
,
7037 &spr_read_generic
, &spr_write_generic
,
7039 /* XXX : not implemented */
7040 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7041 &spr_read_ureg
, SPR_NOACCESS
,
7042 &spr_read_ureg
, SPR_NOACCESS
,
7044 /* XXX : not implemented */
7045 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7046 SPR_NOACCESS
, SPR_NOACCESS
,
7047 &spr_read_generic
, &spr_write_generic
,
7049 /* XXX : not implemented */
7050 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7051 &spr_read_ureg
, SPR_NOACCESS
,
7052 &spr_read_ureg
, SPR_NOACCESS
,
7055 spr_register(env
, SPR_SPRG4
, "SPRG4",
7056 SPR_NOACCESS
, SPR_NOACCESS
,
7057 &spr_read_generic
, &spr_write_generic
,
7059 spr_register(env
, SPR_USPRG4
, "USPRG4",
7060 &spr_read_ureg
, SPR_NOACCESS
,
7061 &spr_read_ureg
, SPR_NOACCESS
,
7063 spr_register(env
, SPR_SPRG5
, "SPRG5",
7064 SPR_NOACCESS
, SPR_NOACCESS
,
7065 &spr_read_generic
, &spr_write_generic
,
7067 spr_register(env
, SPR_USPRG5
, "USPRG5",
7068 &spr_read_ureg
, SPR_NOACCESS
,
7069 &spr_read_ureg
, SPR_NOACCESS
,
7071 spr_register(env
, SPR_SPRG6
, "SPRG6",
7072 SPR_NOACCESS
, SPR_NOACCESS
,
7073 &spr_read_generic
, &spr_write_generic
,
7075 spr_register(env
, SPR_USPRG6
, "USPRG6",
7076 &spr_read_ureg
, SPR_NOACCESS
,
7077 &spr_read_ureg
, SPR_NOACCESS
,
7079 spr_register(env
, SPR_SPRG7
, "SPRG7",
7080 SPR_NOACCESS
, SPR_NOACCESS
,
7081 &spr_read_generic
, &spr_write_generic
,
7083 spr_register(env
, SPR_USPRG7
, "USPRG7",
7084 &spr_read_ureg
, SPR_NOACCESS
,
7085 &spr_read_ureg
, SPR_NOACCESS
,
7087 /* Memory management */
7090 gen_74xx_soft_tlb(env
, 128, 2);
7091 init_excp_7450(env
);
7092 env
->dcache_line_size
= 32;
7093 env
->icache_line_size
= 32;
7094 /* Allocate hardware IRQ controller */
7095 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7098 POWERPC_FAMILY(7455)(ObjectClass
*oc
, void *data
)
7100 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7101 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7103 dc
->desc
= "PowerPC 7455 (aka G4)";
7104 pcc
->init_proc
= init_proc_7455
;
7105 pcc
->check_pow
= check_pow_hid0_74xx
;
7106 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7107 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7108 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7110 PPC_CACHE
| PPC_CACHE_ICBI
|
7111 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7112 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7113 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7114 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7115 PPC_SEGMENT
| PPC_EXTERN
|
7117 pcc
->msr_mask
= (1ull << MSR_VR
) |
7134 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7135 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7136 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7137 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7138 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7139 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7140 POWERPC_FLAG_BUS_CLK
;
7143 static void init_proc_7457(CPUPPCState
*env
)
7145 gen_spr_ne_601(env
);
7150 /* 74xx specific SPR */
7152 /* Level 3 cache control */
7155 /* XXX : not implemented */
7156 spr_register(env
, SPR_L3ITCR1
, "L3ITCR1",
7157 SPR_NOACCESS
, SPR_NOACCESS
,
7158 &spr_read_generic
, &spr_write_generic
,
7161 /* XXX : not implemented */
7162 spr_register(env
, SPR_L3ITCR2
, "L3ITCR2",
7163 SPR_NOACCESS
, SPR_NOACCESS
,
7164 &spr_read_generic
, &spr_write_generic
,
7167 /* XXX : not implemented */
7168 spr_register(env
, SPR_L3ITCR3
, "L3ITCR3",
7169 SPR_NOACCESS
, SPR_NOACCESS
,
7170 &spr_read_generic
, &spr_write_generic
,
7173 /* XXX : not implemented */
7174 spr_register(env
, SPR_L3OHCR
, "L3OHCR",
7175 SPR_NOACCESS
, SPR_NOACCESS
,
7176 &spr_read_generic
, &spr_write_generic
,
7179 /* XXX : not implemented */
7180 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7181 SPR_NOACCESS
, SPR_NOACCESS
,
7182 &spr_read_generic
, &spr_write_generic
,
7185 /* XXX : not implemented */
7186 spr_register(env
, SPR_ICTRL
, "ICTRL",
7187 SPR_NOACCESS
, SPR_NOACCESS
,
7188 &spr_read_generic
, &spr_write_generic
,
7191 /* XXX : not implemented */
7192 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7193 SPR_NOACCESS
, SPR_NOACCESS
,
7194 &spr_read_generic
, &spr_write_generic
,
7197 /* XXX : not implemented */
7198 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7199 SPR_NOACCESS
, SPR_NOACCESS
,
7200 &spr_read_generic
, &spr_write_generic
,
7202 /* XXX : not implemented */
7203 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7204 &spr_read_ureg
, SPR_NOACCESS
,
7205 &spr_read_ureg
, SPR_NOACCESS
,
7207 /* XXX : not implemented */
7208 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7209 SPR_NOACCESS
, SPR_NOACCESS
,
7210 &spr_read_generic
, &spr_write_generic
,
7212 /* XXX : not implemented */
7213 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7214 &spr_read_ureg
, SPR_NOACCESS
,
7215 &spr_read_ureg
, SPR_NOACCESS
,
7218 spr_register(env
, SPR_SPRG4
, "SPRG4",
7219 SPR_NOACCESS
, SPR_NOACCESS
,
7220 &spr_read_generic
, &spr_write_generic
,
7222 spr_register(env
, SPR_USPRG4
, "USPRG4",
7223 &spr_read_ureg
, SPR_NOACCESS
,
7224 &spr_read_ureg
, SPR_NOACCESS
,
7226 spr_register(env
, SPR_SPRG5
, "SPRG5",
7227 SPR_NOACCESS
, SPR_NOACCESS
,
7228 &spr_read_generic
, &spr_write_generic
,
7230 spr_register(env
, SPR_USPRG5
, "USPRG5",
7231 &spr_read_ureg
, SPR_NOACCESS
,
7232 &spr_read_ureg
, SPR_NOACCESS
,
7234 spr_register(env
, SPR_SPRG6
, "SPRG6",
7235 SPR_NOACCESS
, SPR_NOACCESS
,
7236 &spr_read_generic
, &spr_write_generic
,
7238 spr_register(env
, SPR_USPRG6
, "USPRG6",
7239 &spr_read_ureg
, SPR_NOACCESS
,
7240 &spr_read_ureg
, SPR_NOACCESS
,
7242 spr_register(env
, SPR_SPRG7
, "SPRG7",
7243 SPR_NOACCESS
, SPR_NOACCESS
,
7244 &spr_read_generic
, &spr_write_generic
,
7246 spr_register(env
, SPR_USPRG7
, "USPRG7",
7247 &spr_read_ureg
, SPR_NOACCESS
,
7248 &spr_read_ureg
, SPR_NOACCESS
,
7250 /* Memory management */
7253 gen_74xx_soft_tlb(env
, 128, 2);
7254 init_excp_7450(env
);
7255 env
->dcache_line_size
= 32;
7256 env
->icache_line_size
= 32;
7257 /* Allocate hardware IRQ controller */
7258 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7261 POWERPC_FAMILY(7457)(ObjectClass
*oc
, void *data
)
7263 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7264 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7266 dc
->desc
= "PowerPC 7457 (aka G4)";
7267 pcc
->init_proc
= init_proc_7457
;
7268 pcc
->check_pow
= check_pow_hid0_74xx
;
7269 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7270 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7271 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7273 PPC_CACHE
| PPC_CACHE_ICBI
|
7274 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7275 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7276 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7277 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7278 PPC_SEGMENT
| PPC_EXTERN
|
7280 pcc
->msr_mask
= (1ull << MSR_VR
) |
7297 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7298 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7299 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7300 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7301 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7302 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7303 POWERPC_FLAG_BUS_CLK
;
7306 static void init_proc_e600(CPUPPCState
*env
)
7308 gen_spr_ne_601(env
);
7313 /* 74xx specific SPR */
7315 /* XXX : not implemented */
7316 spr_register(env
, SPR_UBAMR
, "UBAMR",
7317 &spr_read_ureg
, SPR_NOACCESS
,
7318 &spr_read_ureg
, SPR_NOACCESS
,
7320 /* XXX : not implemented */
7321 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7322 SPR_NOACCESS
, SPR_NOACCESS
,
7323 &spr_read_generic
, &spr_write_generic
,
7325 /* XXX : not implemented */
7326 spr_register(env
, SPR_ICTRL
, "ICTRL",
7327 SPR_NOACCESS
, SPR_NOACCESS
,
7328 &spr_read_generic
, &spr_write_generic
,
7330 /* XXX : not implemented */
7331 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7332 SPR_NOACCESS
, SPR_NOACCESS
,
7333 &spr_read_generic
, &spr_write_generic
,
7335 /* XXX : not implemented */
7336 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7337 SPR_NOACCESS
, SPR_NOACCESS
,
7338 &spr_read_generic
, &spr_write_generic
,
7340 /* XXX : not implemented */
7341 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7342 &spr_read_ureg
, SPR_NOACCESS
,
7343 &spr_read_ureg
, SPR_NOACCESS
,
7345 /* XXX : not implemented */
7346 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7347 SPR_NOACCESS
, SPR_NOACCESS
,
7348 &spr_read_generic
, &spr_write_generic
,
7350 /* XXX : not implemented */
7351 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7352 &spr_read_ureg
, SPR_NOACCESS
,
7353 &spr_read_ureg
, SPR_NOACCESS
,
7356 spr_register(env
, SPR_SPRG4
, "SPRG4",
7357 SPR_NOACCESS
, SPR_NOACCESS
,
7358 &spr_read_generic
, &spr_write_generic
,
7360 spr_register(env
, SPR_USPRG4
, "USPRG4",
7361 &spr_read_ureg
, SPR_NOACCESS
,
7362 &spr_read_ureg
, SPR_NOACCESS
,
7364 spr_register(env
, SPR_SPRG5
, "SPRG5",
7365 SPR_NOACCESS
, SPR_NOACCESS
,
7366 &spr_read_generic
, &spr_write_generic
,
7368 spr_register(env
, SPR_USPRG5
, "USPRG5",
7369 &spr_read_ureg
, SPR_NOACCESS
,
7370 &spr_read_ureg
, SPR_NOACCESS
,
7372 spr_register(env
, SPR_SPRG6
, "SPRG6",
7373 SPR_NOACCESS
, SPR_NOACCESS
,
7374 &spr_read_generic
, &spr_write_generic
,
7376 spr_register(env
, SPR_USPRG6
, "USPRG6",
7377 &spr_read_ureg
, SPR_NOACCESS
,
7378 &spr_read_ureg
, SPR_NOACCESS
,
7380 spr_register(env
, SPR_SPRG7
, "SPRG7",
7381 SPR_NOACCESS
, SPR_NOACCESS
,
7382 &spr_read_generic
, &spr_write_generic
,
7384 spr_register(env
, SPR_USPRG7
, "USPRG7",
7385 &spr_read_ureg
, SPR_NOACCESS
,
7386 &spr_read_ureg
, SPR_NOACCESS
,
7388 /* Memory management */
7391 gen_74xx_soft_tlb(env
, 128, 2);
7392 init_excp_7450(env
);
7393 env
->dcache_line_size
= 32;
7394 env
->icache_line_size
= 32;
7395 /* Allocate hardware IRQ controller */
7396 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7399 POWERPC_FAMILY(e600
)(ObjectClass
*oc
, void *data
)
7401 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7402 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7404 dc
->desc
= "PowerPC e600";
7405 pcc
->init_proc
= init_proc_e600
;
7406 pcc
->check_pow
= check_pow_hid0_74xx
;
7407 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7408 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7409 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7411 PPC_CACHE
| PPC_CACHE_ICBI
|
7412 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7413 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7414 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7415 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7416 PPC_SEGMENT
| PPC_EXTERN
|
7418 pcc
->insns_flags2
= PPC_NONE
;
7419 pcc
->msr_mask
= (1ull << MSR_VR
) |
7436 pcc
->mmu_model
= POWERPC_MMU_32B
;
7437 #if defined(CONFIG_SOFTMMU)
7438 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
7440 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7441 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7442 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7443 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7444 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7445 POWERPC_FLAG_BUS_CLK
;
7448 #if defined(TARGET_PPC64)
7449 #if defined(CONFIG_USER_ONLY)
7450 #define POWERPC970_HID5_INIT 0x00000080
7452 #define POWERPC970_HID5_INIT 0x00000000
7455 static void gen_fscr_facility_check(DisasContext
*ctx
, int facility_sprn
,
7456 int bit
, int sprn
, int cause
)
7458 TCGv_i32 t1
= tcg_const_i32(bit
);
7459 TCGv_i32 t2
= tcg_const_i32(sprn
);
7460 TCGv_i32 t3
= tcg_const_i32(cause
);
7462 gen_helper_fscr_facility_check(cpu_env
, t1
, t2
, t3
);
7464 tcg_temp_free_i32(t3
);
7465 tcg_temp_free_i32(t2
);
7466 tcg_temp_free_i32(t1
);
7469 static void gen_msr_facility_check(DisasContext
*ctx
, int facility_sprn
,
7470 int bit
, int sprn
, int cause
)
7472 TCGv_i32 t1
= tcg_const_i32(bit
);
7473 TCGv_i32 t2
= tcg_const_i32(sprn
);
7474 TCGv_i32 t3
= tcg_const_i32(cause
);
7476 gen_helper_msr_facility_check(cpu_env
, t1
, t2
, t3
);
7478 tcg_temp_free_i32(t3
);
7479 tcg_temp_free_i32(t2
);
7480 tcg_temp_free_i32(t1
);
7483 static void spr_read_prev_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
7485 TCGv spr_up
= tcg_temp_new();
7486 TCGv spr
= tcg_temp_new();
7488 gen_load_spr(spr
, sprn
- 1);
7489 tcg_gen_shri_tl(spr_up
, spr
, 32);
7490 tcg_gen_ext32u_tl(cpu_gpr
[gprn
], spr_up
);
7493 tcg_temp_free(spr_up
);
7496 static void spr_write_prev_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
7498 TCGv spr
= tcg_temp_new();
7500 gen_load_spr(spr
, sprn
- 1);
7501 tcg_gen_deposit_tl(spr
, spr
, cpu_gpr
[gprn
], 32, 32);
7502 gen_store_spr(sprn
- 1, spr
);
7507 static int check_pow_970(CPUPPCState
*env
)
7509 if (env
->spr
[SPR_HID0
] & (HID0_DEEPNAP
| HID0_DOZE
| HID0_NAP
)) {
7516 static void gen_spr_970_hid(CPUPPCState
*env
)
7518 /* Hardware implementation registers */
7519 /* XXX : not implemented */
7520 spr_register(env
, SPR_HID0
, "HID0",
7521 SPR_NOACCESS
, SPR_NOACCESS
,
7522 &spr_read_generic
, &spr_write_clear
,
7524 spr_register(env
, SPR_HID1
, "HID1",
7525 SPR_NOACCESS
, SPR_NOACCESS
,
7526 &spr_read_generic
, &spr_write_generic
,
7528 spr_register(env
, SPR_970_HID5
, "HID5",
7529 SPR_NOACCESS
, SPR_NOACCESS
,
7530 &spr_read_generic
, &spr_write_generic
,
7531 POWERPC970_HID5_INIT
);
7534 static void gen_spr_970_hior(CPUPPCState
*env
)
7536 spr_register(env
, SPR_HIOR
, "SPR_HIOR",
7537 SPR_NOACCESS
, SPR_NOACCESS
,
7538 &spr_read_hior
, &spr_write_hior
,
7542 static void gen_spr_book3s_ctrl(CPUPPCState
*env
)
7544 spr_register(env
, SPR_CTRL
, "SPR_CTRL",
7545 SPR_NOACCESS
, SPR_NOACCESS
,
7546 SPR_NOACCESS
, &spr_write_generic
,
7548 spr_register(env
, SPR_UCTRL
, "SPR_UCTRL",
7549 &spr_read_ureg
, SPR_NOACCESS
,
7550 &spr_read_ureg
, SPR_NOACCESS
,
7554 static void gen_spr_book3s_altivec(CPUPPCState
*env
)
7556 if (!(env
->insns_flags
& PPC_ALTIVEC
)) {
7560 spr_register_kvm(env
, SPR_VRSAVE
, "VRSAVE",
7561 &spr_read_generic
, &spr_write_generic
,
7562 &spr_read_generic
, &spr_write_generic
,
7563 KVM_REG_PPC_VRSAVE
, 0x00000000);
7565 /* Can't find information on what this should be on reset. This
7566 * value is the one used by 74xx processors. */
7567 vscr_init(env
, 0x00010000);
7570 static void gen_spr_book3s_dbg(CPUPPCState
*env
)
7573 * TODO: different specs define different scopes for these,
7574 * will have to address this:
7575 * 970: super/write and super/read
7576 * powerisa 2.03..2.04: hypv/write and super/read.
7577 * powerisa 2.05 and newer: hypv/write and hypv/read.
7579 spr_register_kvm(env
, SPR_DABR
, "DABR",
7580 SPR_NOACCESS
, SPR_NOACCESS
,
7581 &spr_read_generic
, &spr_write_generic
,
7582 KVM_REG_PPC_DABR
, 0x00000000);
7583 spr_register_kvm(env
, SPR_DABRX
, "DABRX",
7584 SPR_NOACCESS
, SPR_NOACCESS
,
7585 &spr_read_generic
, &spr_write_generic
,
7586 KVM_REG_PPC_DABRX
, 0x00000000);
7589 static void gen_spr_book3s_207_dbg(CPUPPCState
*env
)
7591 spr_register_kvm_hv(env
, SPR_DAWR
, "DAWR",
7592 SPR_NOACCESS
, SPR_NOACCESS
,
7593 SPR_NOACCESS
, SPR_NOACCESS
,
7594 &spr_read_generic
, &spr_write_generic
,
7595 KVM_REG_PPC_DAWR
, 0x00000000);
7596 spr_register_kvm_hv(env
, SPR_DAWRX
, "DAWRX",
7597 SPR_NOACCESS
, SPR_NOACCESS
,
7598 SPR_NOACCESS
, SPR_NOACCESS
,
7599 &spr_read_generic
, &spr_write_generic
,
7600 KVM_REG_PPC_DAWRX
, 0x00000000);
7601 spr_register_kvm_hv(env
, SPR_CIABR
, "CIABR",
7602 SPR_NOACCESS
, SPR_NOACCESS
,
7603 SPR_NOACCESS
, SPR_NOACCESS
,
7604 &spr_read_generic
, &spr_write_generic
,
7605 KVM_REG_PPC_CIABR
, 0x00000000);
7608 static void gen_spr_970_dbg(CPUPPCState
*env
)
7611 spr_register(env
, SPR_IABR
, "IABR",
7612 SPR_NOACCESS
, SPR_NOACCESS
,
7613 &spr_read_generic
, &spr_write_generic
,
7617 static void gen_spr_book3s_pmu_sup(CPUPPCState
*env
)
7619 spr_register_kvm(env
, SPR_POWER_MMCR0
, "MMCR0",
7620 SPR_NOACCESS
, SPR_NOACCESS
,
7621 &spr_read_generic
, &spr_write_generic
,
7622 KVM_REG_PPC_MMCR0
, 0x00000000);
7623 spr_register_kvm(env
, SPR_POWER_MMCR1
, "MMCR1",
7624 SPR_NOACCESS
, SPR_NOACCESS
,
7625 &spr_read_generic
, &spr_write_generic
,
7626 KVM_REG_PPC_MMCR1
, 0x00000000);
7627 spr_register_kvm(env
, SPR_POWER_MMCRA
, "MMCRA",
7628 SPR_NOACCESS
, SPR_NOACCESS
,
7629 &spr_read_generic
, &spr_write_generic
,
7630 KVM_REG_PPC_MMCRA
, 0x00000000);
7631 spr_register_kvm(env
, SPR_POWER_PMC1
, "PMC1",
7632 SPR_NOACCESS
, SPR_NOACCESS
,
7633 &spr_read_generic
, &spr_write_generic
,
7634 KVM_REG_PPC_PMC1
, 0x00000000);
7635 spr_register_kvm(env
, SPR_POWER_PMC2
, "PMC2",
7636 SPR_NOACCESS
, SPR_NOACCESS
,
7637 &spr_read_generic
, &spr_write_generic
,
7638 KVM_REG_PPC_PMC2
, 0x00000000);
7639 spr_register_kvm(env
, SPR_POWER_PMC3
, "PMC3",
7640 SPR_NOACCESS
, SPR_NOACCESS
,
7641 &spr_read_generic
, &spr_write_generic
,
7642 KVM_REG_PPC_PMC3
, 0x00000000);
7643 spr_register_kvm(env
, SPR_POWER_PMC4
, "PMC4",
7644 SPR_NOACCESS
, SPR_NOACCESS
,
7645 &spr_read_generic
, &spr_write_generic
,
7646 KVM_REG_PPC_PMC4
, 0x00000000);
7647 spr_register_kvm(env
, SPR_POWER_PMC5
, "PMC5",
7648 SPR_NOACCESS
, SPR_NOACCESS
,
7649 &spr_read_generic
, &spr_write_generic
,
7650 KVM_REG_PPC_PMC5
, 0x00000000);
7651 spr_register_kvm(env
, SPR_POWER_PMC6
, "PMC6",
7652 SPR_NOACCESS
, SPR_NOACCESS
,
7653 &spr_read_generic
, &spr_write_generic
,
7654 KVM_REG_PPC_PMC6
, 0x00000000);
7655 spr_register_kvm(env
, SPR_POWER_SIAR
, "SIAR",
7656 SPR_NOACCESS
, SPR_NOACCESS
,
7657 &spr_read_generic
, &spr_write_generic
,
7658 KVM_REG_PPC_SIAR
, 0x00000000);
7659 spr_register_kvm(env
, SPR_POWER_SDAR
, "SDAR",
7660 SPR_NOACCESS
, SPR_NOACCESS
,
7661 &spr_read_generic
, &spr_write_generic
,
7662 KVM_REG_PPC_SDAR
, 0x00000000);
7665 static void gen_spr_book3s_pmu_user(CPUPPCState
*env
)
7667 spr_register(env
, SPR_POWER_UMMCR0
, "UMMCR0",
7668 &spr_read_ureg
, SPR_NOACCESS
,
7669 &spr_read_ureg
, &spr_write_ureg
,
7671 spr_register(env
, SPR_POWER_UMMCR1
, "UMMCR1",
7672 &spr_read_ureg
, SPR_NOACCESS
,
7673 &spr_read_ureg
, &spr_write_ureg
,
7675 spr_register(env
, SPR_POWER_UMMCRA
, "UMMCRA",
7676 &spr_read_ureg
, SPR_NOACCESS
,
7677 &spr_read_ureg
, &spr_write_ureg
,
7679 spr_register(env
, SPR_POWER_UPMC1
, "UPMC1",
7680 &spr_read_ureg
, SPR_NOACCESS
,
7681 &spr_read_ureg
, &spr_write_ureg
,
7683 spr_register(env
, SPR_POWER_UPMC2
, "UPMC2",
7684 &spr_read_ureg
, SPR_NOACCESS
,
7685 &spr_read_ureg
, &spr_write_ureg
,
7687 spr_register(env
, SPR_POWER_UPMC3
, "UPMC3",
7688 &spr_read_ureg
, SPR_NOACCESS
,
7689 &spr_read_ureg
, &spr_write_ureg
,
7691 spr_register(env
, SPR_POWER_UPMC4
, "UPMC4",
7692 &spr_read_ureg
, SPR_NOACCESS
,
7693 &spr_read_ureg
, &spr_write_ureg
,
7695 spr_register(env
, SPR_POWER_UPMC5
, "UPMC5",
7696 &spr_read_ureg
, SPR_NOACCESS
,
7697 &spr_read_ureg
, &spr_write_ureg
,
7699 spr_register(env
, SPR_POWER_UPMC6
, "UPMC6",
7700 &spr_read_ureg
, SPR_NOACCESS
,
7701 &spr_read_ureg
, &spr_write_ureg
,
7703 spr_register(env
, SPR_POWER_USIAR
, "USIAR",
7704 &spr_read_ureg
, SPR_NOACCESS
,
7705 &spr_read_ureg
, &spr_write_ureg
,
7707 spr_register(env
, SPR_POWER_USDAR
, "USDAR",
7708 &spr_read_ureg
, SPR_NOACCESS
,
7709 &spr_read_ureg
, &spr_write_ureg
,
7713 static void gen_spr_970_pmu_sup(CPUPPCState
*env
)
7715 spr_register_kvm(env
, SPR_970_PMC7
, "PMC7",
7716 SPR_NOACCESS
, SPR_NOACCESS
,
7717 &spr_read_generic
, &spr_write_generic
,
7718 KVM_REG_PPC_PMC7
, 0x00000000);
7719 spr_register_kvm(env
, SPR_970_PMC8
, "PMC8",
7720 SPR_NOACCESS
, SPR_NOACCESS
,
7721 &spr_read_generic
, &spr_write_generic
,
7722 KVM_REG_PPC_PMC8
, 0x00000000);
7725 static void gen_spr_970_pmu_user(CPUPPCState
*env
)
7727 spr_register(env
, SPR_970_UPMC7
, "UPMC7",
7728 &spr_read_ureg
, SPR_NOACCESS
,
7729 &spr_read_ureg
, &spr_write_ureg
,
7731 spr_register(env
, SPR_970_UPMC8
, "UPMC8",
7732 &spr_read_ureg
, SPR_NOACCESS
,
7733 &spr_read_ureg
, &spr_write_ureg
,
7737 static void gen_spr_power8_pmu_sup(CPUPPCState
*env
)
7739 spr_register_kvm(env
, SPR_POWER_MMCR2
, "MMCR2",
7740 SPR_NOACCESS
, SPR_NOACCESS
,
7741 &spr_read_generic
, &spr_write_generic
,
7742 KVM_REG_PPC_MMCR2
, 0x00000000);
7743 spr_register_kvm(env
, SPR_POWER_MMCRS
, "MMCRS",
7744 SPR_NOACCESS
, SPR_NOACCESS
,
7745 &spr_read_generic
, &spr_write_generic
,
7746 KVM_REG_PPC_MMCRS
, 0x00000000);
7747 spr_register_kvm(env
, SPR_POWER_SIER
, "SIER",
7748 SPR_NOACCESS
, SPR_NOACCESS
,
7749 &spr_read_generic
, &spr_write_generic
,
7750 KVM_REG_PPC_SIER
, 0x00000000);
7751 spr_register_kvm(env
, SPR_POWER_SPMC1
, "SPMC1",
7752 SPR_NOACCESS
, SPR_NOACCESS
,
7753 &spr_read_generic
, &spr_write_generic
,
7754 KVM_REG_PPC_SPMC1
, 0x00000000);
7755 spr_register_kvm(env
, SPR_POWER_SPMC2
, "SPMC2",
7756 SPR_NOACCESS
, SPR_NOACCESS
,
7757 &spr_read_generic
, &spr_write_generic
,
7758 KVM_REG_PPC_SPMC2
, 0x00000000);
7759 spr_register_kvm(env
, SPR_TACR
, "TACR",
7760 SPR_NOACCESS
, SPR_NOACCESS
,
7761 &spr_read_generic
, &spr_write_generic
,
7762 KVM_REG_PPC_TACR
, 0x00000000);
7763 spr_register_kvm(env
, SPR_TCSCR
, "TCSCR",
7764 SPR_NOACCESS
, SPR_NOACCESS
,
7765 &spr_read_generic
, &spr_write_generic
,
7766 KVM_REG_PPC_TCSCR
, 0x00000000);
7767 spr_register_kvm(env
, SPR_CSIGR
, "CSIGR",
7768 SPR_NOACCESS
, SPR_NOACCESS
,
7769 &spr_read_generic
, &spr_write_generic
,
7770 KVM_REG_PPC_CSIGR
, 0x00000000);
7773 static void gen_spr_power8_pmu_user(CPUPPCState
*env
)
7775 spr_register(env
, SPR_POWER_UMMCR2
, "UMMCR2",
7776 &spr_read_ureg
, SPR_NOACCESS
,
7777 &spr_read_ureg
, &spr_write_ureg
,
7779 spr_register(env
, SPR_POWER_USIER
, "USIER",
7780 &spr_read_generic
, SPR_NOACCESS
,
7781 &spr_read_generic
, &spr_write_generic
,
7785 static void gen_spr_power5p_ear(CPUPPCState
*env
)
7787 /* External access control */
7788 spr_register(env
, SPR_EAR
, "EAR",
7789 SPR_NOACCESS
, SPR_NOACCESS
,
7790 &spr_read_generic
, &spr_write_generic
,
7794 #if !defined(CONFIG_USER_ONLY)
7795 static void spr_write_hmer(DisasContext
*ctx
, int sprn
, int gprn
)
7797 TCGv hmer
= tcg_temp_new();
7799 gen_load_spr(hmer
, sprn
);
7800 tcg_gen_and_tl(hmer
, cpu_gpr
[gprn
], hmer
);
7801 gen_store_spr(sprn
, hmer
);
7802 spr_store_dump_spr(sprn
);
7803 tcg_temp_free(hmer
);
7806 static void spr_write_lpcr(DisasContext
*ctx
, int sprn
, int gprn
)
7808 gen_helper_store_lpcr(cpu_env
, cpu_gpr
[gprn
]);
7811 static void spr_write_970_hid4(DisasContext
*ctx
, int sprn
, int gprn
)
7813 #if defined(TARGET_PPC64)
7814 spr_write_generic(ctx
, sprn
, gprn
);
7815 gen_helper_store_lpcr(cpu_env
, cpu_gpr
[gprn
]);
7819 #endif /* !defined(CONFIG_USER_ONLY) */
7821 static void gen_spr_970_lpar(CPUPPCState
*env
)
7823 #if !defined(CONFIG_USER_ONLY)
7824 /* Logical partitionning */
7825 /* PPC970: HID4 is effectively the LPCR */
7826 spr_register(env
, SPR_970_HID4
, "HID4",
7827 SPR_NOACCESS
, SPR_NOACCESS
,
7828 &spr_read_generic
, &spr_write_970_hid4
,
7833 static void gen_spr_power5p_lpar(CPUPPCState
*env
)
7835 #if !defined(CONFIG_USER_ONLY)
7836 /* Logical partitionning */
7837 spr_register_kvm_hv(env
, SPR_LPCR
, "LPCR",
7838 SPR_NOACCESS
, SPR_NOACCESS
,
7839 SPR_NOACCESS
, SPR_NOACCESS
,
7840 &spr_read_generic
, &spr_write_lpcr
,
7841 KVM_REG_PPC_LPCR
, LPCR_LPES0
| LPCR_LPES1
);
7842 spr_register_hv(env
, SPR_HDEC
, "HDEC",
7843 SPR_NOACCESS
, SPR_NOACCESS
,
7844 SPR_NOACCESS
, SPR_NOACCESS
,
7845 &spr_read_hdecr
, &spr_write_hdecr
, 0);
7849 static void gen_spr_book3s_ids(CPUPPCState
*env
)
7851 /* FIXME: Will need to deal with thread vs core only SPRs */
7853 /* Processor identification */
7854 spr_register_hv(env
, SPR_PIR
, "PIR",
7855 SPR_NOACCESS
, SPR_NOACCESS
,
7856 &spr_read_generic
, SPR_NOACCESS
,
7857 &spr_read_generic
, NULL
,
7859 spr_register_hv(env
, SPR_HID0
, "HID0",
7860 SPR_NOACCESS
, SPR_NOACCESS
,
7861 SPR_NOACCESS
, SPR_NOACCESS
,
7862 &spr_read_generic
, &spr_write_generic
,
7864 spr_register_hv(env
, SPR_TSCR
, "TSCR",
7865 SPR_NOACCESS
, SPR_NOACCESS
,
7866 SPR_NOACCESS
, SPR_NOACCESS
,
7867 &spr_read_generic
, &spr_write_generic
,
7869 spr_register_hv(env
, SPR_HMER
, "HMER",
7870 SPR_NOACCESS
, SPR_NOACCESS
,
7871 SPR_NOACCESS
, SPR_NOACCESS
,
7872 &spr_read_generic
, &spr_write_hmer
,
7874 spr_register_hv(env
, SPR_HMEER
, "HMEER",
7875 SPR_NOACCESS
, SPR_NOACCESS
,
7876 SPR_NOACCESS
, SPR_NOACCESS
,
7877 &spr_read_generic
, &spr_write_generic
,
7879 spr_register_hv(env
, SPR_TFMR
, "TFMR",
7880 SPR_NOACCESS
, SPR_NOACCESS
,
7881 SPR_NOACCESS
, SPR_NOACCESS
,
7882 &spr_read_generic
, &spr_write_generic
,
7884 spr_register_hv(env
, SPR_LPIDR
, "LPIDR",
7885 SPR_NOACCESS
, SPR_NOACCESS
,
7886 SPR_NOACCESS
, SPR_NOACCESS
,
7887 &spr_read_generic
, &spr_write_generic
,
7889 spr_register_hv(env
, SPR_HFSCR
, "HFSCR",
7890 SPR_NOACCESS
, SPR_NOACCESS
,
7891 SPR_NOACCESS
, SPR_NOACCESS
,
7892 &spr_read_generic
, &spr_write_generic
,
7894 spr_register_hv(env
, SPR_MMCRC
, "MMCRC",
7895 SPR_NOACCESS
, SPR_NOACCESS
,
7896 SPR_NOACCESS
, SPR_NOACCESS
,
7897 &spr_read_generic
, &spr_write_generic
,
7899 spr_register_hv(env
, SPR_MMCRH
, "MMCRH",
7900 SPR_NOACCESS
, SPR_NOACCESS
,
7901 SPR_NOACCESS
, SPR_NOACCESS
,
7902 &spr_read_generic
, &spr_write_generic
,
7904 spr_register_hv(env
, SPR_HSPRG0
, "HSPRG0",
7905 SPR_NOACCESS
, SPR_NOACCESS
,
7906 SPR_NOACCESS
, SPR_NOACCESS
,
7907 &spr_read_generic
, &spr_write_generic
,
7909 spr_register_hv(env
, SPR_HSPRG1
, "HSPRG1",
7910 SPR_NOACCESS
, SPR_NOACCESS
,
7911 SPR_NOACCESS
, SPR_NOACCESS
,
7912 &spr_read_generic
, &spr_write_generic
,
7914 spr_register_hv(env
, SPR_HSRR0
, "HSRR0",
7915 SPR_NOACCESS
, SPR_NOACCESS
,
7916 SPR_NOACCESS
, SPR_NOACCESS
,
7917 &spr_read_generic
, &spr_write_generic
,
7919 spr_register_hv(env
, SPR_HSRR1
, "HSRR1",
7920 SPR_NOACCESS
, SPR_NOACCESS
,
7921 SPR_NOACCESS
, SPR_NOACCESS
,
7922 &spr_read_generic
, &spr_write_generic
,
7924 spr_register_hv(env
, SPR_HDAR
, "HDAR",
7925 SPR_NOACCESS
, SPR_NOACCESS
,
7926 SPR_NOACCESS
, SPR_NOACCESS
,
7927 &spr_read_generic
, &spr_write_generic
,
7929 spr_register_hv(env
, SPR_HDSISR
, "HDSISR",
7930 SPR_NOACCESS
, SPR_NOACCESS
,
7931 SPR_NOACCESS
, SPR_NOACCESS
,
7932 &spr_read_generic
, &spr_write_generic
,
7934 spr_register_hv(env
, SPR_RMOR
, "RMOR",
7935 SPR_NOACCESS
, SPR_NOACCESS
,
7936 SPR_NOACCESS
, SPR_NOACCESS
,
7937 &spr_read_generic
, &spr_write_generic
,
7939 spr_register_hv(env
, SPR_HRMOR
, "HRMOR",
7940 SPR_NOACCESS
, SPR_NOACCESS
,
7941 SPR_NOACCESS
, SPR_NOACCESS
,
7942 &spr_read_generic
, &spr_write_generic
,
7946 static void gen_spr_power8_ids(CPUPPCState
*env
)
7948 /* Thread identification */
7949 spr_register(env
, SPR_TIR
, "TIR",
7950 SPR_NOACCESS
, SPR_NOACCESS
,
7951 &spr_read_generic
, SPR_NOACCESS
,
7955 static void gen_spr_book3s_purr(CPUPPCState
*env
)
7957 #if !defined(CONFIG_USER_ONLY)
7958 /* PURR & SPURR: Hack - treat these as aliases for the TB for now */
7959 spr_register_kvm(env
, SPR_PURR
, "PURR",
7960 &spr_read_purr
, SPR_NOACCESS
,
7961 &spr_read_purr
, SPR_NOACCESS
,
7962 KVM_REG_PPC_PURR
, 0x00000000);
7963 spr_register_kvm(env
, SPR_SPURR
, "SPURR",
7964 &spr_read_purr
, SPR_NOACCESS
,
7965 &spr_read_purr
, SPR_NOACCESS
,
7966 KVM_REG_PPC_SPURR
, 0x00000000);
7970 static void gen_spr_power6_dbg(CPUPPCState
*env
)
7972 #if !defined(CONFIG_USER_ONLY)
7973 spr_register(env
, SPR_CFAR
, "SPR_CFAR",
7974 SPR_NOACCESS
, SPR_NOACCESS
,
7975 &spr_read_cfar
, &spr_write_cfar
,
7980 static void gen_spr_power5p_common(CPUPPCState
*env
)
7982 spr_register_kvm(env
, SPR_PPR
, "PPR",
7983 &spr_read_generic
, &spr_write_generic
,
7984 &spr_read_generic
, &spr_write_generic
,
7985 KVM_REG_PPC_PPR
, 0x00000000);
7988 static void gen_spr_power6_common(CPUPPCState
*env
)
7990 #if !defined(CONFIG_USER_ONLY)
7991 spr_register_kvm(env
, SPR_DSCR
, "SPR_DSCR",
7992 SPR_NOACCESS
, SPR_NOACCESS
,
7993 &spr_read_generic
, &spr_write_generic
,
7994 KVM_REG_PPC_DSCR
, 0x00000000);
7997 * Register PCR to report POWERPC_EXCP_PRIV_REG instead of
7998 * POWERPC_EXCP_INVAL_SPR in userspace. Permit hypervisor access.
8000 spr_register_hv(env
, SPR_PCR
, "PCR",
8001 SPR_NOACCESS
, SPR_NOACCESS
,
8002 SPR_NOACCESS
, SPR_NOACCESS
,
8003 &spr_read_generic
, &spr_write_pcr
,
8007 static void spr_read_tar(DisasContext
*ctx
, int gprn
, int sprn
)
8009 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_TAR
, sprn
, FSCR_IC_TAR
);
8010 spr_read_generic(ctx
, gprn
, sprn
);
8013 static void spr_write_tar(DisasContext
*ctx
, int sprn
, int gprn
)
8015 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_TAR
, sprn
, FSCR_IC_TAR
);
8016 spr_write_generic(ctx
, sprn
, gprn
);
8019 static void gen_spr_power8_tce_address_control(CPUPPCState
*env
)
8021 spr_register_kvm(env
, SPR_TAR
, "TAR",
8022 &spr_read_tar
, &spr_write_tar
,
8023 &spr_read_generic
, &spr_write_generic
,
8024 KVM_REG_PPC_TAR
, 0x00000000);
8027 static void spr_read_tm(DisasContext
*ctx
, int gprn
, int sprn
)
8029 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8030 spr_read_generic(ctx
, gprn
, sprn
);
8033 static void spr_write_tm(DisasContext
*ctx
, int sprn
, int gprn
)
8035 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8036 spr_write_generic(ctx
, sprn
, gprn
);
8039 static void spr_read_tm_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
8041 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8042 spr_read_prev_upper32(ctx
, gprn
, sprn
);
8045 static void spr_write_tm_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
8047 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8048 spr_write_prev_upper32(ctx
, sprn
, gprn
);
8051 static void gen_spr_power8_tm(CPUPPCState
*env
)
8053 spr_register_kvm(env
, SPR_TFHAR
, "TFHAR",
8054 &spr_read_tm
, &spr_write_tm
,
8055 &spr_read_tm
, &spr_write_tm
,
8056 KVM_REG_PPC_TFHAR
, 0x00000000);
8057 spr_register_kvm(env
, SPR_TFIAR
, "TFIAR",
8058 &spr_read_tm
, &spr_write_tm
,
8059 &spr_read_tm
, &spr_write_tm
,
8060 KVM_REG_PPC_TFIAR
, 0x00000000);
8061 spr_register_kvm(env
, SPR_TEXASR
, "TEXASR",
8062 &spr_read_tm
, &spr_write_tm
,
8063 &spr_read_tm
, &spr_write_tm
,
8064 KVM_REG_PPC_TEXASR
, 0x00000000);
8065 spr_register(env
, SPR_TEXASRU
, "TEXASRU",
8066 &spr_read_tm_upper32
, &spr_write_tm_upper32
,
8067 &spr_read_tm_upper32
, &spr_write_tm_upper32
,
8071 static void spr_read_ebb(DisasContext
*ctx
, int gprn
, int sprn
)
8073 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8074 spr_read_generic(ctx
, gprn
, sprn
);
8077 static void spr_write_ebb(DisasContext
*ctx
, int sprn
, int gprn
)
8079 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8080 spr_write_generic(ctx
, sprn
, gprn
);
8083 static void spr_read_ebb_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
8085 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8086 spr_read_prev_upper32(ctx
, gprn
, sprn
);
8089 static void spr_write_ebb_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
8091 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8092 spr_write_prev_upper32(ctx
, sprn
, gprn
);
8095 static void gen_spr_power8_ebb(CPUPPCState
*env
)
8097 spr_register(env
, SPR_BESCRS
, "BESCRS",
8098 &spr_read_ebb
, &spr_write_ebb
,
8099 &spr_read_generic
, &spr_write_generic
,
8101 spr_register(env
, SPR_BESCRSU
, "BESCRSU",
8102 &spr_read_ebb_upper32
, &spr_write_ebb_upper32
,
8103 &spr_read_prev_upper32
, &spr_write_prev_upper32
,
8105 spr_register(env
, SPR_BESCRR
, "BESCRR",
8106 &spr_read_ebb
, &spr_write_ebb
,
8107 &spr_read_generic
, &spr_write_generic
,
8109 spr_register(env
, SPR_BESCRRU
, "BESCRRU",
8110 &spr_read_ebb_upper32
, &spr_write_ebb_upper32
,
8111 &spr_read_prev_upper32
, &spr_write_prev_upper32
,
8113 spr_register_kvm(env
, SPR_EBBHR
, "EBBHR",
8114 &spr_read_ebb
, &spr_write_ebb
,
8115 &spr_read_generic
, &spr_write_generic
,
8116 KVM_REG_PPC_EBBHR
, 0x00000000);
8117 spr_register_kvm(env
, SPR_EBBRR
, "EBBRR",
8118 &spr_read_ebb
, &spr_write_ebb
,
8119 &spr_read_generic
, &spr_write_generic
,
8120 KVM_REG_PPC_EBBRR
, 0x00000000);
8121 spr_register_kvm(env
, SPR_BESCR
, "BESCR",
8122 &spr_read_ebb
, &spr_write_ebb
,
8123 &spr_read_generic
, &spr_write_generic
,
8124 KVM_REG_PPC_BESCR
, 0x00000000);
8127 /* Virtual Time Base */
8128 static void gen_spr_vtb(CPUPPCState
*env
)
8130 spr_register_kvm(env
, SPR_VTB
, "VTB",
8131 SPR_NOACCESS
, SPR_NOACCESS
,
8132 &spr_read_tbl
, SPR_NOACCESS
,
8133 KVM_REG_PPC_VTB
, 0x00000000);
8136 static void gen_spr_power8_fscr(CPUPPCState
*env
)
8138 #if defined(CONFIG_USER_ONLY)
8139 target_ulong initval
= 1ULL << FSCR_TAR
;
8141 target_ulong initval
= 0;
8143 spr_register_kvm(env
, SPR_FSCR
, "FSCR",
8144 SPR_NOACCESS
, SPR_NOACCESS
,
8145 &spr_read_generic
, &spr_write_generic
,
8146 KVM_REG_PPC_FSCR
, initval
);
8149 static void gen_spr_power8_pspb(CPUPPCState
*env
)
8151 spr_register_kvm(env
, SPR_PSPB
, "PSPB",
8152 SPR_NOACCESS
, SPR_NOACCESS
,
8153 &spr_read_generic
, &spr_write_generic32
,
8154 KVM_REG_PPC_PSPB
, 0);
8157 static void gen_spr_power8_ic(CPUPPCState
*env
)
8159 #if !defined(CONFIG_USER_ONLY)
8160 spr_register_hv(env
, SPR_IC
, "IC",
8161 SPR_NOACCESS
, SPR_NOACCESS
,
8162 &spr_read_generic
, SPR_NOACCESS
,
8163 &spr_read_generic
, &spr_write_generic
,
8168 static void gen_spr_power8_book4(CPUPPCState
*env
)
8170 /* Add a number of P8 book4 registers */
8171 #if !defined(CONFIG_USER_ONLY)
8172 spr_register_kvm(env
, SPR_ACOP
, "ACOP",
8173 SPR_NOACCESS
, SPR_NOACCESS
,
8174 &spr_read_generic
, &spr_write_generic
,
8175 KVM_REG_PPC_ACOP
, 0);
8176 spr_register_kvm(env
, SPR_BOOKS_PID
, "PID",
8177 SPR_NOACCESS
, SPR_NOACCESS
,
8178 &spr_read_generic
, &spr_write_pidr
,
8179 KVM_REG_PPC_PID
, 0);
8180 spr_register_kvm(env
, SPR_WORT
, "WORT",
8181 SPR_NOACCESS
, SPR_NOACCESS
,
8182 &spr_read_generic
, &spr_write_generic
,
8183 KVM_REG_PPC_WORT
, 0);
8187 static void gen_spr_power7_book4(CPUPPCState
*env
)
8189 /* Add a number of P7 book4 registers */
8190 #if !defined(CONFIG_USER_ONLY)
8191 spr_register_kvm(env
, SPR_ACOP
, "ACOP",
8192 SPR_NOACCESS
, SPR_NOACCESS
,
8193 &spr_read_generic
, &spr_write_generic
,
8194 KVM_REG_PPC_ACOP
, 0);
8195 spr_register_kvm(env
, SPR_BOOKS_PID
, "PID",
8196 SPR_NOACCESS
, SPR_NOACCESS
,
8197 &spr_read_generic
, &spr_write_generic
,
8198 KVM_REG_PPC_PID
, 0);
8202 static void gen_spr_power8_rpr(CPUPPCState
*env
)
8204 #if !defined(CONFIG_USER_ONLY)
8205 spr_register_hv(env
, SPR_RPR
, "RPR",
8206 SPR_NOACCESS
, SPR_NOACCESS
,
8207 SPR_NOACCESS
, SPR_NOACCESS
,
8208 &spr_read_generic
, &spr_write_generic
,
8209 0x00000103070F1F3F);
8213 static void gen_spr_power9_mmu(CPUPPCState
*env
)
8215 #if !defined(CONFIG_USER_ONLY)
8216 /* Partition Table Control */
8217 spr_register_kvm_hv(env
, SPR_PTCR
, "PTCR",
8218 SPR_NOACCESS
, SPR_NOACCESS
,
8219 SPR_NOACCESS
, SPR_NOACCESS
,
8220 &spr_read_generic
, &spr_write_ptcr
,
8221 KVM_REG_PPC_PTCR
, 0x00000000);
8225 static void init_proc_book3s_common(CPUPPCState
*env
)
8227 gen_spr_ne_601(env
);
8229 gen_spr_usprg3(env
);
8230 gen_spr_book3s_altivec(env
);
8231 gen_spr_book3s_pmu_sup(env
);
8232 gen_spr_book3s_pmu_user(env
);
8233 gen_spr_book3s_ctrl(env
);
8236 static void init_proc_970(CPUPPCState
*env
)
8238 /* Common Registers */
8239 init_proc_book3s_common(env
);
8241 gen_spr_book3s_dbg(env
);
8243 /* 970 Specific Registers */
8244 gen_spr_970_hid(env
);
8245 gen_spr_970_hior(env
);
8247 gen_spr_970_pmu_sup(env
);
8248 gen_spr_970_pmu_user(env
);
8249 gen_spr_970_lpar(env
);
8250 gen_spr_970_dbg(env
);
8253 env
->dcache_line_size
= 128;
8254 env
->icache_line_size
= 128;
8256 /* Allocate hardware IRQ controller */
8258 ppc970_irq_init(ppc_env_get_cpu(env
));
8261 POWERPC_FAMILY(970)(ObjectClass
*oc
, void *data
)
8263 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8264 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8266 dc
->desc
= "PowerPC 970";
8267 pcc
->init_proc
= init_proc_970
;
8268 pcc
->check_pow
= check_pow_970
;
8269 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
8270 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8271 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8273 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8274 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8275 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8276 PPC_64B
| PPC_ALTIVEC
|
8277 PPC_SEGMENT_64B
| PPC_SLBI
;
8278 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
8279 pcc
->msr_mask
= (1ull << MSR_SF
) |
8294 pcc
->mmu_model
= POWERPC_MMU_64B
;
8295 #if defined(CONFIG_SOFTMMU)
8296 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8297 pcc
->hash64_opts
= &ppc_hash64_opts_basic
;
8299 pcc
->excp_model
= POWERPC_EXCP_970
;
8300 pcc
->bus_model
= PPC_FLAGS_INPUT_970
;
8301 pcc
->bfd_mach
= bfd_mach_ppc64
;
8302 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8303 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8304 POWERPC_FLAG_BUS_CLK
;
8305 pcc
->l1_dcache_size
= 0x8000;
8306 pcc
->l1_icache_size
= 0x10000;
8309 static void init_proc_power5plus(CPUPPCState
*env
)
8311 /* Common Registers */
8312 init_proc_book3s_common(env
);
8314 gen_spr_book3s_dbg(env
);
8316 /* POWER5+ Specific Registers */
8317 gen_spr_970_hid(env
);
8318 gen_spr_970_hior(env
);
8320 gen_spr_970_pmu_sup(env
);
8321 gen_spr_970_pmu_user(env
);
8322 gen_spr_power5p_common(env
);
8323 gen_spr_power5p_lpar(env
);
8324 gen_spr_power5p_ear(env
);
8327 env
->dcache_line_size
= 128;
8328 env
->icache_line_size
= 128;
8330 /* Allocate hardware IRQ controller */
8332 ppc970_irq_init(ppc_env_get_cpu(env
));
8335 POWERPC_FAMILY(POWER5P
)(ObjectClass
*oc
, void *data
)
8337 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8338 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8340 dc
->fw_name
= "PowerPC,POWER5";
8341 dc
->desc
= "POWER5+";
8342 pcc
->init_proc
= init_proc_power5plus
;
8343 pcc
->check_pow
= check_pow_970
;
8344 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
8345 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8346 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8348 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8349 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8350 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8352 PPC_SEGMENT_64B
| PPC_SLBI
;
8353 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
8354 pcc
->msr_mask
= (1ull << MSR_SF
) |
8369 pcc
->mmu_model
= POWERPC_MMU_2_03
;
8370 #if defined(CONFIG_SOFTMMU)
8371 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8372 pcc
->hash64_opts
= &ppc_hash64_opts_basic
;
8374 pcc
->excp_model
= POWERPC_EXCP_970
;
8375 pcc
->bus_model
= PPC_FLAGS_INPUT_970
;
8376 pcc
->bfd_mach
= bfd_mach_ppc64
;
8377 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8378 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8379 POWERPC_FLAG_BUS_CLK
;
8380 pcc
->l1_dcache_size
= 0x8000;
8381 pcc
->l1_icache_size
= 0x10000;
8385 * The CPU used to have a "compat" property which set the
8386 * compatibility mode PVR. However, this was conceptually broken - it
8387 * only makes sense on the pseries machine type (otherwise the guest
8388 * owns the PCR and can control the compatibility mode itself). It's
8389 * been replaced with the 'max-cpu-compat' property on the pseries
8390 * machine type. For backwards compatibility, pseries specially
8391 * parses the -cpu parameter and converts old compat= parameters into
8392 * the appropriate machine parameters. This stub implementation of
8393 * the parameter catches any uses on explicitly created CPUs.
8395 static void getset_compat_deprecated(Object
*obj
, Visitor
*v
, const char *name
,
8396 void *opaque
, Error
**errp
)
8400 if (!qtest_enabled()) {
8401 warn_report("CPU 'compat' property is deprecated and has no effect; "
8402 "use max-cpu-compat machine property instead");
8404 visit_type_null(v
, name
, &null
, NULL
);
8405 qobject_unref(null
);
8408 static const PropertyInfo ppc_compat_deprecated_propinfo
= {
8410 .description
= "compatibility mode (deprecated)",
8411 .get
= getset_compat_deprecated
,
8412 .set
= getset_compat_deprecated
,
8414 static Property powerpc_servercpu_properties
[] = {
8417 .info
= &ppc_compat_deprecated_propinfo
,
8419 DEFINE_PROP_END_OF_LIST(),
8422 static void init_proc_POWER7(CPUPPCState
*env
)
8424 /* Common Registers */
8425 init_proc_book3s_common(env
);
8427 gen_spr_book3s_dbg(env
);
8429 /* POWER7 Specific Registers */
8430 gen_spr_book3s_ids(env
);
8432 gen_spr_book3s_purr(env
);
8433 gen_spr_power5p_common(env
);
8434 gen_spr_power5p_lpar(env
);
8435 gen_spr_power5p_ear(env
);
8436 gen_spr_power6_common(env
);
8437 gen_spr_power6_dbg(env
);
8438 gen_spr_power7_book4(env
);
8441 env
->dcache_line_size
= 128;
8442 env
->icache_line_size
= 128;
8444 /* Allocate hardware IRQ controller */
8445 init_excp_POWER7(env
);
8446 ppcPOWER7_irq_init(ppc_env_get_cpu(env
));
8449 static bool ppc_pvr_match_power7(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8451 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER7P_BASE
) {
8454 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER7_BASE
) {
8460 static bool cpu_has_work_POWER7(CPUState
*cs
)
8462 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8463 CPUPPCState
*env
= &cpu
->env
;
8466 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8469 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8470 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE0
)) {
8473 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8474 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE1
)) {
8477 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
)) &&
8478 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE2
)) {
8481 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HMI
)) &&
8482 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE2
)) {
8485 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8490 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8494 POWERPC_FAMILY(POWER7
)(ObjectClass
*oc
, void *data
)
8496 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8497 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8498 CPUClass
*cc
= CPU_CLASS(oc
);
8500 dc
->fw_name
= "PowerPC,POWER7";
8501 dc
->desc
= "POWER7";
8502 dc
->props
= powerpc_servercpu_properties
;
8503 pcc
->pvr_match
= ppc_pvr_match_power7
;
8504 pcc
->pcr_mask
= PCR_VEC_DIS
| PCR_VSX_DIS
| PCR_COMPAT_2_05
;
8505 pcc
->pcr_supported
= PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8506 pcc
->init_proc
= init_proc_POWER7
;
8507 pcc
->check_pow
= check_pow_nocheck
;
8508 cc
->has_work
= cpu_has_work_POWER7
;
8509 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8510 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8511 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8512 PPC_FLOAT_FRSQRTES
|
8515 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8516 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8517 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8518 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
8519 PPC_SEGMENT_64B
| PPC_SLBI
|
8520 PPC_POPCNTB
| PPC_POPCNTWD
|
8522 pcc
->insns_flags2
= PPC2_VSX
| PPC2_DFP
| PPC2_DBRX
| PPC2_ISA205
|
8523 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8524 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8525 PPC2_FP_TST_ISA206
| PPC2_FP_CVT_S64
|
8527 pcc
->msr_mask
= (1ull << MSR_SF
) |
8543 pcc
->mmu_model
= POWERPC_MMU_2_06
;
8544 #if defined(CONFIG_SOFTMMU)
8545 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8546 pcc
->hash64_opts
= &ppc_hash64_opts_POWER7
;
8548 pcc
->excp_model
= POWERPC_EXCP_POWER7
;
8549 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8550 pcc
->bfd_mach
= bfd_mach_ppc64
;
8551 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8552 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8553 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8555 pcc
->l1_dcache_size
= 0x8000;
8556 pcc
->l1_icache_size
= 0x8000;
8557 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8558 pcc
->lpcr_pm
= LPCR_P7_PECE0
| LPCR_P7_PECE1
| LPCR_P7_PECE2
;
8561 static void init_proc_POWER8(CPUPPCState
*env
)
8563 /* Common Registers */
8564 init_proc_book3s_common(env
);
8566 gen_spr_book3s_207_dbg(env
);
8568 /* POWER8 Specific Registers */
8569 gen_spr_book3s_ids(env
);
8572 gen_spr_book3s_purr(env
);
8573 gen_spr_power5p_common(env
);
8574 gen_spr_power5p_lpar(env
);
8575 gen_spr_power5p_ear(env
);
8576 gen_spr_power6_common(env
);
8577 gen_spr_power6_dbg(env
);
8578 gen_spr_power8_tce_address_control(env
);
8579 gen_spr_power8_ids(env
);
8580 gen_spr_power8_ebb(env
);
8581 gen_spr_power8_fscr(env
);
8582 gen_spr_power8_pmu_sup(env
);
8583 gen_spr_power8_pmu_user(env
);
8584 gen_spr_power8_tm(env
);
8585 gen_spr_power8_pspb(env
);
8587 gen_spr_power8_ic(env
);
8588 gen_spr_power8_book4(env
);
8589 gen_spr_power8_rpr(env
);
8592 env
->dcache_line_size
= 128;
8593 env
->icache_line_size
= 128;
8595 /* Allocate hardware IRQ controller */
8596 init_excp_POWER8(env
);
8597 ppcPOWER7_irq_init(ppc_env_get_cpu(env
));
8600 static bool ppc_pvr_match_power8(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8602 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8NVL_BASE
) {
8605 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8E_BASE
) {
8608 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8_BASE
) {
8614 static bool cpu_has_work_POWER8(CPUState
*cs
)
8616 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8617 CPUPPCState
*env
= &cpu
->env
;
8620 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8623 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8624 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE2
)) {
8627 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8628 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE3
)) {
8631 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
)) &&
8632 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE4
)) {
8635 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HMI
)) &&
8636 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE4
)) {
8639 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DOORBELL
)) &&
8640 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE0
)) {
8643 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HDOORBELL
)) &&
8644 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE1
)) {
8647 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8652 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8656 POWERPC_FAMILY(POWER8
)(ObjectClass
*oc
, void *data
)
8658 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8659 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8660 CPUClass
*cc
= CPU_CLASS(oc
);
8662 dc
->fw_name
= "PowerPC,POWER8";
8663 dc
->desc
= "POWER8";
8664 dc
->props
= powerpc_servercpu_properties
;
8665 pcc
->pvr_match
= ppc_pvr_match_power8
;
8666 pcc
->pcr_mask
= PCR_TM_DIS
| PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8667 pcc
->pcr_supported
= PCR_COMPAT_2_07
| PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8668 pcc
->init_proc
= init_proc_POWER8
;
8669 pcc
->check_pow
= check_pow_nocheck
;
8670 cc
->has_work
= cpu_has_work_POWER8
;
8671 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8672 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8673 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8674 PPC_FLOAT_FRSQRTES
|
8677 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8678 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8679 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8680 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
8681 PPC_SEGMENT_64B
| PPC_SLBI
|
8682 PPC_POPCNTB
| PPC_POPCNTWD
|
8684 pcc
->insns_flags2
= PPC2_VSX
| PPC2_VSX207
| PPC2_DFP
| PPC2_DBRX
|
8685 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8686 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8687 PPC2_FP_TST_ISA206
| PPC2_BCTAR_ISA207
|
8688 PPC2_LSQ_ISA207
| PPC2_ALTIVEC_207
|
8689 PPC2_ISA205
| PPC2_ISA207S
| PPC2_FP_CVT_S64
|
8690 PPC2_TM
| PPC2_PM_ISA206
;
8691 pcc
->msr_mask
= (1ull << MSR_SF
) |
8711 pcc
->mmu_model
= POWERPC_MMU_2_07
;
8712 #if defined(CONFIG_SOFTMMU)
8713 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8714 pcc
->hash64_opts
= &ppc_hash64_opts_POWER7
;
8716 pcc
->excp_model
= POWERPC_EXCP_POWER8
;
8717 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8718 pcc
->bfd_mach
= bfd_mach_ppc64
;
8719 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8720 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8721 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8722 POWERPC_FLAG_VSX
| POWERPC_FLAG_TM
;
8723 pcc
->l1_dcache_size
= 0x8000;
8724 pcc
->l1_icache_size
= 0x8000;
8725 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8726 pcc
->lpcr_pm
= LPCR_P8_PECE0
| LPCR_P8_PECE1
| LPCR_P8_PECE2
|
8727 LPCR_P8_PECE3
| LPCR_P8_PECE4
;
8730 #ifdef CONFIG_SOFTMMU
8732 * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
8733 * Encoded as array of int_32s in the form:
8734 * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
8736 * y -> radix mode supported page size (encoded as a shift)
8738 static struct ppc_radix_page_info POWER9_radix_page_info
= {
8741 0x0000000c, /* 4K - enc: 0x0 */
8742 0xa0000010, /* 64K - enc: 0x5 */
8743 0x20000015, /* 2M - enc: 0x1 */
8744 0x4000001e /* 1G - enc: 0x2 */
8747 #endif /* CONFIG_SOFTMMU */
8749 static void init_proc_POWER9(CPUPPCState
*env
)
8751 /* Common Registers */
8752 init_proc_book3s_common(env
);
8753 gen_spr_book3s_207_dbg(env
);
8755 /* POWER8 Specific Registers */
8756 gen_spr_book3s_ids(env
);
8759 gen_spr_book3s_purr(env
);
8760 gen_spr_power5p_common(env
);
8761 gen_spr_power5p_lpar(env
);
8762 gen_spr_power5p_ear(env
);
8763 gen_spr_power6_common(env
);
8764 gen_spr_power6_dbg(env
);
8765 gen_spr_power8_tce_address_control(env
);
8766 gen_spr_power8_ids(env
);
8767 gen_spr_power8_ebb(env
);
8768 gen_spr_power8_fscr(env
);
8769 gen_spr_power8_pmu_sup(env
);
8770 gen_spr_power8_pmu_user(env
);
8771 gen_spr_power8_tm(env
);
8772 gen_spr_power8_pspb(env
);
8774 gen_spr_power8_ic(env
);
8775 gen_spr_power8_book4(env
);
8776 gen_spr_power8_rpr(env
);
8777 gen_spr_power9_mmu(env
);
8779 /* POWER9 Specific registers */
8780 spr_register_kvm(env
, SPR_TIDR
, "TIDR", NULL
, NULL
,
8781 spr_read_generic
, spr_write_generic
,
8782 KVM_REG_PPC_TIDR
, 0);
8784 /* FIXME: Filter fields properly based on privilege level */
8785 spr_register_kvm_hv(env
, SPR_PSSCR
, "PSSCR", NULL
, NULL
, NULL
, NULL
,
8786 spr_read_generic
, spr_write_generic
,
8787 KVM_REG_PPC_PSSCR
, 0);
8790 env
->dcache_line_size
= 128;
8791 env
->icache_line_size
= 128;
8793 /* Allocate hardware IRQ controller */
8794 init_excp_POWER8(env
);
8795 ppcPOWER7_irq_init(ppc_env_get_cpu(env
));
8798 static bool ppc_pvr_match_power9(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8800 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER9_BASE
) {
8806 static bool cpu_has_work_POWER9(CPUState
*cs
)
8808 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8809 CPUPPCState
*env
= &cpu
->env
;
8812 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8815 /* External Exception */
8816 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8817 (env
->spr
[SPR_LPCR
] & LPCR_EEE
)) {
8820 /* Decrementer Exception */
8821 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8822 (env
->spr
[SPR_LPCR
] & LPCR_DEE
)) {
8825 /* Machine Check or Hypervisor Maintenance Exception */
8826 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
|
8827 1u << PPC_INTERRUPT_HMI
)) && (env
->spr
[SPR_LPCR
] & LPCR_OEE
)) {
8830 /* Privileged Doorbell Exception */
8831 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DOORBELL
)) &&
8832 (env
->spr
[SPR_LPCR
] & LPCR_PDEE
)) {
8835 /* Hypervisor Doorbell Exception */
8836 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HDOORBELL
)) &&
8837 (env
->spr
[SPR_LPCR
] & LPCR_HDEE
)) {
8840 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8845 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8849 POWERPC_FAMILY(POWER9
)(ObjectClass
*oc
, void *data
)
8851 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8852 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8853 CPUClass
*cc
= CPU_CLASS(oc
);
8855 dc
->fw_name
= "PowerPC,POWER9";
8856 dc
->desc
= "POWER9";
8857 dc
->props
= powerpc_servercpu_properties
;
8858 pcc
->pvr_match
= ppc_pvr_match_power9
;
8859 pcc
->pcr_mask
= PCR_COMPAT_2_05
| PCR_COMPAT_2_06
| PCR_COMPAT_2_07
;
8860 pcc
->pcr_supported
= PCR_COMPAT_3_00
| PCR_COMPAT_2_07
| PCR_COMPAT_2_06
|
8862 pcc
->init_proc
= init_proc_POWER9
;
8863 pcc
->check_pow
= check_pow_nocheck
;
8864 cc
->has_work
= cpu_has_work_POWER9
;
8865 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8866 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8867 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8868 PPC_FLOAT_FRSQRTES
|
8871 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8872 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8874 PPC_64B
| PPC_64BX
| PPC_ALTIVEC
|
8875 PPC_SEGMENT_64B
| PPC_SLBI
|
8876 PPC_POPCNTB
| PPC_POPCNTWD
|
8878 pcc
->insns_flags2
= PPC2_VSX
| PPC2_VSX207
| PPC2_DFP
| PPC2_DBRX
|
8879 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8880 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8881 PPC2_FP_TST_ISA206
| PPC2_BCTAR_ISA207
|
8882 PPC2_LSQ_ISA207
| PPC2_ALTIVEC_207
|
8883 PPC2_ISA205
| PPC2_ISA207S
| PPC2_FP_CVT_S64
|
8884 PPC2_TM
| PPC2_PM_ISA206
| PPC2_ISA300
| PPC2_PRCNTL
;
8885 pcc
->msr_mask
= (1ull << MSR_SF
) |
8902 pcc
->mmu_model
= POWERPC_MMU_3_00
;
8903 #if defined(CONFIG_SOFTMMU)
8904 pcc
->handle_mmu_fault
= ppc64_v3_handle_mmu_fault
;
8905 /* segment page size remain the same */
8906 pcc
->hash64_opts
= &ppc_hash64_opts_POWER7
;
8907 pcc
->radix_page_info
= &POWER9_radix_page_info
;
8909 pcc
->excp_model
= POWERPC_EXCP_POWER8
;
8910 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8911 pcc
->bfd_mach
= bfd_mach_ppc64
;
8912 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8913 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8914 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8915 POWERPC_FLAG_VSX
| POWERPC_FLAG_TM
;
8916 pcc
->l1_dcache_size
= 0x8000;
8917 pcc
->l1_icache_size
= 0x8000;
8918 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8919 pcc
->lpcr_pm
= LPCR_PDEE
| LPCR_HDEE
| LPCR_EEE
| LPCR_DEE
| LPCR_OEE
;
8922 #if !defined(CONFIG_USER_ONLY)
8923 void cpu_ppc_set_vhyp(PowerPCCPU
*cpu
, PPCVirtualHypervisor
*vhyp
)
8925 CPUPPCState
*env
= &cpu
->env
;
8930 * With a virtual hypervisor mode we never allow the CPU to go
8931 * hypervisor mode itself
8933 env
->msr_mask
&= ~MSR_HVB
;
8936 #endif /* !defined(CONFIG_USER_ONLY) */
8938 #endif /* defined(TARGET_PPC64) */
8940 /*****************************************************************************/
8941 /* Generic CPU instantiation routine */
8942 static void init_ppc_proc(PowerPCCPU
*cpu
)
8944 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
8945 CPUPPCState
*env
= &cpu
->env
;
8946 #if !defined(CONFIG_USER_ONLY)
8949 env
->irq_inputs
= NULL
;
8950 /* Set all exception vectors to an invalid address */
8951 for (i
= 0; i
< POWERPC_EXCP_NB
; i
++)
8952 env
->excp_vectors
[i
] = (target_ulong
)(-1ULL);
8953 env
->ivor_mask
= 0x00000000;
8954 env
->ivpr_mask
= 0x00000000;
8955 /* Default MMU definitions */
8959 env
->tlb_type
= TLB_NONE
;
8961 /* Register SPR common to all PowerPC implementations */
8962 gen_spr_generic(env
);
8963 spr_register(env
, SPR_PVR
, "PVR",
8964 /* Linux permits userspace to read PVR */
8965 #if defined(CONFIG_LINUX_USER)
8971 &spr_read_generic
, SPR_NOACCESS
,
8973 /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
8974 if (pcc
->svr
!= POWERPC_SVR_NONE
) {
8975 if (pcc
->svr
& POWERPC_SVR_E500
) {
8976 spr_register(env
, SPR_E500_SVR
, "SVR",
8977 SPR_NOACCESS
, SPR_NOACCESS
,
8978 &spr_read_generic
, SPR_NOACCESS
,
8979 pcc
->svr
& ~POWERPC_SVR_E500
);
8981 spr_register(env
, SPR_SVR
, "SVR",
8982 SPR_NOACCESS
, SPR_NOACCESS
,
8983 &spr_read_generic
, SPR_NOACCESS
,
8987 /* PowerPC implementation specific initialisations (SPRs, timers, ...) */
8988 (*pcc
->init_proc
)(env
);
8990 /* MSR bits & flags consistency checks */
8991 if (env
->msr_mask
& (1 << 25)) {
8992 switch (env
->flags
& (POWERPC_FLAG_SPE
| POWERPC_FLAG_VRE
)) {
8993 case POWERPC_FLAG_SPE
:
8994 case POWERPC_FLAG_VRE
:
8997 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
8998 "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n");
9001 } else if (env
->flags
& (POWERPC_FLAG_SPE
| POWERPC_FLAG_VRE
)) {
9002 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9003 "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n");
9006 if (env
->msr_mask
& (1 << 17)) {
9007 switch (env
->flags
& (POWERPC_FLAG_TGPR
| POWERPC_FLAG_CE
)) {
9008 case POWERPC_FLAG_TGPR
:
9009 case POWERPC_FLAG_CE
:
9012 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9013 "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n");
9016 } else if (env
->flags
& (POWERPC_FLAG_TGPR
| POWERPC_FLAG_CE
)) {
9017 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9018 "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n");
9021 if (env
->msr_mask
& (1 << 10)) {
9022 switch (env
->flags
& (POWERPC_FLAG_SE
| POWERPC_FLAG_DWE
|
9023 POWERPC_FLAG_UBLE
)) {
9024 case POWERPC_FLAG_SE
:
9025 case POWERPC_FLAG_DWE
:
9026 case POWERPC_FLAG_UBLE
:
9029 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9030 "Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE or "
9031 "POWERPC_FLAG_UBLE\n");
9034 } else if (env
->flags
& (POWERPC_FLAG_SE
| POWERPC_FLAG_DWE
|
9035 POWERPC_FLAG_UBLE
)) {
9036 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9037 "Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE nor "
9038 "POWERPC_FLAG_UBLE\n");
9041 if (env
->msr_mask
& (1 << 9)) {
9042 switch (env
->flags
& (POWERPC_FLAG_BE
| POWERPC_FLAG_DE
)) {
9043 case POWERPC_FLAG_BE
:
9044 case POWERPC_FLAG_DE
:
9047 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9048 "Should define POWERPC_FLAG_BE or POWERPC_FLAG_DE\n");
9051 } else if (env
->flags
& (POWERPC_FLAG_BE
| POWERPC_FLAG_DE
)) {
9052 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9053 "Should not define POWERPC_FLAG_BE nor POWERPC_FLAG_DE\n");
9056 if (env
->msr_mask
& (1 << 2)) {
9057 switch (env
->flags
& (POWERPC_FLAG_PX
| POWERPC_FLAG_PMM
)) {
9058 case POWERPC_FLAG_PX
:
9059 case POWERPC_FLAG_PMM
:
9062 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9063 "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n");
9066 } else if (env
->flags
& (POWERPC_FLAG_PX
| POWERPC_FLAG_PMM
)) {
9067 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9068 "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
9071 if ((env
->flags
& (POWERPC_FLAG_RTC_CLK
| POWERPC_FLAG_BUS_CLK
)) == 0) {
9072 fprintf(stderr
, "PowerPC flags inconsistency\n"
9073 "Should define the time-base and decrementer clock source\n");
9076 /* Allocate TLBs buffer when needed */
9077 #if !defined(CONFIG_USER_ONLY)
9078 if (env
->nb_tlb
!= 0) {
9079 int nb_tlb
= env
->nb_tlb
;
9080 if (env
->id_tlbs
!= 0)
9082 switch (env
->tlb_type
) {
9084 env
->tlb
.tlb6
= g_new0(ppc6xx_tlb_t
, nb_tlb
);
9087 env
->tlb
.tlbe
= g_new0(ppcemb_tlb_t
, nb_tlb
);
9090 env
->tlb
.tlbm
= g_new0(ppcmas_tlb_t
, nb_tlb
);
9093 /* Pre-compute some useful values */
9094 env
->tlb_per_way
= env
->nb_tlb
/ env
->nb_ways
;
9096 if (env
->irq_inputs
== NULL
) {
9097 warn_report("no internal IRQ controller registered."
9098 " Attempt QEMU to crash very soon !");
9101 if (env
->check_pow
== NULL
) {
9102 warn_report("no power management check handler registered."
9103 " Attempt QEMU to crash very soon !");
9107 #if defined(PPC_DUMP_CPU)
9108 static void dump_ppc_sprs(CPUPPCState
*env
)
9111 #if !defined(CONFIG_USER_ONLY)
9117 printf("Special purpose registers:\n");
9118 for (i
= 0; i
< 32; i
++) {
9119 for (j
= 0; j
< 32; j
++) {
9121 spr
= &env
->spr_cb
[n
];
9122 uw
= spr
->uea_write
!= NULL
&& spr
->uea_write
!= SPR_NOACCESS
;
9123 ur
= spr
->uea_read
!= NULL
&& spr
->uea_read
!= SPR_NOACCESS
;
9124 #if !defined(CONFIG_USER_ONLY)
9125 sw
= spr
->oea_write
!= NULL
&& spr
->oea_write
!= SPR_NOACCESS
;
9126 sr
= spr
->oea_read
!= NULL
&& spr
->oea_read
!= SPR_NOACCESS
;
9127 if (sw
|| sr
|| uw
|| ur
) {
9128 printf("SPR: %4d (%03x) %-8s s%c%c u%c%c\n",
9129 (i
<< 5) | j
, (i
<< 5) | j
, spr
->name
,
9130 sw
? 'w' : '-', sr
? 'r' : '-',
9131 uw
? 'w' : '-', ur
? 'r' : '-');
9135 printf("SPR: %4d (%03x) %-8s u%c%c\n",
9136 (i
<< 5) | j
, (i
<< 5) | j
, spr
->name
,
9137 uw
? 'w' : '-', ur
? 'r' : '-');
9147 /*****************************************************************************/
9151 PPC_DIRECT
= 0, /* Opcode routine */
9152 PPC_INDIRECT
= 1, /* Indirect opcode table */
9155 #define PPC_OPCODE_MASK 0x3
9157 static inline int is_indirect_opcode(void *handler
)
9159 return ((uintptr_t)handler
& PPC_OPCODE_MASK
) == PPC_INDIRECT
;
9162 static inline opc_handler_t
**ind_table(void *handler
)
9164 return (opc_handler_t
**)((uintptr_t)handler
& ~PPC_OPCODE_MASK
);
9167 /* Instruction table creation */
9168 /* Opcodes tables creation */
9169 static void fill_new_table(opc_handler_t
**table
, int len
)
9173 for (i
= 0; i
< len
; i
++)
9174 table
[i
] = &invalid_handler
;
9177 static int create_new_table(opc_handler_t
**table
, unsigned char idx
)
9179 opc_handler_t
**tmp
;
9181 tmp
= g_new(opc_handler_t
*, PPC_CPU_INDIRECT_OPCODES_LEN
);
9182 fill_new_table(tmp
, PPC_CPU_INDIRECT_OPCODES_LEN
);
9183 table
[idx
] = (opc_handler_t
*)((uintptr_t)tmp
| PPC_INDIRECT
);
9188 static int insert_in_table(opc_handler_t
**table
, unsigned char idx
,
9189 opc_handler_t
*handler
)
9191 if (table
[idx
] != &invalid_handler
)
9193 table
[idx
] = handler
;
9198 static int register_direct_insn(opc_handler_t
**ppc_opcodes
,
9199 unsigned char idx
, opc_handler_t
*handler
)
9201 if (insert_in_table(ppc_opcodes
, idx
, handler
) < 0) {
9202 printf("*** ERROR: opcode %02x already assigned in main "
9203 "opcode table\n", idx
);
9204 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9205 printf(" Registered handler '%s' - new handler '%s'\n",
9206 ppc_opcodes
[idx
]->oname
, handler
->oname
);
9214 static int register_ind_in_table(opc_handler_t
**table
,
9215 unsigned char idx1
, unsigned char idx2
,
9216 opc_handler_t
*handler
)
9218 if (table
[idx1
] == &invalid_handler
) {
9219 if (create_new_table(table
, idx1
) < 0) {
9220 printf("*** ERROR: unable to create indirect table "
9221 "idx=%02x\n", idx1
);
9225 if (!is_indirect_opcode(table
[idx1
])) {
9226 printf("*** ERROR: idx %02x already assigned to a direct "
9228 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9229 printf(" Registered handler '%s' - new handler '%s'\n",
9230 ind_table(table
[idx1
])[idx2
]->oname
, handler
->oname
);
9235 if (handler
!= NULL
&&
9236 insert_in_table(ind_table(table
[idx1
]), idx2
, handler
) < 0) {
9237 printf("*** ERROR: opcode %02x already assigned in "
9238 "opcode table %02x\n", idx2
, idx1
);
9239 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9240 printf(" Registered handler '%s' - new handler '%s'\n",
9241 ind_table(table
[idx1
])[idx2
]->oname
, handler
->oname
);
9249 static int register_ind_insn(opc_handler_t
**ppc_opcodes
,
9250 unsigned char idx1
, unsigned char idx2
,
9251 opc_handler_t
*handler
)
9253 return register_ind_in_table(ppc_opcodes
, idx1
, idx2
, handler
);
9256 static int register_dblind_insn(opc_handler_t
**ppc_opcodes
,
9257 unsigned char idx1
, unsigned char idx2
,
9258 unsigned char idx3
, opc_handler_t
*handler
)
9260 if (register_ind_in_table(ppc_opcodes
, idx1
, idx2
, NULL
) < 0) {
9261 printf("*** ERROR: unable to join indirect table idx "
9262 "[%02x-%02x]\n", idx1
, idx2
);
9265 if (register_ind_in_table(ind_table(ppc_opcodes
[idx1
]), idx2
, idx3
,
9267 printf("*** ERROR: unable to insert opcode "
9268 "[%02x-%02x-%02x]\n", idx1
, idx2
, idx3
);
9275 static int register_trplind_insn(opc_handler_t
**ppc_opcodes
,
9276 unsigned char idx1
, unsigned char idx2
,
9277 unsigned char idx3
, unsigned char idx4
,
9278 opc_handler_t
*handler
)
9280 opc_handler_t
**table
;
9282 if (register_ind_in_table(ppc_opcodes
, idx1
, idx2
, NULL
) < 0) {
9283 printf("*** ERROR: unable to join indirect table idx "
9284 "[%02x-%02x]\n", idx1
, idx2
);
9287 table
= ind_table(ppc_opcodes
[idx1
]);
9288 if (register_ind_in_table(table
, idx2
, idx3
, NULL
) < 0) {
9289 printf("*** ERROR: unable to join 2nd-level indirect table idx "
9290 "[%02x-%02x-%02x]\n", idx1
, idx2
, idx3
);
9293 table
= ind_table(table
[idx2
]);
9294 if (register_ind_in_table(table
, idx3
, idx4
, handler
) < 0) {
9295 printf("*** ERROR: unable to insert opcode "
9296 "[%02x-%02x-%02x-%02x]\n", idx1
, idx2
, idx3
, idx4
);
9301 static int register_insn(opc_handler_t
**ppc_opcodes
, opcode_t
*insn
)
9303 if (insn
->opc2
!= 0xFF) {
9304 if (insn
->opc3
!= 0xFF) {
9305 if (insn
->opc4
!= 0xFF) {
9306 if (register_trplind_insn(ppc_opcodes
, insn
->opc1
, insn
->opc2
,
9307 insn
->opc3
, insn
->opc4
,
9308 &insn
->handler
) < 0) {
9312 if (register_dblind_insn(ppc_opcodes
, insn
->opc1
, insn
->opc2
,
9313 insn
->opc3
, &insn
->handler
) < 0)
9317 if (register_ind_insn(ppc_opcodes
, insn
->opc1
,
9318 insn
->opc2
, &insn
->handler
) < 0)
9322 if (register_direct_insn(ppc_opcodes
, insn
->opc1
, &insn
->handler
) < 0)
9329 static int test_opcode_table(opc_handler_t
**table
, int len
)
9333 for (i
= 0, count
= 0; i
< len
; i
++) {
9334 /* Consistency fixup */
9335 if (table
[i
] == NULL
)
9336 table
[i
] = &invalid_handler
;
9337 if (table
[i
] != &invalid_handler
) {
9338 if (is_indirect_opcode(table
[i
])) {
9339 tmp
= test_opcode_table(ind_table(table
[i
]),
9340 PPC_CPU_INDIRECT_OPCODES_LEN
);
9343 table
[i
] = &invalid_handler
;
9356 static void fix_opcode_tables(opc_handler_t
**ppc_opcodes
)
9358 if (test_opcode_table(ppc_opcodes
, PPC_CPU_OPCODES_LEN
) == 0)
9359 printf("*** WARNING: no opcode defined !\n");
9362 /*****************************************************************************/
9363 static void create_ppc_opcodes(PowerPCCPU
*cpu
, Error
**errp
)
9365 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9366 CPUPPCState
*env
= &cpu
->env
;
9369 fill_new_table(env
->opcodes
, PPC_CPU_OPCODES_LEN
);
9370 for (opc
= opcodes
; opc
< &opcodes
[ARRAY_SIZE(opcodes
)]; opc
++) {
9371 if (((opc
->handler
.type
& pcc
->insns_flags
) != 0) ||
9372 ((opc
->handler
.type2
& pcc
->insns_flags2
) != 0)) {
9373 if (register_insn(env
->opcodes
, opc
) < 0) {
9374 error_setg(errp
, "ERROR initializing PowerPC instruction "
9375 "0x%02x 0x%02x 0x%02x", opc
->opc1
, opc
->opc2
,
9381 fix_opcode_tables(env
->opcodes
);
9386 #if defined(PPC_DUMP_CPU)
9387 static void dump_ppc_insns(CPUPPCState
*env
)
9389 opc_handler_t
**table
, *handler
;
9391 uint8_t opc1
, opc2
, opc3
, opc4
;
9393 printf("Instructions set:\n");
9394 /* opc1 is 6 bits long */
9395 for (opc1
= 0x00; opc1
< PPC_CPU_OPCODES_LEN
; opc1
++) {
9396 table
= env
->opcodes
;
9397 handler
= table
[opc1
];
9398 if (is_indirect_opcode(handler
)) {
9399 /* opc2 is 5 bits long */
9400 for (opc2
= 0; opc2
< PPC_CPU_INDIRECT_OPCODES_LEN
; opc2
++) {
9401 table
= env
->opcodes
;
9402 handler
= env
->opcodes
[opc1
];
9403 table
= ind_table(handler
);
9404 handler
= table
[opc2
];
9405 if (is_indirect_opcode(handler
)) {
9406 table
= ind_table(handler
);
9407 /* opc3 is 5 bits long */
9408 for (opc3
= 0; opc3
< PPC_CPU_INDIRECT_OPCODES_LEN
;
9410 handler
= table
[opc3
];
9411 if (is_indirect_opcode(handler
)) {
9412 table
= ind_table(handler
);
9413 /* opc4 is 5 bits long */
9414 for (opc4
= 0; opc4
< PPC_CPU_INDIRECT_OPCODES_LEN
;
9416 handler
= table
[opc4
];
9417 if (handler
->handler
!= &gen_invalid
) {
9418 printf("INSN: %02x %02x %02x %02x -- "
9419 "(%02d %04d %02d) : %s\n",
9420 opc1
, opc2
, opc3
, opc4
,
9421 opc1
, (opc3
<< 5) | opc2
, opc4
,
9426 if (handler
->handler
!= &gen_invalid
) {
9427 /* Special hack to properly dump SPE insns */
9428 p
= strchr(handler
->oname
, '_');
9430 printf("INSN: %02x %02x %02x (%02d %04d) : "
9432 opc1
, opc2
, opc3
, opc1
,
9437 if ((p
- handler
->oname
) != strlen(q
)
9438 || (memcmp(handler
->oname
, q
, strlen(q
))
9440 /* First instruction */
9441 printf("INSN: %02x %02x %02x"
9442 "(%02d %04d) : %.*s\n",
9443 opc1
, opc2
<< 1, opc3
, opc1
,
9444 (opc3
<< 6) | (opc2
<< 1),
9445 (int)(p
- handler
->oname
),
9448 if (strcmp(p
+ 1, q
) != 0) {
9449 /* Second instruction */
9450 printf("INSN: %02x %02x %02x "
9451 "(%02d %04d) : %s\n", opc1
,
9452 (opc2
<< 1) | 1, opc3
, opc1
,
9453 (opc3
<< 6) | (opc2
<< 1) | 1,
9461 if (handler
->handler
!= &gen_invalid
) {
9462 printf("INSN: %02x %02x -- (%02d %04d) : %s\n",
9463 opc1
, opc2
, opc1
, opc2
, handler
->oname
);
9468 if (handler
->handler
!= &gen_invalid
) {
9469 printf("INSN: %02x -- -- (%02d ----) : %s\n",
9470 opc1
, opc1
, handler
->oname
);
9477 static bool avr_need_swap(CPUPPCState
*env
)
9479 #ifdef HOST_WORDS_BIGENDIAN
9486 static int gdb_get_float_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9489 stfq_p(mem_buf
, env
->fpr
[n
]);
9490 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9494 stl_p(mem_buf
, env
->fpscr
);
9495 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9501 static int gdb_set_float_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9504 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9505 env
->fpr
[n
] = ldfq_p(mem_buf
);
9509 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9510 helper_store_fpscr(env
, ldl_p(mem_buf
), 0xffffffff);
9516 static int gdb_get_avr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9519 if (!avr_need_swap(env
)) {
9520 stq_p(mem_buf
, env
->avr
[n
].u64
[0]);
9521 stq_p(mem_buf
+8, env
->avr
[n
].u64
[1]);
9523 stq_p(mem_buf
, env
->avr
[n
].u64
[1]);
9524 stq_p(mem_buf
+8, env
->avr
[n
].u64
[0]);
9526 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9527 ppc_maybe_bswap_register(env
, mem_buf
+ 8, 8);
9531 stl_p(mem_buf
, env
->vscr
);
9532 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9536 stl_p(mem_buf
, (uint32_t)env
->spr
[SPR_VRSAVE
]);
9537 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9543 static int gdb_set_avr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9546 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9547 ppc_maybe_bswap_register(env
, mem_buf
+ 8, 8);
9548 if (!avr_need_swap(env
)) {
9549 env
->avr
[n
].u64
[0] = ldq_p(mem_buf
);
9550 env
->avr
[n
].u64
[1] = ldq_p(mem_buf
+8);
9552 env
->avr
[n
].u64
[1] = ldq_p(mem_buf
);
9553 env
->avr
[n
].u64
[0] = ldq_p(mem_buf
+8);
9558 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9559 env
->vscr
= ldl_p(mem_buf
);
9563 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9564 env
->spr
[SPR_VRSAVE
] = (target_ulong
)ldl_p(mem_buf
);
9570 static int gdb_get_spe_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9573 #if defined(TARGET_PPC64)
9574 stl_p(mem_buf
, env
->gpr
[n
] >> 32);
9575 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9577 stl_p(mem_buf
, env
->gprh
[n
]);
9582 stq_p(mem_buf
, env
->spe_acc
);
9583 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9587 stl_p(mem_buf
, env
->spe_fscr
);
9588 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9594 static int gdb_set_spe_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9597 #if defined(TARGET_PPC64)
9598 target_ulong lo
= (uint32_t)env
->gpr
[n
];
9601 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9603 hi
= (target_ulong
)ldl_p(mem_buf
) << 32;
9604 env
->gpr
[n
] = lo
| hi
;
9606 env
->gprh
[n
] = ldl_p(mem_buf
);
9611 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9612 env
->spe_acc
= ldq_p(mem_buf
);
9616 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9617 env
->spe_fscr
= ldl_p(mem_buf
);
9623 static int gdb_get_vsx_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9626 stq_p(mem_buf
, env
->vsr
[n
]);
9627 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9633 static int gdb_set_vsx_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9636 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9637 env
->vsr
[n
] = ldq_p(mem_buf
);
9643 static int ppc_fixup_cpu(PowerPCCPU
*cpu
)
9645 CPUPPCState
*env
= &cpu
->env
;
9647 /* TCG doesn't (yet) emulate some groups of instructions that
9648 * are implemented on some otherwise supported CPUs (e.g. VSX
9649 * and decimal floating point instructions on POWER7). We
9650 * remove unsupported instruction groups from the cpu state's
9651 * instruction masks and hope the guest can cope. For at
9652 * least the pseries machine, the unavailability of these
9653 * instructions can be advertised to the guest via the device
9655 if ((env
->insns_flags
& ~PPC_TCG_INSNS
)
9656 || (env
->insns_flags2
& ~PPC_TCG_INSNS2
)) {
9657 warn_report("Disabling some instructions which are not "
9658 "emulated by TCG (0x%" PRIx64
", 0x%" PRIx64
")",
9659 env
->insns_flags
& ~PPC_TCG_INSNS
,
9660 env
->insns_flags2
& ~PPC_TCG_INSNS2
);
9662 env
->insns_flags
&= PPC_TCG_INSNS
;
9663 env
->insns_flags2
&= PPC_TCG_INSNS2
;
9667 static void ppc_cpu_realize(DeviceState
*dev
, Error
**errp
)
9669 CPUState
*cs
= CPU(dev
);
9670 PowerPCCPU
*cpu
= POWERPC_CPU(dev
);
9671 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9672 Error
*local_err
= NULL
;
9674 cpu_exec_realizefn(cs
, &local_err
);
9675 if (local_err
!= NULL
) {
9676 error_propagate(errp
, local_err
);
9679 if (cpu
->vcpu_id
== UNASSIGNED_CPU_INDEX
) {
9680 cpu
->vcpu_id
= cs
->cpu_index
;
9683 if (tcg_enabled()) {
9684 if (ppc_fixup_cpu(cpu
) != 0) {
9685 error_setg(errp
, "Unable to emulate selected CPU with TCG");
9690 create_ppc_opcodes(cpu
, &local_err
);
9691 if (local_err
!= NULL
) {
9692 error_propagate(errp
, local_err
);
9697 if (pcc
->insns_flags
& PPC_FLOAT
) {
9698 gdb_register_coprocessor(cs
, gdb_get_float_reg
, gdb_set_float_reg
,
9699 33, "power-fpu.xml", 0);
9701 if (pcc
->insns_flags
& PPC_ALTIVEC
) {
9702 gdb_register_coprocessor(cs
, gdb_get_avr_reg
, gdb_set_avr_reg
,
9703 34, "power-altivec.xml", 0);
9705 if (pcc
->insns_flags
& PPC_SPE
) {
9706 gdb_register_coprocessor(cs
, gdb_get_spe_reg
, gdb_set_spe_reg
,
9707 34, "power-spe.xml", 0);
9709 if (pcc
->insns_flags2
& PPC2_VSX
) {
9710 gdb_register_coprocessor(cs
, gdb_get_vsx_reg
, gdb_set_vsx_reg
,
9711 32, "power-vsx.xml", 0);
9716 pcc
->parent_realize(dev
, errp
);
9718 #if defined(PPC_DUMP_CPU)
9720 CPUPPCState
*env
= &cpu
->env
;
9721 const char *mmu_model
, *excp_model
, *bus_model
;
9722 switch (env
->mmu_model
) {
9723 case POWERPC_MMU_32B
:
9724 mmu_model
= "PowerPC 32";
9726 case POWERPC_MMU_SOFT_6xx
:
9727 mmu_model
= "PowerPC 6xx/7xx with software driven TLBs";
9729 case POWERPC_MMU_SOFT_74xx
:
9730 mmu_model
= "PowerPC 74xx with software driven TLBs";
9732 case POWERPC_MMU_SOFT_4xx
:
9733 mmu_model
= "PowerPC 4xx with software driven TLBs";
9735 case POWERPC_MMU_SOFT_4xx_Z
:
9736 mmu_model
= "PowerPC 4xx with software driven TLBs "
9737 "and zones protections";
9739 case POWERPC_MMU_REAL
:
9740 mmu_model
= "PowerPC real mode only";
9742 case POWERPC_MMU_MPC8xx
:
9743 mmu_model
= "PowerPC MPC8xx";
9745 case POWERPC_MMU_BOOKE
:
9746 mmu_model
= "PowerPC BookE";
9748 case POWERPC_MMU_BOOKE206
:
9749 mmu_model
= "PowerPC BookE 2.06";
9751 case POWERPC_MMU_601
:
9752 mmu_model
= "PowerPC 601";
9754 #if defined(TARGET_PPC64)
9755 case POWERPC_MMU_64B
:
9756 mmu_model
= "PowerPC 64";
9760 mmu_model
= "Unknown or invalid";
9763 switch (env
->excp_model
) {
9764 case POWERPC_EXCP_STD
:
9765 excp_model
= "PowerPC";
9767 case POWERPC_EXCP_40x
:
9768 excp_model
= "PowerPC 40x";
9770 case POWERPC_EXCP_601
:
9771 excp_model
= "PowerPC 601";
9773 case POWERPC_EXCP_602
:
9774 excp_model
= "PowerPC 602";
9776 case POWERPC_EXCP_603
:
9777 excp_model
= "PowerPC 603";
9779 case POWERPC_EXCP_603E
:
9780 excp_model
= "PowerPC 603e";
9782 case POWERPC_EXCP_604
:
9783 excp_model
= "PowerPC 604";
9785 case POWERPC_EXCP_7x0
:
9786 excp_model
= "PowerPC 740/750";
9788 case POWERPC_EXCP_7x5
:
9789 excp_model
= "PowerPC 745/755";
9791 case POWERPC_EXCP_74xx
:
9792 excp_model
= "PowerPC 74xx";
9794 case POWERPC_EXCP_BOOKE
:
9795 excp_model
= "PowerPC BookE";
9797 #if defined(TARGET_PPC64)
9798 case POWERPC_EXCP_970
:
9799 excp_model
= "PowerPC 970";
9803 excp_model
= "Unknown or invalid";
9806 switch (env
->bus_model
) {
9807 case PPC_FLAGS_INPUT_6xx
:
9808 bus_model
= "PowerPC 6xx";
9810 case PPC_FLAGS_INPUT_BookE
:
9811 bus_model
= "PowerPC BookE";
9813 case PPC_FLAGS_INPUT_405
:
9814 bus_model
= "PowerPC 405";
9816 case PPC_FLAGS_INPUT_401
:
9817 bus_model
= "PowerPC 401/403";
9819 case PPC_FLAGS_INPUT_RCPU
:
9820 bus_model
= "RCPU / MPC8xx";
9822 #if defined(TARGET_PPC64)
9823 case PPC_FLAGS_INPUT_970
:
9824 bus_model
= "PowerPC 970";
9828 bus_model
= "Unknown or invalid";
9831 printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64
"\n"
9832 " MMU model : %s\n",
9833 object_class_get_name(OBJECT_CLASS(pcc
)),
9834 pcc
->pvr
, pcc
->msr_mask
, mmu_model
);
9835 #if !defined(CONFIG_USER_ONLY)
9836 if (env
->tlb
.tlb6
) {
9837 printf(" %d %s TLB in %d ways\n",
9838 env
->nb_tlb
, env
->id_tlbs
? "splitted" : "merged",
9842 printf(" Exceptions model : %s\n"
9843 " Bus model : %s\n",
9844 excp_model
, bus_model
);
9845 printf(" MSR features :\n");
9846 if (env
->flags
& POWERPC_FLAG_SPE
)
9847 printf(" signal processing engine enable"
9849 else if (env
->flags
& POWERPC_FLAG_VRE
)
9850 printf(" vector processor enable\n");
9851 if (env
->flags
& POWERPC_FLAG_TGPR
)
9852 printf(" temporary GPRs\n");
9853 else if (env
->flags
& POWERPC_FLAG_CE
)
9854 printf(" critical input enable\n");
9855 if (env
->flags
& POWERPC_FLAG_SE
)
9856 printf(" single-step trace mode\n");
9857 else if (env
->flags
& POWERPC_FLAG_DWE
)
9858 printf(" debug wait enable\n");
9859 else if (env
->flags
& POWERPC_FLAG_UBLE
)
9860 printf(" user BTB lock enable\n");
9861 if (env
->flags
& POWERPC_FLAG_BE
)
9862 printf(" branch-step trace mode\n");
9863 else if (env
->flags
& POWERPC_FLAG_DE
)
9864 printf(" debug interrupt enable\n");
9865 if (env
->flags
& POWERPC_FLAG_PX
)
9866 printf(" inclusive protection\n");
9867 else if (env
->flags
& POWERPC_FLAG_PMM
)
9868 printf(" performance monitor mark\n");
9869 if (env
->flags
== POWERPC_FLAG_NONE
)
9871 printf(" Time-base/decrementer clock source: %s\n",
9872 env
->flags
& POWERPC_FLAG_RTC_CLK
? "RTC clock" : "bus clock");
9873 dump_ppc_insns(env
);
9881 cpu_exec_unrealizefn(cs
);
9884 static void ppc_cpu_unrealize(DeviceState
*dev
, Error
**errp
)
9886 PowerPCCPU
*cpu
= POWERPC_CPU(dev
);
9887 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9888 CPUPPCState
*env
= &cpu
->env
;
9889 Error
*local_err
= NULL
;
9890 opc_handler_t
**table
, **table_2
;
9893 pcc
->parent_unrealize(dev
, &local_err
);
9894 if (local_err
!= NULL
) {
9895 error_propagate(errp
, local_err
);
9899 for (i
= 0; i
< PPC_CPU_OPCODES_LEN
; i
++) {
9900 if (env
->opcodes
[i
] == &invalid_handler
) {
9903 if (is_indirect_opcode(env
->opcodes
[i
])) {
9904 table
= ind_table(env
->opcodes
[i
]);
9905 for (j
= 0; j
< PPC_CPU_INDIRECT_OPCODES_LEN
; j
++) {
9906 if (table
[j
] == &invalid_handler
) {
9909 if (is_indirect_opcode(table
[j
])) {
9910 table_2
= ind_table(table
[j
]);
9911 for (k
= 0; k
< PPC_CPU_INDIRECT_OPCODES_LEN
; k
++) {
9912 if (table_2
[k
] != &invalid_handler
&&
9913 is_indirect_opcode(table_2
[k
])) {
9914 g_free((opc_handler_t
*)((uintptr_t)table_2
[k
] &
9918 g_free((opc_handler_t
*)((uintptr_t)table
[j
] &
9922 g_free((opc_handler_t
*)((uintptr_t)env
->opcodes
[i
] &
9928 static gint
ppc_cpu_compare_class_pvr(gconstpointer a
, gconstpointer b
)
9930 ObjectClass
*oc
= (ObjectClass
*)a
;
9931 uint32_t pvr
= *(uint32_t *)b
;
9932 PowerPCCPUClass
*pcc
= (PowerPCCPUClass
*)a
;
9934 /* -cpu host does a PVR lookup during construction */
9935 if (unlikely(strcmp(object_class_get_name(oc
),
9936 TYPE_HOST_POWERPC_CPU
) == 0)) {
9940 return pcc
->pvr
== pvr
? 0 : -1;
9943 PowerPCCPUClass
*ppc_cpu_class_by_pvr(uint32_t pvr
)
9945 GSList
*list
, *item
;
9946 PowerPCCPUClass
*pcc
= NULL
;
9948 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
9949 item
= g_slist_find_custom(list
, &pvr
, ppc_cpu_compare_class_pvr
);
9951 pcc
= POWERPC_CPU_CLASS(item
->data
);
9958 static gint
ppc_cpu_compare_class_pvr_mask(gconstpointer a
, gconstpointer b
)
9960 ObjectClass
*oc
= (ObjectClass
*)a
;
9961 uint32_t pvr
= *(uint32_t *)b
;
9962 PowerPCCPUClass
*pcc
= (PowerPCCPUClass
*)a
;
9964 /* -cpu host does a PVR lookup during construction */
9965 if (unlikely(strcmp(object_class_get_name(oc
),
9966 TYPE_HOST_POWERPC_CPU
) == 0)) {
9970 if (pcc
->pvr_match(pcc
, pvr
)) {
9977 PowerPCCPUClass
*ppc_cpu_class_by_pvr_mask(uint32_t pvr
)
9979 GSList
*list
, *item
;
9980 PowerPCCPUClass
*pcc
= NULL
;
9982 list
= object_class_get_list(TYPE_POWERPC_CPU
, true);
9983 item
= g_slist_find_custom(list
, &pvr
, ppc_cpu_compare_class_pvr_mask
);
9985 pcc
= POWERPC_CPU_CLASS(item
->data
);
9992 static const char *ppc_cpu_lookup_alias(const char *alias
)
9996 for (ai
= 0; ppc_cpu_aliases
[ai
].alias
!= NULL
; ai
++) {
9997 if (strcmp(ppc_cpu_aliases
[ai
].alias
, alias
) == 0) {
9998 return ppc_cpu_aliases
[ai
].model
;
10005 static ObjectClass
*ppc_cpu_class_by_name(const char *name
)
10007 char *cpu_model
, *typename
;
10012 /* Lookup by PVR if cpu_model is valid 8 digit hex number
10013 * (excl: 0x prefix if present)
10015 if (!qemu_strtoul(name
, &p
, 16, &pvr
)) {
10016 int len
= p
- name
;
10017 len
= (len
== 10) && (name
[1] == 'x') ? len
- 2 : len
;
10018 if ((len
== 8) && (*p
== '\0')) {
10019 return OBJECT_CLASS(ppc_cpu_class_by_pvr(pvr
));
10023 cpu_model
= g_ascii_strdown(name
, -1);
10024 p
= ppc_cpu_lookup_alias(cpu_model
);
10027 cpu_model
= g_strdup(p
);
10030 typename
= g_strdup_printf("%s" POWERPC_CPU_TYPE_SUFFIX
, cpu_model
);
10031 oc
= object_class_by_name(typename
);
10038 static void ppc_cpu_parse_featurestr(const char *type
, char *features
,
10041 Object
*machine
= qdev_get_machine();
10042 const PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(object_class_by_name(type
));
10048 if (object_property_find(machine
, "max-cpu-compat", NULL
)) {
10051 char *s
= features
;
10052 Error
*local_err
= NULL
;
10053 char *compat_str
= NULL
;
10056 * Backwards compatibility hack:
10058 * CPUs had a "compat=" property which didn't make sense for
10059 * anything except pseries. It was replaced by "max-cpu-compat"
10060 * machine option. This supports old command lines like
10061 * -cpu POWER8,compat=power7
10062 * By stripping the compat option and applying it to the machine
10063 * before passing it on to the cpu level parser.
10065 inpieces
= g_strsplit(features
, ",", 0);
10067 for (i
= 0; inpieces
[i
]; i
++) {
10068 if (g_str_has_prefix(inpieces
[i
], "compat=")) {
10069 compat_str
= inpieces
[i
];
10072 if ((i
!= 0) && (s
!= features
)) {
10073 s
= g_stpcpy(s
, ",");
10075 s
= g_stpcpy(s
, inpieces
[i
]);
10079 char *v
= compat_str
+ strlen("compat=");
10080 object_property_set_str(machine
, v
, "max-cpu-compat", &local_err
);
10082 g_strfreev(inpieces
);
10084 error_propagate(errp
, local_err
);
10089 /* do property processing with generic handler */
10090 pcc
->parent_parse_features(type
, features
, errp
);
10093 PowerPCCPUClass
*ppc_cpu_get_family_class(PowerPCCPUClass
*pcc
)
10095 ObjectClass
*oc
= OBJECT_CLASS(pcc
);
10097 while (oc
&& !object_class_is_abstract(oc
)) {
10098 oc
= object_class_get_parent(oc
);
10102 return POWERPC_CPU_CLASS(oc
);
10105 /* Sort by PVR, ordering special case "host" last. */
10106 static gint
ppc_cpu_list_compare(gconstpointer a
, gconstpointer b
)
10108 ObjectClass
*oc_a
= (ObjectClass
*)a
;
10109 ObjectClass
*oc_b
= (ObjectClass
*)b
;
10110 PowerPCCPUClass
*pcc_a
= POWERPC_CPU_CLASS(oc_a
);
10111 PowerPCCPUClass
*pcc_b
= POWERPC_CPU_CLASS(oc_b
);
10112 const char *name_a
= object_class_get_name(oc_a
);
10113 const char *name_b
= object_class_get_name(oc_b
);
10115 if (strcmp(name_a
, TYPE_HOST_POWERPC_CPU
) == 0) {
10117 } else if (strcmp(name_b
, TYPE_HOST_POWERPC_CPU
) == 0) {
10120 /* Avoid an integer overflow during subtraction */
10121 if (pcc_a
->pvr
< pcc_b
->pvr
) {
10123 } else if (pcc_a
->pvr
> pcc_b
->pvr
) {
10131 static void ppc_cpu_list_entry(gpointer data
, gpointer user_data
)
10133 ObjectClass
*oc
= data
;
10134 CPUListState
*s
= user_data
;
10135 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10136 DeviceClass
*family
= DEVICE_CLASS(ppc_cpu_get_family_class(pcc
));
10137 const char *typename
= object_class_get_name(oc
);
10141 if (unlikely(strcmp(typename
, TYPE_HOST_POWERPC_CPU
) == 0)) {
10145 name
= g_strndup(typename
,
10146 strlen(typename
) - strlen(POWERPC_CPU_TYPE_SUFFIX
));
10147 (*s
->cpu_fprintf
)(s
->file
, "PowerPC %-16s PVR %08x\n",
10149 for (i
= 0; ppc_cpu_aliases
[i
].alias
!= NULL
; i
++) {
10150 PowerPCCPUAlias
*alias
= &ppc_cpu_aliases
[i
];
10151 ObjectClass
*alias_oc
= ppc_cpu_class_by_name(alias
->model
);
10153 if (alias_oc
!= oc
) {
10157 * If running with KVM, we might update the family alias later, so
10158 * avoid printing the wrong alias here and use "preferred" instead
10160 if (strcmp(alias
->alias
, family
->desc
) == 0) {
10161 (*s
->cpu_fprintf
)(s
->file
,
10162 "PowerPC %-16s (alias for preferred %s CPU)\n",
10163 alias
->alias
, family
->desc
);
10165 (*s
->cpu_fprintf
)(s
->file
, "PowerPC %-16s (alias for %s)\n",
10166 alias
->alias
, name
);
10172 void ppc_cpu_list(FILE *f
, fprintf_function cpu_fprintf
)
10176 .cpu_fprintf
= cpu_fprintf
,
10180 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10181 list
= g_slist_sort(list
, ppc_cpu_list_compare
);
10182 g_slist_foreach(list
, ppc_cpu_list_entry
, &s
);
10183 g_slist_free(list
);
10186 cpu_fprintf(f
, "\n");
10187 cpu_fprintf(f
, "PowerPC %-16s\n", "host");
10191 static void ppc_cpu_defs_entry(gpointer data
, gpointer user_data
)
10193 ObjectClass
*oc
= data
;
10194 CpuDefinitionInfoList
**first
= user_data
;
10195 const char *typename
;
10196 CpuDefinitionInfoList
*entry
;
10197 CpuDefinitionInfo
*info
;
10199 typename
= object_class_get_name(oc
);
10200 info
= g_malloc0(sizeof(*info
));
10201 info
->name
= g_strndup(typename
,
10202 strlen(typename
) - strlen(POWERPC_CPU_TYPE_SUFFIX
));
10204 entry
= g_malloc0(sizeof(*entry
));
10205 entry
->value
= info
;
10206 entry
->next
= *first
;
10210 CpuDefinitionInfoList
*arch_query_cpu_definitions(Error
**errp
)
10212 CpuDefinitionInfoList
*cpu_list
= NULL
;
10216 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10217 g_slist_foreach(list
, ppc_cpu_defs_entry
, &cpu_list
);
10218 g_slist_free(list
);
10220 for (i
= 0; ppc_cpu_aliases
[i
].alias
!= NULL
; i
++) {
10221 PowerPCCPUAlias
*alias
= &ppc_cpu_aliases
[i
];
10223 CpuDefinitionInfoList
*entry
;
10224 CpuDefinitionInfo
*info
;
10226 oc
= ppc_cpu_class_by_name(alias
->model
);
10231 info
= g_malloc0(sizeof(*info
));
10232 info
->name
= g_strdup(alias
->alias
);
10233 info
->q_typename
= g_strdup(object_class_get_name(oc
));
10235 entry
= g_malloc0(sizeof(*entry
));
10236 entry
->value
= info
;
10237 entry
->next
= cpu_list
;
10244 static void ppc_cpu_set_pc(CPUState
*cs
, vaddr value
)
10246 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10248 cpu
->env
.nip
= value
;
10251 static bool ppc_cpu_has_work(CPUState
*cs
)
10253 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10254 CPUPPCState
*env
= &cpu
->env
;
10256 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
10259 /* CPUClass::reset() */
10260 static void ppc_cpu_reset(CPUState
*s
)
10262 PowerPCCPU
*cpu
= POWERPC_CPU(s
);
10263 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10264 CPUPPCState
*env
= &cpu
->env
;
10268 pcc
->parent_reset(s
);
10270 msr
= (target_ulong
)0;
10271 msr
|= (target_ulong
)MSR_HVB
;
10272 msr
|= (target_ulong
)0 << MSR_AP
; /* TO BE CHECKED */
10273 msr
|= (target_ulong
)0 << MSR_SA
; /* TO BE CHECKED */
10274 msr
|= (target_ulong
)1 << MSR_EP
;
10275 #if defined(DO_SINGLE_STEP) && 0
10276 /* Single step trace mode */
10277 msr
|= (target_ulong
)1 << MSR_SE
;
10278 msr
|= (target_ulong
)1 << MSR_BE
;
10280 #if defined(CONFIG_USER_ONLY)
10281 msr
|= (target_ulong
)1 << MSR_FP
; /* Allow floating point usage */
10282 msr
|= (target_ulong
)1 << MSR_FE0
; /* Allow floating point exceptions */
10283 msr
|= (target_ulong
)1 << MSR_FE1
;
10284 msr
|= (target_ulong
)1 << MSR_VR
; /* Allow altivec usage */
10285 msr
|= (target_ulong
)1 << MSR_VSX
; /* Allow VSX usage */
10286 msr
|= (target_ulong
)1 << MSR_SPE
; /* Allow SPE usage */
10287 msr
|= (target_ulong
)1 << MSR_PR
;
10288 #if defined(TARGET_PPC64)
10289 msr
|= (target_ulong
)1 << MSR_TM
; /* Transactional memory */
10291 #if !defined(TARGET_WORDS_BIGENDIAN)
10292 msr
|= (target_ulong
)1 << MSR_LE
; /* Little-endian user mode */
10293 if (!((env
->msr_mask
>> MSR_LE
) & 1)) {
10294 fprintf(stderr
, "Selected CPU does not support little-endian.\n");
10300 #if defined(TARGET_PPC64)
10301 if (env
->mmu_model
& POWERPC_MMU_64
) {
10302 msr
|= (1ULL << MSR_SF
);
10306 hreg_store_msr(env
, msr
, 1);
10308 #if !defined(CONFIG_USER_ONLY)
10309 env
->nip
= env
->hreset_vector
| env
->excp_prefix
;
10310 if (env
->mmu_model
!= POWERPC_MMU_REAL
) {
10311 ppc_tlb_invalidate_all(env
);
10315 hreg_compute_hflags(env
);
10316 env
->reserve_addr
= (target_ulong
)-1ULL;
10317 /* Be sure no exception or interrupt is pending */
10318 env
->pending_interrupts
= 0;
10319 s
->exception_index
= POWERPC_EXCP_NONE
;
10320 env
->error_code
= 0;
10322 for (i
= 0; i
< ARRAY_SIZE(env
->spr_cb
); i
++) {
10323 ppc_spr_t
*spr
= &env
->spr_cb
[i
];
10328 env
->spr
[i
] = spr
->default_value
;
10332 #ifndef CONFIG_USER_ONLY
10333 static bool ppc_cpu_is_big_endian(CPUState
*cs
)
10335 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10336 CPUPPCState
*env
= &cpu
->env
;
10338 cpu_synchronize_state(cs
);
10344 static void ppc_cpu_instance_init(Object
*obj
)
10346 CPUState
*cs
= CPU(obj
);
10347 PowerPCCPU
*cpu
= POWERPC_CPU(obj
);
10348 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10349 CPUPPCState
*env
= &cpu
->env
;
10352 cpu
->vcpu_id
= UNASSIGNED_CPU_INDEX
;
10354 env
->msr_mask
= pcc
->msr_mask
;
10355 env
->mmu_model
= pcc
->mmu_model
;
10356 env
->excp_model
= pcc
->excp_model
;
10357 env
->bus_model
= pcc
->bus_model
;
10358 env
->insns_flags
= pcc
->insns_flags
;
10359 env
->insns_flags2
= pcc
->insns_flags2
;
10360 env
->flags
= pcc
->flags
;
10361 env
->bfd_mach
= pcc
->bfd_mach
;
10362 env
->check_pow
= pcc
->check_pow
;
10364 /* Mark HV mode as supported if the CPU has an MSR_HV bit
10365 * in the msr_mask. The mask can later be cleared by PAPR
10366 * mode but the hv mode support will remain, thus enforcing
10367 * that we cannot use priv. instructions in guest in PAPR
10368 * mode. For 970 we currently simply don't set HV in msr_mask
10369 * thus simulating an "Apple mode" 970. If we ever want to
10370 * support 970 HV mode, we'll have to add a processor attribute
10373 #if !defined(CONFIG_USER_ONLY)
10374 env
->has_hv_mode
= !!(env
->msr_mask
& MSR_HVB
);
10377 ppc_hash64_init(cpu
);
10380 static void ppc_cpu_instance_finalize(Object
*obj
)
10382 PowerPCCPU
*cpu
= POWERPC_CPU(obj
);
10384 ppc_hash64_finalize(cpu
);
10387 static bool ppc_pvr_match_default(PowerPCCPUClass
*pcc
, uint32_t pvr
)
10389 return pcc
->pvr
== pvr
;
10392 static gchar
*ppc_gdb_arch_name(CPUState
*cs
)
10394 #if defined(TARGET_PPC64)
10395 return g_strdup("powerpc:common64");
10397 return g_strdup("powerpc:common");
10401 static void ppc_disas_set_info(CPUState
*cs
, disassemble_info
*info
)
10403 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10404 CPUPPCState
*env
= &cpu
->env
;
10406 if ((env
->hflags
>> MSR_LE
) & 1) {
10407 info
->endian
= BFD_ENDIAN_LITTLE
;
10409 info
->mach
= env
->bfd_mach
;
10410 if (!env
->bfd_mach
) {
10411 #ifdef TARGET_PPC64
10412 info
->mach
= bfd_mach_ppc64
;
10414 info
->mach
= bfd_mach_ppc
;
10417 info
->disassembler_options
= (char *)"any";
10418 info
->print_insn
= print_insn_ppc
;
10420 info
->cap_arch
= CS_ARCH_PPC
;
10421 #ifdef TARGET_PPC64
10422 info
->cap_mode
= CS_MODE_64
;
10426 static Property ppc_cpu_properties
[] = {
10427 DEFINE_PROP_BOOL("pre-2.8-migration", PowerPCCPU
, pre_2_8_migration
, false),
10428 DEFINE_PROP_BOOL("pre-2.10-migration", PowerPCCPU
, pre_2_10_migration
,
10430 DEFINE_PROP_BOOL("pre-3.0-migration", PowerPCCPU
, pre_3_0_migration
,
10432 DEFINE_PROP_END_OF_LIST(),
10435 static void ppc_cpu_class_init(ObjectClass
*oc
, void *data
)
10437 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10438 CPUClass
*cc
= CPU_CLASS(oc
);
10439 DeviceClass
*dc
= DEVICE_CLASS(oc
);
10441 device_class_set_parent_realize(dc
, ppc_cpu_realize
,
10442 &pcc
->parent_realize
);
10443 device_class_set_parent_unrealize(dc
, ppc_cpu_unrealize
,
10444 &pcc
->parent_unrealize
);
10445 pcc
->pvr_match
= ppc_pvr_match_default
;
10446 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_always
;
10447 dc
->props
= ppc_cpu_properties
;
10449 pcc
->parent_reset
= cc
->reset
;
10450 cc
->reset
= ppc_cpu_reset
;
10452 cc
->class_by_name
= ppc_cpu_class_by_name
;
10453 pcc
->parent_parse_features
= cc
->parse_features
;
10454 cc
->parse_features
= ppc_cpu_parse_featurestr
;
10455 cc
->has_work
= ppc_cpu_has_work
;
10456 cc
->do_interrupt
= ppc_cpu_do_interrupt
;
10457 cc
->cpu_exec_interrupt
= ppc_cpu_exec_interrupt
;
10458 cc
->dump_state
= ppc_cpu_dump_state
;
10459 cc
->dump_statistics
= ppc_cpu_dump_statistics
;
10460 cc
->set_pc
= ppc_cpu_set_pc
;
10461 cc
->gdb_read_register
= ppc_cpu_gdb_read_register
;
10462 cc
->gdb_write_register
= ppc_cpu_gdb_write_register
;
10463 cc
->do_unaligned_access
= ppc_cpu_do_unaligned_access
;
10464 #ifdef CONFIG_USER_ONLY
10465 cc
->handle_mmu_fault
= ppc_cpu_handle_mmu_fault
;
10467 cc
->get_phys_page_debug
= ppc_cpu_get_phys_page_debug
;
10468 cc
->vmsd
= &vmstate_ppc_cpu
;
10470 #if defined(CONFIG_SOFTMMU)
10471 cc
->write_elf64_note
= ppc64_cpu_write_elf64_note
;
10472 cc
->write_elf32_note
= ppc32_cpu_write_elf32_note
;
10475 cc
->gdb_num_core_regs
= 71;
10477 #ifdef USE_APPLE_GDB
10478 cc
->gdb_read_register
= ppc_cpu_gdb_read_register_apple
;
10479 cc
->gdb_write_register
= ppc_cpu_gdb_write_register_apple
;
10480 cc
->gdb_num_core_regs
= 71 + 32;
10483 cc
->gdb_arch_name
= ppc_gdb_arch_name
;
10484 #if defined(TARGET_PPC64)
10485 cc
->gdb_core_xml_file
= "power64-core.xml";
10487 cc
->gdb_core_xml_file
= "power-core.xml";
10489 #ifndef CONFIG_USER_ONLY
10490 cc
->virtio_is_big_endian
= ppc_cpu_is_big_endian
;
10493 cc
->tcg_initialize
= ppc_translate_init
;
10495 cc
->disas_set_info
= ppc_disas_set_info
;
10497 dc
->fw_name
= "PowerPC,UNKNOWN";
10500 static const TypeInfo ppc_cpu_type_info
= {
10501 .name
= TYPE_POWERPC_CPU
,
10502 .parent
= TYPE_CPU
,
10503 .instance_size
= sizeof(PowerPCCPU
),
10504 .instance_init
= ppc_cpu_instance_init
,
10505 .instance_finalize
= ppc_cpu_instance_finalize
,
10507 .class_size
= sizeof(PowerPCCPUClass
),
10508 .class_init
= ppc_cpu_class_init
,
10511 static const TypeInfo ppc_vhyp_type_info
= {
10512 .name
= TYPE_PPC_VIRTUAL_HYPERVISOR
,
10513 .parent
= TYPE_INTERFACE
,
10514 .class_size
= sizeof(PPCVirtualHypervisorClass
),
10517 static void ppc_cpu_register_types(void)
10519 type_register_static(&ppc_cpu_type_info
);
10520 type_register_static(&ppc_vhyp_type_info
);
10523 type_init(ppc_cpu_register_types
)