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
);
1658 static void gen_spr_usprg3(CPUPPCState
*env
)
1660 spr_register(env
, SPR_USPRG3
, "USPRG3",
1661 &spr_read_ureg
, SPR_NOACCESS
,
1662 &spr_read_ureg
, SPR_NOACCESS
,
1666 static void gen_spr_usprgh(CPUPPCState
*env
)
1668 spr_register(env
, SPR_USPRG4
, "USPRG4",
1669 &spr_read_ureg
, SPR_NOACCESS
,
1670 &spr_read_ureg
, SPR_NOACCESS
,
1672 spr_register(env
, SPR_USPRG5
, "USPRG5",
1673 &spr_read_ureg
, SPR_NOACCESS
,
1674 &spr_read_ureg
, SPR_NOACCESS
,
1676 spr_register(env
, SPR_USPRG6
, "USPRG6",
1677 &spr_read_ureg
, SPR_NOACCESS
,
1678 &spr_read_ureg
, SPR_NOACCESS
,
1680 spr_register(env
, SPR_USPRG7
, "USPRG7",
1681 &spr_read_ureg
, SPR_NOACCESS
,
1682 &spr_read_ureg
, SPR_NOACCESS
,
1686 /* PowerPC BookE SPR */
1687 static void gen_spr_BookE(CPUPPCState
*env
, uint64_t ivor_mask
)
1689 const char *ivor_names
[64] = {
1690 "IVOR0", "IVOR1", "IVOR2", "IVOR3",
1691 "IVOR4", "IVOR5", "IVOR6", "IVOR7",
1692 "IVOR8", "IVOR9", "IVOR10", "IVOR11",
1693 "IVOR12", "IVOR13", "IVOR14", "IVOR15",
1694 "IVOR16", "IVOR17", "IVOR18", "IVOR19",
1695 "IVOR20", "IVOR21", "IVOR22", "IVOR23",
1696 "IVOR24", "IVOR25", "IVOR26", "IVOR27",
1697 "IVOR28", "IVOR29", "IVOR30", "IVOR31",
1698 "IVOR32", "IVOR33", "IVOR34", "IVOR35",
1699 "IVOR36", "IVOR37", "IVOR38", "IVOR39",
1700 "IVOR40", "IVOR41", "IVOR42", "IVOR43",
1701 "IVOR44", "IVOR45", "IVOR46", "IVOR47",
1702 "IVOR48", "IVOR49", "IVOR50", "IVOR51",
1703 "IVOR52", "IVOR53", "IVOR54", "IVOR55",
1704 "IVOR56", "IVOR57", "IVOR58", "IVOR59",
1705 "IVOR60", "IVOR61", "IVOR62", "IVOR63",
1707 #define SPR_BOOKE_IVORxx (-1)
1708 int ivor_sprn
[64] = {
1709 SPR_BOOKE_IVOR0
, SPR_BOOKE_IVOR1
, SPR_BOOKE_IVOR2
, SPR_BOOKE_IVOR3
,
1710 SPR_BOOKE_IVOR4
, SPR_BOOKE_IVOR5
, SPR_BOOKE_IVOR6
, SPR_BOOKE_IVOR7
,
1711 SPR_BOOKE_IVOR8
, SPR_BOOKE_IVOR9
, SPR_BOOKE_IVOR10
, SPR_BOOKE_IVOR11
,
1712 SPR_BOOKE_IVOR12
, SPR_BOOKE_IVOR13
, SPR_BOOKE_IVOR14
, SPR_BOOKE_IVOR15
,
1713 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1714 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1715 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1716 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1717 SPR_BOOKE_IVOR32
, SPR_BOOKE_IVOR33
, SPR_BOOKE_IVOR34
, SPR_BOOKE_IVOR35
,
1718 SPR_BOOKE_IVOR36
, SPR_BOOKE_IVOR37
, SPR_BOOKE_IVOR38
, SPR_BOOKE_IVOR39
,
1719 SPR_BOOKE_IVOR40
, SPR_BOOKE_IVOR41
, SPR_BOOKE_IVOR42
, SPR_BOOKE_IVORxx
,
1720 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1721 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1722 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1723 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1724 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1728 /* Interrupt processing */
1729 spr_register(env
, SPR_BOOKE_CSRR0
, "CSRR0",
1730 SPR_NOACCESS
, SPR_NOACCESS
,
1731 &spr_read_generic
, &spr_write_generic
,
1733 spr_register(env
, SPR_BOOKE_CSRR1
, "CSRR1",
1734 SPR_NOACCESS
, SPR_NOACCESS
,
1735 &spr_read_generic
, &spr_write_generic
,
1738 /* XXX : not implemented */
1739 spr_register(env
, SPR_BOOKE_IAC1
, "IAC1",
1740 SPR_NOACCESS
, SPR_NOACCESS
,
1741 &spr_read_generic
, &spr_write_generic
,
1743 /* XXX : not implemented */
1744 spr_register(env
, SPR_BOOKE_IAC2
, "IAC2",
1745 SPR_NOACCESS
, SPR_NOACCESS
,
1746 &spr_read_generic
, &spr_write_generic
,
1748 /* XXX : not implemented */
1749 spr_register(env
, SPR_BOOKE_DAC1
, "DAC1",
1750 SPR_NOACCESS
, SPR_NOACCESS
,
1751 &spr_read_generic
, &spr_write_generic
,
1753 /* XXX : not implemented */
1754 spr_register(env
, SPR_BOOKE_DAC2
, "DAC2",
1755 SPR_NOACCESS
, SPR_NOACCESS
,
1756 &spr_read_generic
, &spr_write_generic
,
1758 /* XXX : not implemented */
1759 spr_register(env
, SPR_BOOKE_DBCR0
, "DBCR0",
1760 SPR_NOACCESS
, SPR_NOACCESS
,
1761 &spr_read_generic
, &spr_write_40x_dbcr0
,
1763 /* XXX : not implemented */
1764 spr_register(env
, SPR_BOOKE_DBCR1
, "DBCR1",
1765 SPR_NOACCESS
, SPR_NOACCESS
,
1766 &spr_read_generic
, &spr_write_generic
,
1768 /* XXX : not implemented */
1769 spr_register(env
, SPR_BOOKE_DBCR2
, "DBCR2",
1770 SPR_NOACCESS
, SPR_NOACCESS
,
1771 &spr_read_generic
, &spr_write_generic
,
1773 spr_register(env
, SPR_BOOKE_DSRR0
, "DSRR0",
1774 SPR_NOACCESS
, SPR_NOACCESS
,
1775 &spr_read_generic
, &spr_write_generic
,
1777 spr_register(env
, SPR_BOOKE_DSRR1
, "DSRR1",
1778 SPR_NOACCESS
, SPR_NOACCESS
,
1779 &spr_read_generic
, &spr_write_generic
,
1781 /* XXX : not implemented */
1782 spr_register(env
, SPR_BOOKE_DBSR
, "DBSR",
1783 SPR_NOACCESS
, SPR_NOACCESS
,
1784 &spr_read_generic
, &spr_write_clear
,
1786 spr_register(env
, SPR_BOOKE_DEAR
, "DEAR",
1787 SPR_NOACCESS
, SPR_NOACCESS
,
1788 &spr_read_generic
, &spr_write_generic
,
1790 spr_register(env
, SPR_BOOKE_ESR
, "ESR",
1791 SPR_NOACCESS
, SPR_NOACCESS
,
1792 &spr_read_generic
, &spr_write_generic
,
1794 spr_register(env
, SPR_BOOKE_IVPR
, "IVPR",
1795 SPR_NOACCESS
, SPR_NOACCESS
,
1796 &spr_read_generic
, &spr_write_excp_prefix
,
1798 /* Exception vectors */
1799 for (i
= 0; i
< 64; i
++) {
1800 if (ivor_mask
& (1ULL << i
)) {
1801 if (ivor_sprn
[i
] == SPR_BOOKE_IVORxx
) {
1802 fprintf(stderr
, "ERROR: IVOR %d SPR is not defined\n", i
);
1805 spr_register(env
, ivor_sprn
[i
], ivor_names
[i
],
1806 SPR_NOACCESS
, SPR_NOACCESS
,
1807 &spr_read_generic
, &spr_write_excp_vector
,
1811 spr_register(env
, SPR_BOOKE_PID
, "PID",
1812 SPR_NOACCESS
, SPR_NOACCESS
,
1813 &spr_read_generic
, &spr_write_booke_pid
,
1815 spr_register(env
, SPR_BOOKE_TCR
, "TCR",
1816 SPR_NOACCESS
, SPR_NOACCESS
,
1817 &spr_read_generic
, &spr_write_booke_tcr
,
1819 spr_register(env
, SPR_BOOKE_TSR
, "TSR",
1820 SPR_NOACCESS
, SPR_NOACCESS
,
1821 &spr_read_generic
, &spr_write_booke_tsr
,
1824 spr_register(env
, SPR_DECR
, "DECR",
1825 SPR_NOACCESS
, SPR_NOACCESS
,
1826 &spr_read_decr
, &spr_write_decr
,
1828 spr_register(env
, SPR_BOOKE_DECAR
, "DECAR",
1829 SPR_NOACCESS
, SPR_NOACCESS
,
1830 SPR_NOACCESS
, &spr_write_generic
,
1833 spr_register(env
, SPR_USPRG0
, "USPRG0",
1834 &spr_read_generic
, &spr_write_generic
,
1835 &spr_read_generic
, &spr_write_generic
,
1837 spr_register(env
, SPR_SPRG4
, "SPRG4",
1838 SPR_NOACCESS
, SPR_NOACCESS
,
1839 &spr_read_generic
, &spr_write_generic
,
1841 spr_register(env
, SPR_SPRG5
, "SPRG5",
1842 SPR_NOACCESS
, SPR_NOACCESS
,
1843 &spr_read_generic
, &spr_write_generic
,
1845 spr_register(env
, SPR_SPRG6
, "SPRG6",
1846 SPR_NOACCESS
, SPR_NOACCESS
,
1847 &spr_read_generic
, &spr_write_generic
,
1849 spr_register(env
, SPR_SPRG7
, "SPRG7",
1850 SPR_NOACCESS
, SPR_NOACCESS
,
1851 &spr_read_generic
, &spr_write_generic
,
1853 spr_register(env
, SPR_BOOKE_SPRG8
, "SPRG8",
1854 SPR_NOACCESS
, SPR_NOACCESS
,
1855 &spr_read_generic
, &spr_write_generic
,
1857 spr_register(env
, SPR_BOOKE_SPRG9
, "SPRG9",
1858 SPR_NOACCESS
, SPR_NOACCESS
,
1859 &spr_read_generic
, &spr_write_generic
,
1863 static inline uint32_t gen_tlbncfg(uint32_t assoc
, uint32_t minsize
,
1864 uint32_t maxsize
, uint32_t flags
,
1867 return (assoc
<< TLBnCFG_ASSOC_SHIFT
) |
1868 (minsize
<< TLBnCFG_MINSIZE_SHIFT
) |
1869 (maxsize
<< TLBnCFG_MAXSIZE_SHIFT
) |
1873 /* BookE 2.06 storage control registers */
1874 static void gen_spr_BookE206(CPUPPCState
*env
, uint32_t mas_mask
,
1875 uint32_t *tlbncfg
, uint32_t mmucfg
)
1877 #if !defined(CONFIG_USER_ONLY)
1878 const char *mas_names
[8] = {
1879 "MAS0", "MAS1", "MAS2", "MAS3", "MAS4", "MAS5", "MAS6", "MAS7",
1882 SPR_BOOKE_MAS0
, SPR_BOOKE_MAS1
, SPR_BOOKE_MAS2
, SPR_BOOKE_MAS3
,
1883 SPR_BOOKE_MAS4
, SPR_BOOKE_MAS5
, SPR_BOOKE_MAS6
, SPR_BOOKE_MAS7
,
1887 /* TLB assist registers */
1888 /* XXX : not implemented */
1889 for (i
= 0; i
< 8; i
++) {
1890 void (*uea_write
)(DisasContext
*ctx
, int sprn
, int gprn
) = &spr_write_generic32
;
1891 if (i
== 2 && (mas_mask
& (1 << i
)) && (env
->insns_flags
& PPC_64B
)) {
1892 uea_write
= &spr_write_generic
;
1894 if (mas_mask
& (1 << i
)) {
1895 spr_register(env
, mas_sprn
[i
], mas_names
[i
],
1896 SPR_NOACCESS
, SPR_NOACCESS
,
1897 &spr_read_generic
, uea_write
,
1901 if (env
->nb_pids
> 1) {
1902 /* XXX : not implemented */
1903 spr_register(env
, SPR_BOOKE_PID1
, "PID1",
1904 SPR_NOACCESS
, SPR_NOACCESS
,
1905 &spr_read_generic
, &spr_write_booke_pid
,
1908 if (env
->nb_pids
> 2) {
1909 /* XXX : not implemented */
1910 spr_register(env
, SPR_BOOKE_PID2
, "PID2",
1911 SPR_NOACCESS
, SPR_NOACCESS
,
1912 &spr_read_generic
, &spr_write_booke_pid
,
1915 /* XXX : not implemented */
1916 spr_register(env
, SPR_MMUCFG
, "MMUCFG",
1917 SPR_NOACCESS
, SPR_NOACCESS
,
1918 &spr_read_generic
, SPR_NOACCESS
,
1920 switch (env
->nb_ways
) {
1922 spr_register(env
, SPR_BOOKE_TLB3CFG
, "TLB3CFG",
1923 SPR_NOACCESS
, SPR_NOACCESS
,
1924 &spr_read_generic
, SPR_NOACCESS
,
1928 spr_register(env
, SPR_BOOKE_TLB2CFG
, "TLB2CFG",
1929 SPR_NOACCESS
, SPR_NOACCESS
,
1930 &spr_read_generic
, SPR_NOACCESS
,
1934 spr_register(env
, SPR_BOOKE_TLB1CFG
, "TLB1CFG",
1935 SPR_NOACCESS
, SPR_NOACCESS
,
1936 &spr_read_generic
, SPR_NOACCESS
,
1940 spr_register(env
, SPR_BOOKE_TLB0CFG
, "TLB0CFG",
1941 SPR_NOACCESS
, SPR_NOACCESS
,
1942 &spr_read_generic
, SPR_NOACCESS
,
1951 gen_spr_usprgh(env
);
1954 /* SPR specific to PowerPC 440 implementation */
1955 static void gen_spr_440(CPUPPCState
*env
)
1958 /* XXX : not implemented */
1959 spr_register(env
, SPR_440_DNV0
, "DNV0",
1960 SPR_NOACCESS
, SPR_NOACCESS
,
1961 &spr_read_generic
, &spr_write_generic
,
1963 /* XXX : not implemented */
1964 spr_register(env
, SPR_440_DNV1
, "DNV1",
1965 SPR_NOACCESS
, SPR_NOACCESS
,
1966 &spr_read_generic
, &spr_write_generic
,
1968 /* XXX : not implemented */
1969 spr_register(env
, SPR_440_DNV2
, "DNV2",
1970 SPR_NOACCESS
, SPR_NOACCESS
,
1971 &spr_read_generic
, &spr_write_generic
,
1973 /* XXX : not implemented */
1974 spr_register(env
, SPR_440_DNV3
, "DNV3",
1975 SPR_NOACCESS
, SPR_NOACCESS
,
1976 &spr_read_generic
, &spr_write_generic
,
1978 /* XXX : not implemented */
1979 spr_register(env
, SPR_440_DTV0
, "DTV0",
1980 SPR_NOACCESS
, SPR_NOACCESS
,
1981 &spr_read_generic
, &spr_write_generic
,
1983 /* XXX : not implemented */
1984 spr_register(env
, SPR_440_DTV1
, "DTV1",
1985 SPR_NOACCESS
, SPR_NOACCESS
,
1986 &spr_read_generic
, &spr_write_generic
,
1988 /* XXX : not implemented */
1989 spr_register(env
, SPR_440_DTV2
, "DTV2",
1990 SPR_NOACCESS
, SPR_NOACCESS
,
1991 &spr_read_generic
, &spr_write_generic
,
1993 /* XXX : not implemented */
1994 spr_register(env
, SPR_440_DTV3
, "DTV3",
1995 SPR_NOACCESS
, SPR_NOACCESS
,
1996 &spr_read_generic
, &spr_write_generic
,
1998 /* XXX : not implemented */
1999 spr_register(env
, SPR_440_DVLIM
, "DVLIM",
2000 SPR_NOACCESS
, SPR_NOACCESS
,
2001 &spr_read_generic
, &spr_write_generic
,
2003 /* XXX : not implemented */
2004 spr_register(env
, SPR_440_INV0
, "INV0",
2005 SPR_NOACCESS
, SPR_NOACCESS
,
2006 &spr_read_generic
, &spr_write_generic
,
2008 /* XXX : not implemented */
2009 spr_register(env
, SPR_440_INV1
, "INV1",
2010 SPR_NOACCESS
, SPR_NOACCESS
,
2011 &spr_read_generic
, &spr_write_generic
,
2013 /* XXX : not implemented */
2014 spr_register(env
, SPR_440_INV2
, "INV2",
2015 SPR_NOACCESS
, SPR_NOACCESS
,
2016 &spr_read_generic
, &spr_write_generic
,
2018 /* XXX : not implemented */
2019 spr_register(env
, SPR_440_INV3
, "INV3",
2020 SPR_NOACCESS
, SPR_NOACCESS
,
2021 &spr_read_generic
, &spr_write_generic
,
2023 /* XXX : not implemented */
2024 spr_register(env
, SPR_440_ITV0
, "ITV0",
2025 SPR_NOACCESS
, SPR_NOACCESS
,
2026 &spr_read_generic
, &spr_write_generic
,
2028 /* XXX : not implemented */
2029 spr_register(env
, SPR_440_ITV1
, "ITV1",
2030 SPR_NOACCESS
, SPR_NOACCESS
,
2031 &spr_read_generic
, &spr_write_generic
,
2033 /* XXX : not implemented */
2034 spr_register(env
, SPR_440_ITV2
, "ITV2",
2035 SPR_NOACCESS
, SPR_NOACCESS
,
2036 &spr_read_generic
, &spr_write_generic
,
2038 /* XXX : not implemented */
2039 spr_register(env
, SPR_440_ITV3
, "ITV3",
2040 SPR_NOACCESS
, SPR_NOACCESS
,
2041 &spr_read_generic
, &spr_write_generic
,
2043 /* XXX : not implemented */
2044 spr_register(env
, SPR_440_IVLIM
, "IVLIM",
2045 SPR_NOACCESS
, SPR_NOACCESS
,
2046 &spr_read_generic
, &spr_write_generic
,
2049 /* XXX : not implemented */
2050 spr_register(env
, SPR_BOOKE_DCDBTRH
, "DCDBTRH",
2051 SPR_NOACCESS
, SPR_NOACCESS
,
2052 &spr_read_generic
, SPR_NOACCESS
,
2054 /* XXX : not implemented */
2055 spr_register(env
, SPR_BOOKE_DCDBTRL
, "DCDBTRL",
2056 SPR_NOACCESS
, SPR_NOACCESS
,
2057 &spr_read_generic
, SPR_NOACCESS
,
2059 /* XXX : not implemented */
2060 spr_register(env
, SPR_BOOKE_ICDBDR
, "ICDBDR",
2061 SPR_NOACCESS
, SPR_NOACCESS
,
2062 &spr_read_generic
, SPR_NOACCESS
,
2064 /* XXX : not implemented */
2065 spr_register(env
, SPR_BOOKE_ICDBTRH
, "ICDBTRH",
2066 SPR_NOACCESS
, SPR_NOACCESS
,
2067 &spr_read_generic
, SPR_NOACCESS
,
2069 /* XXX : not implemented */
2070 spr_register(env
, SPR_BOOKE_ICDBTRL
, "ICDBTRL",
2071 SPR_NOACCESS
, SPR_NOACCESS
,
2072 &spr_read_generic
, SPR_NOACCESS
,
2074 /* XXX : not implemented */
2075 spr_register(env
, SPR_440_DBDR
, "DBDR",
2076 SPR_NOACCESS
, SPR_NOACCESS
,
2077 &spr_read_generic
, &spr_write_generic
,
2079 /* Processor control */
2080 spr_register(env
, SPR_4xx_CCR0
, "CCR0",
2081 SPR_NOACCESS
, SPR_NOACCESS
,
2082 &spr_read_generic
, &spr_write_generic
,
2084 spr_register(env
, SPR_440_RSTCFG
, "RSTCFG",
2085 SPR_NOACCESS
, SPR_NOACCESS
,
2086 &spr_read_generic
, SPR_NOACCESS
,
2088 /* Storage control */
2089 spr_register(env
, SPR_440_MMUCR
, "MMUCR",
2090 SPR_NOACCESS
, SPR_NOACCESS
,
2091 &spr_read_generic
, &spr_write_generic
,
2095 /* SPR shared between PowerPC 40x implementations */
2096 static void gen_spr_40x(CPUPPCState
*env
)
2099 /* not emulated, as QEMU do not emulate caches */
2100 spr_register(env
, SPR_40x_DCCR
, "DCCR",
2101 SPR_NOACCESS
, SPR_NOACCESS
,
2102 &spr_read_generic
, &spr_write_generic
,
2104 /* not emulated, as QEMU do not emulate caches */
2105 spr_register(env
, SPR_40x_ICCR
, "ICCR",
2106 SPR_NOACCESS
, SPR_NOACCESS
,
2107 &spr_read_generic
, &spr_write_generic
,
2109 /* not emulated, as QEMU do not emulate caches */
2110 spr_register(env
, SPR_BOOKE_ICDBDR
, "ICDBDR",
2111 SPR_NOACCESS
, SPR_NOACCESS
,
2112 &spr_read_generic
, SPR_NOACCESS
,
2115 spr_register(env
, SPR_40x_DEAR
, "DEAR",
2116 SPR_NOACCESS
, SPR_NOACCESS
,
2117 &spr_read_generic
, &spr_write_generic
,
2119 spr_register(env
, SPR_40x_ESR
, "ESR",
2120 SPR_NOACCESS
, SPR_NOACCESS
,
2121 &spr_read_generic
, &spr_write_generic
,
2123 spr_register(env
, SPR_40x_EVPR
, "EVPR",
2124 SPR_NOACCESS
, SPR_NOACCESS
,
2125 &spr_read_generic
, &spr_write_excp_prefix
,
2127 spr_register(env
, SPR_40x_SRR2
, "SRR2",
2128 &spr_read_generic
, &spr_write_generic
,
2129 &spr_read_generic
, &spr_write_generic
,
2131 spr_register(env
, SPR_40x_SRR3
, "SRR3",
2132 &spr_read_generic
, &spr_write_generic
,
2133 &spr_read_generic
, &spr_write_generic
,
2136 spr_register(env
, SPR_40x_PIT
, "PIT",
2137 SPR_NOACCESS
, SPR_NOACCESS
,
2138 &spr_read_40x_pit
, &spr_write_40x_pit
,
2140 spr_register(env
, SPR_40x_TCR
, "TCR",
2141 SPR_NOACCESS
, SPR_NOACCESS
,
2142 &spr_read_generic
, &spr_write_booke_tcr
,
2144 spr_register(env
, SPR_40x_TSR
, "TSR",
2145 SPR_NOACCESS
, SPR_NOACCESS
,
2146 &spr_read_generic
, &spr_write_booke_tsr
,
2150 /* SPR specific to PowerPC 405 implementation */
2151 static void gen_spr_405(CPUPPCState
*env
)
2154 spr_register(env
, SPR_40x_PID
, "PID",
2155 SPR_NOACCESS
, SPR_NOACCESS
,
2156 &spr_read_generic
, &spr_write_generic
,
2158 spr_register(env
, SPR_4xx_CCR0
, "CCR0",
2159 SPR_NOACCESS
, SPR_NOACCESS
,
2160 &spr_read_generic
, &spr_write_generic
,
2162 /* Debug interface */
2163 /* XXX : not implemented */
2164 spr_register(env
, SPR_40x_DBCR0
, "DBCR0",
2165 SPR_NOACCESS
, SPR_NOACCESS
,
2166 &spr_read_generic
, &spr_write_40x_dbcr0
,
2168 /* XXX : not implemented */
2169 spr_register(env
, SPR_405_DBCR1
, "DBCR1",
2170 SPR_NOACCESS
, SPR_NOACCESS
,
2171 &spr_read_generic
, &spr_write_generic
,
2173 /* XXX : not implemented */
2174 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2175 SPR_NOACCESS
, SPR_NOACCESS
,
2176 &spr_read_generic
, &spr_write_clear
,
2177 /* Last reset was system reset */
2179 /* XXX : not implemented */
2180 spr_register(env
, SPR_40x_DAC1
, "DAC1",
2181 SPR_NOACCESS
, SPR_NOACCESS
,
2182 &spr_read_generic
, &spr_write_generic
,
2184 spr_register(env
, SPR_40x_DAC2
, "DAC2",
2185 SPR_NOACCESS
, SPR_NOACCESS
,
2186 &spr_read_generic
, &spr_write_generic
,
2188 /* XXX : not implemented */
2189 spr_register(env
, SPR_405_DVC1
, "DVC1",
2190 SPR_NOACCESS
, SPR_NOACCESS
,
2191 &spr_read_generic
, &spr_write_generic
,
2193 /* XXX : not implemented */
2194 spr_register(env
, SPR_405_DVC2
, "DVC2",
2195 SPR_NOACCESS
, SPR_NOACCESS
,
2196 &spr_read_generic
, &spr_write_generic
,
2198 /* XXX : not implemented */
2199 spr_register(env
, SPR_40x_IAC1
, "IAC1",
2200 SPR_NOACCESS
, SPR_NOACCESS
,
2201 &spr_read_generic
, &spr_write_generic
,
2203 spr_register(env
, SPR_40x_IAC2
, "IAC2",
2204 SPR_NOACCESS
, SPR_NOACCESS
,
2205 &spr_read_generic
, &spr_write_generic
,
2207 /* XXX : not implemented */
2208 spr_register(env
, SPR_405_IAC3
, "IAC3",
2209 SPR_NOACCESS
, SPR_NOACCESS
,
2210 &spr_read_generic
, &spr_write_generic
,
2212 /* XXX : not implemented */
2213 spr_register(env
, SPR_405_IAC4
, "IAC4",
2214 SPR_NOACCESS
, SPR_NOACCESS
,
2215 &spr_read_generic
, &spr_write_generic
,
2217 /* Storage control */
2218 /* XXX: TODO: not implemented */
2219 spr_register(env
, SPR_405_SLER
, "SLER",
2220 SPR_NOACCESS
, SPR_NOACCESS
,
2221 &spr_read_generic
, &spr_write_40x_sler
,
2223 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2224 SPR_NOACCESS
, SPR_NOACCESS
,
2225 &spr_read_generic
, &spr_write_generic
,
2227 /* XXX : not implemented */
2228 spr_register(env
, SPR_405_SU0R
, "SU0R",
2229 SPR_NOACCESS
, SPR_NOACCESS
,
2230 &spr_read_generic
, &spr_write_generic
,
2233 spr_register(env
, SPR_USPRG0
, "USPRG0",
2234 &spr_read_ureg
, SPR_NOACCESS
,
2235 &spr_read_ureg
, SPR_NOACCESS
,
2237 spr_register(env
, SPR_SPRG4
, "SPRG4",
2238 SPR_NOACCESS
, SPR_NOACCESS
,
2239 &spr_read_generic
, &spr_write_generic
,
2241 spr_register(env
, SPR_SPRG5
, "SPRG5",
2242 SPR_NOACCESS
, SPR_NOACCESS
,
2243 spr_read_generic
, &spr_write_generic
,
2245 spr_register(env
, SPR_SPRG6
, "SPRG6",
2246 SPR_NOACCESS
, SPR_NOACCESS
,
2247 spr_read_generic
, &spr_write_generic
,
2249 spr_register(env
, SPR_SPRG7
, "SPRG7",
2250 SPR_NOACCESS
, SPR_NOACCESS
,
2251 spr_read_generic
, &spr_write_generic
,
2253 gen_spr_usprgh(env
);
2256 /* SPR shared between PowerPC 401 & 403 implementations */
2257 static void gen_spr_401_403(CPUPPCState
*env
)
2260 spr_register(env
, SPR_403_VTBL
, "TBL",
2261 &spr_read_tbl
, SPR_NOACCESS
,
2262 &spr_read_tbl
, SPR_NOACCESS
,
2264 spr_register(env
, SPR_403_TBL
, "TBL",
2265 SPR_NOACCESS
, SPR_NOACCESS
,
2266 SPR_NOACCESS
, &spr_write_tbl
,
2268 spr_register(env
, SPR_403_VTBU
, "TBU",
2269 &spr_read_tbu
, SPR_NOACCESS
,
2270 &spr_read_tbu
, SPR_NOACCESS
,
2272 spr_register(env
, SPR_403_TBU
, "TBU",
2273 SPR_NOACCESS
, SPR_NOACCESS
,
2274 SPR_NOACCESS
, &spr_write_tbu
,
2277 /* not emulated, as QEMU do not emulate caches */
2278 spr_register(env
, SPR_403_CDBCR
, "CDBCR",
2279 SPR_NOACCESS
, SPR_NOACCESS
,
2280 &spr_read_generic
, &spr_write_generic
,
2284 /* SPR specific to PowerPC 401 implementation */
2285 static void gen_spr_401(CPUPPCState
*env
)
2287 /* Debug interface */
2288 /* XXX : not implemented */
2289 spr_register(env
, SPR_40x_DBCR0
, "DBCR",
2290 SPR_NOACCESS
, SPR_NOACCESS
,
2291 &spr_read_generic
, &spr_write_40x_dbcr0
,
2293 /* XXX : not implemented */
2294 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2295 SPR_NOACCESS
, SPR_NOACCESS
,
2296 &spr_read_generic
, &spr_write_clear
,
2297 /* Last reset was system reset */
2299 /* XXX : not implemented */
2300 spr_register(env
, SPR_40x_DAC1
, "DAC",
2301 SPR_NOACCESS
, SPR_NOACCESS
,
2302 &spr_read_generic
, &spr_write_generic
,
2304 /* XXX : not implemented */
2305 spr_register(env
, SPR_40x_IAC1
, "IAC",
2306 SPR_NOACCESS
, SPR_NOACCESS
,
2307 &spr_read_generic
, &spr_write_generic
,
2309 /* Storage control */
2310 /* XXX: TODO: not implemented */
2311 spr_register(env
, SPR_405_SLER
, "SLER",
2312 SPR_NOACCESS
, SPR_NOACCESS
,
2313 &spr_read_generic
, &spr_write_40x_sler
,
2315 /* not emulated, as QEMU never does speculative access */
2316 spr_register(env
, SPR_40x_SGR
, "SGR",
2317 SPR_NOACCESS
, SPR_NOACCESS
,
2318 &spr_read_generic
, &spr_write_generic
,
2320 /* not emulated, as QEMU do not emulate caches */
2321 spr_register(env
, SPR_40x_DCWR
, "DCWR",
2322 SPR_NOACCESS
, SPR_NOACCESS
,
2323 &spr_read_generic
, &spr_write_generic
,
2327 static void gen_spr_401x2(CPUPPCState
*env
)
2330 spr_register(env
, SPR_40x_PID
, "PID",
2331 SPR_NOACCESS
, SPR_NOACCESS
,
2332 &spr_read_generic
, &spr_write_generic
,
2334 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2335 SPR_NOACCESS
, SPR_NOACCESS
,
2336 &spr_read_generic
, &spr_write_generic
,
2340 /* SPR specific to PowerPC 403 implementation */
2341 static void gen_spr_403(CPUPPCState
*env
)
2343 /* Debug interface */
2344 /* XXX : not implemented */
2345 spr_register(env
, SPR_40x_DBCR0
, "DBCR0",
2346 SPR_NOACCESS
, SPR_NOACCESS
,
2347 &spr_read_generic
, &spr_write_40x_dbcr0
,
2349 /* XXX : not implemented */
2350 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2351 SPR_NOACCESS
, SPR_NOACCESS
,
2352 &spr_read_generic
, &spr_write_clear
,
2353 /* Last reset was system reset */
2355 /* XXX : not implemented */
2356 spr_register(env
, SPR_40x_DAC1
, "DAC1",
2357 SPR_NOACCESS
, SPR_NOACCESS
,
2358 &spr_read_generic
, &spr_write_generic
,
2360 /* XXX : not implemented */
2361 spr_register(env
, SPR_40x_DAC2
, "DAC2",
2362 SPR_NOACCESS
, SPR_NOACCESS
,
2363 &spr_read_generic
, &spr_write_generic
,
2365 /* XXX : not implemented */
2366 spr_register(env
, SPR_40x_IAC1
, "IAC1",
2367 SPR_NOACCESS
, SPR_NOACCESS
,
2368 &spr_read_generic
, &spr_write_generic
,
2370 /* XXX : not implemented */
2371 spr_register(env
, SPR_40x_IAC2
, "IAC2",
2372 SPR_NOACCESS
, SPR_NOACCESS
,
2373 &spr_read_generic
, &spr_write_generic
,
2377 static void gen_spr_403_real(CPUPPCState
*env
)
2379 spr_register(env
, SPR_403_PBL1
, "PBL1",
2380 SPR_NOACCESS
, SPR_NOACCESS
,
2381 &spr_read_403_pbr
, &spr_write_403_pbr
,
2383 spr_register(env
, SPR_403_PBU1
, "PBU1",
2384 SPR_NOACCESS
, SPR_NOACCESS
,
2385 &spr_read_403_pbr
, &spr_write_403_pbr
,
2387 spr_register(env
, SPR_403_PBL2
, "PBL2",
2388 SPR_NOACCESS
, SPR_NOACCESS
,
2389 &spr_read_403_pbr
, &spr_write_403_pbr
,
2391 spr_register(env
, SPR_403_PBU2
, "PBU2",
2392 SPR_NOACCESS
, SPR_NOACCESS
,
2393 &spr_read_403_pbr
, &spr_write_403_pbr
,
2397 static void gen_spr_403_mmu(CPUPPCState
*env
)
2400 spr_register(env
, SPR_40x_PID
, "PID",
2401 SPR_NOACCESS
, SPR_NOACCESS
,
2402 &spr_read_generic
, &spr_write_generic
,
2404 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2405 SPR_NOACCESS
, SPR_NOACCESS
,
2406 &spr_read_generic
, &spr_write_generic
,
2410 /* SPR specific to PowerPC compression coprocessor extension */
2411 static void gen_spr_compress(CPUPPCState
*env
)
2413 /* XXX : not implemented */
2414 spr_register(env
, SPR_401_SKR
, "SKR",
2415 SPR_NOACCESS
, SPR_NOACCESS
,
2416 &spr_read_generic
, &spr_write_generic
,
2420 static void gen_spr_5xx_8xx(CPUPPCState
*env
)
2422 /* Exception processing */
2423 spr_register_kvm(env
, SPR_DSISR
, "DSISR",
2424 SPR_NOACCESS
, SPR_NOACCESS
,
2425 &spr_read_generic
, &spr_write_generic
,
2426 KVM_REG_PPC_DSISR
, 0x00000000);
2427 spr_register_kvm(env
, SPR_DAR
, "DAR",
2428 SPR_NOACCESS
, SPR_NOACCESS
,
2429 &spr_read_generic
, &spr_write_generic
,
2430 KVM_REG_PPC_DAR
, 0x00000000);
2432 spr_register(env
, SPR_DECR
, "DECR",
2433 SPR_NOACCESS
, SPR_NOACCESS
,
2434 &spr_read_decr
, &spr_write_decr
,
2436 /* XXX : not implemented */
2437 spr_register(env
, SPR_MPC_EIE
, "EIE",
2438 SPR_NOACCESS
, SPR_NOACCESS
,
2439 &spr_read_generic
, &spr_write_generic
,
2441 /* XXX : not implemented */
2442 spr_register(env
, SPR_MPC_EID
, "EID",
2443 SPR_NOACCESS
, SPR_NOACCESS
,
2444 &spr_read_generic
, &spr_write_generic
,
2446 /* XXX : not implemented */
2447 spr_register(env
, SPR_MPC_NRI
, "NRI",
2448 SPR_NOACCESS
, SPR_NOACCESS
,
2449 &spr_read_generic
, &spr_write_generic
,
2451 /* XXX : not implemented */
2452 spr_register(env
, SPR_MPC_CMPA
, "CMPA",
2453 SPR_NOACCESS
, SPR_NOACCESS
,
2454 &spr_read_generic
, &spr_write_generic
,
2456 /* XXX : not implemented */
2457 spr_register(env
, SPR_MPC_CMPB
, "CMPB",
2458 SPR_NOACCESS
, SPR_NOACCESS
,
2459 &spr_read_generic
, &spr_write_generic
,
2461 /* XXX : not implemented */
2462 spr_register(env
, SPR_MPC_CMPC
, "CMPC",
2463 SPR_NOACCESS
, SPR_NOACCESS
,
2464 &spr_read_generic
, &spr_write_generic
,
2466 /* XXX : not implemented */
2467 spr_register(env
, SPR_MPC_CMPD
, "CMPD",
2468 SPR_NOACCESS
, SPR_NOACCESS
,
2469 &spr_read_generic
, &spr_write_generic
,
2471 /* XXX : not implemented */
2472 spr_register(env
, SPR_MPC_ECR
, "ECR",
2473 SPR_NOACCESS
, SPR_NOACCESS
,
2474 &spr_read_generic
, &spr_write_generic
,
2476 /* XXX : not implemented */
2477 spr_register(env
, SPR_MPC_DER
, "DER",
2478 SPR_NOACCESS
, SPR_NOACCESS
,
2479 &spr_read_generic
, &spr_write_generic
,
2481 /* XXX : not implemented */
2482 spr_register(env
, SPR_MPC_COUNTA
, "COUNTA",
2483 SPR_NOACCESS
, SPR_NOACCESS
,
2484 &spr_read_generic
, &spr_write_generic
,
2486 /* XXX : not implemented */
2487 spr_register(env
, SPR_MPC_COUNTB
, "COUNTB",
2488 SPR_NOACCESS
, SPR_NOACCESS
,
2489 &spr_read_generic
, &spr_write_generic
,
2491 /* XXX : not implemented */
2492 spr_register(env
, SPR_MPC_CMPE
, "CMPE",
2493 SPR_NOACCESS
, SPR_NOACCESS
,
2494 &spr_read_generic
, &spr_write_generic
,
2496 /* XXX : not implemented */
2497 spr_register(env
, SPR_MPC_CMPF
, "CMPF",
2498 SPR_NOACCESS
, SPR_NOACCESS
,
2499 &spr_read_generic
, &spr_write_generic
,
2501 /* XXX : not implemented */
2502 spr_register(env
, SPR_MPC_CMPG
, "CMPG",
2503 SPR_NOACCESS
, SPR_NOACCESS
,
2504 &spr_read_generic
, &spr_write_generic
,
2506 /* XXX : not implemented */
2507 spr_register(env
, SPR_MPC_CMPH
, "CMPH",
2508 SPR_NOACCESS
, SPR_NOACCESS
,
2509 &spr_read_generic
, &spr_write_generic
,
2511 /* XXX : not implemented */
2512 spr_register(env
, SPR_MPC_LCTRL1
, "LCTRL1",
2513 SPR_NOACCESS
, SPR_NOACCESS
,
2514 &spr_read_generic
, &spr_write_generic
,
2516 /* XXX : not implemented */
2517 spr_register(env
, SPR_MPC_LCTRL2
, "LCTRL2",
2518 SPR_NOACCESS
, SPR_NOACCESS
,
2519 &spr_read_generic
, &spr_write_generic
,
2521 /* XXX : not implemented */
2522 spr_register(env
, SPR_MPC_BAR
, "BAR",
2523 SPR_NOACCESS
, SPR_NOACCESS
,
2524 &spr_read_generic
, &spr_write_generic
,
2526 /* XXX : not implemented */
2527 spr_register(env
, SPR_MPC_DPDR
, "DPDR",
2528 SPR_NOACCESS
, SPR_NOACCESS
,
2529 &spr_read_generic
, &spr_write_generic
,
2531 /* XXX : not implemented */
2532 spr_register(env
, SPR_MPC_IMMR
, "IMMR",
2533 SPR_NOACCESS
, SPR_NOACCESS
,
2534 &spr_read_generic
, &spr_write_generic
,
2538 static void gen_spr_5xx(CPUPPCState
*env
)
2540 /* XXX : not implemented */
2541 spr_register(env
, SPR_RCPU_MI_GRA
, "MI_GRA",
2542 SPR_NOACCESS
, SPR_NOACCESS
,
2543 &spr_read_generic
, &spr_write_generic
,
2545 /* XXX : not implemented */
2546 spr_register(env
, SPR_RCPU_L2U_GRA
, "L2U_GRA",
2547 SPR_NOACCESS
, SPR_NOACCESS
,
2548 &spr_read_generic
, &spr_write_generic
,
2550 /* XXX : not implemented */
2551 spr_register(env
, SPR_RPCU_BBCMCR
, "L2U_BBCMCR",
2552 SPR_NOACCESS
, SPR_NOACCESS
,
2553 &spr_read_generic
, &spr_write_generic
,
2555 /* XXX : not implemented */
2556 spr_register(env
, SPR_RCPU_L2U_MCR
, "L2U_MCR",
2557 SPR_NOACCESS
, SPR_NOACCESS
,
2558 &spr_read_generic
, &spr_write_generic
,
2560 /* XXX : not implemented */
2561 spr_register(env
, SPR_RCPU_MI_RBA0
, "MI_RBA0",
2562 SPR_NOACCESS
, SPR_NOACCESS
,
2563 &spr_read_generic
, &spr_write_generic
,
2565 /* XXX : not implemented */
2566 spr_register(env
, SPR_RCPU_MI_RBA1
, "MI_RBA1",
2567 SPR_NOACCESS
, SPR_NOACCESS
,
2568 &spr_read_generic
, &spr_write_generic
,
2570 /* XXX : not implemented */
2571 spr_register(env
, SPR_RCPU_MI_RBA2
, "MI_RBA2",
2572 SPR_NOACCESS
, SPR_NOACCESS
,
2573 &spr_read_generic
, &spr_write_generic
,
2575 /* XXX : not implemented */
2576 spr_register(env
, SPR_RCPU_MI_RBA3
, "MI_RBA3",
2577 SPR_NOACCESS
, SPR_NOACCESS
,
2578 &spr_read_generic
, &spr_write_generic
,
2580 /* XXX : not implemented */
2581 spr_register(env
, SPR_RCPU_L2U_RBA0
, "L2U_RBA0",
2582 SPR_NOACCESS
, SPR_NOACCESS
,
2583 &spr_read_generic
, &spr_write_generic
,
2585 /* XXX : not implemented */
2586 spr_register(env
, SPR_RCPU_L2U_RBA1
, "L2U_RBA1",
2587 SPR_NOACCESS
, SPR_NOACCESS
,
2588 &spr_read_generic
, &spr_write_generic
,
2590 /* XXX : not implemented */
2591 spr_register(env
, SPR_RCPU_L2U_RBA2
, "L2U_RBA2",
2592 SPR_NOACCESS
, SPR_NOACCESS
,
2593 &spr_read_generic
, &spr_write_generic
,
2595 /* XXX : not implemented */
2596 spr_register(env
, SPR_RCPU_L2U_RBA3
, "L2U_RBA3",
2597 SPR_NOACCESS
, SPR_NOACCESS
,
2598 &spr_read_generic
, &spr_write_generic
,
2600 /* XXX : not implemented */
2601 spr_register(env
, SPR_RCPU_MI_RA0
, "MI_RA0",
2602 SPR_NOACCESS
, SPR_NOACCESS
,
2603 &spr_read_generic
, &spr_write_generic
,
2605 /* XXX : not implemented */
2606 spr_register(env
, SPR_RCPU_MI_RA1
, "MI_RA1",
2607 SPR_NOACCESS
, SPR_NOACCESS
,
2608 &spr_read_generic
, &spr_write_generic
,
2610 /* XXX : not implemented */
2611 spr_register(env
, SPR_RCPU_MI_RA2
, "MI_RA2",
2612 SPR_NOACCESS
, SPR_NOACCESS
,
2613 &spr_read_generic
, &spr_write_generic
,
2615 /* XXX : not implemented */
2616 spr_register(env
, SPR_RCPU_MI_RA3
, "MI_RA3",
2617 SPR_NOACCESS
, SPR_NOACCESS
,
2618 &spr_read_generic
, &spr_write_generic
,
2620 /* XXX : not implemented */
2621 spr_register(env
, SPR_RCPU_L2U_RA0
, "L2U_RA0",
2622 SPR_NOACCESS
, SPR_NOACCESS
,
2623 &spr_read_generic
, &spr_write_generic
,
2625 /* XXX : not implemented */
2626 spr_register(env
, SPR_RCPU_L2U_RA1
, "L2U_RA1",
2627 SPR_NOACCESS
, SPR_NOACCESS
,
2628 &spr_read_generic
, &spr_write_generic
,
2630 /* XXX : not implemented */
2631 spr_register(env
, SPR_RCPU_L2U_RA2
, "L2U_RA2",
2632 SPR_NOACCESS
, SPR_NOACCESS
,
2633 &spr_read_generic
, &spr_write_generic
,
2635 /* XXX : not implemented */
2636 spr_register(env
, SPR_RCPU_L2U_RA3
, "L2U_RA3",
2637 SPR_NOACCESS
, SPR_NOACCESS
,
2638 &spr_read_generic
, &spr_write_generic
,
2640 /* XXX : not implemented */
2641 spr_register(env
, SPR_RCPU_FPECR
, "FPECR",
2642 SPR_NOACCESS
, SPR_NOACCESS
,
2643 &spr_read_generic
, &spr_write_generic
,
2647 static void gen_spr_8xx(CPUPPCState
*env
)
2649 /* XXX : not implemented */
2650 spr_register(env
, SPR_MPC_IC_CST
, "IC_CST",
2651 SPR_NOACCESS
, SPR_NOACCESS
,
2652 &spr_read_generic
, &spr_write_generic
,
2654 /* XXX : not implemented */
2655 spr_register(env
, SPR_MPC_IC_ADR
, "IC_ADR",
2656 SPR_NOACCESS
, SPR_NOACCESS
,
2657 &spr_read_generic
, &spr_write_generic
,
2659 /* XXX : not implemented */
2660 spr_register(env
, SPR_MPC_IC_DAT
, "IC_DAT",
2661 SPR_NOACCESS
, SPR_NOACCESS
,
2662 &spr_read_generic
, &spr_write_generic
,
2664 /* XXX : not implemented */
2665 spr_register(env
, SPR_MPC_DC_CST
, "DC_CST",
2666 SPR_NOACCESS
, SPR_NOACCESS
,
2667 &spr_read_generic
, &spr_write_generic
,
2669 /* XXX : not implemented */
2670 spr_register(env
, SPR_MPC_DC_ADR
, "DC_ADR",
2671 SPR_NOACCESS
, SPR_NOACCESS
,
2672 &spr_read_generic
, &spr_write_generic
,
2674 /* XXX : not implemented */
2675 spr_register(env
, SPR_MPC_DC_DAT
, "DC_DAT",
2676 SPR_NOACCESS
, SPR_NOACCESS
,
2677 &spr_read_generic
, &spr_write_generic
,
2679 /* XXX : not implemented */
2680 spr_register(env
, SPR_MPC_MI_CTR
, "MI_CTR",
2681 SPR_NOACCESS
, SPR_NOACCESS
,
2682 &spr_read_generic
, &spr_write_generic
,
2684 /* XXX : not implemented */
2685 spr_register(env
, SPR_MPC_MI_AP
, "MI_AP",
2686 SPR_NOACCESS
, SPR_NOACCESS
,
2687 &spr_read_generic
, &spr_write_generic
,
2689 /* XXX : not implemented */
2690 spr_register(env
, SPR_MPC_MI_EPN
, "MI_EPN",
2691 SPR_NOACCESS
, SPR_NOACCESS
,
2692 &spr_read_generic
, &spr_write_generic
,
2694 /* XXX : not implemented */
2695 spr_register(env
, SPR_MPC_MI_TWC
, "MI_TWC",
2696 SPR_NOACCESS
, SPR_NOACCESS
,
2697 &spr_read_generic
, &spr_write_generic
,
2699 /* XXX : not implemented */
2700 spr_register(env
, SPR_MPC_MI_RPN
, "MI_RPN",
2701 SPR_NOACCESS
, SPR_NOACCESS
,
2702 &spr_read_generic
, &spr_write_generic
,
2704 /* XXX : not implemented */
2705 spr_register(env
, SPR_MPC_MI_DBCAM
, "MI_DBCAM",
2706 SPR_NOACCESS
, SPR_NOACCESS
,
2707 &spr_read_generic
, &spr_write_generic
,
2709 /* XXX : not implemented */
2710 spr_register(env
, SPR_MPC_MI_DBRAM0
, "MI_DBRAM0",
2711 SPR_NOACCESS
, SPR_NOACCESS
,
2712 &spr_read_generic
, &spr_write_generic
,
2714 /* XXX : not implemented */
2715 spr_register(env
, SPR_MPC_MI_DBRAM1
, "MI_DBRAM1",
2716 SPR_NOACCESS
, SPR_NOACCESS
,
2717 &spr_read_generic
, &spr_write_generic
,
2719 /* XXX : not implemented */
2720 spr_register(env
, SPR_MPC_MD_CTR
, "MD_CTR",
2721 SPR_NOACCESS
, SPR_NOACCESS
,
2722 &spr_read_generic
, &spr_write_generic
,
2724 /* XXX : not implemented */
2725 spr_register(env
, SPR_MPC_MD_CASID
, "MD_CASID",
2726 SPR_NOACCESS
, SPR_NOACCESS
,
2727 &spr_read_generic
, &spr_write_generic
,
2729 /* XXX : not implemented */
2730 spr_register(env
, SPR_MPC_MD_AP
, "MD_AP",
2731 SPR_NOACCESS
, SPR_NOACCESS
,
2732 &spr_read_generic
, &spr_write_generic
,
2734 /* XXX : not implemented */
2735 spr_register(env
, SPR_MPC_MD_EPN
, "MD_EPN",
2736 SPR_NOACCESS
, SPR_NOACCESS
,
2737 &spr_read_generic
, &spr_write_generic
,
2739 /* XXX : not implemented */
2740 spr_register(env
, SPR_MPC_MD_TWB
, "MD_TWB",
2741 SPR_NOACCESS
, SPR_NOACCESS
,
2742 &spr_read_generic
, &spr_write_generic
,
2744 /* XXX : not implemented */
2745 spr_register(env
, SPR_MPC_MD_TWC
, "MD_TWC",
2746 SPR_NOACCESS
, SPR_NOACCESS
,
2747 &spr_read_generic
, &spr_write_generic
,
2749 /* XXX : not implemented */
2750 spr_register(env
, SPR_MPC_MD_RPN
, "MD_RPN",
2751 SPR_NOACCESS
, SPR_NOACCESS
,
2752 &spr_read_generic
, &spr_write_generic
,
2754 /* XXX : not implemented */
2755 spr_register(env
, SPR_MPC_MD_TW
, "MD_TW",
2756 SPR_NOACCESS
, SPR_NOACCESS
,
2757 &spr_read_generic
, &spr_write_generic
,
2759 /* XXX : not implemented */
2760 spr_register(env
, SPR_MPC_MD_DBCAM
, "MD_DBCAM",
2761 SPR_NOACCESS
, SPR_NOACCESS
,
2762 &spr_read_generic
, &spr_write_generic
,
2764 /* XXX : not implemented */
2765 spr_register(env
, SPR_MPC_MD_DBRAM0
, "MD_DBRAM0",
2766 SPR_NOACCESS
, SPR_NOACCESS
,
2767 &spr_read_generic
, &spr_write_generic
,
2769 /* XXX : not implemented */
2770 spr_register(env
, SPR_MPC_MD_DBRAM1
, "MD_DBRAM1",
2771 SPR_NOACCESS
, SPR_NOACCESS
,
2772 &spr_read_generic
, &spr_write_generic
,
2778 * AMR => SPR 29 (Power 2.04)
2779 * CTRL => SPR 136 (Power 2.04)
2780 * CTRL => SPR 152 (Power 2.04)
2781 * SCOMC => SPR 276 (64 bits ?)
2782 * SCOMD => SPR 277 (64 bits ?)
2783 * TBU40 => SPR 286 (Power 2.04 hypv)
2784 * HSPRG0 => SPR 304 (Power 2.04 hypv)
2785 * HSPRG1 => SPR 305 (Power 2.04 hypv)
2786 * HDSISR => SPR 306 (Power 2.04 hypv)
2787 * HDAR => SPR 307 (Power 2.04 hypv)
2788 * PURR => SPR 309 (Power 2.04 hypv)
2789 * HDEC => SPR 310 (Power 2.04 hypv)
2790 * HIOR => SPR 311 (hypv)
2791 * RMOR => SPR 312 (970)
2792 * HRMOR => SPR 313 (Power 2.04 hypv)
2793 * HSRR0 => SPR 314 (Power 2.04 hypv)
2794 * HSRR1 => SPR 315 (Power 2.04 hypv)
2795 * LPIDR => SPR 317 (970)
2796 * EPR => SPR 702 (Power 2.04 emb)
2797 * perf => 768-783 (Power 2.04)
2798 * perf => 784-799 (Power 2.04)
2799 * PPR => SPR 896 (Power 2.04)
2800 * EPLC => SPR 947 (Power 2.04 emb)
2801 * EPSC => SPR 948 (Power 2.04 emb)
2802 * DABRX => 1015 (Power 2.04 hypv)
2803 * FPECR => SPR 1022 (?)
2804 * ... and more (thermal management, performance counters, ...)
2807 /*****************************************************************************/
2808 /* Exception vectors models */
2809 static void init_excp_4xx_real(CPUPPCState
*env
)
2811 #if !defined(CONFIG_USER_ONLY)
2812 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000100;
2813 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2814 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2815 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2816 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2817 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2818 env
->excp_vectors
[POWERPC_EXCP_PIT
] = 0x00001000;
2819 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00001010;
2820 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001020;
2821 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00002000;
2822 env
->ivor_mask
= 0x0000FFF0UL
;
2823 env
->ivpr_mask
= 0xFFFF0000UL
;
2824 /* Hardware reset vector */
2825 env
->hreset_vector
= 0xFFFFFFFCUL
;
2829 static void init_excp_4xx_softmmu(CPUPPCState
*env
)
2831 #if !defined(CONFIG_USER_ONLY)
2832 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000100;
2833 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2834 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2835 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2836 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2837 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2838 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2839 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2840 env
->excp_vectors
[POWERPC_EXCP_PIT
] = 0x00001000;
2841 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00001010;
2842 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001020;
2843 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00001100;
2844 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00001200;
2845 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00002000;
2846 env
->ivor_mask
= 0x0000FFF0UL
;
2847 env
->ivpr_mask
= 0xFFFF0000UL
;
2848 /* Hardware reset vector */
2849 env
->hreset_vector
= 0xFFFFFFFCUL
;
2853 static void init_excp_MPC5xx(CPUPPCState
*env
)
2855 #if !defined(CONFIG_USER_ONLY)
2856 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2857 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2858 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2859 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2860 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2861 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000900;
2862 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2863 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2864 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2865 env
->excp_vectors
[POWERPC_EXCP_FPA
] = 0x00000E00;
2866 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001000;
2867 env
->excp_vectors
[POWERPC_EXCP_DABR
] = 0x00001C00;
2868 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001C00;
2869 env
->excp_vectors
[POWERPC_EXCP_MEXTBR
] = 0x00001E00;
2870 env
->excp_vectors
[POWERPC_EXCP_NMEXTBR
] = 0x00001F00;
2871 env
->ivor_mask
= 0x0000FFF0UL
;
2872 env
->ivpr_mask
= 0xFFFF0000UL
;
2873 /* Hardware reset vector */
2874 env
->hreset_vector
= 0x00000100UL
;
2878 static void init_excp_MPC8xx(CPUPPCState
*env
)
2880 #if !defined(CONFIG_USER_ONLY)
2881 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2882 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2883 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2884 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2885 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2886 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2887 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2888 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000900;
2889 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2890 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2891 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2892 env
->excp_vectors
[POWERPC_EXCP_FPA
] = 0x00000E00;
2893 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001000;
2894 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00001100;
2895 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00001200;
2896 env
->excp_vectors
[POWERPC_EXCP_ITLBE
] = 0x00001300;
2897 env
->excp_vectors
[POWERPC_EXCP_DTLBE
] = 0x00001400;
2898 env
->excp_vectors
[POWERPC_EXCP_DABR
] = 0x00001C00;
2899 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001C00;
2900 env
->excp_vectors
[POWERPC_EXCP_MEXTBR
] = 0x00001E00;
2901 env
->excp_vectors
[POWERPC_EXCP_NMEXTBR
] = 0x00001F00;
2902 env
->ivor_mask
= 0x0000FFF0UL
;
2903 env
->ivpr_mask
= 0xFFFF0000UL
;
2904 /* Hardware reset vector */
2905 env
->hreset_vector
= 0x00000100UL
;
2909 static void init_excp_G2(CPUPPCState
*env
)
2911 #if !defined(CONFIG_USER_ONLY)
2912 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2913 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2914 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2915 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2916 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2917 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2918 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2919 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
2920 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2921 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000A00;
2922 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2923 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2924 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
2925 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
2926 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
2927 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
2928 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
2929 /* Hardware reset vector */
2930 env
->hreset_vector
= 0x00000100UL
;
2934 static void init_excp_e200(CPUPPCState
*env
, target_ulong ivpr_mask
)
2936 #if !defined(CONFIG_USER_ONLY)
2937 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000FFC;
2938 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000000;
2939 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000000;
2940 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000000;
2941 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000000;
2942 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000000;
2943 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000000;
2944 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000000;
2945 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000000;
2946 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000000;
2947 env
->excp_vectors
[POWERPC_EXCP_APU
] = 0x00000000;
2948 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000000;
2949 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00000000;
2950 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00000000;
2951 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00000000;
2952 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00000000;
2953 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00000000;
2954 env
->excp_vectors
[POWERPC_EXCP_SPEU
] = 0x00000000;
2955 env
->excp_vectors
[POWERPC_EXCP_EFPDI
] = 0x00000000;
2956 env
->excp_vectors
[POWERPC_EXCP_EFPRI
] = 0x00000000;
2957 env
->ivor_mask
= 0x0000FFF7UL
;
2958 env
->ivpr_mask
= ivpr_mask
;
2959 /* Hardware reset vector */
2960 env
->hreset_vector
= 0xFFFFFFFCUL
;
2964 static void init_excp_BookE(CPUPPCState
*env
)
2966 #if !defined(CONFIG_USER_ONLY)
2967 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000000;
2968 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000000;
2969 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000000;
2970 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000000;
2971 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000000;
2972 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000000;
2973 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000000;
2974 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000000;
2975 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000000;
2976 env
->excp_vectors
[POWERPC_EXCP_APU
] = 0x00000000;
2977 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000000;
2978 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00000000;
2979 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00000000;
2980 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00000000;
2981 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00000000;
2982 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00000000;
2983 env
->ivor_mask
= 0x0000FFF0UL
;
2984 env
->ivpr_mask
= 0xFFFF0000UL
;
2985 /* Hardware reset vector */
2986 env
->hreset_vector
= 0xFFFFFFFCUL
;
2990 static void init_excp_601(CPUPPCState
*env
)
2992 #if !defined(CONFIG_USER_ONLY)
2993 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2994 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2995 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2996 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2997 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2998 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2999 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3000 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3001 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3002 env
->excp_vectors
[POWERPC_EXCP_IO
] = 0x00000A00;
3003 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3004 env
->excp_vectors
[POWERPC_EXCP_RUNM
] = 0x00002000;
3005 /* Hardware reset vector */
3006 env
->hreset_vector
= 0x00000100UL
;
3010 static void init_excp_602(CPUPPCState
*env
)
3012 #if !defined(CONFIG_USER_ONLY)
3013 /* XXX: exception prefix has a special behavior on 602 */
3014 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3015 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3016 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3017 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3018 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3019 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3020 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3021 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3022 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3023 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3024 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3025 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3026 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3027 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3028 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3029 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3030 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001500;
3031 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001600;
3032 /* Hardware reset vector */
3033 env
->hreset_vector
= 0x00000100UL
;
3037 static void init_excp_603(CPUPPCState
*env
)
3039 #if !defined(CONFIG_USER_ONLY)
3040 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3041 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3042 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3043 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3044 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3045 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3046 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3047 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3048 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3049 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3050 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3051 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3052 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3053 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3054 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3055 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3056 /* Hardware reset vector */
3057 env
->hreset_vector
= 0x00000100UL
;
3061 static void init_excp_604(CPUPPCState
*env
)
3063 #if !defined(CONFIG_USER_ONLY)
3064 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3065 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3066 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3067 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3068 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3069 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3070 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3071 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3072 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3073 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3074 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3075 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3076 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3077 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3078 /* Hardware reset vector */
3079 env
->hreset_vector
= 0x00000100UL
;
3083 static void init_excp_7x0(CPUPPCState
*env
)
3085 #if !defined(CONFIG_USER_ONLY)
3086 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3087 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3088 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3089 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3090 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3091 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3092 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3093 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3094 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3095 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3096 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3097 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3098 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3099 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3100 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3101 /* Hardware reset vector */
3102 env
->hreset_vector
= 0x00000100UL
;
3106 static void init_excp_750cl(CPUPPCState
*env
)
3108 #if !defined(CONFIG_USER_ONLY)
3109 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3110 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3111 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3112 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3113 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3114 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3115 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3116 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3117 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3118 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3119 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3120 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3121 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3122 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3123 /* Hardware reset vector */
3124 env
->hreset_vector
= 0x00000100UL
;
3128 static void init_excp_750cx(CPUPPCState
*env
)
3130 #if !defined(CONFIG_USER_ONLY)
3131 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3132 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3133 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3134 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3135 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3136 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3137 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3138 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3139 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3140 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3141 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3142 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3143 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3144 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3145 /* Hardware reset vector */
3146 env
->hreset_vector
= 0x00000100UL
;
3150 /* XXX: Check if this is correct */
3151 static void init_excp_7x5(CPUPPCState
*env
)
3153 #if !defined(CONFIG_USER_ONLY)
3154 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3155 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3156 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3157 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3158 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3159 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3160 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3161 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3162 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3163 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3164 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3165 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3166 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3167 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3168 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3169 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3170 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3171 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3172 /* Hardware reset vector */
3173 env
->hreset_vector
= 0x00000100UL
;
3177 static void init_excp_7400(CPUPPCState
*env
)
3179 #if !defined(CONFIG_USER_ONLY)
3180 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3181 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3182 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3183 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3184 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3185 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3186 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3187 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3188 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3189 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3190 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3191 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3192 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3193 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3194 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3195 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001600;
3196 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3197 /* Hardware reset vector */
3198 env
->hreset_vector
= 0x00000100UL
;
3202 static void init_excp_7450(CPUPPCState
*env
)
3204 #if !defined(CONFIG_USER_ONLY)
3205 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3206 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3207 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3208 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3209 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3210 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3211 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3212 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3213 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3214 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3215 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3216 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3217 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3218 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3219 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3220 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3221 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3222 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3223 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001600;
3224 /* Hardware reset vector */
3225 env
->hreset_vector
= 0x00000100UL
;
3229 #if defined(TARGET_PPC64)
3230 static void init_excp_970(CPUPPCState
*env
)
3232 #if !defined(CONFIG_USER_ONLY)
3233 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3234 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3235 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3236 env
->excp_vectors
[POWERPC_EXCP_DSEG
] = 0x00000380;
3237 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3238 env
->excp_vectors
[POWERPC_EXCP_ISEG
] = 0x00000480;
3239 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3240 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3241 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3242 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3243 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3244 env
->excp_vectors
[POWERPC_EXCP_HDECR
] = 0x00000980;
3245 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3246 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3247 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3248 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3249 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3250 env
->excp_vectors
[POWERPC_EXCP_MAINT
] = 0x00001600;
3251 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001700;
3252 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001800;
3253 /* Hardware reset vector */
3254 env
->hreset_vector
= 0x0000000000000100ULL
;
3258 static void init_excp_POWER7(CPUPPCState
*env
)
3260 #if !defined(CONFIG_USER_ONLY)
3261 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3262 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3263 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3264 env
->excp_vectors
[POWERPC_EXCP_DSEG
] = 0x00000380;
3265 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3266 env
->excp_vectors
[POWERPC_EXCP_ISEG
] = 0x00000480;
3267 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3268 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3269 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3270 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3271 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3272 env
->excp_vectors
[POWERPC_EXCP_HDECR
] = 0x00000980;
3273 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3274 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3275 env
->excp_vectors
[POWERPC_EXCP_HDSI
] = 0x00000E00;
3276 env
->excp_vectors
[POWERPC_EXCP_HISI
] = 0x00000E20;
3277 env
->excp_vectors
[POWERPC_EXCP_HV_EMU
] = 0x00000E40;
3278 env
->excp_vectors
[POWERPC_EXCP_HV_MAINT
] = 0x00000E60;
3279 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3280 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3281 env
->excp_vectors
[POWERPC_EXCP_VSXU
] = 0x00000F40;
3282 /* Hardware reset vector */
3283 env
->hreset_vector
= 0x0000000000000100ULL
;
3287 static void init_excp_POWER8(CPUPPCState
*env
)
3289 init_excp_POWER7(env
);
3291 #if !defined(CONFIG_USER_ONLY)
3292 env
->excp_vectors
[POWERPC_EXCP_SDOOR
] = 0x00000A00;
3293 env
->excp_vectors
[POWERPC_EXCP_FU
] = 0x00000F60;
3294 env
->excp_vectors
[POWERPC_EXCP_HV_FU
] = 0x00000F80;
3295 env
->excp_vectors
[POWERPC_EXCP_SDOOR_HV
] = 0x00000E80;
3301 /*****************************************************************************/
3302 /* Power management enable checks */
3303 static int check_pow_none(CPUPPCState
*env
)
3308 static int check_pow_nocheck(CPUPPCState
*env
)
3313 static int check_pow_hid0(CPUPPCState
*env
)
3315 if (env
->spr
[SPR_HID0
] & 0x00E00000)
3321 static int check_pow_hid0_74xx(CPUPPCState
*env
)
3323 if (env
->spr
[SPR_HID0
] & 0x00600000)
3329 static bool ppc_cpu_interrupts_big_endian_always(PowerPCCPU
*cpu
)
3335 static bool ppc_cpu_interrupts_big_endian_lpcr(PowerPCCPU
*cpu
)
3337 return !(cpu
->env
.spr
[SPR_LPCR
] & LPCR_ILE
);
3341 /*****************************************************************************/
3342 /* PowerPC implementations definitions */
3344 #define POWERPC_FAMILY(_name) \
3346 glue(glue(ppc_, _name), _cpu_family_class_init)(ObjectClass *, void *); \
3348 static const TypeInfo \
3349 glue(glue(ppc_, _name), _cpu_family_type_info) = { \
3350 .name = stringify(_name) "-family-" TYPE_POWERPC_CPU, \
3351 .parent = TYPE_POWERPC_CPU, \
3353 .class_init = glue(glue(ppc_, _name), _cpu_family_class_init), \
3356 static void glue(glue(ppc_, _name), _cpu_family_register_types)(void) \
3358 type_register_static( \
3359 &glue(glue(ppc_, _name), _cpu_family_type_info)); \
3362 type_init(glue(glue(ppc_, _name), _cpu_family_register_types)) \
3364 static void glue(glue(ppc_, _name), _cpu_family_class_init)
3366 static void init_proc_401(CPUPPCState
*env
)
3369 gen_spr_401_403(env
);
3371 init_excp_4xx_real(env
);
3372 env
->dcache_line_size
= 32;
3373 env
->icache_line_size
= 32;
3374 /* Allocate hardware IRQ controller */
3375 ppc40x_irq_init(ppc_env_get_cpu(env
));
3377 SET_FIT_PERIOD(12, 16, 20, 24);
3378 SET_WDT_PERIOD(16, 20, 24, 28);
3381 POWERPC_FAMILY(401)(ObjectClass
*oc
, void *data
)
3383 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3384 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3386 dc
->desc
= "PowerPC 401";
3387 pcc
->init_proc
= init_proc_401
;
3388 pcc
->check_pow
= check_pow_nocheck
;
3389 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3390 PPC_WRTEE
| PPC_DCR
|
3391 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3393 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3394 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3395 pcc
->msr_mask
= (1ull << MSR_KEY
) |
3404 pcc
->mmu_model
= POWERPC_MMU_REAL
;
3405 pcc
->excp_model
= POWERPC_EXCP_40x
;
3406 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3407 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3408 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3409 POWERPC_FLAG_BUS_CLK
;
3412 static void init_proc_401x2(CPUPPCState
*env
)
3415 gen_spr_401_403(env
);
3417 gen_spr_compress(env
);
3418 /* Memory management */
3419 #if !defined(CONFIG_USER_ONLY)
3423 env
->tlb_type
= TLB_EMB
;
3425 init_excp_4xx_softmmu(env
);
3426 env
->dcache_line_size
= 32;
3427 env
->icache_line_size
= 32;
3428 /* Allocate hardware IRQ controller */
3429 ppc40x_irq_init(ppc_env_get_cpu(env
));
3431 SET_FIT_PERIOD(12, 16, 20, 24);
3432 SET_WDT_PERIOD(16, 20, 24, 28);
3435 POWERPC_FAMILY(401x2
)(ObjectClass
*oc
, void *data
)
3437 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3438 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3440 dc
->desc
= "PowerPC 401x2";
3441 pcc
->init_proc
= init_proc_401x2
;
3442 pcc
->check_pow
= check_pow_nocheck
;
3443 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3444 PPC_DCR
| PPC_WRTEE
|
3445 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3446 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3447 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3448 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3449 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3450 pcc
->msr_mask
= (1ull << 20) |
3462 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3463 pcc
->excp_model
= POWERPC_EXCP_40x
;
3464 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3465 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3466 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3467 POWERPC_FLAG_BUS_CLK
;
3470 static void init_proc_401x3(CPUPPCState
*env
)
3473 gen_spr_401_403(env
);
3476 gen_spr_compress(env
);
3477 init_excp_4xx_softmmu(env
);
3478 env
->dcache_line_size
= 32;
3479 env
->icache_line_size
= 32;
3480 /* Allocate hardware IRQ controller */
3481 ppc40x_irq_init(ppc_env_get_cpu(env
));
3483 SET_FIT_PERIOD(12, 16, 20, 24);
3484 SET_WDT_PERIOD(16, 20, 24, 28);
3487 POWERPC_FAMILY(401x3
)(ObjectClass
*oc
, void *data
)
3489 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3490 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3492 dc
->desc
= "PowerPC 401x3";
3493 pcc
->init_proc
= init_proc_401x3
;
3494 pcc
->check_pow
= check_pow_nocheck
;
3495 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3496 PPC_DCR
| PPC_WRTEE
|
3497 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3498 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3499 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3500 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3501 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3502 pcc
->msr_mask
= (1ull << 20) |
3515 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3516 pcc
->excp_model
= POWERPC_EXCP_40x
;
3517 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3518 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3519 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3520 POWERPC_FLAG_BUS_CLK
;
3523 static void init_proc_IOP480(CPUPPCState
*env
)
3526 gen_spr_401_403(env
);
3528 gen_spr_compress(env
);
3529 /* Memory management */
3530 #if !defined(CONFIG_USER_ONLY)
3534 env
->tlb_type
= TLB_EMB
;
3536 init_excp_4xx_softmmu(env
);
3537 env
->dcache_line_size
= 32;
3538 env
->icache_line_size
= 32;
3539 /* Allocate hardware IRQ controller */
3540 ppc40x_irq_init(ppc_env_get_cpu(env
));
3542 SET_FIT_PERIOD(8, 12, 16, 20);
3543 SET_WDT_PERIOD(16, 20, 24, 28);
3546 POWERPC_FAMILY(IOP480
)(ObjectClass
*oc
, void *data
)
3548 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3549 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3551 dc
->desc
= "IOP480";
3552 pcc
->init_proc
= init_proc_IOP480
;
3553 pcc
->check_pow
= check_pow_nocheck
;
3554 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3555 PPC_DCR
| PPC_WRTEE
|
3556 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3557 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3558 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3559 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3560 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3561 pcc
->msr_mask
= (1ull << 20) |
3573 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3574 pcc
->excp_model
= POWERPC_EXCP_40x
;
3575 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3576 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3577 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3578 POWERPC_FLAG_BUS_CLK
;
3581 static void init_proc_403(CPUPPCState
*env
)
3584 gen_spr_401_403(env
);
3586 gen_spr_403_real(env
);
3587 init_excp_4xx_real(env
);
3588 env
->dcache_line_size
= 32;
3589 env
->icache_line_size
= 32;
3590 /* Allocate hardware IRQ controller */
3591 ppc40x_irq_init(ppc_env_get_cpu(env
));
3593 SET_FIT_PERIOD(8, 12, 16, 20);
3594 SET_WDT_PERIOD(16, 20, 24, 28);
3597 POWERPC_FAMILY(403)(ObjectClass
*oc
, void *data
)
3599 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3600 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3602 dc
->desc
= "PowerPC 403";
3603 pcc
->init_proc
= init_proc_403
;
3604 pcc
->check_pow
= check_pow_nocheck
;
3605 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3606 PPC_DCR
| PPC_WRTEE
|
3607 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3609 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3610 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3611 pcc
->msr_mask
= (1ull << MSR_POW
) |
3620 pcc
->mmu_model
= POWERPC_MMU_REAL
;
3621 pcc
->excp_model
= POWERPC_EXCP_40x
;
3622 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3623 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3624 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_PX
|
3625 POWERPC_FLAG_BUS_CLK
;
3628 static void init_proc_403GCX(CPUPPCState
*env
)
3631 gen_spr_401_403(env
);
3633 gen_spr_403_real(env
);
3634 gen_spr_403_mmu(env
);
3635 /* Bus access control */
3636 /* not emulated, as QEMU never does speculative access */
3637 spr_register(env
, SPR_40x_SGR
, "SGR",
3638 SPR_NOACCESS
, SPR_NOACCESS
,
3639 &spr_read_generic
, &spr_write_generic
,
3641 /* not emulated, as QEMU do not emulate caches */
3642 spr_register(env
, SPR_40x_DCWR
, "DCWR",
3643 SPR_NOACCESS
, SPR_NOACCESS
,
3644 &spr_read_generic
, &spr_write_generic
,
3646 /* Memory management */
3647 #if !defined(CONFIG_USER_ONLY)
3651 env
->tlb_type
= TLB_EMB
;
3653 init_excp_4xx_softmmu(env
);
3654 env
->dcache_line_size
= 32;
3655 env
->icache_line_size
= 32;
3656 /* Allocate hardware IRQ controller */
3657 ppc40x_irq_init(ppc_env_get_cpu(env
));
3659 SET_FIT_PERIOD(8, 12, 16, 20);
3660 SET_WDT_PERIOD(16, 20, 24, 28);
3663 POWERPC_FAMILY(403GCX
)(ObjectClass
*oc
, void *data
)
3665 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3666 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3668 dc
->desc
= "PowerPC 403 GCX";
3669 pcc
->init_proc
= init_proc_403GCX
;
3670 pcc
->check_pow
= check_pow_nocheck
;
3671 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3672 PPC_DCR
| PPC_WRTEE
|
3673 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3675 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3676 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3677 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3678 pcc
->msr_mask
= (1ull << MSR_POW
) |
3687 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3688 pcc
->excp_model
= POWERPC_EXCP_40x
;
3689 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3690 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3691 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_PX
|
3692 POWERPC_FLAG_BUS_CLK
;
3695 static void init_proc_405(CPUPPCState
*env
)
3701 /* Bus access control */
3702 /* not emulated, as QEMU never does speculative access */
3703 spr_register(env
, SPR_40x_SGR
, "SGR",
3704 SPR_NOACCESS
, SPR_NOACCESS
,
3705 &spr_read_generic
, &spr_write_generic
,
3707 /* not emulated, as QEMU do not emulate caches */
3708 spr_register(env
, SPR_40x_DCWR
, "DCWR",
3709 SPR_NOACCESS
, SPR_NOACCESS
,
3710 &spr_read_generic
, &spr_write_generic
,
3712 /* Memory management */
3713 #if !defined(CONFIG_USER_ONLY)
3717 env
->tlb_type
= TLB_EMB
;
3719 init_excp_4xx_softmmu(env
);
3720 env
->dcache_line_size
= 32;
3721 env
->icache_line_size
= 32;
3722 /* Allocate hardware IRQ controller */
3723 ppc40x_irq_init(ppc_env_get_cpu(env
));
3725 SET_FIT_PERIOD(8, 12, 16, 20);
3726 SET_WDT_PERIOD(16, 20, 24, 28);
3729 POWERPC_FAMILY(405)(ObjectClass
*oc
, void *data
)
3731 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3732 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3734 dc
->desc
= "PowerPC 405";
3735 pcc
->init_proc
= init_proc_405
;
3736 pcc
->check_pow
= check_pow_nocheck
;
3737 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3738 PPC_DCR
| PPC_WRTEE
|
3739 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3740 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3741 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3742 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3743 PPC_4xx_COMMON
| PPC_405_MAC
| PPC_40x_EXCP
;
3744 pcc
->msr_mask
= (1ull << MSR_POW
) |
3753 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx
;
3754 pcc
->excp_model
= POWERPC_EXCP_40x
;
3755 pcc
->bus_model
= PPC_FLAGS_INPUT_405
;
3756 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3757 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3758 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3761 static void init_proc_440EP(CPUPPCState
*env
)
3765 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3767 gen_spr_usprgh(env
);
3768 /* Processor identification */
3769 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3770 SPR_NOACCESS
, SPR_NOACCESS
,
3771 &spr_read_generic
, &spr_write_pir
,
3773 /* XXX : not implemented */
3774 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
3775 SPR_NOACCESS
, SPR_NOACCESS
,
3776 &spr_read_generic
, &spr_write_generic
,
3778 /* XXX : not implemented */
3779 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
3780 SPR_NOACCESS
, SPR_NOACCESS
,
3781 &spr_read_generic
, &spr_write_generic
,
3783 /* XXX : not implemented */
3784 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
3785 SPR_NOACCESS
, SPR_NOACCESS
,
3786 &spr_read_generic
, &spr_write_generic
,
3788 /* XXX : not implemented */
3789 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
3790 SPR_NOACCESS
, SPR_NOACCESS
,
3791 &spr_read_generic
, &spr_write_generic
,
3793 /* XXX : not implemented */
3794 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
3795 SPR_NOACCESS
, SPR_NOACCESS
,
3796 &spr_read_generic
, &spr_write_generic
,
3798 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
3799 SPR_NOACCESS
, SPR_NOACCESS
,
3800 &spr_read_generic
, &spr_write_generic
,
3802 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
3803 SPR_NOACCESS
, SPR_NOACCESS
,
3804 &spr_read_generic
, &spr_write_generic
,
3806 /* XXX : not implemented */
3807 spr_register(env
, SPR_440_CCR1
, "CCR1",
3808 SPR_NOACCESS
, SPR_NOACCESS
,
3809 &spr_read_generic
, &spr_write_generic
,
3811 /* Memory management */
3812 #if !defined(CONFIG_USER_ONLY)
3816 env
->tlb_type
= TLB_EMB
;
3818 init_excp_BookE(env
);
3819 env
->dcache_line_size
= 32;
3820 env
->icache_line_size
= 32;
3821 ppc40x_irq_init(ppc_env_get_cpu(env
));
3823 SET_FIT_PERIOD(12, 16, 20, 24);
3824 SET_WDT_PERIOD(20, 24, 28, 32);
3827 POWERPC_FAMILY(440EP
)(ObjectClass
*oc
, void *data
)
3829 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3830 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3832 dc
->desc
= "PowerPC 440 EP";
3833 pcc
->init_proc
= init_proc_440EP
;
3834 pcc
->check_pow
= check_pow_nocheck
;
3835 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3836 PPC_FLOAT
| PPC_FLOAT_FRES
| PPC_FLOAT_FSEL
|
3837 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
3839 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
3840 PPC_CACHE
| PPC_CACHE_ICBI
|
3841 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3842 PPC_MEM_TLBSYNC
| PPC_MFTB
|
3843 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3845 pcc
->msr_mask
= (1ull << MSR_POW
) |
3857 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3858 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3859 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3860 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3861 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3862 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3865 POWERPC_FAMILY(460EX
)(ObjectClass
*oc
, void *data
)
3867 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3868 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3870 dc
->desc
= "PowerPC 460 EX";
3871 pcc
->init_proc
= init_proc_440EP
;
3872 pcc
->check_pow
= check_pow_nocheck
;
3873 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3874 PPC_FLOAT
| PPC_FLOAT_FRES
| PPC_FLOAT_FSEL
|
3875 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
3877 PPC_DCR
| PPC_DCRX
| PPC_WRTEE
| PPC_RFMCI
|
3878 PPC_CACHE
| PPC_CACHE_ICBI
|
3879 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3880 PPC_MEM_TLBSYNC
| PPC_MFTB
|
3881 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3883 pcc
->msr_mask
= (1ull << MSR_POW
) |
3895 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3896 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3897 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3898 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3899 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3900 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3903 static void init_proc_440GP(CPUPPCState
*env
)
3907 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3909 gen_spr_usprgh(env
);
3910 /* Processor identification */
3911 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3912 SPR_NOACCESS
, SPR_NOACCESS
,
3913 &spr_read_generic
, &spr_write_pir
,
3915 /* XXX : not implemented */
3916 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
3917 SPR_NOACCESS
, SPR_NOACCESS
,
3918 &spr_read_generic
, &spr_write_generic
,
3920 /* XXX : not implemented */
3921 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
3922 SPR_NOACCESS
, SPR_NOACCESS
,
3923 &spr_read_generic
, &spr_write_generic
,
3925 /* XXX : not implemented */
3926 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
3927 SPR_NOACCESS
, SPR_NOACCESS
,
3928 &spr_read_generic
, &spr_write_generic
,
3930 /* XXX : not implemented */
3931 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
3932 SPR_NOACCESS
, SPR_NOACCESS
,
3933 &spr_read_generic
, &spr_write_generic
,
3935 /* Memory management */
3936 #if !defined(CONFIG_USER_ONLY)
3940 env
->tlb_type
= TLB_EMB
;
3942 init_excp_BookE(env
);
3943 env
->dcache_line_size
= 32;
3944 env
->icache_line_size
= 32;
3945 /* XXX: TODO: allocate internal IRQ controller */
3947 SET_FIT_PERIOD(12, 16, 20, 24);
3948 SET_WDT_PERIOD(20, 24, 28, 32);
3951 POWERPC_FAMILY(440GP
)(ObjectClass
*oc
, void *data
)
3953 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3954 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3956 dc
->desc
= "PowerPC 440 GP";
3957 pcc
->init_proc
= init_proc_440GP
;
3958 pcc
->check_pow
= check_pow_nocheck
;
3959 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3960 PPC_DCR
| PPC_DCRX
| PPC_WRTEE
| PPC_MFAPIDI
|
3961 PPC_CACHE
| PPC_CACHE_ICBI
|
3962 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3963 PPC_MEM_TLBSYNC
| PPC_TLBIVA
| PPC_MFTB
|
3964 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3966 pcc
->msr_mask
= (1ull << MSR_POW
) |
3978 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3979 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3980 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3981 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3982 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3983 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3986 static void init_proc_440x4(CPUPPCState
*env
)
3990 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3992 gen_spr_usprgh(env
);
3993 /* Processor identification */
3994 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3995 SPR_NOACCESS
, SPR_NOACCESS
,
3996 &spr_read_generic
, &spr_write_pir
,
3998 /* XXX : not implemented */
3999 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4000 SPR_NOACCESS
, SPR_NOACCESS
,
4001 &spr_read_generic
, &spr_write_generic
,
4003 /* XXX : not implemented */
4004 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4005 SPR_NOACCESS
, SPR_NOACCESS
,
4006 &spr_read_generic
, &spr_write_generic
,
4008 /* XXX : not implemented */
4009 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
4010 SPR_NOACCESS
, SPR_NOACCESS
,
4011 &spr_read_generic
, &spr_write_generic
,
4013 /* XXX : not implemented */
4014 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
4015 SPR_NOACCESS
, SPR_NOACCESS
,
4016 &spr_read_generic
, &spr_write_generic
,
4018 /* Memory management */
4019 #if !defined(CONFIG_USER_ONLY)
4023 env
->tlb_type
= TLB_EMB
;
4025 init_excp_BookE(env
);
4026 env
->dcache_line_size
= 32;
4027 env
->icache_line_size
= 32;
4028 /* XXX: TODO: allocate internal IRQ controller */
4030 SET_FIT_PERIOD(12, 16, 20, 24);
4031 SET_WDT_PERIOD(20, 24, 28, 32);
4034 POWERPC_FAMILY(440x4
)(ObjectClass
*oc
, void *data
)
4036 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4037 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4039 dc
->desc
= "PowerPC 440x4";
4040 pcc
->init_proc
= init_proc_440x4
;
4041 pcc
->check_pow
= check_pow_nocheck
;
4042 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4043 PPC_DCR
| PPC_WRTEE
|
4044 PPC_CACHE
| PPC_CACHE_ICBI
|
4045 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4046 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4047 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4049 pcc
->msr_mask
= (1ull << MSR_POW
) |
4061 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4062 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4063 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4064 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4065 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4066 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4069 static void init_proc_440x5(CPUPPCState
*env
)
4073 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
4075 gen_spr_usprgh(env
);
4076 /* Processor identification */
4077 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4078 SPR_NOACCESS
, SPR_NOACCESS
,
4079 &spr_read_generic
, &spr_write_pir
,
4081 /* XXX : not implemented */
4082 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4083 SPR_NOACCESS
, SPR_NOACCESS
,
4084 &spr_read_generic
, &spr_write_generic
,
4086 /* XXX : not implemented */
4087 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4088 SPR_NOACCESS
, SPR_NOACCESS
,
4089 &spr_read_generic
, &spr_write_generic
,
4091 /* XXX : not implemented */
4092 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
4093 SPR_NOACCESS
, SPR_NOACCESS
,
4094 &spr_read_generic
, &spr_write_generic
,
4096 /* XXX : not implemented */
4097 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
4098 SPR_NOACCESS
, SPR_NOACCESS
,
4099 &spr_read_generic
, &spr_write_generic
,
4101 /* XXX : not implemented */
4102 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
4103 SPR_NOACCESS
, SPR_NOACCESS
,
4104 &spr_read_generic
, &spr_write_generic
,
4106 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
4107 SPR_NOACCESS
, SPR_NOACCESS
,
4108 &spr_read_generic
, &spr_write_generic
,
4110 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
4111 SPR_NOACCESS
, SPR_NOACCESS
,
4112 &spr_read_generic
, &spr_write_generic
,
4114 /* XXX : not implemented */
4115 spr_register(env
, SPR_440_CCR1
, "CCR1",
4116 SPR_NOACCESS
, SPR_NOACCESS
,
4117 &spr_read_generic
, &spr_write_generic
,
4119 /* Memory management */
4120 #if !defined(CONFIG_USER_ONLY)
4124 env
->tlb_type
= TLB_EMB
;
4126 init_excp_BookE(env
);
4127 env
->dcache_line_size
= 32;
4128 env
->icache_line_size
= 32;
4129 ppc40x_irq_init(ppc_env_get_cpu(env
));
4131 SET_FIT_PERIOD(12, 16, 20, 24);
4132 SET_WDT_PERIOD(20, 24, 28, 32);
4135 POWERPC_FAMILY(440x5
)(ObjectClass
*oc
, void *data
)
4137 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4138 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4140 dc
->desc
= "PowerPC 440x5";
4141 pcc
->init_proc
= init_proc_440x5
;
4142 pcc
->check_pow
= check_pow_nocheck
;
4143 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4144 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
4145 PPC_CACHE
| PPC_CACHE_ICBI
|
4146 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4147 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4148 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4150 pcc
->msr_mask
= (1ull << MSR_POW
) |
4162 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4163 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4164 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4165 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4166 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4167 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4170 POWERPC_FAMILY(440x5wDFPU
)(ObjectClass
*oc
, void *data
)
4172 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4173 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4175 dc
->desc
= "PowerPC 440x5 with double precision FPU";
4176 pcc
->init_proc
= init_proc_440x5
;
4177 pcc
->check_pow
= check_pow_nocheck
;
4178 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4179 PPC_FLOAT
| PPC_FLOAT_FSQRT
|
4181 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
4182 PPC_CACHE
| PPC_CACHE_ICBI
|
4183 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4184 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4185 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4187 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
4188 pcc
->msr_mask
= (1ull << MSR_POW
) |
4200 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4201 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4202 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4203 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4204 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4205 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4208 static void init_proc_MPC5xx(CPUPPCState
*env
)
4212 gen_spr_5xx_8xx(env
);
4214 init_excp_MPC5xx(env
);
4215 env
->dcache_line_size
= 32;
4216 env
->icache_line_size
= 32;
4217 /* XXX: TODO: allocate internal IRQ controller */
4220 POWERPC_FAMILY(MPC5xx
)(ObjectClass
*oc
, void *data
)
4222 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4223 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4225 dc
->desc
= "Freescale 5xx cores (aka RCPU)";
4226 pcc
->init_proc
= init_proc_MPC5xx
;
4227 pcc
->check_pow
= check_pow_none
;
4228 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4229 PPC_MEM_EIEIO
| PPC_MEM_SYNC
|
4230 PPC_CACHE_ICBI
| PPC_FLOAT
| PPC_FLOAT_STFIWX
|
4232 pcc
->msr_mask
= (1ull << MSR_ILE
) |
4244 pcc
->mmu_model
= POWERPC_MMU_REAL
;
4245 pcc
->excp_model
= POWERPC_EXCP_603
;
4246 pcc
->bus_model
= PPC_FLAGS_INPUT_RCPU
;
4247 pcc
->bfd_mach
= bfd_mach_ppc_505
;
4248 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
4249 POWERPC_FLAG_BUS_CLK
;
4252 static void init_proc_MPC8xx(CPUPPCState
*env
)
4256 gen_spr_5xx_8xx(env
);
4258 init_excp_MPC8xx(env
);
4259 env
->dcache_line_size
= 32;
4260 env
->icache_line_size
= 32;
4261 /* XXX: TODO: allocate internal IRQ controller */
4264 POWERPC_FAMILY(MPC8xx
)(ObjectClass
*oc
, void *data
)
4266 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4267 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4269 dc
->desc
= "Freescale 8xx cores (aka PowerQUICC)";
4270 pcc
->init_proc
= init_proc_MPC8xx
;
4271 pcc
->check_pow
= check_pow_none
;
4272 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4273 PPC_MEM_EIEIO
| PPC_MEM_SYNC
|
4274 PPC_CACHE_ICBI
| PPC_MFTB
;
4275 pcc
->msr_mask
= (1ull << MSR_ILE
) |
4287 pcc
->mmu_model
= POWERPC_MMU_MPC8xx
;
4288 pcc
->excp_model
= POWERPC_EXCP_603
;
4289 pcc
->bus_model
= PPC_FLAGS_INPUT_RCPU
;
4290 pcc
->bfd_mach
= bfd_mach_ppc_860
;
4291 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
4292 POWERPC_FLAG_BUS_CLK
;
4295 /* Freescale 82xx cores (aka PowerQUICC-II) */
4297 static void init_proc_G2(CPUPPCState
*env
)
4299 gen_spr_ne_601(env
);
4301 gen_spr_G2_755(env
);
4305 /* External access control */
4306 /* XXX : not implemented */
4307 spr_register(env
, SPR_EAR
, "EAR",
4308 SPR_NOACCESS
, SPR_NOACCESS
,
4309 &spr_read_generic
, &spr_write_generic
,
4311 /* Hardware implementation register */
4312 /* XXX : not implemented */
4313 spr_register(env
, SPR_HID0
, "HID0",
4314 SPR_NOACCESS
, SPR_NOACCESS
,
4315 &spr_read_generic
, &spr_write_generic
,
4317 /* XXX : not implemented */
4318 spr_register(env
, SPR_HID1
, "HID1",
4319 SPR_NOACCESS
, SPR_NOACCESS
,
4320 &spr_read_generic
, &spr_write_generic
,
4322 /* XXX : not implemented */
4323 spr_register(env
, SPR_HID2
, "HID2",
4324 SPR_NOACCESS
, SPR_NOACCESS
,
4325 &spr_read_generic
, &spr_write_generic
,
4327 /* Memory management */
4330 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4332 env
->dcache_line_size
= 32;
4333 env
->icache_line_size
= 32;
4334 /* Allocate hardware IRQ controller */
4335 ppc6xx_irq_init(ppc_env_get_cpu(env
));
4338 POWERPC_FAMILY(G2
)(ObjectClass
*oc
, void *data
)
4340 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4341 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4343 dc
->desc
= "PowerPC G2";
4344 pcc
->init_proc
= init_proc_G2
;
4345 pcc
->check_pow
= check_pow_hid0
;
4346 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4347 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4349 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4350 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4351 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4352 PPC_SEGMENT
| PPC_EXTERN
;
4353 pcc
->msr_mask
= (1ull << MSR_POW
) |
4354 (1ull << MSR_TGPR
) |
4368 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4369 pcc
->excp_model
= POWERPC_EXCP_G2
;
4370 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4371 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
4372 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4373 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4376 static void init_proc_G2LE(CPUPPCState
*env
)
4378 gen_spr_ne_601(env
);
4380 gen_spr_G2_755(env
);
4384 /* External access control */
4385 /* XXX : not implemented */
4386 spr_register(env
, SPR_EAR
, "EAR",
4387 SPR_NOACCESS
, SPR_NOACCESS
,
4388 &spr_read_generic
, &spr_write_generic
,
4390 /* Hardware implementation register */
4391 /* XXX : not implemented */
4392 spr_register(env
, SPR_HID0
, "HID0",
4393 SPR_NOACCESS
, SPR_NOACCESS
,
4394 &spr_read_generic
, &spr_write_generic
,
4396 /* XXX : not implemented */
4397 spr_register(env
, SPR_HID1
, "HID1",
4398 SPR_NOACCESS
, SPR_NOACCESS
,
4399 &spr_read_generic
, &spr_write_generic
,
4401 /* XXX : not implemented */
4402 spr_register(env
, SPR_HID2
, "HID2",
4403 SPR_NOACCESS
, SPR_NOACCESS
,
4404 &spr_read_generic
, &spr_write_generic
,
4407 /* Memory management */
4410 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4412 env
->dcache_line_size
= 32;
4413 env
->icache_line_size
= 32;
4414 /* Allocate hardware IRQ controller */
4415 ppc6xx_irq_init(ppc_env_get_cpu(env
));
4418 POWERPC_FAMILY(G2LE
)(ObjectClass
*oc
, void *data
)
4420 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4421 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4423 dc
->desc
= "PowerPC G2LE";
4424 pcc
->init_proc
= init_proc_G2LE
;
4425 pcc
->check_pow
= check_pow_hid0
;
4426 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4427 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4429 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4430 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4431 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4432 PPC_SEGMENT
| PPC_EXTERN
;
4433 pcc
->msr_mask
= (1ull << MSR_POW
) |
4434 (1ull << MSR_TGPR
) |
4450 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4451 pcc
->excp_model
= POWERPC_EXCP_G2
;
4452 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4453 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
4454 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4455 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4458 static void init_proc_e200(CPUPPCState
*env
)
4462 gen_spr_BookE(env
, 0x000000070000FFFFULL
);
4463 /* XXX : not implemented */
4464 spr_register(env
, SPR_BOOKE_SPEFSCR
, "SPEFSCR",
4465 &spr_read_spefscr
, &spr_write_spefscr
,
4466 &spr_read_spefscr
, &spr_write_spefscr
,
4468 /* Memory management */
4469 gen_spr_BookE206(env
, 0x0000005D, NULL
, 0);
4470 /* XXX : not implemented */
4471 spr_register(env
, SPR_HID0
, "HID0",
4472 SPR_NOACCESS
, SPR_NOACCESS
,
4473 &spr_read_generic
, &spr_write_generic
,
4475 /* XXX : not implemented */
4476 spr_register(env
, SPR_HID1
, "HID1",
4477 SPR_NOACCESS
, SPR_NOACCESS
,
4478 &spr_read_generic
, &spr_write_generic
,
4480 /* XXX : not implemented */
4481 spr_register(env
, SPR_Exxx_ALTCTXCR
, "ALTCTXCR",
4482 SPR_NOACCESS
, SPR_NOACCESS
,
4483 &spr_read_generic
, &spr_write_generic
,
4485 /* XXX : not implemented */
4486 spr_register(env
, SPR_Exxx_BUCSR
, "BUCSR",
4487 SPR_NOACCESS
, SPR_NOACCESS
,
4488 &spr_read_generic
, &spr_write_generic
,
4490 /* XXX : not implemented */
4491 spr_register(env
, SPR_Exxx_CTXCR
, "CTXCR",
4492 SPR_NOACCESS
, SPR_NOACCESS
,
4493 &spr_read_generic
, &spr_write_generic
,
4495 /* XXX : not implemented */
4496 spr_register(env
, SPR_Exxx_DBCNT
, "DBCNT",
4497 SPR_NOACCESS
, SPR_NOACCESS
,
4498 &spr_read_generic
, &spr_write_generic
,
4500 /* XXX : not implemented */
4501 spr_register(env
, SPR_Exxx_DBCR3
, "DBCR3",
4502 SPR_NOACCESS
, SPR_NOACCESS
,
4503 &spr_read_generic
, &spr_write_generic
,
4505 /* XXX : not implemented */
4506 spr_register(env
, SPR_Exxx_L1CFG0
, "L1CFG0",
4507 &spr_read_generic
, SPR_NOACCESS
,
4508 &spr_read_generic
, SPR_NOACCESS
,
4510 /* XXX : not implemented */
4511 spr_register(env
, SPR_Exxx_L1CSR0
, "L1CSR0",
4512 SPR_NOACCESS
, SPR_NOACCESS
,
4513 &spr_read_generic
, &spr_write_generic
,
4515 /* XXX : not implemented */
4516 spr_register(env
, SPR_Exxx_L1FINV0
, "L1FINV0",
4517 SPR_NOACCESS
, SPR_NOACCESS
,
4518 &spr_read_generic
, &spr_write_generic
,
4520 /* XXX : not implemented */
4521 spr_register(env
, SPR_BOOKE_TLB0CFG
, "TLB0CFG",
4522 SPR_NOACCESS
, SPR_NOACCESS
,
4523 &spr_read_generic
, &spr_write_generic
,
4525 /* XXX : not implemented */
4526 spr_register(env
, SPR_BOOKE_TLB1CFG
, "TLB1CFG",
4527 SPR_NOACCESS
, SPR_NOACCESS
,
4528 &spr_read_generic
, &spr_write_generic
,
4530 /* XXX : not implemented */
4531 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4532 SPR_NOACCESS
, SPR_NOACCESS
,
4533 &spr_read_generic
, &spr_write_generic
,
4535 /* XXX : not implemented */
4536 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4537 SPR_NOACCESS
, SPR_NOACCESS
,
4538 &spr_read_generic
, &spr_write_generic
,
4540 /* XXX : not implemented */
4541 spr_register(env
, SPR_MMUCSR0
, "MMUCSR0",
4542 SPR_NOACCESS
, SPR_NOACCESS
,
4543 &spr_read_generic
, &spr_write_generic
,
4544 0x00000000); /* TOFIX */
4545 spr_register(env
, SPR_BOOKE_DSRR0
, "DSRR0",
4546 SPR_NOACCESS
, SPR_NOACCESS
,
4547 &spr_read_generic
, &spr_write_generic
,
4549 spr_register(env
, SPR_BOOKE_DSRR1
, "DSRR1",
4550 SPR_NOACCESS
, SPR_NOACCESS
,
4551 &spr_read_generic
, &spr_write_generic
,
4553 #if !defined(CONFIG_USER_ONLY)
4557 env
->tlb_type
= TLB_EMB
;
4559 init_excp_e200(env
, 0xFFFF0000UL
);
4560 env
->dcache_line_size
= 32;
4561 env
->icache_line_size
= 32;
4562 /* XXX: TODO: allocate internal IRQ controller */
4565 POWERPC_FAMILY(e200
)(ObjectClass
*oc
, void *data
)
4567 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4568 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4570 dc
->desc
= "e200 core";
4571 pcc
->init_proc
= init_proc_e200
;
4572 pcc
->check_pow
= check_pow_hid0
;
4573 /* XXX: unimplemented instructions:
4580 * all SPE multiply-accumulate instructions
4582 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
4583 PPC_SPE
| PPC_SPE_SINGLE
|
4584 PPC_WRTEE
| PPC_RFDI
|
4585 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
4586 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4587 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
|
4589 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
4603 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
4604 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4605 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4606 pcc
->bfd_mach
= bfd_mach_ppc_860
;
4607 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
4608 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
4609 POWERPC_FLAG_BUS_CLK
;
4612 static void init_proc_e300(CPUPPCState
*env
)
4614 gen_spr_ne_601(env
);
4619 /* hardware implementation registers */
4620 /* XXX : not implemented */
4621 spr_register(env
, SPR_HID0
, "HID0",
4622 SPR_NOACCESS
, SPR_NOACCESS
,
4623 &spr_read_generic
, &spr_write_generic
,
4625 /* XXX : not implemented */
4626 spr_register(env
, SPR_HID1
, "HID1",
4627 SPR_NOACCESS
, SPR_NOACCESS
,
4628 &spr_read_generic
, &spr_write_generic
,
4630 /* XXX : not implemented */
4631 spr_register(env
, SPR_HID2
, "HID2",
4632 SPR_NOACCESS
, SPR_NOACCESS
,
4633 &spr_read_generic
, &spr_write_generic
,
4636 /* XXX : not implemented */
4637 spr_register(env
, SPR_DABR
, "DABR",
4638 SPR_NOACCESS
, SPR_NOACCESS
,
4639 &spr_read_generic
, &spr_write_generic
,
4641 /* XXX : not implemented */
4642 spr_register(env
, SPR_DABR2
, "DABR2",
4643 SPR_NOACCESS
, SPR_NOACCESS
,
4644 &spr_read_generic
, &spr_write_generic
,
4646 /* XXX : not implemented */
4647 spr_register(env
, SPR_IABR2
, "IABR2",
4648 SPR_NOACCESS
, SPR_NOACCESS
,
4649 &spr_read_generic
, &spr_write_generic
,
4651 /* XXX : not implemented */
4652 spr_register(env
, SPR_IBCR
, "IBCR",
4653 SPR_NOACCESS
, SPR_NOACCESS
,
4654 &spr_read_generic
, &spr_write_generic
,
4656 /* XXX : not implemented */
4657 spr_register(env
, SPR_DBCR
, "DBCR",
4658 SPR_NOACCESS
, SPR_NOACCESS
,
4659 &spr_read_generic
, &spr_write_generic
,
4661 /* Memory management */
4664 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4666 env
->dcache_line_size
= 32;
4667 env
->icache_line_size
= 32;
4668 /* Allocate hardware IRQ controller */
4669 ppc6xx_irq_init(ppc_env_get_cpu(env
));
4672 POWERPC_FAMILY(e300
)(ObjectClass
*oc
, void *data
)
4674 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4675 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4677 dc
->desc
= "e300 core";
4678 pcc
->init_proc
= init_proc_e300
;
4679 pcc
->check_pow
= check_pow_hid0
;
4680 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4681 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4683 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4684 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4685 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4686 PPC_SEGMENT
| PPC_EXTERN
;
4687 pcc
->msr_mask
= (1ull << MSR_POW
) |
4688 (1ull << MSR_TGPR
) |
4704 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4705 pcc
->excp_model
= POWERPC_EXCP_603
;
4706 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4707 pcc
->bfd_mach
= bfd_mach_ppc_603
;
4708 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4709 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4712 #if !defined(CONFIG_USER_ONLY)
4713 static void spr_write_mas73(DisasContext
*ctx
, int sprn
, int gprn
)
4715 TCGv val
= tcg_temp_new();
4716 tcg_gen_ext32u_tl(val
, cpu_gpr
[gprn
]);
4717 gen_store_spr(SPR_BOOKE_MAS3
, val
);
4718 tcg_gen_shri_tl(val
, cpu_gpr
[gprn
], 32);
4719 gen_store_spr(SPR_BOOKE_MAS7
, val
);
4723 static void spr_read_mas73(DisasContext
*ctx
, int gprn
, int sprn
)
4725 TCGv mas7
= tcg_temp_new();
4726 TCGv mas3
= tcg_temp_new();
4727 gen_load_spr(mas7
, SPR_BOOKE_MAS7
);
4728 tcg_gen_shli_tl(mas7
, mas7
, 32);
4729 gen_load_spr(mas3
, SPR_BOOKE_MAS3
);
4730 tcg_gen_or_tl(cpu_gpr
[gprn
], mas3
, mas7
);
4731 tcg_temp_free(mas3
);
4732 tcg_temp_free(mas7
);
4737 enum fsl_e500_version
{
4745 static void init_proc_e500(CPUPPCState
*env
, int version
)
4747 PowerPCCPU
*cpu
= ppc_env_get_cpu(env
);
4748 uint32_t tlbncfg
[2];
4750 uint64_t ivpr_mask
= 0xFFFF0000ULL
;
4751 uint32_t l1cfg0
= 0x3800 /* 8 ways */
4752 | 0x0020; /* 32 kb */
4753 uint32_t l1cfg1
= 0x3800 /* 8 ways */
4754 | 0x0020; /* 32 kb */
4755 uint32_t mmucfg
= 0;
4756 #if !defined(CONFIG_USER_ONLY)
4763 * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't
4764 * complain when accessing them.
4765 * gen_spr_BookE(env, 0x0000000F0000FD7FULL);
4771 ivor_mask
= 0x0000000F0000FFFFULL
;
4775 ivor_mask
= 0x000003FE0000FFFFULL
;
4778 ivor_mask
= 0x000003FF0000FFFFULL
;
4781 gen_spr_BookE(env
, ivor_mask
);
4782 gen_spr_usprg3(env
);
4783 /* Processor identification */
4784 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4785 SPR_NOACCESS
, SPR_NOACCESS
,
4786 &spr_read_generic
, &spr_write_pir
,
4788 /* XXX : not implemented */
4789 spr_register(env
, SPR_BOOKE_SPEFSCR
, "SPEFSCR",
4790 &spr_read_spefscr
, &spr_write_spefscr
,
4791 &spr_read_spefscr
, &spr_write_spefscr
,
4793 #if !defined(CONFIG_USER_ONLY)
4794 /* Memory management */
4800 tlbncfg
[0] = gen_tlbncfg(2, 1, 1, 0, 256);
4801 tlbncfg
[1] = gen_tlbncfg(16, 1, 9, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 16);
4804 tlbncfg
[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4805 tlbncfg
[1] = gen_tlbncfg(16, 1, 12, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 16);
4809 tlbncfg
[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4810 tlbncfg
[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 64);
4815 tlbncfg
[0] = 0x08052400;
4816 tlbncfg
[1] = 0x40028040;
4819 cpu_abort(CPU(cpu
), "Unknown CPU: " TARGET_FMT_lx
"\n", env
->spr
[SPR_PVR
]);
4826 env
->dcache_line_size
= 32;
4827 env
->icache_line_size
= 32;
4831 env
->dcache_line_size
= 64;
4832 env
->icache_line_size
= 64;
4833 l1cfg0
|= 0x1000000; /* 64 byte cache block size */
4834 l1cfg1
|= 0x1000000; /* 64 byte cache block size */
4837 env
->dcache_line_size
= 32;
4838 env
->icache_line_size
= 32;
4839 l1cfg0
|= 0x0F83820;
4840 l1cfg1
|= 0x0B83820;
4843 cpu_abort(CPU(cpu
), "Unknown CPU: " TARGET_FMT_lx
"\n", env
->spr
[SPR_PVR
]);
4845 gen_spr_BookE206(env
, 0x000000DF, tlbncfg
, mmucfg
);
4846 /* XXX : not implemented */
4847 spr_register(env
, SPR_HID0
, "HID0",
4848 SPR_NOACCESS
, SPR_NOACCESS
,
4849 &spr_read_generic
, &spr_write_generic
,
4851 /* XXX : not implemented */
4852 spr_register(env
, SPR_HID1
, "HID1",
4853 SPR_NOACCESS
, SPR_NOACCESS
,
4854 &spr_read_generic
, &spr_write_generic
,
4856 /* XXX : not implemented */
4857 spr_register(env
, SPR_Exxx_BBEAR
, "BBEAR",
4858 SPR_NOACCESS
, SPR_NOACCESS
,
4859 &spr_read_generic
, &spr_write_generic
,
4861 /* XXX : not implemented */
4862 spr_register(env
, SPR_Exxx_BBTAR
, "BBTAR",
4863 SPR_NOACCESS
, SPR_NOACCESS
,
4864 &spr_read_generic
, &spr_write_generic
,
4866 /* XXX : not implemented */
4867 spr_register(env
, SPR_Exxx_MCAR
, "MCAR",
4868 SPR_NOACCESS
, SPR_NOACCESS
,
4869 &spr_read_generic
, &spr_write_generic
,
4871 /* XXX : not implemented */
4872 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
4873 SPR_NOACCESS
, SPR_NOACCESS
,
4874 &spr_read_generic
, &spr_write_generic
,
4876 /* XXX : not implemented */
4877 spr_register(env
, SPR_Exxx_NPIDR
, "NPIDR",
4878 SPR_NOACCESS
, SPR_NOACCESS
,
4879 &spr_read_generic
, &spr_write_generic
,
4881 /* XXX : not implemented */
4882 spr_register(env
, SPR_Exxx_BUCSR
, "BUCSR",
4883 SPR_NOACCESS
, SPR_NOACCESS
,
4884 &spr_read_generic
, &spr_write_generic
,
4886 /* XXX : not implemented */
4887 spr_register(env
, SPR_Exxx_L1CFG0
, "L1CFG0",
4888 &spr_read_generic
, SPR_NOACCESS
,
4889 &spr_read_generic
, SPR_NOACCESS
,
4891 spr_register(env
, SPR_Exxx_L1CFG1
, "L1CFG1",
4892 &spr_read_generic
, SPR_NOACCESS
,
4893 &spr_read_generic
, SPR_NOACCESS
,
4895 spr_register(env
, SPR_Exxx_L1CSR0
, "L1CSR0",
4896 SPR_NOACCESS
, SPR_NOACCESS
,
4897 &spr_read_generic
, &spr_write_e500_l1csr0
,
4899 spr_register(env
, SPR_Exxx_L1CSR1
, "L1CSR1",
4900 SPR_NOACCESS
, SPR_NOACCESS
,
4901 &spr_read_generic
, &spr_write_e500_l1csr1
,
4903 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
4904 SPR_NOACCESS
, SPR_NOACCESS
,
4905 &spr_read_generic
, &spr_write_generic
,
4907 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
4908 SPR_NOACCESS
, SPR_NOACCESS
,
4909 &spr_read_generic
, &spr_write_generic
,
4911 spr_register(env
, SPR_MMUCSR0
, "MMUCSR0",
4912 SPR_NOACCESS
, SPR_NOACCESS
,
4913 &spr_read_generic
, &spr_write_booke206_mmucsr0
,
4915 spr_register(env
, SPR_BOOKE_EPR
, "EPR",
4916 SPR_NOACCESS
, SPR_NOACCESS
,
4917 &spr_read_generic
, SPR_NOACCESS
,
4919 /* XXX better abstract into Emb.xxx features */
4920 if ((version
== fsl_e5500
) || (version
== fsl_e6500
)) {
4921 spr_register(env
, SPR_BOOKE_EPCR
, "EPCR",
4922 SPR_NOACCESS
, SPR_NOACCESS
,
4923 &spr_read_generic
, &spr_write_generic
,
4925 spr_register(env
, SPR_BOOKE_MAS7_MAS3
, "MAS7_MAS3",
4926 SPR_NOACCESS
, SPR_NOACCESS
,
4927 &spr_read_mas73
, &spr_write_mas73
,
4929 ivpr_mask
= (target_ulong
)~0xFFFFULL
;
4932 if (version
== fsl_e6500
) {
4933 spr_register(env
, SPR_BOOKE_SPRG8
, "SPRG8",
4934 SPR_NOACCESS
, SPR_NOACCESS
,
4935 &spr_read_generic
, &spr_write_generic
,
4937 spr_register(env
, SPR_BOOKE_SPRG9
, "SPRG9",
4938 SPR_NOACCESS
, SPR_NOACCESS
,
4939 &spr_read_generic
, &spr_write_generic
,
4941 /* Thread identification */
4942 spr_register(env
, SPR_TIR
, "TIR",
4943 SPR_NOACCESS
, SPR_NOACCESS
,
4944 &spr_read_generic
, SPR_NOACCESS
,
4946 spr_register(env
, SPR_BOOKE_TLB0PS
, "TLB0PS",
4947 SPR_NOACCESS
, SPR_NOACCESS
,
4948 &spr_read_generic
, SPR_NOACCESS
,
4950 spr_register(env
, SPR_BOOKE_TLB1PS
, "TLB1PS",
4951 SPR_NOACCESS
, SPR_NOACCESS
,
4952 &spr_read_generic
, SPR_NOACCESS
,
4956 #if !defined(CONFIG_USER_ONLY)
4958 env
->tlb_type
= TLB_MAS
;
4959 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
4960 env
->nb_tlb
+= booke206_tlb_size(env
, i
);
4964 init_excp_e200(env
, ivpr_mask
);
4965 /* Allocate hardware IRQ controller */
4966 ppce500_irq_init(ppc_env_get_cpu(env
));
4969 static void init_proc_e500v1(CPUPPCState
*env
)
4971 init_proc_e500(env
, fsl_e500v1
);
4974 POWERPC_FAMILY(e500v1
)(ObjectClass
*oc
, void *data
)
4976 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4977 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4979 dc
->desc
= "e500v1 core";
4980 pcc
->init_proc
= init_proc_e500v1
;
4981 pcc
->check_pow
= check_pow_hid0
;
4982 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
4983 PPC_SPE
| PPC_SPE_SINGLE
|
4984 PPC_WRTEE
| PPC_RFDI
|
4985 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
4986 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4987 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
4988 pcc
->insns_flags2
= PPC2_BOOKE206
;
4989 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
5003 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5004 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5005 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5006 pcc
->bfd_mach
= bfd_mach_ppc_860
;
5007 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
5008 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
5009 POWERPC_FLAG_BUS_CLK
;
5012 static void init_proc_e500v2(CPUPPCState
*env
)
5014 init_proc_e500(env
, fsl_e500v2
);
5017 POWERPC_FAMILY(e500v2
)(ObjectClass
*oc
, void *data
)
5019 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5020 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5022 dc
->desc
= "e500v2 core";
5023 pcc
->init_proc
= init_proc_e500v2
;
5024 pcc
->check_pow
= check_pow_hid0
;
5025 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
5026 PPC_SPE
| PPC_SPE_SINGLE
| PPC_SPE_DOUBLE
|
5027 PPC_WRTEE
| PPC_RFDI
|
5028 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5029 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5030 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5031 pcc
->insns_flags2
= PPC2_BOOKE206
;
5032 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
5046 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5047 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5048 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5049 pcc
->bfd_mach
= bfd_mach_ppc_860
;
5050 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
5051 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
5052 POWERPC_FLAG_BUS_CLK
;
5055 static void init_proc_e500mc(CPUPPCState
*env
)
5057 init_proc_e500(env
, fsl_e500mc
);
5060 POWERPC_FAMILY(e500mc
)(ObjectClass
*oc
, void *data
)
5062 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5063 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5065 dc
->desc
= "e500mc core";
5066 pcc
->init_proc
= init_proc_e500mc
;
5067 pcc
->check_pow
= check_pow_none
;
5068 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5069 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5070 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5071 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5072 PPC_FLOAT
| PPC_FLOAT_FRES
|
5073 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5074 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5075 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5076 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
;
5077 pcc
->msr_mask
= (1ull << MSR_GS
) |
5078 (1ull << MSR_UCLE
) |
5091 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5092 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5093 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5094 /* FIXME: figure out the correct flag for e500mc */
5095 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5096 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5097 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5101 static void init_proc_e5500(CPUPPCState
*env
)
5103 init_proc_e500(env
, fsl_e5500
);
5106 POWERPC_FAMILY(e5500
)(ObjectClass
*oc
, void *data
)
5108 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5109 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5111 dc
->desc
= "e5500 core";
5112 pcc
->init_proc
= init_proc_e5500
;
5113 pcc
->check_pow
= check_pow_none
;
5114 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5115 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5116 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5117 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5118 PPC_FLOAT
| PPC_FLOAT_FRES
|
5119 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5120 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5121 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
|
5122 PPC_64B
| PPC_POPCNTB
| PPC_POPCNTWD
;
5123 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
| PPC2_PERM_ISA206
| \
5125 pcc
->msr_mask
= (1ull << MSR_CM
) |
5127 (1ull << MSR_UCLE
) |
5140 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5141 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5142 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5143 /* FIXME: figure out the correct flag for e5500 */
5144 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5145 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5146 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5149 static void init_proc_e6500(CPUPPCState
*env
)
5151 init_proc_e500(env
, fsl_e6500
);
5154 POWERPC_FAMILY(e6500
)(ObjectClass
*oc
, void *data
)
5156 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5157 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5159 dc
->desc
= "e6500 core";
5160 pcc
->init_proc
= init_proc_e6500
;
5161 pcc
->check_pow
= check_pow_none
;
5162 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5163 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5164 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5165 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5166 PPC_FLOAT
| PPC_FLOAT_FRES
|
5167 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5168 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5169 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
|
5170 PPC_64B
| PPC_POPCNTB
| PPC_POPCNTWD
| PPC_ALTIVEC
;
5171 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
| PPC2_PERM_ISA206
| \
5172 PPC2_FP_CVT_S64
| PPC2_ATOMIC_ISA206
;
5173 pcc
->msr_mask
= (1ull << MSR_CM
) |
5175 (1ull << MSR_UCLE
) |
5189 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5190 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5191 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5192 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5193 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5194 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_VRE
;
5199 /* Non-embedded PowerPC */
5201 #define POWERPC_MSRR_601 (0x0000000000001040ULL)
5203 static void init_proc_601(CPUPPCState
*env
)
5205 gen_spr_ne_601(env
);
5208 /* Hardware implementation registers */
5209 /* XXX : not implemented */
5210 spr_register(env
, SPR_HID0
, "HID0",
5211 SPR_NOACCESS
, SPR_NOACCESS
,
5212 &spr_read_generic
, &spr_write_hid0_601
,
5214 /* XXX : not implemented */
5215 spr_register(env
, SPR_HID1
, "HID1",
5216 SPR_NOACCESS
, SPR_NOACCESS
,
5217 &spr_read_generic
, &spr_write_generic
,
5219 /* XXX : not implemented */
5220 spr_register(env
, SPR_601_HID2
, "HID2",
5221 SPR_NOACCESS
, SPR_NOACCESS
,
5222 &spr_read_generic
, &spr_write_generic
,
5224 /* XXX : not implemented */
5225 spr_register(env
, SPR_601_HID5
, "HID5",
5226 SPR_NOACCESS
, SPR_NOACCESS
,
5227 &spr_read_generic
, &spr_write_generic
,
5229 /* Memory management */
5231 /* XXX: beware that dcache line size is 64
5232 * but dcbz uses 32 bytes "sectors"
5233 * XXX: this breaks clcs instruction !
5235 env
->dcache_line_size
= 32;
5236 env
->icache_line_size
= 64;
5237 /* Allocate hardware IRQ controller */
5238 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5241 POWERPC_FAMILY(601)(ObjectClass
*oc
, void *data
)
5243 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5244 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5246 dc
->desc
= "PowerPC 601";
5247 pcc
->init_proc
= init_proc_601
;
5248 pcc
->check_pow
= check_pow_none
;
5249 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_POWER_BR
|
5251 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5252 PPC_MEM_SYNC
| PPC_MEM_EIEIO
| PPC_MEM_TLBIE
|
5253 PPC_SEGMENT
| PPC_EXTERN
;
5254 pcc
->msr_mask
= (1ull << MSR_EE
) |
5264 pcc
->mmu_model
= POWERPC_MMU_601
;
5265 #if defined(CONFIG_SOFTMMU)
5266 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5268 pcc
->excp_model
= POWERPC_EXCP_601
;
5269 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5270 pcc
->bfd_mach
= bfd_mach_ppc_601
;
5271 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_RTC_CLK
;
5274 #define POWERPC_MSRR_601v (0x0000000000001040ULL)
5276 static void init_proc_601v(CPUPPCState
*env
)
5279 /* XXX : not implemented */
5280 spr_register(env
, SPR_601_HID15
, "HID15",
5281 SPR_NOACCESS
, SPR_NOACCESS
,
5282 &spr_read_generic
, &spr_write_generic
,
5286 POWERPC_FAMILY(601v
)(ObjectClass
*oc
, void *data
)
5288 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5289 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5291 dc
->desc
= "PowerPC 601v";
5292 pcc
->init_proc
= init_proc_601v
;
5293 pcc
->check_pow
= check_pow_none
;
5294 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_POWER_BR
|
5296 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5297 PPC_MEM_SYNC
| PPC_MEM_EIEIO
| PPC_MEM_TLBIE
|
5298 PPC_SEGMENT
| PPC_EXTERN
;
5299 pcc
->msr_mask
= (1ull << MSR_EE
) |
5309 pcc
->mmu_model
= POWERPC_MMU_601
;
5310 #if defined(CONFIG_SOFTMMU)
5311 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5313 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5314 pcc
->bfd_mach
= bfd_mach_ppc_601
;
5315 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_RTC_CLK
;
5318 static void init_proc_602(CPUPPCState
*env
)
5320 gen_spr_ne_601(env
);
5325 /* hardware implementation registers */
5326 /* XXX : not implemented */
5327 spr_register(env
, SPR_HID0
, "HID0",
5328 SPR_NOACCESS
, SPR_NOACCESS
,
5329 &spr_read_generic
, &spr_write_generic
,
5331 /* XXX : not implemented */
5332 spr_register(env
, SPR_HID1
, "HID1",
5333 SPR_NOACCESS
, SPR_NOACCESS
,
5334 &spr_read_generic
, &spr_write_generic
,
5336 /* Memory management */
5338 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5340 env
->dcache_line_size
= 32;
5341 env
->icache_line_size
= 32;
5342 /* Allocate hardware IRQ controller */
5343 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5346 POWERPC_FAMILY(602)(ObjectClass
*oc
, void *data
)
5348 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5349 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5351 dc
->desc
= "PowerPC 602";
5352 pcc
->init_proc
= init_proc_602
;
5353 pcc
->check_pow
= check_pow_hid0
;
5354 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5355 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5356 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5357 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5358 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5359 PPC_MEM_TLBIE
| PPC_6xx_TLB
| PPC_MEM_TLBSYNC
|
5360 PPC_SEGMENT
| PPC_602_SPEC
;
5361 pcc
->msr_mask
= (1ull << MSR_VSX
) |
5364 (1ull << MSR_TGPR
) |
5379 /* XXX: 602 MMU is quite specific. Should add a special case */
5380 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5381 pcc
->excp_model
= POWERPC_EXCP_602
;
5382 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5383 pcc
->bfd_mach
= bfd_mach_ppc_602
;
5384 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5385 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5388 static void init_proc_603(CPUPPCState
*env
)
5390 gen_spr_ne_601(env
);
5395 /* hardware implementation registers */
5396 /* XXX : not implemented */
5397 spr_register(env
, SPR_HID0
, "HID0",
5398 SPR_NOACCESS
, SPR_NOACCESS
,
5399 &spr_read_generic
, &spr_write_generic
,
5401 /* XXX : not implemented */
5402 spr_register(env
, SPR_HID1
, "HID1",
5403 SPR_NOACCESS
, SPR_NOACCESS
,
5404 &spr_read_generic
, &spr_write_generic
,
5406 /* Memory management */
5408 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5410 env
->dcache_line_size
= 32;
5411 env
->icache_line_size
= 32;
5412 /* Allocate hardware IRQ controller */
5413 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5416 POWERPC_FAMILY(603)(ObjectClass
*oc
, void *data
)
5418 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5419 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5421 dc
->desc
= "PowerPC 603";
5422 pcc
->init_proc
= init_proc_603
;
5423 pcc
->check_pow
= check_pow_hid0
;
5424 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5425 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5426 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5427 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5428 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5429 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
5430 PPC_SEGMENT
| PPC_EXTERN
;
5431 pcc
->msr_mask
= (1ull << MSR_POW
) |
5432 (1ull << MSR_TGPR
) |
5447 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5448 pcc
->excp_model
= POWERPC_EXCP_603
;
5449 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5450 pcc
->bfd_mach
= bfd_mach_ppc_603
;
5451 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5452 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5455 static void init_proc_603E(CPUPPCState
*env
)
5457 gen_spr_ne_601(env
);
5462 /* hardware implementation registers */
5463 /* XXX : not implemented */
5464 spr_register(env
, SPR_HID0
, "HID0",
5465 SPR_NOACCESS
, SPR_NOACCESS
,
5466 &spr_read_generic
, &spr_write_generic
,
5468 /* XXX : not implemented */
5469 spr_register(env
, SPR_HID1
, "HID1",
5470 SPR_NOACCESS
, SPR_NOACCESS
,
5471 &spr_read_generic
, &spr_write_generic
,
5473 /* Memory management */
5475 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5477 env
->dcache_line_size
= 32;
5478 env
->icache_line_size
= 32;
5479 /* Allocate hardware IRQ controller */
5480 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5483 POWERPC_FAMILY(603E
)(ObjectClass
*oc
, void *data
)
5485 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5486 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5488 dc
->desc
= "PowerPC 603e";
5489 pcc
->init_proc
= init_proc_603E
;
5490 pcc
->check_pow
= check_pow_hid0
;
5491 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5492 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5493 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5494 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5495 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5496 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
5497 PPC_SEGMENT
| PPC_EXTERN
;
5498 pcc
->msr_mask
= (1ull << MSR_POW
) |
5499 (1ull << MSR_TGPR
) |
5514 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5515 pcc
->excp_model
= POWERPC_EXCP_603E
;
5516 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5517 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
5518 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5519 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5522 static void init_proc_604(CPUPPCState
*env
)
5524 gen_spr_ne_601(env
);
5529 /* Hardware implementation registers */
5530 /* XXX : not implemented */
5531 spr_register(env
, SPR_HID0
, "HID0",
5532 SPR_NOACCESS
, SPR_NOACCESS
,
5533 &spr_read_generic
, &spr_write_generic
,
5535 /* Memory management */
5538 env
->dcache_line_size
= 32;
5539 env
->icache_line_size
= 32;
5540 /* Allocate hardware IRQ controller */
5541 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5544 POWERPC_FAMILY(604)(ObjectClass
*oc
, void *data
)
5546 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5547 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5549 dc
->desc
= "PowerPC 604";
5550 pcc
->init_proc
= init_proc_604
;
5551 pcc
->check_pow
= check_pow_nocheck
;
5552 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5553 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5554 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5555 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5556 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5557 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5558 PPC_SEGMENT
| PPC_EXTERN
;
5559 pcc
->msr_mask
= (1ull << MSR_POW
) |
5575 pcc
->mmu_model
= POWERPC_MMU_32B
;
5576 #if defined(CONFIG_SOFTMMU)
5577 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5579 pcc
->excp_model
= POWERPC_EXCP_604
;
5580 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5581 pcc
->bfd_mach
= bfd_mach_ppc_604
;
5582 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5583 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5586 static void init_proc_604E(CPUPPCState
*env
)
5588 gen_spr_ne_601(env
);
5591 /* XXX : not implemented */
5592 spr_register(env
, SPR_7XX_MMCR1
, "MMCR1",
5593 SPR_NOACCESS
, SPR_NOACCESS
,
5594 &spr_read_generic
, &spr_write_generic
,
5596 /* XXX : not implemented */
5597 spr_register(env
, SPR_7XX_PMC3
, "PMC3",
5598 SPR_NOACCESS
, SPR_NOACCESS
,
5599 &spr_read_generic
, &spr_write_generic
,
5601 /* XXX : not implemented */
5602 spr_register(env
, SPR_7XX_PMC4
, "PMC4",
5603 SPR_NOACCESS
, SPR_NOACCESS
,
5604 &spr_read_generic
, &spr_write_generic
,
5608 /* Hardware implementation registers */
5609 /* XXX : not implemented */
5610 spr_register(env
, SPR_HID0
, "HID0",
5611 SPR_NOACCESS
, SPR_NOACCESS
,
5612 &spr_read_generic
, &spr_write_generic
,
5614 /* XXX : not implemented */
5615 spr_register(env
, SPR_HID1
, "HID1",
5616 SPR_NOACCESS
, SPR_NOACCESS
,
5617 &spr_read_generic
, &spr_write_generic
,
5619 /* Memory management */
5622 env
->dcache_line_size
= 32;
5623 env
->icache_line_size
= 32;
5624 /* Allocate hardware IRQ controller */
5625 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5628 POWERPC_FAMILY(604E
)(ObjectClass
*oc
, void *data
)
5630 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5631 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5633 dc
->desc
= "PowerPC 604E";
5634 pcc
->init_proc
= init_proc_604E
;
5635 pcc
->check_pow
= check_pow_nocheck
;
5636 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5637 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5638 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5639 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5640 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5641 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5642 PPC_SEGMENT
| PPC_EXTERN
;
5643 pcc
->msr_mask
= (1ull << MSR_POW
) |
5659 pcc
->mmu_model
= POWERPC_MMU_32B
;
5660 #if defined(CONFIG_SOFTMMU)
5661 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5663 pcc
->excp_model
= POWERPC_EXCP_604
;
5664 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5665 pcc
->bfd_mach
= bfd_mach_ppc_604
;
5666 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5667 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5670 static void init_proc_740(CPUPPCState
*env
)
5672 gen_spr_ne_601(env
);
5677 /* Thermal management */
5679 /* Hardware implementation registers */
5680 /* XXX : not implemented */
5681 spr_register(env
, SPR_HID0
, "HID0",
5682 SPR_NOACCESS
, SPR_NOACCESS
,
5683 &spr_read_generic
, &spr_write_generic
,
5685 /* XXX : not implemented */
5686 spr_register(env
, SPR_HID1
, "HID1",
5687 SPR_NOACCESS
, SPR_NOACCESS
,
5688 &spr_read_generic
, &spr_write_generic
,
5690 /* Memory management */
5693 env
->dcache_line_size
= 32;
5694 env
->icache_line_size
= 32;
5695 /* Allocate hardware IRQ controller */
5696 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5699 POWERPC_FAMILY(740)(ObjectClass
*oc
, void *data
)
5701 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5702 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5704 dc
->desc
= "PowerPC 740";
5705 pcc
->init_proc
= init_proc_740
;
5706 pcc
->check_pow
= check_pow_hid0
;
5707 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5708 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5709 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5710 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5711 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5712 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5713 PPC_SEGMENT
| PPC_EXTERN
;
5714 pcc
->msr_mask
= (1ull << MSR_POW
) |
5730 pcc
->mmu_model
= POWERPC_MMU_32B
;
5731 #if defined(CONFIG_SOFTMMU)
5732 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5734 pcc
->excp_model
= POWERPC_EXCP_7x0
;
5735 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5736 pcc
->bfd_mach
= bfd_mach_ppc_750
;
5737 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5738 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5741 static void init_proc_750(CPUPPCState
*env
)
5743 gen_spr_ne_601(env
);
5746 /* XXX : not implemented */
5747 spr_register(env
, SPR_L2CR
, "L2CR",
5748 SPR_NOACCESS
, SPR_NOACCESS
,
5749 &spr_read_generic
, spr_access_nop
,
5753 /* Thermal management */
5755 /* Hardware implementation registers */
5756 /* XXX : not implemented */
5757 spr_register(env
, SPR_HID0
, "HID0",
5758 SPR_NOACCESS
, SPR_NOACCESS
,
5759 &spr_read_generic
, &spr_write_generic
,
5761 /* XXX : not implemented */
5762 spr_register(env
, SPR_HID1
, "HID1",
5763 SPR_NOACCESS
, SPR_NOACCESS
,
5764 &spr_read_generic
, &spr_write_generic
,
5766 /* Memory management */
5768 /* XXX: high BATs are also present but are known to be bugged on
5772 env
->dcache_line_size
= 32;
5773 env
->icache_line_size
= 32;
5774 /* Allocate hardware IRQ controller */
5775 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5778 POWERPC_FAMILY(750)(ObjectClass
*oc
, void *data
)
5780 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5781 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5783 dc
->desc
= "PowerPC 750";
5784 pcc
->init_proc
= init_proc_750
;
5785 pcc
->check_pow
= check_pow_hid0
;
5786 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5787 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5788 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5789 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5790 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5791 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5792 PPC_SEGMENT
| PPC_EXTERN
;
5793 pcc
->msr_mask
= (1ull << MSR_POW
) |
5809 pcc
->mmu_model
= POWERPC_MMU_32B
;
5810 #if defined(CONFIG_SOFTMMU)
5811 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5813 pcc
->excp_model
= POWERPC_EXCP_7x0
;
5814 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5815 pcc
->bfd_mach
= bfd_mach_ppc_750
;
5816 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5817 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5820 static void init_proc_750cl(CPUPPCState
*env
)
5822 gen_spr_ne_601(env
);
5825 /* XXX : not implemented */
5826 spr_register(env
, SPR_L2CR
, "L2CR",
5827 SPR_NOACCESS
, SPR_NOACCESS
,
5828 &spr_read_generic
, spr_access_nop
,
5832 /* Thermal management */
5833 /* Those registers are fake on 750CL */
5834 spr_register(env
, SPR_THRM1
, "THRM1",
5835 SPR_NOACCESS
, SPR_NOACCESS
,
5836 &spr_read_generic
, &spr_write_generic
,
5838 spr_register(env
, SPR_THRM2
, "THRM2",
5839 SPR_NOACCESS
, SPR_NOACCESS
,
5840 &spr_read_generic
, &spr_write_generic
,
5842 spr_register(env
, SPR_THRM3
, "THRM3",
5843 SPR_NOACCESS
, SPR_NOACCESS
,
5844 &spr_read_generic
, &spr_write_generic
,
5846 /* XXX: not implemented */
5847 spr_register(env
, SPR_750_TDCL
, "TDCL",
5848 SPR_NOACCESS
, SPR_NOACCESS
,
5849 &spr_read_generic
, &spr_write_generic
,
5851 spr_register(env
, SPR_750_TDCH
, "TDCH",
5852 SPR_NOACCESS
, SPR_NOACCESS
,
5853 &spr_read_generic
, &spr_write_generic
,
5856 /* XXX : not implemented */
5857 spr_register(env
, SPR_750_WPAR
, "WPAR",
5858 SPR_NOACCESS
, SPR_NOACCESS
,
5859 &spr_read_generic
, &spr_write_generic
,
5861 spr_register(env
, SPR_750_DMAL
, "DMAL",
5862 SPR_NOACCESS
, SPR_NOACCESS
,
5863 &spr_read_generic
, &spr_write_generic
,
5865 spr_register(env
, SPR_750_DMAU
, "DMAU",
5866 SPR_NOACCESS
, SPR_NOACCESS
,
5867 &spr_read_generic
, &spr_write_generic
,
5869 /* Hardware implementation registers */
5870 /* XXX : not implemented */
5871 spr_register(env
, SPR_HID0
, "HID0",
5872 SPR_NOACCESS
, SPR_NOACCESS
,
5873 &spr_read_generic
, &spr_write_generic
,
5875 /* XXX : not implemented */
5876 spr_register(env
, SPR_HID1
, "HID1",
5877 SPR_NOACCESS
, SPR_NOACCESS
,
5878 &spr_read_generic
, &spr_write_generic
,
5880 /* XXX : not implemented */
5881 spr_register(env
, SPR_750CL_HID2
, "HID2",
5882 SPR_NOACCESS
, SPR_NOACCESS
,
5883 &spr_read_generic
, &spr_write_generic
,
5885 /* XXX : not implemented */
5886 spr_register(env
, SPR_750CL_HID4
, "HID4",
5887 SPR_NOACCESS
, SPR_NOACCESS
,
5888 &spr_read_generic
, &spr_write_generic
,
5890 /* Quantization registers */
5891 /* XXX : not implemented */
5892 spr_register(env
, SPR_750_GQR0
, "GQR0",
5893 SPR_NOACCESS
, SPR_NOACCESS
,
5894 &spr_read_generic
, &spr_write_generic
,
5896 /* XXX : not implemented */
5897 spr_register(env
, SPR_750_GQR1
, "GQR1",
5898 SPR_NOACCESS
, SPR_NOACCESS
,
5899 &spr_read_generic
, &spr_write_generic
,
5901 /* XXX : not implemented */
5902 spr_register(env
, SPR_750_GQR2
, "GQR2",
5903 SPR_NOACCESS
, SPR_NOACCESS
,
5904 &spr_read_generic
, &spr_write_generic
,
5906 /* XXX : not implemented */
5907 spr_register(env
, SPR_750_GQR3
, "GQR3",
5908 SPR_NOACCESS
, SPR_NOACCESS
,
5909 &spr_read_generic
, &spr_write_generic
,
5911 /* XXX : not implemented */
5912 spr_register(env
, SPR_750_GQR4
, "GQR4",
5913 SPR_NOACCESS
, SPR_NOACCESS
,
5914 &spr_read_generic
, &spr_write_generic
,
5916 /* XXX : not implemented */
5917 spr_register(env
, SPR_750_GQR5
, "GQR5",
5918 SPR_NOACCESS
, SPR_NOACCESS
,
5919 &spr_read_generic
, &spr_write_generic
,
5921 /* XXX : not implemented */
5922 spr_register(env
, SPR_750_GQR6
, "GQR6",
5923 SPR_NOACCESS
, SPR_NOACCESS
,
5924 &spr_read_generic
, &spr_write_generic
,
5926 /* XXX : not implemented */
5927 spr_register(env
, SPR_750_GQR7
, "GQR7",
5928 SPR_NOACCESS
, SPR_NOACCESS
,
5929 &spr_read_generic
, &spr_write_generic
,
5931 /* Memory management */
5933 /* PowerPC 750cl has 8 DBATs and 8 IBATs */
5935 init_excp_750cl(env
);
5936 env
->dcache_line_size
= 32;
5937 env
->icache_line_size
= 32;
5938 /* Allocate hardware IRQ controller */
5939 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5942 POWERPC_FAMILY(750cl
)(ObjectClass
*oc
, void *data
)
5944 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5945 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5947 dc
->desc
= "PowerPC 750 CL";
5948 pcc
->init_proc
= init_proc_750cl
;
5949 pcc
->check_pow
= check_pow_hid0
;
5950 /* XXX: not implemented:
5951 * cache lock instructions:
5953 * floating point paired instructions
5988 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5989 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5990 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5991 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5992 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5993 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5994 PPC_SEGMENT
| PPC_EXTERN
;
5995 pcc
->msr_mask
= (1ull << MSR_POW
) |
6011 pcc
->mmu_model
= POWERPC_MMU_32B
;
6012 #if defined(CONFIG_SOFTMMU)
6013 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6015 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6016 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6017 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6018 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6019 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6022 static void init_proc_750cx(CPUPPCState
*env
)
6024 gen_spr_ne_601(env
);
6027 /* XXX : not implemented */
6028 spr_register(env
, SPR_L2CR
, "L2CR",
6029 SPR_NOACCESS
, SPR_NOACCESS
,
6030 &spr_read_generic
, spr_access_nop
,
6034 /* Thermal management */
6036 /* This register is not implemented but is present for compatibility */
6037 spr_register(env
, SPR_SDA
, "SDA",
6038 SPR_NOACCESS
, SPR_NOACCESS
,
6039 &spr_read_generic
, &spr_write_generic
,
6041 /* Hardware implementation registers */
6042 /* XXX : not implemented */
6043 spr_register(env
, SPR_HID0
, "HID0",
6044 SPR_NOACCESS
, SPR_NOACCESS
,
6045 &spr_read_generic
, &spr_write_generic
,
6047 /* XXX : not implemented */
6048 spr_register(env
, SPR_HID1
, "HID1",
6049 SPR_NOACCESS
, SPR_NOACCESS
,
6050 &spr_read_generic
, &spr_write_generic
,
6052 /* Memory management */
6054 /* PowerPC 750cx has 8 DBATs and 8 IBATs */
6056 init_excp_750cx(env
);
6057 env
->dcache_line_size
= 32;
6058 env
->icache_line_size
= 32;
6059 /* Allocate hardware IRQ controller */
6060 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6063 POWERPC_FAMILY(750cx
)(ObjectClass
*oc
, void *data
)
6065 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6066 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6068 dc
->desc
= "PowerPC 750CX";
6069 pcc
->init_proc
= init_proc_750cx
;
6070 pcc
->check_pow
= check_pow_hid0
;
6071 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6072 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6073 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6074 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6075 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6076 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6077 PPC_SEGMENT
| PPC_EXTERN
;
6078 pcc
->msr_mask
= (1ull << MSR_POW
) |
6094 pcc
->mmu_model
= POWERPC_MMU_32B
;
6095 #if defined(CONFIG_SOFTMMU)
6096 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6098 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6099 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6100 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6101 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6102 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6105 static void init_proc_750fx(CPUPPCState
*env
)
6107 gen_spr_ne_601(env
);
6110 /* XXX : not implemented */
6111 spr_register(env
, SPR_L2CR
, "L2CR",
6112 SPR_NOACCESS
, SPR_NOACCESS
,
6113 &spr_read_generic
, spr_access_nop
,
6117 /* Thermal management */
6119 /* XXX : not implemented */
6120 spr_register(env
, SPR_750_THRM4
, "THRM4",
6121 SPR_NOACCESS
, SPR_NOACCESS
,
6122 &spr_read_generic
, &spr_write_generic
,
6124 /* Hardware implementation registers */
6125 /* XXX : not implemented */
6126 spr_register(env
, SPR_HID0
, "HID0",
6127 SPR_NOACCESS
, SPR_NOACCESS
,
6128 &spr_read_generic
, &spr_write_generic
,
6130 /* XXX : not implemented */
6131 spr_register(env
, SPR_HID1
, "HID1",
6132 SPR_NOACCESS
, SPR_NOACCESS
,
6133 &spr_read_generic
, &spr_write_generic
,
6135 /* XXX : not implemented */
6136 spr_register(env
, SPR_750FX_HID2
, "HID2",
6137 SPR_NOACCESS
, SPR_NOACCESS
,
6138 &spr_read_generic
, &spr_write_generic
,
6140 /* Memory management */
6142 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6145 env
->dcache_line_size
= 32;
6146 env
->icache_line_size
= 32;
6147 /* Allocate hardware IRQ controller */
6148 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6151 POWERPC_FAMILY(750fx
)(ObjectClass
*oc
, void *data
)
6153 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6154 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6156 dc
->desc
= "PowerPC 750FX";
6157 pcc
->init_proc
= init_proc_750fx
;
6158 pcc
->check_pow
= check_pow_hid0
;
6159 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6160 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6161 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6162 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6163 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6164 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6165 PPC_SEGMENT
| PPC_EXTERN
;
6166 pcc
->msr_mask
= (1ull << MSR_POW
) |
6182 pcc
->mmu_model
= POWERPC_MMU_32B
;
6183 #if defined(CONFIG_SOFTMMU)
6184 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6186 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6187 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6188 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6189 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6190 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6193 static void init_proc_750gx(CPUPPCState
*env
)
6195 gen_spr_ne_601(env
);
6198 /* XXX : not implemented (XXX: different from 750fx) */
6199 spr_register(env
, SPR_L2CR
, "L2CR",
6200 SPR_NOACCESS
, SPR_NOACCESS
,
6201 &spr_read_generic
, spr_access_nop
,
6205 /* Thermal management */
6207 /* XXX : not implemented */
6208 spr_register(env
, SPR_750_THRM4
, "THRM4",
6209 SPR_NOACCESS
, SPR_NOACCESS
,
6210 &spr_read_generic
, &spr_write_generic
,
6212 /* Hardware implementation registers */
6213 /* XXX : not implemented (XXX: different from 750fx) */
6214 spr_register(env
, SPR_HID0
, "HID0",
6215 SPR_NOACCESS
, SPR_NOACCESS
,
6216 &spr_read_generic
, &spr_write_generic
,
6218 /* XXX : not implemented */
6219 spr_register(env
, SPR_HID1
, "HID1",
6220 SPR_NOACCESS
, SPR_NOACCESS
,
6221 &spr_read_generic
, &spr_write_generic
,
6223 /* XXX : not implemented (XXX: different from 750fx) */
6224 spr_register(env
, SPR_750FX_HID2
, "HID2",
6225 SPR_NOACCESS
, SPR_NOACCESS
,
6226 &spr_read_generic
, &spr_write_generic
,
6228 /* Memory management */
6230 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6233 env
->dcache_line_size
= 32;
6234 env
->icache_line_size
= 32;
6235 /* Allocate hardware IRQ controller */
6236 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6239 POWERPC_FAMILY(750gx
)(ObjectClass
*oc
, void *data
)
6241 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6242 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6244 dc
->desc
= "PowerPC 750GX";
6245 pcc
->init_proc
= init_proc_750gx
;
6246 pcc
->check_pow
= check_pow_hid0
;
6247 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6248 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6249 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6250 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6251 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6252 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6253 PPC_SEGMENT
| PPC_EXTERN
;
6254 pcc
->msr_mask
= (1ull << MSR_POW
) |
6270 pcc
->mmu_model
= POWERPC_MMU_32B
;
6271 #if defined(CONFIG_SOFTMMU)
6272 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6274 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6275 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6276 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6277 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6278 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6281 static void init_proc_745(CPUPPCState
*env
)
6283 gen_spr_ne_601(env
);
6286 gen_spr_G2_755(env
);
6289 /* Thermal management */
6291 /* Hardware implementation registers */
6292 /* XXX : not implemented */
6293 spr_register(env
, SPR_HID0
, "HID0",
6294 SPR_NOACCESS
, SPR_NOACCESS
,
6295 &spr_read_generic
, &spr_write_generic
,
6297 /* XXX : not implemented */
6298 spr_register(env
, SPR_HID1
, "HID1",
6299 SPR_NOACCESS
, SPR_NOACCESS
,
6300 &spr_read_generic
, &spr_write_generic
,
6302 /* XXX : not implemented */
6303 spr_register(env
, SPR_HID2
, "HID2",
6304 SPR_NOACCESS
, SPR_NOACCESS
,
6305 &spr_read_generic
, &spr_write_generic
,
6307 /* Memory management */
6310 gen_6xx_7xx_soft_tlb(env
, 64, 2);
6312 env
->dcache_line_size
= 32;
6313 env
->icache_line_size
= 32;
6314 /* Allocate hardware IRQ controller */
6315 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6318 POWERPC_FAMILY(745)(ObjectClass
*oc
, void *data
)
6320 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6321 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6323 dc
->desc
= "PowerPC 745";
6324 pcc
->init_proc
= init_proc_745
;
6325 pcc
->check_pow
= check_pow_hid0
;
6326 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6327 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6328 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6329 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6330 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6331 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
6332 PPC_SEGMENT
| PPC_EXTERN
;
6333 pcc
->msr_mask
= (1ull << MSR_POW
) |
6349 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
6350 pcc
->excp_model
= POWERPC_EXCP_7x5
;
6351 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6352 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6353 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6354 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6357 static void init_proc_755(CPUPPCState
*env
)
6359 gen_spr_ne_601(env
);
6362 gen_spr_G2_755(env
);
6365 /* L2 cache control */
6366 /* XXX : not implemented */
6367 spr_register(env
, SPR_L2CR
, "L2CR",
6368 SPR_NOACCESS
, SPR_NOACCESS
,
6369 &spr_read_generic
, spr_access_nop
,
6371 /* XXX : not implemented */
6372 spr_register(env
, SPR_L2PMCR
, "L2PMCR",
6373 SPR_NOACCESS
, SPR_NOACCESS
,
6374 &spr_read_generic
, &spr_write_generic
,
6376 /* Thermal management */
6378 /* Hardware implementation registers */
6379 /* XXX : not implemented */
6380 spr_register(env
, SPR_HID0
, "HID0",
6381 SPR_NOACCESS
, SPR_NOACCESS
,
6382 &spr_read_generic
, &spr_write_generic
,
6384 /* XXX : not implemented */
6385 spr_register(env
, SPR_HID1
, "HID1",
6386 SPR_NOACCESS
, SPR_NOACCESS
,
6387 &spr_read_generic
, &spr_write_generic
,
6389 /* XXX : not implemented */
6390 spr_register(env
, SPR_HID2
, "HID2",
6391 SPR_NOACCESS
, SPR_NOACCESS
,
6392 &spr_read_generic
, &spr_write_generic
,
6394 /* Memory management */
6397 gen_6xx_7xx_soft_tlb(env
, 64, 2);
6399 env
->dcache_line_size
= 32;
6400 env
->icache_line_size
= 32;
6401 /* Allocate hardware IRQ controller */
6402 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6405 POWERPC_FAMILY(755)(ObjectClass
*oc
, void *data
)
6407 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6408 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6410 dc
->desc
= "PowerPC 755";
6411 pcc
->init_proc
= init_proc_755
;
6412 pcc
->check_pow
= check_pow_hid0
;
6413 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6414 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6415 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6416 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6417 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6418 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
6419 PPC_SEGMENT
| PPC_EXTERN
;
6420 pcc
->msr_mask
= (1ull << MSR_POW
) |
6436 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
6437 pcc
->excp_model
= POWERPC_EXCP_7x5
;
6438 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6439 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6440 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6441 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6444 static void init_proc_7400(CPUPPCState
*env
)
6446 gen_spr_ne_601(env
);
6451 /* 74xx specific SPR */
6453 /* XXX : not implemented */
6454 spr_register(env
, SPR_UBAMR
, "UBAMR",
6455 &spr_read_ureg
, SPR_NOACCESS
,
6456 &spr_read_ureg
, SPR_NOACCESS
,
6458 /* XXX: this seems not implemented on all revisions. */
6459 /* XXX : not implemented */
6460 spr_register(env
, SPR_MSSCR1
, "MSSCR1",
6461 SPR_NOACCESS
, SPR_NOACCESS
,
6462 &spr_read_generic
, &spr_write_generic
,
6464 /* Thermal management */
6466 /* Memory management */
6468 init_excp_7400(env
);
6469 env
->dcache_line_size
= 32;
6470 env
->icache_line_size
= 32;
6471 /* Allocate hardware IRQ controller */
6472 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6475 POWERPC_FAMILY(7400)(ObjectClass
*oc
, void *data
)
6477 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6478 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6480 dc
->desc
= "PowerPC 7400 (aka G4)";
6481 pcc
->init_proc
= init_proc_7400
;
6482 pcc
->check_pow
= check_pow_hid0
;
6483 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6484 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6485 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6487 PPC_CACHE
| PPC_CACHE_ICBI
|
6488 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6489 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6490 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6492 PPC_SEGMENT
| PPC_EXTERN
|
6494 pcc
->msr_mask
= (1ull << MSR_VR
) |
6511 pcc
->mmu_model
= POWERPC_MMU_32B
;
6512 #if defined(CONFIG_SOFTMMU)
6513 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6515 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6516 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6517 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6518 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6519 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6520 POWERPC_FLAG_BUS_CLK
;
6523 static void init_proc_7410(CPUPPCState
*env
)
6525 gen_spr_ne_601(env
);
6530 /* 74xx specific SPR */
6532 /* XXX : not implemented */
6533 spr_register(env
, SPR_UBAMR
, "UBAMR",
6534 &spr_read_ureg
, SPR_NOACCESS
,
6535 &spr_read_ureg
, SPR_NOACCESS
,
6537 /* Thermal management */
6540 /* XXX : not implemented */
6541 spr_register(env
, SPR_L2PMCR
, "L2PMCR",
6542 SPR_NOACCESS
, SPR_NOACCESS
,
6543 &spr_read_generic
, &spr_write_generic
,
6546 /* XXX : not implemented */
6547 spr_register(env
, SPR_LDSTDB
, "LDSTDB",
6548 SPR_NOACCESS
, SPR_NOACCESS
,
6549 &spr_read_generic
, &spr_write_generic
,
6551 /* Memory management */
6553 init_excp_7400(env
);
6554 env
->dcache_line_size
= 32;
6555 env
->icache_line_size
= 32;
6556 /* Allocate hardware IRQ controller */
6557 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6560 POWERPC_FAMILY(7410)(ObjectClass
*oc
, void *data
)
6562 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6563 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6565 dc
->desc
= "PowerPC 7410 (aka G4)";
6566 pcc
->init_proc
= init_proc_7410
;
6567 pcc
->check_pow
= check_pow_hid0
;
6568 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6569 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6570 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6572 PPC_CACHE
| PPC_CACHE_ICBI
|
6573 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6574 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6575 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6577 PPC_SEGMENT
| PPC_EXTERN
|
6579 pcc
->msr_mask
= (1ull << MSR_VR
) |
6596 pcc
->mmu_model
= POWERPC_MMU_32B
;
6597 #if defined(CONFIG_SOFTMMU)
6598 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6600 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6601 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6602 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6603 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6604 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6605 POWERPC_FLAG_BUS_CLK
;
6608 static void init_proc_7440(CPUPPCState
*env
)
6610 gen_spr_ne_601(env
);
6615 /* 74xx specific SPR */
6617 /* XXX : not implemented */
6618 spr_register(env
, SPR_UBAMR
, "UBAMR",
6619 &spr_read_ureg
, SPR_NOACCESS
,
6620 &spr_read_ureg
, SPR_NOACCESS
,
6623 /* XXX : not implemented */
6624 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6625 SPR_NOACCESS
, SPR_NOACCESS
,
6626 &spr_read_generic
, &spr_write_generic
,
6629 /* XXX : not implemented */
6630 spr_register(env
, SPR_ICTRL
, "ICTRL",
6631 SPR_NOACCESS
, SPR_NOACCESS
,
6632 &spr_read_generic
, &spr_write_generic
,
6635 /* XXX : not implemented */
6636 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6637 SPR_NOACCESS
, SPR_NOACCESS
,
6638 &spr_read_generic
, &spr_write_generic
,
6641 /* XXX : not implemented */
6642 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6643 SPR_NOACCESS
, SPR_NOACCESS
,
6644 &spr_read_generic
, &spr_write_generic
,
6646 /* XXX : not implemented */
6647 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6648 &spr_read_ureg
, SPR_NOACCESS
,
6649 &spr_read_ureg
, SPR_NOACCESS
,
6651 /* XXX : not implemented */
6652 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6653 SPR_NOACCESS
, SPR_NOACCESS
,
6654 &spr_read_generic
, &spr_write_generic
,
6656 /* XXX : not implemented */
6657 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6658 &spr_read_ureg
, SPR_NOACCESS
,
6659 &spr_read_ureg
, SPR_NOACCESS
,
6661 /* Memory management */
6663 gen_74xx_soft_tlb(env
, 128, 2);
6664 init_excp_7450(env
);
6665 env
->dcache_line_size
= 32;
6666 env
->icache_line_size
= 32;
6667 /* Allocate hardware IRQ controller */
6668 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6671 POWERPC_FAMILY(7440)(ObjectClass
*oc
, void *data
)
6673 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6674 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6676 dc
->desc
= "PowerPC 7440 (aka G4)";
6677 pcc
->init_proc
= init_proc_7440
;
6678 pcc
->check_pow
= check_pow_hid0_74xx
;
6679 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6680 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6681 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6683 PPC_CACHE
| PPC_CACHE_ICBI
|
6684 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6685 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6686 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6687 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6688 PPC_SEGMENT
| PPC_EXTERN
|
6690 pcc
->msr_mask
= (1ull << MSR_VR
) |
6707 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6708 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6709 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6710 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6711 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6712 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6713 POWERPC_FLAG_BUS_CLK
;
6716 static void init_proc_7450(CPUPPCState
*env
)
6718 gen_spr_ne_601(env
);
6723 /* 74xx specific SPR */
6725 /* Level 3 cache control */
6728 /* XXX : not implemented */
6729 spr_register(env
, SPR_L3ITCR1
, "L3ITCR1",
6730 SPR_NOACCESS
, SPR_NOACCESS
,
6731 &spr_read_generic
, &spr_write_generic
,
6734 /* XXX : not implemented */
6735 spr_register(env
, SPR_L3ITCR2
, "L3ITCR2",
6736 SPR_NOACCESS
, SPR_NOACCESS
,
6737 &spr_read_generic
, &spr_write_generic
,
6740 /* XXX : not implemented */
6741 spr_register(env
, SPR_L3ITCR3
, "L3ITCR3",
6742 SPR_NOACCESS
, SPR_NOACCESS
,
6743 &spr_read_generic
, &spr_write_generic
,
6746 /* XXX : not implemented */
6747 spr_register(env
, SPR_L3OHCR
, "L3OHCR",
6748 SPR_NOACCESS
, SPR_NOACCESS
,
6749 &spr_read_generic
, &spr_write_generic
,
6751 /* XXX : not implemented */
6752 spr_register(env
, SPR_UBAMR
, "UBAMR",
6753 &spr_read_ureg
, SPR_NOACCESS
,
6754 &spr_read_ureg
, SPR_NOACCESS
,
6757 /* XXX : not implemented */
6758 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6759 SPR_NOACCESS
, SPR_NOACCESS
,
6760 &spr_read_generic
, &spr_write_generic
,
6763 /* XXX : not implemented */
6764 spr_register(env
, SPR_ICTRL
, "ICTRL",
6765 SPR_NOACCESS
, SPR_NOACCESS
,
6766 &spr_read_generic
, &spr_write_generic
,
6769 /* XXX : not implemented */
6770 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6771 SPR_NOACCESS
, SPR_NOACCESS
,
6772 &spr_read_generic
, &spr_write_generic
,
6775 /* XXX : not implemented */
6776 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6777 SPR_NOACCESS
, SPR_NOACCESS
,
6778 &spr_read_generic
, &spr_write_generic
,
6780 /* XXX : not implemented */
6781 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6782 &spr_read_ureg
, SPR_NOACCESS
,
6783 &spr_read_ureg
, SPR_NOACCESS
,
6785 /* XXX : not implemented */
6786 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6787 SPR_NOACCESS
, SPR_NOACCESS
,
6788 &spr_read_generic
, &spr_write_generic
,
6790 /* XXX : not implemented */
6791 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6792 &spr_read_ureg
, SPR_NOACCESS
,
6793 &spr_read_ureg
, SPR_NOACCESS
,
6795 /* Memory management */
6797 gen_74xx_soft_tlb(env
, 128, 2);
6798 init_excp_7450(env
);
6799 env
->dcache_line_size
= 32;
6800 env
->icache_line_size
= 32;
6801 /* Allocate hardware IRQ controller */
6802 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6805 POWERPC_FAMILY(7450)(ObjectClass
*oc
, void *data
)
6807 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6808 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6810 dc
->desc
= "PowerPC 7450 (aka G4)";
6811 pcc
->init_proc
= init_proc_7450
;
6812 pcc
->check_pow
= check_pow_hid0_74xx
;
6813 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6814 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6815 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6817 PPC_CACHE
| PPC_CACHE_ICBI
|
6818 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6819 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6820 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6821 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6822 PPC_SEGMENT
| PPC_EXTERN
|
6824 pcc
->msr_mask
= (1ull << MSR_VR
) |
6841 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6842 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6843 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6844 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6845 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6846 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6847 POWERPC_FLAG_BUS_CLK
;
6850 static void init_proc_7445(CPUPPCState
*env
)
6852 gen_spr_ne_601(env
);
6857 /* 74xx specific SPR */
6860 /* XXX : not implemented */
6861 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6862 SPR_NOACCESS
, SPR_NOACCESS
,
6863 &spr_read_generic
, &spr_write_generic
,
6866 /* XXX : not implemented */
6867 spr_register(env
, SPR_ICTRL
, "ICTRL",
6868 SPR_NOACCESS
, SPR_NOACCESS
,
6869 &spr_read_generic
, &spr_write_generic
,
6872 /* XXX : not implemented */
6873 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6874 SPR_NOACCESS
, SPR_NOACCESS
,
6875 &spr_read_generic
, &spr_write_generic
,
6878 /* XXX : not implemented */
6879 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6880 SPR_NOACCESS
, SPR_NOACCESS
,
6881 &spr_read_generic
, &spr_write_generic
,
6883 /* XXX : not implemented */
6884 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6885 &spr_read_ureg
, SPR_NOACCESS
,
6886 &spr_read_ureg
, SPR_NOACCESS
,
6888 /* XXX : not implemented */
6889 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6890 SPR_NOACCESS
, SPR_NOACCESS
,
6891 &spr_read_generic
, &spr_write_generic
,
6893 /* XXX : not implemented */
6894 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6895 &spr_read_ureg
, SPR_NOACCESS
,
6896 &spr_read_ureg
, SPR_NOACCESS
,
6899 spr_register(env
, SPR_SPRG4
, "SPRG4",
6900 SPR_NOACCESS
, SPR_NOACCESS
,
6901 &spr_read_generic
, &spr_write_generic
,
6903 spr_register(env
, SPR_USPRG4
, "USPRG4",
6904 &spr_read_ureg
, SPR_NOACCESS
,
6905 &spr_read_ureg
, SPR_NOACCESS
,
6907 spr_register(env
, SPR_SPRG5
, "SPRG5",
6908 SPR_NOACCESS
, SPR_NOACCESS
,
6909 &spr_read_generic
, &spr_write_generic
,
6911 spr_register(env
, SPR_USPRG5
, "USPRG5",
6912 &spr_read_ureg
, SPR_NOACCESS
,
6913 &spr_read_ureg
, SPR_NOACCESS
,
6915 spr_register(env
, SPR_SPRG6
, "SPRG6",
6916 SPR_NOACCESS
, SPR_NOACCESS
,
6917 &spr_read_generic
, &spr_write_generic
,
6919 spr_register(env
, SPR_USPRG6
, "USPRG6",
6920 &spr_read_ureg
, SPR_NOACCESS
,
6921 &spr_read_ureg
, SPR_NOACCESS
,
6923 spr_register(env
, SPR_SPRG7
, "SPRG7",
6924 SPR_NOACCESS
, SPR_NOACCESS
,
6925 &spr_read_generic
, &spr_write_generic
,
6927 spr_register(env
, SPR_USPRG7
, "USPRG7",
6928 &spr_read_ureg
, SPR_NOACCESS
,
6929 &spr_read_ureg
, SPR_NOACCESS
,
6931 /* Memory management */
6934 gen_74xx_soft_tlb(env
, 128, 2);
6935 init_excp_7450(env
);
6936 env
->dcache_line_size
= 32;
6937 env
->icache_line_size
= 32;
6938 /* Allocate hardware IRQ controller */
6939 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6942 POWERPC_FAMILY(7445)(ObjectClass
*oc
, void *data
)
6944 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6945 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6947 dc
->desc
= "PowerPC 7445 (aka G4)";
6948 pcc
->init_proc
= init_proc_7445
;
6949 pcc
->check_pow
= check_pow_hid0_74xx
;
6950 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6951 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6952 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6954 PPC_CACHE
| PPC_CACHE_ICBI
|
6955 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6956 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6957 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6958 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6959 PPC_SEGMENT
| PPC_EXTERN
|
6961 pcc
->msr_mask
= (1ull << MSR_VR
) |
6978 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6979 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6980 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6981 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6982 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6983 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6984 POWERPC_FLAG_BUS_CLK
;
6987 static void init_proc_7455(CPUPPCState
*env
)
6989 gen_spr_ne_601(env
);
6994 /* 74xx specific SPR */
6996 /* Level 3 cache control */
6999 /* XXX : not implemented */
7000 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7001 SPR_NOACCESS
, SPR_NOACCESS
,
7002 &spr_read_generic
, &spr_write_generic
,
7005 /* XXX : not implemented */
7006 spr_register(env
, SPR_ICTRL
, "ICTRL",
7007 SPR_NOACCESS
, SPR_NOACCESS
,
7008 &spr_read_generic
, &spr_write_generic
,
7011 /* XXX : not implemented */
7012 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7013 SPR_NOACCESS
, SPR_NOACCESS
,
7014 &spr_read_generic
, &spr_write_generic
,
7017 /* XXX : not implemented */
7018 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7019 SPR_NOACCESS
, SPR_NOACCESS
,
7020 &spr_read_generic
, &spr_write_generic
,
7022 /* XXX : not implemented */
7023 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7024 &spr_read_ureg
, SPR_NOACCESS
,
7025 &spr_read_ureg
, SPR_NOACCESS
,
7027 /* XXX : not implemented */
7028 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7029 SPR_NOACCESS
, SPR_NOACCESS
,
7030 &spr_read_generic
, &spr_write_generic
,
7032 /* XXX : not implemented */
7033 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7034 &spr_read_ureg
, SPR_NOACCESS
,
7035 &spr_read_ureg
, SPR_NOACCESS
,
7038 spr_register(env
, SPR_SPRG4
, "SPRG4",
7039 SPR_NOACCESS
, SPR_NOACCESS
,
7040 &spr_read_generic
, &spr_write_generic
,
7042 spr_register(env
, SPR_USPRG4
, "USPRG4",
7043 &spr_read_ureg
, SPR_NOACCESS
,
7044 &spr_read_ureg
, SPR_NOACCESS
,
7046 spr_register(env
, SPR_SPRG5
, "SPRG5",
7047 SPR_NOACCESS
, SPR_NOACCESS
,
7048 &spr_read_generic
, &spr_write_generic
,
7050 spr_register(env
, SPR_USPRG5
, "USPRG5",
7051 &spr_read_ureg
, SPR_NOACCESS
,
7052 &spr_read_ureg
, SPR_NOACCESS
,
7054 spr_register(env
, SPR_SPRG6
, "SPRG6",
7055 SPR_NOACCESS
, SPR_NOACCESS
,
7056 &spr_read_generic
, &spr_write_generic
,
7058 spr_register(env
, SPR_USPRG6
, "USPRG6",
7059 &spr_read_ureg
, SPR_NOACCESS
,
7060 &spr_read_ureg
, SPR_NOACCESS
,
7062 spr_register(env
, SPR_SPRG7
, "SPRG7",
7063 SPR_NOACCESS
, SPR_NOACCESS
,
7064 &spr_read_generic
, &spr_write_generic
,
7066 spr_register(env
, SPR_USPRG7
, "USPRG7",
7067 &spr_read_ureg
, SPR_NOACCESS
,
7068 &spr_read_ureg
, SPR_NOACCESS
,
7070 /* Memory management */
7073 gen_74xx_soft_tlb(env
, 128, 2);
7074 init_excp_7450(env
);
7075 env
->dcache_line_size
= 32;
7076 env
->icache_line_size
= 32;
7077 /* Allocate hardware IRQ controller */
7078 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7081 POWERPC_FAMILY(7455)(ObjectClass
*oc
, void *data
)
7083 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7084 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7086 dc
->desc
= "PowerPC 7455 (aka G4)";
7087 pcc
->init_proc
= init_proc_7455
;
7088 pcc
->check_pow
= check_pow_hid0_74xx
;
7089 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7090 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7091 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7093 PPC_CACHE
| PPC_CACHE_ICBI
|
7094 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7095 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7096 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7097 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7098 PPC_SEGMENT
| PPC_EXTERN
|
7100 pcc
->msr_mask
= (1ull << MSR_VR
) |
7117 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7118 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7119 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7120 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7121 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7122 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7123 POWERPC_FLAG_BUS_CLK
;
7126 static void init_proc_7457(CPUPPCState
*env
)
7128 gen_spr_ne_601(env
);
7133 /* 74xx specific SPR */
7135 /* Level 3 cache control */
7138 /* XXX : not implemented */
7139 spr_register(env
, SPR_L3ITCR1
, "L3ITCR1",
7140 SPR_NOACCESS
, SPR_NOACCESS
,
7141 &spr_read_generic
, &spr_write_generic
,
7144 /* XXX : not implemented */
7145 spr_register(env
, SPR_L3ITCR2
, "L3ITCR2",
7146 SPR_NOACCESS
, SPR_NOACCESS
,
7147 &spr_read_generic
, &spr_write_generic
,
7150 /* XXX : not implemented */
7151 spr_register(env
, SPR_L3ITCR3
, "L3ITCR3",
7152 SPR_NOACCESS
, SPR_NOACCESS
,
7153 &spr_read_generic
, &spr_write_generic
,
7156 /* XXX : not implemented */
7157 spr_register(env
, SPR_L3OHCR
, "L3OHCR",
7158 SPR_NOACCESS
, SPR_NOACCESS
,
7159 &spr_read_generic
, &spr_write_generic
,
7162 /* XXX : not implemented */
7163 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7164 SPR_NOACCESS
, SPR_NOACCESS
,
7165 &spr_read_generic
, &spr_write_generic
,
7168 /* XXX : not implemented */
7169 spr_register(env
, SPR_ICTRL
, "ICTRL",
7170 SPR_NOACCESS
, SPR_NOACCESS
,
7171 &spr_read_generic
, &spr_write_generic
,
7174 /* XXX : not implemented */
7175 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7176 SPR_NOACCESS
, SPR_NOACCESS
,
7177 &spr_read_generic
, &spr_write_generic
,
7180 /* XXX : not implemented */
7181 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7182 SPR_NOACCESS
, SPR_NOACCESS
,
7183 &spr_read_generic
, &spr_write_generic
,
7185 /* XXX : not implemented */
7186 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7187 &spr_read_ureg
, SPR_NOACCESS
,
7188 &spr_read_ureg
, SPR_NOACCESS
,
7190 /* XXX : not implemented */
7191 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7192 SPR_NOACCESS
, SPR_NOACCESS
,
7193 &spr_read_generic
, &spr_write_generic
,
7195 /* XXX : not implemented */
7196 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7197 &spr_read_ureg
, SPR_NOACCESS
,
7198 &spr_read_ureg
, SPR_NOACCESS
,
7201 spr_register(env
, SPR_SPRG4
, "SPRG4",
7202 SPR_NOACCESS
, SPR_NOACCESS
,
7203 &spr_read_generic
, &spr_write_generic
,
7205 spr_register(env
, SPR_USPRG4
, "USPRG4",
7206 &spr_read_ureg
, SPR_NOACCESS
,
7207 &spr_read_ureg
, SPR_NOACCESS
,
7209 spr_register(env
, SPR_SPRG5
, "SPRG5",
7210 SPR_NOACCESS
, SPR_NOACCESS
,
7211 &spr_read_generic
, &spr_write_generic
,
7213 spr_register(env
, SPR_USPRG5
, "USPRG5",
7214 &spr_read_ureg
, SPR_NOACCESS
,
7215 &spr_read_ureg
, SPR_NOACCESS
,
7217 spr_register(env
, SPR_SPRG6
, "SPRG6",
7218 SPR_NOACCESS
, SPR_NOACCESS
,
7219 &spr_read_generic
, &spr_write_generic
,
7221 spr_register(env
, SPR_USPRG6
, "USPRG6",
7222 &spr_read_ureg
, SPR_NOACCESS
,
7223 &spr_read_ureg
, SPR_NOACCESS
,
7225 spr_register(env
, SPR_SPRG7
, "SPRG7",
7226 SPR_NOACCESS
, SPR_NOACCESS
,
7227 &spr_read_generic
, &spr_write_generic
,
7229 spr_register(env
, SPR_USPRG7
, "USPRG7",
7230 &spr_read_ureg
, SPR_NOACCESS
,
7231 &spr_read_ureg
, SPR_NOACCESS
,
7233 /* Memory management */
7236 gen_74xx_soft_tlb(env
, 128, 2);
7237 init_excp_7450(env
);
7238 env
->dcache_line_size
= 32;
7239 env
->icache_line_size
= 32;
7240 /* Allocate hardware IRQ controller */
7241 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7244 POWERPC_FAMILY(7457)(ObjectClass
*oc
, void *data
)
7246 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7247 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7249 dc
->desc
= "PowerPC 7457 (aka G4)";
7250 pcc
->init_proc
= init_proc_7457
;
7251 pcc
->check_pow
= check_pow_hid0_74xx
;
7252 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7253 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7254 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7256 PPC_CACHE
| PPC_CACHE_ICBI
|
7257 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7258 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7259 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7260 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7261 PPC_SEGMENT
| PPC_EXTERN
|
7263 pcc
->msr_mask
= (1ull << MSR_VR
) |
7280 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7281 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7282 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7283 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7284 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7285 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7286 POWERPC_FLAG_BUS_CLK
;
7289 static void init_proc_e600(CPUPPCState
*env
)
7291 gen_spr_ne_601(env
);
7296 /* 74xx specific SPR */
7298 /* XXX : not implemented */
7299 spr_register(env
, SPR_UBAMR
, "UBAMR",
7300 &spr_read_ureg
, SPR_NOACCESS
,
7301 &spr_read_ureg
, SPR_NOACCESS
,
7303 /* XXX : not implemented */
7304 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7305 SPR_NOACCESS
, SPR_NOACCESS
,
7306 &spr_read_generic
, &spr_write_generic
,
7308 /* XXX : not implemented */
7309 spr_register(env
, SPR_ICTRL
, "ICTRL",
7310 SPR_NOACCESS
, SPR_NOACCESS
,
7311 &spr_read_generic
, &spr_write_generic
,
7313 /* XXX : not implemented */
7314 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7315 SPR_NOACCESS
, SPR_NOACCESS
,
7316 &spr_read_generic
, &spr_write_generic
,
7318 /* XXX : not implemented */
7319 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7320 SPR_NOACCESS
, SPR_NOACCESS
,
7321 &spr_read_generic
, &spr_write_generic
,
7323 /* XXX : not implemented */
7324 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7325 &spr_read_ureg
, SPR_NOACCESS
,
7326 &spr_read_ureg
, SPR_NOACCESS
,
7328 /* XXX : not implemented */
7329 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7330 SPR_NOACCESS
, SPR_NOACCESS
,
7331 &spr_read_generic
, &spr_write_generic
,
7333 /* XXX : not implemented */
7334 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7335 &spr_read_ureg
, SPR_NOACCESS
,
7336 &spr_read_ureg
, SPR_NOACCESS
,
7339 spr_register(env
, SPR_SPRG4
, "SPRG4",
7340 SPR_NOACCESS
, SPR_NOACCESS
,
7341 &spr_read_generic
, &spr_write_generic
,
7343 spr_register(env
, SPR_USPRG4
, "USPRG4",
7344 &spr_read_ureg
, SPR_NOACCESS
,
7345 &spr_read_ureg
, SPR_NOACCESS
,
7347 spr_register(env
, SPR_SPRG5
, "SPRG5",
7348 SPR_NOACCESS
, SPR_NOACCESS
,
7349 &spr_read_generic
, &spr_write_generic
,
7351 spr_register(env
, SPR_USPRG5
, "USPRG5",
7352 &spr_read_ureg
, SPR_NOACCESS
,
7353 &spr_read_ureg
, SPR_NOACCESS
,
7355 spr_register(env
, SPR_SPRG6
, "SPRG6",
7356 SPR_NOACCESS
, SPR_NOACCESS
,
7357 &spr_read_generic
, &spr_write_generic
,
7359 spr_register(env
, SPR_USPRG6
, "USPRG6",
7360 &spr_read_ureg
, SPR_NOACCESS
,
7361 &spr_read_ureg
, SPR_NOACCESS
,
7363 spr_register(env
, SPR_SPRG7
, "SPRG7",
7364 SPR_NOACCESS
, SPR_NOACCESS
,
7365 &spr_read_generic
, &spr_write_generic
,
7367 spr_register(env
, SPR_USPRG7
, "USPRG7",
7368 &spr_read_ureg
, SPR_NOACCESS
,
7369 &spr_read_ureg
, SPR_NOACCESS
,
7371 /* Memory management */
7374 gen_74xx_soft_tlb(env
, 128, 2);
7375 init_excp_7450(env
);
7376 env
->dcache_line_size
= 32;
7377 env
->icache_line_size
= 32;
7378 /* Allocate hardware IRQ controller */
7379 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7382 POWERPC_FAMILY(e600
)(ObjectClass
*oc
, void *data
)
7384 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7385 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7387 dc
->desc
= "PowerPC e600";
7388 pcc
->init_proc
= init_proc_e600
;
7389 pcc
->check_pow
= check_pow_hid0_74xx
;
7390 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7391 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7392 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7394 PPC_CACHE
| PPC_CACHE_ICBI
|
7395 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7396 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7397 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7398 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7399 PPC_SEGMENT
| PPC_EXTERN
|
7401 pcc
->insns_flags2
= PPC_NONE
;
7402 pcc
->msr_mask
= (1ull << MSR_VR
) |
7419 pcc
->mmu_model
= POWERPC_MMU_32B
;
7420 #if defined(CONFIG_SOFTMMU)
7421 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
7423 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7424 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7425 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7426 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7427 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7428 POWERPC_FLAG_BUS_CLK
;
7431 #if defined(TARGET_PPC64)
7432 #if defined(CONFIG_USER_ONLY)
7433 #define POWERPC970_HID5_INIT 0x00000080
7435 #define POWERPC970_HID5_INIT 0x00000000
7438 static void gen_fscr_facility_check(DisasContext
*ctx
, int facility_sprn
,
7439 int bit
, int sprn
, int cause
)
7441 TCGv_i32 t1
= tcg_const_i32(bit
);
7442 TCGv_i32 t2
= tcg_const_i32(sprn
);
7443 TCGv_i32 t3
= tcg_const_i32(cause
);
7445 gen_helper_fscr_facility_check(cpu_env
, t1
, t2
, t3
);
7447 tcg_temp_free_i32(t3
);
7448 tcg_temp_free_i32(t2
);
7449 tcg_temp_free_i32(t1
);
7452 static void gen_msr_facility_check(DisasContext
*ctx
, int facility_sprn
,
7453 int bit
, int sprn
, int cause
)
7455 TCGv_i32 t1
= tcg_const_i32(bit
);
7456 TCGv_i32 t2
= tcg_const_i32(sprn
);
7457 TCGv_i32 t3
= tcg_const_i32(cause
);
7459 gen_helper_msr_facility_check(cpu_env
, t1
, t2
, t3
);
7461 tcg_temp_free_i32(t3
);
7462 tcg_temp_free_i32(t2
);
7463 tcg_temp_free_i32(t1
);
7466 static void spr_read_prev_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
7468 TCGv spr_up
= tcg_temp_new();
7469 TCGv spr
= tcg_temp_new();
7471 gen_load_spr(spr
, sprn
- 1);
7472 tcg_gen_shri_tl(spr_up
, spr
, 32);
7473 tcg_gen_ext32u_tl(cpu_gpr
[gprn
], spr_up
);
7476 tcg_temp_free(spr_up
);
7479 static void spr_write_prev_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
7481 TCGv spr
= tcg_temp_new();
7483 gen_load_spr(spr
, sprn
- 1);
7484 tcg_gen_deposit_tl(spr
, spr
, cpu_gpr
[gprn
], 32, 32);
7485 gen_store_spr(sprn
- 1, spr
);
7490 static int check_pow_970(CPUPPCState
*env
)
7492 if (env
->spr
[SPR_HID0
] & (HID0_DEEPNAP
| HID0_DOZE
| HID0_NAP
)) {
7499 static void gen_spr_970_hid(CPUPPCState
*env
)
7501 /* Hardware implementation registers */
7502 /* XXX : not implemented */
7503 spr_register(env
, SPR_HID0
, "HID0",
7504 SPR_NOACCESS
, SPR_NOACCESS
,
7505 &spr_read_generic
, &spr_write_clear
,
7507 spr_register(env
, SPR_HID1
, "HID1",
7508 SPR_NOACCESS
, SPR_NOACCESS
,
7509 &spr_read_generic
, &spr_write_generic
,
7511 spr_register(env
, SPR_970_HID5
, "HID5",
7512 SPR_NOACCESS
, SPR_NOACCESS
,
7513 &spr_read_generic
, &spr_write_generic
,
7514 POWERPC970_HID5_INIT
);
7517 static void gen_spr_970_hior(CPUPPCState
*env
)
7519 spr_register(env
, SPR_HIOR
, "SPR_HIOR",
7520 SPR_NOACCESS
, SPR_NOACCESS
,
7521 &spr_read_hior
, &spr_write_hior
,
7525 static void gen_spr_book3s_ctrl(CPUPPCState
*env
)
7527 spr_register(env
, SPR_CTRL
, "SPR_CTRL",
7528 SPR_NOACCESS
, SPR_NOACCESS
,
7529 SPR_NOACCESS
, &spr_write_generic
,
7531 spr_register(env
, SPR_UCTRL
, "SPR_UCTRL",
7532 &spr_read_ureg
, SPR_NOACCESS
,
7533 &spr_read_ureg
, SPR_NOACCESS
,
7537 static void gen_spr_book3s_altivec(CPUPPCState
*env
)
7539 if (!(env
->insns_flags
& PPC_ALTIVEC
)) {
7543 spr_register_kvm(env
, SPR_VRSAVE
, "VRSAVE",
7544 &spr_read_generic
, &spr_write_generic
,
7545 &spr_read_generic
, &spr_write_generic
,
7546 KVM_REG_PPC_VRSAVE
, 0x00000000);
7548 /* Can't find information on what this should be on reset. This
7549 * value is the one used by 74xx processors. */
7550 vscr_init(env
, 0x00010000);
7553 static void gen_spr_book3s_dbg(CPUPPCState
*env
)
7556 * TODO: different specs define different scopes for these,
7557 * will have to address this:
7558 * 970: super/write and super/read
7559 * powerisa 2.03..2.04: hypv/write and super/read.
7560 * powerisa 2.05 and newer: hypv/write and hypv/read.
7562 spr_register_kvm(env
, SPR_DABR
, "DABR",
7563 SPR_NOACCESS
, SPR_NOACCESS
,
7564 &spr_read_generic
, &spr_write_generic
,
7565 KVM_REG_PPC_DABR
, 0x00000000);
7566 spr_register_kvm(env
, SPR_DABRX
, "DABRX",
7567 SPR_NOACCESS
, SPR_NOACCESS
,
7568 &spr_read_generic
, &spr_write_generic
,
7569 KVM_REG_PPC_DABRX
, 0x00000000);
7572 static void gen_spr_book3s_207_dbg(CPUPPCState
*env
)
7574 spr_register_kvm_hv(env
, SPR_DAWR
, "DAWR",
7575 SPR_NOACCESS
, SPR_NOACCESS
,
7576 SPR_NOACCESS
, SPR_NOACCESS
,
7577 &spr_read_generic
, &spr_write_generic
,
7578 KVM_REG_PPC_DAWR
, 0x00000000);
7579 spr_register_kvm_hv(env
, SPR_DAWRX
, "DAWRX",
7580 SPR_NOACCESS
, SPR_NOACCESS
,
7581 SPR_NOACCESS
, SPR_NOACCESS
,
7582 &spr_read_generic
, &spr_write_generic
,
7583 KVM_REG_PPC_DAWRX
, 0x00000000);
7584 spr_register_kvm_hv(env
, SPR_CIABR
, "CIABR",
7585 SPR_NOACCESS
, SPR_NOACCESS
,
7586 SPR_NOACCESS
, SPR_NOACCESS
,
7587 &spr_read_generic
, &spr_write_generic
,
7588 KVM_REG_PPC_CIABR
, 0x00000000);
7591 static void gen_spr_970_dbg(CPUPPCState
*env
)
7594 spr_register(env
, SPR_IABR
, "IABR",
7595 SPR_NOACCESS
, SPR_NOACCESS
,
7596 &spr_read_generic
, &spr_write_generic
,
7600 static void gen_spr_book3s_pmu_sup(CPUPPCState
*env
)
7602 spr_register_kvm(env
, SPR_POWER_MMCR0
, "MMCR0",
7603 SPR_NOACCESS
, SPR_NOACCESS
,
7604 &spr_read_generic
, &spr_write_generic
,
7605 KVM_REG_PPC_MMCR0
, 0x00000000);
7606 spr_register_kvm(env
, SPR_POWER_MMCR1
, "MMCR1",
7607 SPR_NOACCESS
, SPR_NOACCESS
,
7608 &spr_read_generic
, &spr_write_generic
,
7609 KVM_REG_PPC_MMCR1
, 0x00000000);
7610 spr_register_kvm(env
, SPR_POWER_MMCRA
, "MMCRA",
7611 SPR_NOACCESS
, SPR_NOACCESS
,
7612 &spr_read_generic
, &spr_write_generic
,
7613 KVM_REG_PPC_MMCRA
, 0x00000000);
7614 spr_register_kvm(env
, SPR_POWER_PMC1
, "PMC1",
7615 SPR_NOACCESS
, SPR_NOACCESS
,
7616 &spr_read_generic
, &spr_write_generic
,
7617 KVM_REG_PPC_PMC1
, 0x00000000);
7618 spr_register_kvm(env
, SPR_POWER_PMC2
, "PMC2",
7619 SPR_NOACCESS
, SPR_NOACCESS
,
7620 &spr_read_generic
, &spr_write_generic
,
7621 KVM_REG_PPC_PMC2
, 0x00000000);
7622 spr_register_kvm(env
, SPR_POWER_PMC3
, "PMC3",
7623 SPR_NOACCESS
, SPR_NOACCESS
,
7624 &spr_read_generic
, &spr_write_generic
,
7625 KVM_REG_PPC_PMC3
, 0x00000000);
7626 spr_register_kvm(env
, SPR_POWER_PMC4
, "PMC4",
7627 SPR_NOACCESS
, SPR_NOACCESS
,
7628 &spr_read_generic
, &spr_write_generic
,
7629 KVM_REG_PPC_PMC4
, 0x00000000);
7630 spr_register_kvm(env
, SPR_POWER_PMC5
, "PMC5",
7631 SPR_NOACCESS
, SPR_NOACCESS
,
7632 &spr_read_generic
, &spr_write_generic
,
7633 KVM_REG_PPC_PMC5
, 0x00000000);
7634 spr_register_kvm(env
, SPR_POWER_PMC6
, "PMC6",
7635 SPR_NOACCESS
, SPR_NOACCESS
,
7636 &spr_read_generic
, &spr_write_generic
,
7637 KVM_REG_PPC_PMC6
, 0x00000000);
7638 spr_register_kvm(env
, SPR_POWER_SIAR
, "SIAR",
7639 SPR_NOACCESS
, SPR_NOACCESS
,
7640 &spr_read_generic
, &spr_write_generic
,
7641 KVM_REG_PPC_SIAR
, 0x00000000);
7642 spr_register_kvm(env
, SPR_POWER_SDAR
, "SDAR",
7643 SPR_NOACCESS
, SPR_NOACCESS
,
7644 &spr_read_generic
, &spr_write_generic
,
7645 KVM_REG_PPC_SDAR
, 0x00000000);
7648 static void gen_spr_book3s_pmu_user(CPUPPCState
*env
)
7650 spr_register(env
, SPR_POWER_UMMCR0
, "UMMCR0",
7651 &spr_read_ureg
, SPR_NOACCESS
,
7652 &spr_read_ureg
, &spr_write_ureg
,
7654 spr_register(env
, SPR_POWER_UMMCR1
, "UMMCR1",
7655 &spr_read_ureg
, SPR_NOACCESS
,
7656 &spr_read_ureg
, &spr_write_ureg
,
7658 spr_register(env
, SPR_POWER_UMMCRA
, "UMMCRA",
7659 &spr_read_ureg
, SPR_NOACCESS
,
7660 &spr_read_ureg
, &spr_write_ureg
,
7662 spr_register(env
, SPR_POWER_UPMC1
, "UPMC1",
7663 &spr_read_ureg
, SPR_NOACCESS
,
7664 &spr_read_ureg
, &spr_write_ureg
,
7666 spr_register(env
, SPR_POWER_UPMC2
, "UPMC2",
7667 &spr_read_ureg
, SPR_NOACCESS
,
7668 &spr_read_ureg
, &spr_write_ureg
,
7670 spr_register(env
, SPR_POWER_UPMC3
, "UPMC3",
7671 &spr_read_ureg
, SPR_NOACCESS
,
7672 &spr_read_ureg
, &spr_write_ureg
,
7674 spr_register(env
, SPR_POWER_UPMC4
, "UPMC4",
7675 &spr_read_ureg
, SPR_NOACCESS
,
7676 &spr_read_ureg
, &spr_write_ureg
,
7678 spr_register(env
, SPR_POWER_UPMC5
, "UPMC5",
7679 &spr_read_ureg
, SPR_NOACCESS
,
7680 &spr_read_ureg
, &spr_write_ureg
,
7682 spr_register(env
, SPR_POWER_UPMC6
, "UPMC6",
7683 &spr_read_ureg
, SPR_NOACCESS
,
7684 &spr_read_ureg
, &spr_write_ureg
,
7686 spr_register(env
, SPR_POWER_USIAR
, "USIAR",
7687 &spr_read_ureg
, SPR_NOACCESS
,
7688 &spr_read_ureg
, &spr_write_ureg
,
7690 spr_register(env
, SPR_POWER_USDAR
, "USDAR",
7691 &spr_read_ureg
, SPR_NOACCESS
,
7692 &spr_read_ureg
, &spr_write_ureg
,
7696 static void gen_spr_970_pmu_sup(CPUPPCState
*env
)
7698 spr_register_kvm(env
, SPR_970_PMC7
, "PMC7",
7699 SPR_NOACCESS
, SPR_NOACCESS
,
7700 &spr_read_generic
, &spr_write_generic
,
7701 KVM_REG_PPC_PMC7
, 0x00000000);
7702 spr_register_kvm(env
, SPR_970_PMC8
, "PMC8",
7703 SPR_NOACCESS
, SPR_NOACCESS
,
7704 &spr_read_generic
, &spr_write_generic
,
7705 KVM_REG_PPC_PMC8
, 0x00000000);
7708 static void gen_spr_970_pmu_user(CPUPPCState
*env
)
7710 spr_register(env
, SPR_970_UPMC7
, "UPMC7",
7711 &spr_read_ureg
, SPR_NOACCESS
,
7712 &spr_read_ureg
, &spr_write_ureg
,
7714 spr_register(env
, SPR_970_UPMC8
, "UPMC8",
7715 &spr_read_ureg
, SPR_NOACCESS
,
7716 &spr_read_ureg
, &spr_write_ureg
,
7720 static void gen_spr_power8_pmu_sup(CPUPPCState
*env
)
7722 spr_register_kvm(env
, SPR_POWER_MMCR2
, "MMCR2",
7723 SPR_NOACCESS
, SPR_NOACCESS
,
7724 &spr_read_generic
, &spr_write_generic
,
7725 KVM_REG_PPC_MMCR2
, 0x00000000);
7726 spr_register_kvm(env
, SPR_POWER_MMCRS
, "MMCRS",
7727 SPR_NOACCESS
, SPR_NOACCESS
,
7728 &spr_read_generic
, &spr_write_generic
,
7729 KVM_REG_PPC_MMCRS
, 0x00000000);
7730 spr_register_kvm(env
, SPR_POWER_SIER
, "SIER",
7731 SPR_NOACCESS
, SPR_NOACCESS
,
7732 &spr_read_generic
, &spr_write_generic
,
7733 KVM_REG_PPC_SIER
, 0x00000000);
7734 spr_register_kvm(env
, SPR_POWER_SPMC1
, "SPMC1",
7735 SPR_NOACCESS
, SPR_NOACCESS
,
7736 &spr_read_generic
, &spr_write_generic
,
7737 KVM_REG_PPC_SPMC1
, 0x00000000);
7738 spr_register_kvm(env
, SPR_POWER_SPMC2
, "SPMC2",
7739 SPR_NOACCESS
, SPR_NOACCESS
,
7740 &spr_read_generic
, &spr_write_generic
,
7741 KVM_REG_PPC_SPMC2
, 0x00000000);
7742 spr_register_kvm(env
, SPR_TACR
, "TACR",
7743 SPR_NOACCESS
, SPR_NOACCESS
,
7744 &spr_read_generic
, &spr_write_generic
,
7745 KVM_REG_PPC_TACR
, 0x00000000);
7746 spr_register_kvm(env
, SPR_TCSCR
, "TCSCR",
7747 SPR_NOACCESS
, SPR_NOACCESS
,
7748 &spr_read_generic
, &spr_write_generic
,
7749 KVM_REG_PPC_TCSCR
, 0x00000000);
7750 spr_register_kvm(env
, SPR_CSIGR
, "CSIGR",
7751 SPR_NOACCESS
, SPR_NOACCESS
,
7752 &spr_read_generic
, &spr_write_generic
,
7753 KVM_REG_PPC_CSIGR
, 0x00000000);
7756 static void gen_spr_power8_pmu_user(CPUPPCState
*env
)
7758 spr_register(env
, SPR_POWER_UMMCR2
, "UMMCR2",
7759 &spr_read_ureg
, SPR_NOACCESS
,
7760 &spr_read_ureg
, &spr_write_ureg
,
7762 spr_register(env
, SPR_POWER_USIER
, "USIER",
7763 &spr_read_generic
, SPR_NOACCESS
,
7764 &spr_read_generic
, &spr_write_generic
,
7768 static void gen_spr_power5p_ear(CPUPPCState
*env
)
7770 /* External access control */
7771 spr_register(env
, SPR_EAR
, "EAR",
7772 SPR_NOACCESS
, SPR_NOACCESS
,
7773 &spr_read_generic
, &spr_write_generic
,
7777 #if !defined(CONFIG_USER_ONLY)
7778 static void spr_write_hmer(DisasContext
*ctx
, int sprn
, int gprn
)
7780 TCGv hmer
= tcg_temp_new();
7782 gen_load_spr(hmer
, sprn
);
7783 tcg_gen_and_tl(hmer
, cpu_gpr
[gprn
], hmer
);
7784 gen_store_spr(sprn
, hmer
);
7785 spr_store_dump_spr(sprn
);
7786 tcg_temp_free(hmer
);
7789 static void spr_write_lpcr(DisasContext
*ctx
, int sprn
, int gprn
)
7791 gen_helper_store_lpcr(cpu_env
, cpu_gpr
[gprn
]);
7794 static void spr_write_970_hid4(DisasContext
*ctx
, int sprn
, int gprn
)
7796 #if defined(TARGET_PPC64)
7797 spr_write_generic(ctx
, sprn
, gprn
);
7798 gen_helper_store_lpcr(cpu_env
, cpu_gpr
[gprn
]);
7802 #endif /* !defined(CONFIG_USER_ONLY) */
7804 static void gen_spr_970_lpar(CPUPPCState
*env
)
7806 #if !defined(CONFIG_USER_ONLY)
7807 /* Logical partitionning */
7808 /* PPC970: HID4 is effectively the LPCR */
7809 spr_register(env
, SPR_970_HID4
, "HID4",
7810 SPR_NOACCESS
, SPR_NOACCESS
,
7811 &spr_read_generic
, &spr_write_970_hid4
,
7816 static void gen_spr_power5p_lpar(CPUPPCState
*env
)
7818 #if !defined(CONFIG_USER_ONLY)
7819 /* Logical partitionning */
7820 spr_register_kvm_hv(env
, SPR_LPCR
, "LPCR",
7821 SPR_NOACCESS
, SPR_NOACCESS
,
7822 SPR_NOACCESS
, SPR_NOACCESS
,
7823 &spr_read_generic
, &spr_write_lpcr
,
7824 KVM_REG_PPC_LPCR
, LPCR_LPES0
| LPCR_LPES1
);
7825 spr_register_hv(env
, SPR_HDEC
, "HDEC",
7826 SPR_NOACCESS
, SPR_NOACCESS
,
7827 SPR_NOACCESS
, SPR_NOACCESS
,
7828 &spr_read_hdecr
, &spr_write_hdecr
, 0);
7832 static void gen_spr_book3s_ids(CPUPPCState
*env
)
7834 /* FIXME: Will need to deal with thread vs core only SPRs */
7836 /* Processor identification */
7837 spr_register_hv(env
, SPR_PIR
, "PIR",
7838 SPR_NOACCESS
, SPR_NOACCESS
,
7839 &spr_read_generic
, SPR_NOACCESS
,
7840 &spr_read_generic
, NULL
,
7842 spr_register_hv(env
, SPR_HID0
, "HID0",
7843 SPR_NOACCESS
, SPR_NOACCESS
,
7844 SPR_NOACCESS
, SPR_NOACCESS
,
7845 &spr_read_generic
, &spr_write_generic
,
7847 spr_register_hv(env
, SPR_TSCR
, "TSCR",
7848 SPR_NOACCESS
, SPR_NOACCESS
,
7849 SPR_NOACCESS
, SPR_NOACCESS
,
7850 &spr_read_generic
, &spr_write_generic
,
7852 spr_register_hv(env
, SPR_HMER
, "HMER",
7853 SPR_NOACCESS
, SPR_NOACCESS
,
7854 SPR_NOACCESS
, SPR_NOACCESS
,
7855 &spr_read_generic
, &spr_write_hmer
,
7857 spr_register_hv(env
, SPR_HMEER
, "HMEER",
7858 SPR_NOACCESS
, SPR_NOACCESS
,
7859 SPR_NOACCESS
, SPR_NOACCESS
,
7860 &spr_read_generic
, &spr_write_generic
,
7862 spr_register_hv(env
, SPR_TFMR
, "TFMR",
7863 SPR_NOACCESS
, SPR_NOACCESS
,
7864 SPR_NOACCESS
, SPR_NOACCESS
,
7865 &spr_read_generic
, &spr_write_generic
,
7867 spr_register_hv(env
, SPR_LPIDR
, "LPIDR",
7868 SPR_NOACCESS
, SPR_NOACCESS
,
7869 SPR_NOACCESS
, SPR_NOACCESS
,
7870 &spr_read_generic
, &spr_write_generic
,
7872 spr_register_hv(env
, SPR_HFSCR
, "HFSCR",
7873 SPR_NOACCESS
, SPR_NOACCESS
,
7874 SPR_NOACCESS
, SPR_NOACCESS
,
7875 &spr_read_generic
, &spr_write_generic
,
7877 spr_register_hv(env
, SPR_MMCRC
, "MMCRC",
7878 SPR_NOACCESS
, SPR_NOACCESS
,
7879 SPR_NOACCESS
, SPR_NOACCESS
,
7880 &spr_read_generic
, &spr_write_generic
,
7882 spr_register_hv(env
, SPR_MMCRH
, "MMCRH",
7883 SPR_NOACCESS
, SPR_NOACCESS
,
7884 SPR_NOACCESS
, SPR_NOACCESS
,
7885 &spr_read_generic
, &spr_write_generic
,
7887 spr_register_hv(env
, SPR_HSPRG0
, "HSPRG0",
7888 SPR_NOACCESS
, SPR_NOACCESS
,
7889 SPR_NOACCESS
, SPR_NOACCESS
,
7890 &spr_read_generic
, &spr_write_generic
,
7892 spr_register_hv(env
, SPR_HSPRG1
, "HSPRG1",
7893 SPR_NOACCESS
, SPR_NOACCESS
,
7894 SPR_NOACCESS
, SPR_NOACCESS
,
7895 &spr_read_generic
, &spr_write_generic
,
7897 spr_register_hv(env
, SPR_HSRR0
, "HSRR0",
7898 SPR_NOACCESS
, SPR_NOACCESS
,
7899 SPR_NOACCESS
, SPR_NOACCESS
,
7900 &spr_read_generic
, &spr_write_generic
,
7902 spr_register_hv(env
, SPR_HSRR1
, "HSRR1",
7903 SPR_NOACCESS
, SPR_NOACCESS
,
7904 SPR_NOACCESS
, SPR_NOACCESS
,
7905 &spr_read_generic
, &spr_write_generic
,
7907 spr_register_hv(env
, SPR_HDAR
, "HDAR",
7908 SPR_NOACCESS
, SPR_NOACCESS
,
7909 SPR_NOACCESS
, SPR_NOACCESS
,
7910 &spr_read_generic
, &spr_write_generic
,
7912 spr_register_hv(env
, SPR_HDSISR
, "HDSISR",
7913 SPR_NOACCESS
, SPR_NOACCESS
,
7914 SPR_NOACCESS
, SPR_NOACCESS
,
7915 &spr_read_generic
, &spr_write_generic
,
7917 spr_register_hv(env
, SPR_RMOR
, "RMOR",
7918 SPR_NOACCESS
, SPR_NOACCESS
,
7919 SPR_NOACCESS
, SPR_NOACCESS
,
7920 &spr_read_generic
, &spr_write_generic
,
7922 spr_register_hv(env
, SPR_HRMOR
, "HRMOR",
7923 SPR_NOACCESS
, SPR_NOACCESS
,
7924 SPR_NOACCESS
, SPR_NOACCESS
,
7925 &spr_read_generic
, &spr_write_generic
,
7929 static void gen_spr_power8_ids(CPUPPCState
*env
)
7931 /* Thread identification */
7932 spr_register(env
, SPR_TIR
, "TIR",
7933 SPR_NOACCESS
, SPR_NOACCESS
,
7934 &spr_read_generic
, SPR_NOACCESS
,
7938 static void gen_spr_book3s_purr(CPUPPCState
*env
)
7940 #if !defined(CONFIG_USER_ONLY)
7941 /* PURR & SPURR: Hack - treat these as aliases for the TB for now */
7942 spr_register_kvm(env
, SPR_PURR
, "PURR",
7943 &spr_read_purr
, SPR_NOACCESS
,
7944 &spr_read_purr
, SPR_NOACCESS
,
7945 KVM_REG_PPC_PURR
, 0x00000000);
7946 spr_register_kvm(env
, SPR_SPURR
, "SPURR",
7947 &spr_read_purr
, SPR_NOACCESS
,
7948 &spr_read_purr
, SPR_NOACCESS
,
7949 KVM_REG_PPC_SPURR
, 0x00000000);
7953 static void gen_spr_power6_dbg(CPUPPCState
*env
)
7955 #if !defined(CONFIG_USER_ONLY)
7956 spr_register(env
, SPR_CFAR
, "SPR_CFAR",
7957 SPR_NOACCESS
, SPR_NOACCESS
,
7958 &spr_read_cfar
, &spr_write_cfar
,
7963 static void gen_spr_power5p_common(CPUPPCState
*env
)
7965 spr_register_kvm(env
, SPR_PPR
, "PPR",
7966 &spr_read_generic
, &spr_write_generic
,
7967 &spr_read_generic
, &spr_write_generic
,
7968 KVM_REG_PPC_PPR
, 0x00000000);
7971 static void gen_spr_power6_common(CPUPPCState
*env
)
7973 #if !defined(CONFIG_USER_ONLY)
7974 spr_register_kvm(env
, SPR_DSCR
, "SPR_DSCR",
7975 SPR_NOACCESS
, SPR_NOACCESS
,
7976 &spr_read_generic
, &spr_write_generic
,
7977 KVM_REG_PPC_DSCR
, 0x00000000);
7980 * Register PCR to report POWERPC_EXCP_PRIV_REG instead of
7981 * POWERPC_EXCP_INVAL_SPR in userspace. Permit hypervisor access.
7983 spr_register_hv(env
, SPR_PCR
, "PCR",
7984 SPR_NOACCESS
, SPR_NOACCESS
,
7985 SPR_NOACCESS
, SPR_NOACCESS
,
7986 &spr_read_generic
, &spr_write_pcr
,
7990 static void spr_read_tar(DisasContext
*ctx
, int gprn
, int sprn
)
7992 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_TAR
, sprn
, FSCR_IC_TAR
);
7993 spr_read_generic(ctx
, gprn
, sprn
);
7996 static void spr_write_tar(DisasContext
*ctx
, int sprn
, int gprn
)
7998 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_TAR
, sprn
, FSCR_IC_TAR
);
7999 spr_write_generic(ctx
, sprn
, gprn
);
8002 static void gen_spr_power8_tce_address_control(CPUPPCState
*env
)
8004 spr_register_kvm(env
, SPR_TAR
, "TAR",
8005 &spr_read_tar
, &spr_write_tar
,
8006 &spr_read_generic
, &spr_write_generic
,
8007 KVM_REG_PPC_TAR
, 0x00000000);
8010 static void spr_read_tm(DisasContext
*ctx
, int gprn
, int sprn
)
8012 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8013 spr_read_generic(ctx
, gprn
, sprn
);
8016 static void spr_write_tm(DisasContext
*ctx
, int sprn
, int gprn
)
8018 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8019 spr_write_generic(ctx
, sprn
, gprn
);
8022 static void spr_read_tm_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
8024 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8025 spr_read_prev_upper32(ctx
, gprn
, sprn
);
8028 static void spr_write_tm_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
8030 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8031 spr_write_prev_upper32(ctx
, sprn
, gprn
);
8034 static void gen_spr_power8_tm(CPUPPCState
*env
)
8036 spr_register_kvm(env
, SPR_TFHAR
, "TFHAR",
8037 &spr_read_tm
, &spr_write_tm
,
8038 &spr_read_tm
, &spr_write_tm
,
8039 KVM_REG_PPC_TFHAR
, 0x00000000);
8040 spr_register_kvm(env
, SPR_TFIAR
, "TFIAR",
8041 &spr_read_tm
, &spr_write_tm
,
8042 &spr_read_tm
, &spr_write_tm
,
8043 KVM_REG_PPC_TFIAR
, 0x00000000);
8044 spr_register_kvm(env
, SPR_TEXASR
, "TEXASR",
8045 &spr_read_tm
, &spr_write_tm
,
8046 &spr_read_tm
, &spr_write_tm
,
8047 KVM_REG_PPC_TEXASR
, 0x00000000);
8048 spr_register(env
, SPR_TEXASRU
, "TEXASRU",
8049 &spr_read_tm_upper32
, &spr_write_tm_upper32
,
8050 &spr_read_tm_upper32
, &spr_write_tm_upper32
,
8054 static void spr_read_ebb(DisasContext
*ctx
, int gprn
, int sprn
)
8056 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8057 spr_read_generic(ctx
, gprn
, sprn
);
8060 static void spr_write_ebb(DisasContext
*ctx
, int sprn
, int gprn
)
8062 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8063 spr_write_generic(ctx
, sprn
, gprn
);
8066 static void spr_read_ebb_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
8068 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8069 spr_read_prev_upper32(ctx
, gprn
, sprn
);
8072 static void spr_write_ebb_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
8074 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8075 spr_write_prev_upper32(ctx
, sprn
, gprn
);
8078 static void gen_spr_power8_ebb(CPUPPCState
*env
)
8080 spr_register(env
, SPR_BESCRS
, "BESCRS",
8081 &spr_read_ebb
, &spr_write_ebb
,
8082 &spr_read_generic
, &spr_write_generic
,
8084 spr_register(env
, SPR_BESCRSU
, "BESCRSU",
8085 &spr_read_ebb_upper32
, &spr_write_ebb_upper32
,
8086 &spr_read_prev_upper32
, &spr_write_prev_upper32
,
8088 spr_register(env
, SPR_BESCRR
, "BESCRR",
8089 &spr_read_ebb
, &spr_write_ebb
,
8090 &spr_read_generic
, &spr_write_generic
,
8092 spr_register(env
, SPR_BESCRRU
, "BESCRRU",
8093 &spr_read_ebb_upper32
, &spr_write_ebb_upper32
,
8094 &spr_read_prev_upper32
, &spr_write_prev_upper32
,
8096 spr_register_kvm(env
, SPR_EBBHR
, "EBBHR",
8097 &spr_read_ebb
, &spr_write_ebb
,
8098 &spr_read_generic
, &spr_write_generic
,
8099 KVM_REG_PPC_EBBHR
, 0x00000000);
8100 spr_register_kvm(env
, SPR_EBBRR
, "EBBRR",
8101 &spr_read_ebb
, &spr_write_ebb
,
8102 &spr_read_generic
, &spr_write_generic
,
8103 KVM_REG_PPC_EBBRR
, 0x00000000);
8104 spr_register_kvm(env
, SPR_BESCR
, "BESCR",
8105 &spr_read_ebb
, &spr_write_ebb
,
8106 &spr_read_generic
, &spr_write_generic
,
8107 KVM_REG_PPC_BESCR
, 0x00000000);
8110 /* Virtual Time Base */
8111 static void gen_spr_vtb(CPUPPCState
*env
)
8113 spr_register_kvm(env
, SPR_VTB
, "VTB",
8114 SPR_NOACCESS
, SPR_NOACCESS
,
8115 &spr_read_tbl
, SPR_NOACCESS
,
8116 KVM_REG_PPC_VTB
, 0x00000000);
8119 static void gen_spr_power8_fscr(CPUPPCState
*env
)
8121 #if defined(CONFIG_USER_ONLY)
8122 target_ulong initval
= 1ULL << FSCR_TAR
;
8124 target_ulong initval
= 0;
8126 spr_register_kvm(env
, SPR_FSCR
, "FSCR",
8127 SPR_NOACCESS
, SPR_NOACCESS
,
8128 &spr_read_generic
, &spr_write_generic
,
8129 KVM_REG_PPC_FSCR
, initval
);
8132 static void gen_spr_power8_pspb(CPUPPCState
*env
)
8134 spr_register_kvm(env
, SPR_PSPB
, "PSPB",
8135 SPR_NOACCESS
, SPR_NOACCESS
,
8136 &spr_read_generic
, &spr_write_generic32
,
8137 KVM_REG_PPC_PSPB
, 0);
8140 static void gen_spr_power8_ic(CPUPPCState
*env
)
8142 #if !defined(CONFIG_USER_ONLY)
8143 spr_register_hv(env
, SPR_IC
, "IC",
8144 SPR_NOACCESS
, SPR_NOACCESS
,
8145 &spr_read_generic
, SPR_NOACCESS
,
8146 &spr_read_generic
, &spr_write_generic
,
8151 static void gen_spr_power8_book4(CPUPPCState
*env
)
8153 /* Add a number of P8 book4 registers */
8154 #if !defined(CONFIG_USER_ONLY)
8155 spr_register_kvm(env
, SPR_ACOP
, "ACOP",
8156 SPR_NOACCESS
, SPR_NOACCESS
,
8157 &spr_read_generic
, &spr_write_generic
,
8158 KVM_REG_PPC_ACOP
, 0);
8159 spr_register_kvm(env
, SPR_BOOKS_PID
, "PID",
8160 SPR_NOACCESS
, SPR_NOACCESS
,
8161 &spr_read_generic
, &spr_write_pidr
,
8162 KVM_REG_PPC_PID
, 0);
8163 spr_register_kvm(env
, SPR_WORT
, "WORT",
8164 SPR_NOACCESS
, SPR_NOACCESS
,
8165 &spr_read_generic
, &spr_write_generic
,
8166 KVM_REG_PPC_WORT
, 0);
8170 static void gen_spr_power7_book4(CPUPPCState
*env
)
8172 /* Add a number of P7 book4 registers */
8173 #if !defined(CONFIG_USER_ONLY)
8174 spr_register_kvm(env
, SPR_ACOP
, "ACOP",
8175 SPR_NOACCESS
, SPR_NOACCESS
,
8176 &spr_read_generic
, &spr_write_generic
,
8177 KVM_REG_PPC_ACOP
, 0);
8178 spr_register_kvm(env
, SPR_BOOKS_PID
, "PID",
8179 SPR_NOACCESS
, SPR_NOACCESS
,
8180 &spr_read_generic
, &spr_write_generic
,
8181 KVM_REG_PPC_PID
, 0);
8185 static void gen_spr_power8_rpr(CPUPPCState
*env
)
8187 #if !defined(CONFIG_USER_ONLY)
8188 spr_register_hv(env
, SPR_RPR
, "RPR",
8189 SPR_NOACCESS
, SPR_NOACCESS
,
8190 SPR_NOACCESS
, SPR_NOACCESS
,
8191 &spr_read_generic
, &spr_write_generic
,
8192 0x00000103070F1F3F);
8196 static void gen_spr_power9_mmu(CPUPPCState
*env
)
8198 #if !defined(CONFIG_USER_ONLY)
8199 /* Partition Table Control */
8200 spr_register_hv(env
, SPR_PTCR
, "PTCR",
8201 SPR_NOACCESS
, SPR_NOACCESS
,
8202 SPR_NOACCESS
, SPR_NOACCESS
,
8203 &spr_read_generic
, &spr_write_ptcr
,
8208 static void init_proc_book3s_common(CPUPPCState
*env
)
8210 gen_spr_ne_601(env
);
8212 gen_spr_usprg3(env
);
8213 gen_spr_book3s_altivec(env
);
8214 gen_spr_book3s_pmu_sup(env
);
8215 gen_spr_book3s_pmu_user(env
);
8216 gen_spr_book3s_ctrl(env
);
8219 static void init_proc_970(CPUPPCState
*env
)
8221 /* Common Registers */
8222 init_proc_book3s_common(env
);
8224 gen_spr_book3s_dbg(env
);
8226 /* 970 Specific Registers */
8227 gen_spr_970_hid(env
);
8228 gen_spr_970_hior(env
);
8230 gen_spr_970_pmu_sup(env
);
8231 gen_spr_970_pmu_user(env
);
8232 gen_spr_970_lpar(env
);
8233 gen_spr_970_dbg(env
);
8236 env
->dcache_line_size
= 128;
8237 env
->icache_line_size
= 128;
8239 /* Allocate hardware IRQ controller */
8241 ppc970_irq_init(ppc_env_get_cpu(env
));
8244 POWERPC_FAMILY(970)(ObjectClass
*oc
, void *data
)
8246 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8247 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8249 dc
->desc
= "PowerPC 970";
8250 pcc
->init_proc
= init_proc_970
;
8251 pcc
->check_pow
= check_pow_970
;
8252 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
8253 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8254 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8256 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8257 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8258 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8259 PPC_64B
| PPC_ALTIVEC
|
8260 PPC_SEGMENT_64B
| PPC_SLBI
;
8261 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
8262 pcc
->msr_mask
= (1ull << MSR_SF
) |
8277 pcc
->mmu_model
= POWERPC_MMU_64B
;
8278 #if defined(CONFIG_SOFTMMU)
8279 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8280 pcc
->hash64_opts
= &ppc_hash64_opts_basic
;
8282 pcc
->excp_model
= POWERPC_EXCP_970
;
8283 pcc
->bus_model
= PPC_FLAGS_INPUT_970
;
8284 pcc
->bfd_mach
= bfd_mach_ppc64
;
8285 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8286 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8287 POWERPC_FLAG_BUS_CLK
;
8288 pcc
->l1_dcache_size
= 0x8000;
8289 pcc
->l1_icache_size
= 0x10000;
8292 static void init_proc_power5plus(CPUPPCState
*env
)
8294 /* Common Registers */
8295 init_proc_book3s_common(env
);
8297 gen_spr_book3s_dbg(env
);
8299 /* POWER5+ Specific Registers */
8300 gen_spr_970_hid(env
);
8301 gen_spr_970_hior(env
);
8303 gen_spr_970_pmu_sup(env
);
8304 gen_spr_970_pmu_user(env
);
8305 gen_spr_power5p_common(env
);
8306 gen_spr_power5p_lpar(env
);
8307 gen_spr_power5p_ear(env
);
8310 env
->dcache_line_size
= 128;
8311 env
->icache_line_size
= 128;
8313 /* Allocate hardware IRQ controller */
8315 ppc970_irq_init(ppc_env_get_cpu(env
));
8318 POWERPC_FAMILY(POWER5P
)(ObjectClass
*oc
, void *data
)
8320 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8321 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8323 dc
->fw_name
= "PowerPC,POWER5";
8324 dc
->desc
= "POWER5+";
8325 pcc
->init_proc
= init_proc_power5plus
;
8326 pcc
->check_pow
= check_pow_970
;
8327 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
8328 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8329 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8331 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8332 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8333 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8335 PPC_SEGMENT_64B
| PPC_SLBI
;
8336 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
8337 pcc
->msr_mask
= (1ull << MSR_SF
) |
8352 pcc
->mmu_model
= POWERPC_MMU_2_03
;
8353 #if defined(CONFIG_SOFTMMU)
8354 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8355 pcc
->hash64_opts
= &ppc_hash64_opts_basic
;
8357 pcc
->excp_model
= POWERPC_EXCP_970
;
8358 pcc
->bus_model
= PPC_FLAGS_INPUT_970
;
8359 pcc
->bfd_mach
= bfd_mach_ppc64
;
8360 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8361 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8362 POWERPC_FLAG_BUS_CLK
;
8363 pcc
->l1_dcache_size
= 0x8000;
8364 pcc
->l1_icache_size
= 0x10000;
8368 * The CPU used to have a "compat" property which set the
8369 * compatibility mode PVR. However, this was conceptually broken - it
8370 * only makes sense on the pseries machine type (otherwise the guest
8371 * owns the PCR and can control the compatibility mode itself). It's
8372 * been replaced with the 'max-cpu-compat' property on the pseries
8373 * machine type. For backwards compatibility, pseries specially
8374 * parses the -cpu parameter and converts old compat= parameters into
8375 * the appropriate machine parameters. This stub implementation of
8376 * the parameter catches any uses on explicitly created CPUs.
8378 static void getset_compat_deprecated(Object
*obj
, Visitor
*v
, const char *name
,
8379 void *opaque
, Error
**errp
)
8383 if (!qtest_enabled()) {
8384 error_report("CPU 'compat' property is deprecated and has no effect; "
8385 "use max-cpu-compat machine property instead");
8387 visit_type_null(v
, name
, &null
, NULL
);
8388 qobject_unref(null
);
8391 static const PropertyInfo ppc_compat_deprecated_propinfo
= {
8393 .description
= "compatibility mode (deprecated)",
8394 .get
= getset_compat_deprecated
,
8395 .set
= getset_compat_deprecated
,
8397 static Property powerpc_servercpu_properties
[] = {
8400 .info
= &ppc_compat_deprecated_propinfo
,
8402 DEFINE_PROP_END_OF_LIST(),
8405 static void init_proc_POWER7(CPUPPCState
*env
)
8407 /* Common Registers */
8408 init_proc_book3s_common(env
);
8410 gen_spr_book3s_dbg(env
);
8412 /* POWER7 Specific Registers */
8413 gen_spr_book3s_ids(env
);
8415 gen_spr_book3s_purr(env
);
8416 gen_spr_power5p_common(env
);
8417 gen_spr_power5p_lpar(env
);
8418 gen_spr_power5p_ear(env
);
8419 gen_spr_power6_common(env
);
8420 gen_spr_power6_dbg(env
);
8421 gen_spr_power7_book4(env
);
8424 env
->dcache_line_size
= 128;
8425 env
->icache_line_size
= 128;
8427 /* Allocate hardware IRQ controller */
8428 init_excp_POWER7(env
);
8429 ppcPOWER7_irq_init(ppc_env_get_cpu(env
));
8432 static bool ppc_pvr_match_power7(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8434 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER7P_BASE
) {
8437 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER7_BASE
) {
8443 static bool cpu_has_work_POWER7(CPUState
*cs
)
8445 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8446 CPUPPCState
*env
= &cpu
->env
;
8449 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8452 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8453 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE0
)) {
8456 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8457 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE1
)) {
8460 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
)) &&
8461 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE2
)) {
8464 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HMI
)) &&
8465 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE2
)) {
8468 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8473 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8477 POWERPC_FAMILY(POWER7
)(ObjectClass
*oc
, void *data
)
8479 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8480 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8481 CPUClass
*cc
= CPU_CLASS(oc
);
8483 dc
->fw_name
= "PowerPC,POWER7";
8484 dc
->desc
= "POWER7";
8485 dc
->props
= powerpc_servercpu_properties
;
8486 pcc
->pvr_match
= ppc_pvr_match_power7
;
8487 pcc
->pcr_mask
= PCR_VEC_DIS
| PCR_VSX_DIS
| PCR_COMPAT_2_05
;
8488 pcc
->pcr_supported
= PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8489 pcc
->init_proc
= init_proc_POWER7
;
8490 pcc
->check_pow
= check_pow_nocheck
;
8491 cc
->has_work
= cpu_has_work_POWER7
;
8492 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8493 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8494 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8495 PPC_FLOAT_FRSQRTES
|
8498 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8499 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8500 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8501 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
8502 PPC_SEGMENT_64B
| PPC_SLBI
|
8503 PPC_POPCNTB
| PPC_POPCNTWD
|
8505 pcc
->insns_flags2
= PPC2_VSX
| PPC2_DFP
| PPC2_DBRX
| PPC2_ISA205
|
8506 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8507 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8508 PPC2_FP_TST_ISA206
| PPC2_FP_CVT_S64
|
8510 pcc
->msr_mask
= (1ull << MSR_SF
) |
8526 pcc
->mmu_model
= POWERPC_MMU_2_06
;
8527 #if defined(CONFIG_SOFTMMU)
8528 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8529 pcc
->hash64_opts
= &ppc_hash64_opts_POWER7
;
8531 pcc
->excp_model
= POWERPC_EXCP_POWER7
;
8532 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8533 pcc
->bfd_mach
= bfd_mach_ppc64
;
8534 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8535 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8536 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8538 pcc
->l1_dcache_size
= 0x8000;
8539 pcc
->l1_icache_size
= 0x8000;
8540 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8541 pcc
->lpcr_pm
= LPCR_P7_PECE0
| LPCR_P7_PECE1
| LPCR_P7_PECE2
;
8544 static void init_proc_POWER8(CPUPPCState
*env
)
8546 /* Common Registers */
8547 init_proc_book3s_common(env
);
8549 gen_spr_book3s_207_dbg(env
);
8551 /* POWER8 Specific Registers */
8552 gen_spr_book3s_ids(env
);
8555 gen_spr_book3s_purr(env
);
8556 gen_spr_power5p_common(env
);
8557 gen_spr_power5p_lpar(env
);
8558 gen_spr_power5p_ear(env
);
8559 gen_spr_power6_common(env
);
8560 gen_spr_power6_dbg(env
);
8561 gen_spr_power8_tce_address_control(env
);
8562 gen_spr_power8_ids(env
);
8563 gen_spr_power8_ebb(env
);
8564 gen_spr_power8_fscr(env
);
8565 gen_spr_power8_pmu_sup(env
);
8566 gen_spr_power8_pmu_user(env
);
8567 gen_spr_power8_tm(env
);
8568 gen_spr_power8_pspb(env
);
8570 gen_spr_power8_ic(env
);
8571 gen_spr_power8_book4(env
);
8572 gen_spr_power8_rpr(env
);
8575 env
->dcache_line_size
= 128;
8576 env
->icache_line_size
= 128;
8578 /* Allocate hardware IRQ controller */
8579 init_excp_POWER8(env
);
8580 ppcPOWER7_irq_init(ppc_env_get_cpu(env
));
8583 static bool ppc_pvr_match_power8(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8585 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8NVL_BASE
) {
8588 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8E_BASE
) {
8591 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8_BASE
) {
8597 static bool cpu_has_work_POWER8(CPUState
*cs
)
8599 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8600 CPUPPCState
*env
= &cpu
->env
;
8603 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8606 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8607 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE2
)) {
8610 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8611 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE3
)) {
8614 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
)) &&
8615 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE4
)) {
8618 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HMI
)) &&
8619 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE4
)) {
8622 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DOORBELL
)) &&
8623 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE0
)) {
8626 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HDOORBELL
)) &&
8627 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE1
)) {
8630 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8635 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8639 POWERPC_FAMILY(POWER8
)(ObjectClass
*oc
, void *data
)
8641 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8642 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8643 CPUClass
*cc
= CPU_CLASS(oc
);
8645 dc
->fw_name
= "PowerPC,POWER8";
8646 dc
->desc
= "POWER8";
8647 dc
->props
= powerpc_servercpu_properties
;
8648 pcc
->pvr_match
= ppc_pvr_match_power8
;
8649 pcc
->pcr_mask
= PCR_TM_DIS
| PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8650 pcc
->pcr_supported
= PCR_COMPAT_2_07
| PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8651 pcc
->init_proc
= init_proc_POWER8
;
8652 pcc
->check_pow
= check_pow_nocheck
;
8653 cc
->has_work
= cpu_has_work_POWER8
;
8654 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8655 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8656 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8657 PPC_FLOAT_FRSQRTES
|
8660 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8661 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8662 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8663 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
8664 PPC_SEGMENT_64B
| PPC_SLBI
|
8665 PPC_POPCNTB
| PPC_POPCNTWD
|
8667 pcc
->insns_flags2
= PPC2_VSX
| PPC2_VSX207
| PPC2_DFP
| PPC2_DBRX
|
8668 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8669 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8670 PPC2_FP_TST_ISA206
| PPC2_BCTAR_ISA207
|
8671 PPC2_LSQ_ISA207
| PPC2_ALTIVEC_207
|
8672 PPC2_ISA205
| PPC2_ISA207S
| PPC2_FP_CVT_S64
|
8673 PPC2_TM
| PPC2_PM_ISA206
;
8674 pcc
->msr_mask
= (1ull << MSR_SF
) |
8694 pcc
->mmu_model
= POWERPC_MMU_2_07
;
8695 #if defined(CONFIG_SOFTMMU)
8696 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8697 pcc
->hash64_opts
= &ppc_hash64_opts_POWER7
;
8699 pcc
->excp_model
= POWERPC_EXCP_POWER8
;
8700 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8701 pcc
->bfd_mach
= bfd_mach_ppc64
;
8702 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8703 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8704 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8705 POWERPC_FLAG_VSX
| POWERPC_FLAG_TM
;
8706 pcc
->l1_dcache_size
= 0x8000;
8707 pcc
->l1_icache_size
= 0x8000;
8708 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8709 pcc
->lpcr_pm
= LPCR_P8_PECE0
| LPCR_P8_PECE1
| LPCR_P8_PECE2
|
8710 LPCR_P8_PECE3
| LPCR_P8_PECE4
;
8713 #ifdef CONFIG_SOFTMMU
8715 * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
8716 * Encoded as array of int_32s in the form:
8717 * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
8719 * y -> radix mode supported page size (encoded as a shift)
8721 static struct ppc_radix_page_info POWER9_radix_page_info
= {
8724 0x0000000c, /* 4K - enc: 0x0 */
8725 0xa0000010, /* 64K - enc: 0x5 */
8726 0x20000015, /* 2M - enc: 0x1 */
8727 0x4000001e /* 1G - enc: 0x2 */
8730 #endif /* CONFIG_SOFTMMU */
8732 static void init_proc_POWER9(CPUPPCState
*env
)
8734 /* Common Registers */
8735 init_proc_book3s_common(env
);
8736 gen_spr_book3s_207_dbg(env
);
8738 /* POWER8 Specific Registers */
8739 gen_spr_book3s_ids(env
);
8742 gen_spr_book3s_purr(env
);
8743 gen_spr_power5p_common(env
);
8744 gen_spr_power5p_lpar(env
);
8745 gen_spr_power5p_ear(env
);
8746 gen_spr_power6_common(env
);
8747 gen_spr_power6_dbg(env
);
8748 gen_spr_power8_tce_address_control(env
);
8749 gen_spr_power8_ids(env
);
8750 gen_spr_power8_ebb(env
);
8751 gen_spr_power8_fscr(env
);
8752 gen_spr_power8_pmu_sup(env
);
8753 gen_spr_power8_pmu_user(env
);
8754 gen_spr_power8_tm(env
);
8755 gen_spr_power8_pspb(env
);
8757 gen_spr_power8_ic(env
);
8758 gen_spr_power8_book4(env
);
8759 gen_spr_power8_rpr(env
);
8760 gen_spr_power9_mmu(env
);
8762 /* POWER9 Specific registers */
8763 spr_register_kvm(env
, SPR_TIDR
, "TIDR", NULL
, NULL
,
8764 spr_read_generic
, spr_write_generic
,
8765 KVM_REG_PPC_TIDR
, 0);
8767 /* FIXME: Filter fields properly based on privilege level */
8768 spr_register_kvm_hv(env
, SPR_PSSCR
, "PSSCR", NULL
, NULL
, NULL
, NULL
,
8769 spr_read_generic
, spr_write_generic
,
8770 KVM_REG_PPC_PSSCR
, 0);
8773 env
->dcache_line_size
= 128;
8774 env
->icache_line_size
= 128;
8776 /* Allocate hardware IRQ controller */
8777 init_excp_POWER8(env
);
8778 ppcPOWER7_irq_init(ppc_env_get_cpu(env
));
8781 static bool ppc_pvr_match_power9(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8783 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER9_BASE
) {
8789 static bool cpu_has_work_POWER9(CPUState
*cs
)
8791 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8792 CPUPPCState
*env
= &cpu
->env
;
8795 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8798 /* External Exception */
8799 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8800 (env
->spr
[SPR_LPCR
] & LPCR_EEE
)) {
8803 /* Decrementer Exception */
8804 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8805 (env
->spr
[SPR_LPCR
] & LPCR_DEE
)) {
8808 /* Machine Check or Hypervisor Maintenance Exception */
8809 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
|
8810 1u << PPC_INTERRUPT_HMI
)) && (env
->spr
[SPR_LPCR
] & LPCR_OEE
)) {
8813 /* Privileged Doorbell Exception */
8814 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DOORBELL
)) &&
8815 (env
->spr
[SPR_LPCR
] & LPCR_PDEE
)) {
8818 /* Hypervisor Doorbell Exception */
8819 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HDOORBELL
)) &&
8820 (env
->spr
[SPR_LPCR
] & LPCR_HDEE
)) {
8823 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8828 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8832 POWERPC_FAMILY(POWER9
)(ObjectClass
*oc
, void *data
)
8834 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8835 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8836 CPUClass
*cc
= CPU_CLASS(oc
);
8838 dc
->fw_name
= "PowerPC,POWER9";
8839 dc
->desc
= "POWER9";
8840 dc
->props
= powerpc_servercpu_properties
;
8841 pcc
->pvr_match
= ppc_pvr_match_power9
;
8842 pcc
->pcr_mask
= PCR_COMPAT_2_05
| PCR_COMPAT_2_06
| PCR_COMPAT_2_07
;
8843 pcc
->pcr_supported
= PCR_COMPAT_3_00
| PCR_COMPAT_2_07
| PCR_COMPAT_2_06
|
8845 pcc
->init_proc
= init_proc_POWER9
;
8846 pcc
->check_pow
= check_pow_nocheck
;
8847 cc
->has_work
= cpu_has_work_POWER9
;
8848 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8849 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8850 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8851 PPC_FLOAT_FRSQRTES
|
8854 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8855 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8857 PPC_64B
| PPC_64BX
| PPC_ALTIVEC
|
8858 PPC_SEGMENT_64B
| PPC_SLBI
|
8859 PPC_POPCNTB
| PPC_POPCNTWD
|
8861 pcc
->insns_flags2
= PPC2_VSX
| PPC2_VSX207
| PPC2_DFP
| PPC2_DBRX
|
8862 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8863 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8864 PPC2_FP_TST_ISA206
| PPC2_BCTAR_ISA207
|
8865 PPC2_LSQ_ISA207
| PPC2_ALTIVEC_207
|
8866 PPC2_ISA205
| PPC2_ISA207S
| PPC2_FP_CVT_S64
|
8867 PPC2_TM
| PPC2_PM_ISA206
| PPC2_ISA300
| PPC2_PRCNTL
;
8868 pcc
->msr_mask
= (1ull << MSR_SF
) |
8885 pcc
->mmu_model
= POWERPC_MMU_3_00
;
8886 #if defined(CONFIG_SOFTMMU)
8887 pcc
->handle_mmu_fault
= ppc64_v3_handle_mmu_fault
;
8888 /* segment page size remain the same */
8889 pcc
->hash64_opts
= &ppc_hash64_opts_POWER7
;
8890 pcc
->radix_page_info
= &POWER9_radix_page_info
;
8892 pcc
->excp_model
= POWERPC_EXCP_POWER8
;
8893 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8894 pcc
->bfd_mach
= bfd_mach_ppc64
;
8895 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8896 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8897 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8898 POWERPC_FLAG_VSX
| POWERPC_FLAG_TM
;
8899 pcc
->l1_dcache_size
= 0x8000;
8900 pcc
->l1_icache_size
= 0x8000;
8901 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8902 pcc
->lpcr_pm
= LPCR_PDEE
| LPCR_HDEE
| LPCR_EEE
| LPCR_DEE
| LPCR_OEE
;
8905 #if !defined(CONFIG_USER_ONLY)
8906 void cpu_ppc_set_vhyp(PowerPCCPU
*cpu
, PPCVirtualHypervisor
*vhyp
)
8908 CPUPPCState
*env
= &cpu
->env
;
8913 * With a virtual hypervisor mode we never allow the CPU to go
8914 * hypervisor mode itself
8916 env
->msr_mask
&= ~MSR_HVB
;
8919 #endif /* !defined(CONFIG_USER_ONLY) */
8921 #endif /* defined(TARGET_PPC64) */
8923 /*****************************************************************************/
8924 /* Generic CPU instantiation routine */
8925 static void init_ppc_proc(PowerPCCPU
*cpu
)
8927 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
8928 CPUPPCState
*env
= &cpu
->env
;
8929 #if !defined(CONFIG_USER_ONLY)
8932 env
->irq_inputs
= NULL
;
8933 /* Set all exception vectors to an invalid address */
8934 for (i
= 0; i
< POWERPC_EXCP_NB
; i
++)
8935 env
->excp_vectors
[i
] = (target_ulong
)(-1ULL);
8936 env
->ivor_mask
= 0x00000000;
8937 env
->ivpr_mask
= 0x00000000;
8938 /* Default MMU definitions */
8942 env
->tlb_type
= TLB_NONE
;
8944 /* Register SPR common to all PowerPC implementations */
8945 gen_spr_generic(env
);
8946 spr_register(env
, SPR_PVR
, "PVR",
8947 /* Linux permits userspace to read PVR */
8948 #if defined(CONFIG_LINUX_USER)
8954 &spr_read_generic
, SPR_NOACCESS
,
8956 /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
8957 if (pcc
->svr
!= POWERPC_SVR_NONE
) {
8958 if (pcc
->svr
& POWERPC_SVR_E500
) {
8959 spr_register(env
, SPR_E500_SVR
, "SVR",
8960 SPR_NOACCESS
, SPR_NOACCESS
,
8961 &spr_read_generic
, SPR_NOACCESS
,
8962 pcc
->svr
& ~POWERPC_SVR_E500
);
8964 spr_register(env
, SPR_SVR
, "SVR",
8965 SPR_NOACCESS
, SPR_NOACCESS
,
8966 &spr_read_generic
, SPR_NOACCESS
,
8970 /* PowerPC implementation specific initialisations (SPRs, timers, ...) */
8971 (*pcc
->init_proc
)(env
);
8973 /* MSR bits & flags consistency checks */
8974 if (env
->msr_mask
& (1 << 25)) {
8975 switch (env
->flags
& (POWERPC_FLAG_SPE
| POWERPC_FLAG_VRE
)) {
8976 case POWERPC_FLAG_SPE
:
8977 case POWERPC_FLAG_VRE
:
8980 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
8981 "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n");
8984 } else if (env
->flags
& (POWERPC_FLAG_SPE
| POWERPC_FLAG_VRE
)) {
8985 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
8986 "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n");
8989 if (env
->msr_mask
& (1 << 17)) {
8990 switch (env
->flags
& (POWERPC_FLAG_TGPR
| POWERPC_FLAG_CE
)) {
8991 case POWERPC_FLAG_TGPR
:
8992 case POWERPC_FLAG_CE
:
8995 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
8996 "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n");
8999 } else if (env
->flags
& (POWERPC_FLAG_TGPR
| POWERPC_FLAG_CE
)) {
9000 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9001 "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n");
9004 if (env
->msr_mask
& (1 << 10)) {
9005 switch (env
->flags
& (POWERPC_FLAG_SE
| POWERPC_FLAG_DWE
|
9006 POWERPC_FLAG_UBLE
)) {
9007 case POWERPC_FLAG_SE
:
9008 case POWERPC_FLAG_DWE
:
9009 case POWERPC_FLAG_UBLE
:
9012 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9013 "Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE or "
9014 "POWERPC_FLAG_UBLE\n");
9017 } else if (env
->flags
& (POWERPC_FLAG_SE
| POWERPC_FLAG_DWE
|
9018 POWERPC_FLAG_UBLE
)) {
9019 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9020 "Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE nor "
9021 "POWERPC_FLAG_UBLE\n");
9024 if (env
->msr_mask
& (1 << 9)) {
9025 switch (env
->flags
& (POWERPC_FLAG_BE
| POWERPC_FLAG_DE
)) {
9026 case POWERPC_FLAG_BE
:
9027 case POWERPC_FLAG_DE
:
9030 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9031 "Should define POWERPC_FLAG_BE or POWERPC_FLAG_DE\n");
9034 } else if (env
->flags
& (POWERPC_FLAG_BE
| POWERPC_FLAG_DE
)) {
9035 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9036 "Should not define POWERPC_FLAG_BE nor POWERPC_FLAG_DE\n");
9039 if (env
->msr_mask
& (1 << 2)) {
9040 switch (env
->flags
& (POWERPC_FLAG_PX
| POWERPC_FLAG_PMM
)) {
9041 case POWERPC_FLAG_PX
:
9042 case POWERPC_FLAG_PMM
:
9045 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9046 "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n");
9049 } else if (env
->flags
& (POWERPC_FLAG_PX
| POWERPC_FLAG_PMM
)) {
9050 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9051 "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
9054 if ((env
->flags
& (POWERPC_FLAG_RTC_CLK
| POWERPC_FLAG_BUS_CLK
)) == 0) {
9055 fprintf(stderr
, "PowerPC flags inconsistency\n"
9056 "Should define the time-base and decrementer clock source\n");
9059 /* Allocate TLBs buffer when needed */
9060 #if !defined(CONFIG_USER_ONLY)
9061 if (env
->nb_tlb
!= 0) {
9062 int nb_tlb
= env
->nb_tlb
;
9063 if (env
->id_tlbs
!= 0)
9065 switch (env
->tlb_type
) {
9067 env
->tlb
.tlb6
= g_malloc0(nb_tlb
* sizeof(ppc6xx_tlb_t
));
9070 env
->tlb
.tlbe
= g_malloc0(nb_tlb
* sizeof(ppcemb_tlb_t
));
9073 env
->tlb
.tlbm
= g_malloc0(nb_tlb
* sizeof(ppcmas_tlb_t
));
9076 /* Pre-compute some useful values */
9077 env
->tlb_per_way
= env
->nb_tlb
/ env
->nb_ways
;
9079 if (env
->irq_inputs
== NULL
) {
9080 warn_report("no internal IRQ controller registered."
9081 " Attempt QEMU to crash very soon !");
9084 if (env
->check_pow
== NULL
) {
9085 warn_report("no power management check handler registered."
9086 " Attempt QEMU to crash very soon !");
9090 #if defined(PPC_DUMP_CPU)
9091 static void dump_ppc_sprs(CPUPPCState
*env
)
9094 #if !defined(CONFIG_USER_ONLY)
9100 printf("Special purpose registers:\n");
9101 for (i
= 0; i
< 32; i
++) {
9102 for (j
= 0; j
< 32; j
++) {
9104 spr
= &env
->spr_cb
[n
];
9105 uw
= spr
->uea_write
!= NULL
&& spr
->uea_write
!= SPR_NOACCESS
;
9106 ur
= spr
->uea_read
!= NULL
&& spr
->uea_read
!= SPR_NOACCESS
;
9107 #if !defined(CONFIG_USER_ONLY)
9108 sw
= spr
->oea_write
!= NULL
&& spr
->oea_write
!= SPR_NOACCESS
;
9109 sr
= spr
->oea_read
!= NULL
&& spr
->oea_read
!= SPR_NOACCESS
;
9110 if (sw
|| sr
|| uw
|| ur
) {
9111 printf("SPR: %4d (%03x) %-8s s%c%c u%c%c\n",
9112 (i
<< 5) | j
, (i
<< 5) | j
, spr
->name
,
9113 sw
? 'w' : '-', sr
? 'r' : '-',
9114 uw
? 'w' : '-', ur
? 'r' : '-');
9118 printf("SPR: %4d (%03x) %-8s u%c%c\n",
9119 (i
<< 5) | j
, (i
<< 5) | j
, spr
->name
,
9120 uw
? 'w' : '-', ur
? 'r' : '-');
9130 /*****************************************************************************/
9134 PPC_DIRECT
= 0, /* Opcode routine */
9135 PPC_INDIRECT
= 1, /* Indirect opcode table */
9138 #define PPC_OPCODE_MASK 0x3
9140 static inline int is_indirect_opcode(void *handler
)
9142 return ((uintptr_t)handler
& PPC_OPCODE_MASK
) == PPC_INDIRECT
;
9145 static inline opc_handler_t
**ind_table(void *handler
)
9147 return (opc_handler_t
**)((uintptr_t)handler
& ~PPC_OPCODE_MASK
);
9150 /* Instruction table creation */
9151 /* Opcodes tables creation */
9152 static void fill_new_table(opc_handler_t
**table
, int len
)
9156 for (i
= 0; i
< len
; i
++)
9157 table
[i
] = &invalid_handler
;
9160 static int create_new_table(opc_handler_t
**table
, unsigned char idx
)
9162 opc_handler_t
**tmp
;
9164 tmp
= g_new(opc_handler_t
*, PPC_CPU_INDIRECT_OPCODES_LEN
);
9165 fill_new_table(tmp
, PPC_CPU_INDIRECT_OPCODES_LEN
);
9166 table
[idx
] = (opc_handler_t
*)((uintptr_t)tmp
| PPC_INDIRECT
);
9171 static int insert_in_table(opc_handler_t
**table
, unsigned char idx
,
9172 opc_handler_t
*handler
)
9174 if (table
[idx
] != &invalid_handler
)
9176 table
[idx
] = handler
;
9181 static int register_direct_insn(opc_handler_t
**ppc_opcodes
,
9182 unsigned char idx
, opc_handler_t
*handler
)
9184 if (insert_in_table(ppc_opcodes
, idx
, handler
) < 0) {
9185 printf("*** ERROR: opcode %02x already assigned in main "
9186 "opcode table\n", idx
);
9187 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9188 printf(" Registered handler '%s' - new handler '%s'\n",
9189 ppc_opcodes
[idx
]->oname
, handler
->oname
);
9197 static int register_ind_in_table(opc_handler_t
**table
,
9198 unsigned char idx1
, unsigned char idx2
,
9199 opc_handler_t
*handler
)
9201 if (table
[idx1
] == &invalid_handler
) {
9202 if (create_new_table(table
, idx1
) < 0) {
9203 printf("*** ERROR: unable to create indirect table "
9204 "idx=%02x\n", idx1
);
9208 if (!is_indirect_opcode(table
[idx1
])) {
9209 printf("*** ERROR: idx %02x already assigned to a direct "
9211 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9212 printf(" Registered handler '%s' - new handler '%s'\n",
9213 ind_table(table
[idx1
])[idx2
]->oname
, handler
->oname
);
9218 if (handler
!= NULL
&&
9219 insert_in_table(ind_table(table
[idx1
]), idx2
, handler
) < 0) {
9220 printf("*** ERROR: opcode %02x already assigned in "
9221 "opcode table %02x\n", idx2
, idx1
);
9222 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9223 printf(" Registered handler '%s' - new handler '%s'\n",
9224 ind_table(table
[idx1
])[idx2
]->oname
, handler
->oname
);
9232 static int register_ind_insn(opc_handler_t
**ppc_opcodes
,
9233 unsigned char idx1
, unsigned char idx2
,
9234 opc_handler_t
*handler
)
9236 return register_ind_in_table(ppc_opcodes
, idx1
, idx2
, handler
);
9239 static int register_dblind_insn(opc_handler_t
**ppc_opcodes
,
9240 unsigned char idx1
, unsigned char idx2
,
9241 unsigned char idx3
, opc_handler_t
*handler
)
9243 if (register_ind_in_table(ppc_opcodes
, idx1
, idx2
, NULL
) < 0) {
9244 printf("*** ERROR: unable to join indirect table idx "
9245 "[%02x-%02x]\n", idx1
, idx2
);
9248 if (register_ind_in_table(ind_table(ppc_opcodes
[idx1
]), idx2
, idx3
,
9250 printf("*** ERROR: unable to insert opcode "
9251 "[%02x-%02x-%02x]\n", idx1
, idx2
, idx3
);
9258 static int register_trplind_insn(opc_handler_t
**ppc_opcodes
,
9259 unsigned char idx1
, unsigned char idx2
,
9260 unsigned char idx3
, unsigned char idx4
,
9261 opc_handler_t
*handler
)
9263 opc_handler_t
**table
;
9265 if (register_ind_in_table(ppc_opcodes
, idx1
, idx2
, NULL
) < 0) {
9266 printf("*** ERROR: unable to join indirect table idx "
9267 "[%02x-%02x]\n", idx1
, idx2
);
9270 table
= ind_table(ppc_opcodes
[idx1
]);
9271 if (register_ind_in_table(table
, idx2
, idx3
, NULL
) < 0) {
9272 printf("*** ERROR: unable to join 2nd-level indirect table idx "
9273 "[%02x-%02x-%02x]\n", idx1
, idx2
, idx3
);
9276 table
= ind_table(table
[idx2
]);
9277 if (register_ind_in_table(table
, idx3
, idx4
, handler
) < 0) {
9278 printf("*** ERROR: unable to insert opcode "
9279 "[%02x-%02x-%02x-%02x]\n", idx1
, idx2
, idx3
, idx4
);
9284 static int register_insn(opc_handler_t
**ppc_opcodes
, opcode_t
*insn
)
9286 if (insn
->opc2
!= 0xFF) {
9287 if (insn
->opc3
!= 0xFF) {
9288 if (insn
->opc4
!= 0xFF) {
9289 if (register_trplind_insn(ppc_opcodes
, insn
->opc1
, insn
->opc2
,
9290 insn
->opc3
, insn
->opc4
,
9291 &insn
->handler
) < 0) {
9295 if (register_dblind_insn(ppc_opcodes
, insn
->opc1
, insn
->opc2
,
9296 insn
->opc3
, &insn
->handler
) < 0)
9300 if (register_ind_insn(ppc_opcodes
, insn
->opc1
,
9301 insn
->opc2
, &insn
->handler
) < 0)
9305 if (register_direct_insn(ppc_opcodes
, insn
->opc1
, &insn
->handler
) < 0)
9312 static int test_opcode_table(opc_handler_t
**table
, int len
)
9316 for (i
= 0, count
= 0; i
< len
; i
++) {
9317 /* Consistency fixup */
9318 if (table
[i
] == NULL
)
9319 table
[i
] = &invalid_handler
;
9320 if (table
[i
] != &invalid_handler
) {
9321 if (is_indirect_opcode(table
[i
])) {
9322 tmp
= test_opcode_table(ind_table(table
[i
]),
9323 PPC_CPU_INDIRECT_OPCODES_LEN
);
9326 table
[i
] = &invalid_handler
;
9339 static void fix_opcode_tables(opc_handler_t
**ppc_opcodes
)
9341 if (test_opcode_table(ppc_opcodes
, PPC_CPU_OPCODES_LEN
) == 0)
9342 printf("*** WARNING: no opcode defined !\n");
9345 /*****************************************************************************/
9346 static void create_ppc_opcodes(PowerPCCPU
*cpu
, Error
**errp
)
9348 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9349 CPUPPCState
*env
= &cpu
->env
;
9352 fill_new_table(env
->opcodes
, PPC_CPU_OPCODES_LEN
);
9353 for (opc
= opcodes
; opc
< &opcodes
[ARRAY_SIZE(opcodes
)]; opc
++) {
9354 if (((opc
->handler
.type
& pcc
->insns_flags
) != 0) ||
9355 ((opc
->handler
.type2
& pcc
->insns_flags2
) != 0)) {
9356 if (register_insn(env
->opcodes
, opc
) < 0) {
9357 error_setg(errp
, "ERROR initializing PowerPC instruction "
9358 "0x%02x 0x%02x 0x%02x", opc
->opc1
, opc
->opc2
,
9364 fix_opcode_tables(env
->opcodes
);
9369 #if defined(PPC_DUMP_CPU)
9370 static void dump_ppc_insns(CPUPPCState
*env
)
9372 opc_handler_t
**table
, *handler
;
9374 uint8_t opc1
, opc2
, opc3
, opc4
;
9376 printf("Instructions set:\n");
9377 /* opc1 is 6 bits long */
9378 for (opc1
= 0x00; opc1
< PPC_CPU_OPCODES_LEN
; opc1
++) {
9379 table
= env
->opcodes
;
9380 handler
= table
[opc1
];
9381 if (is_indirect_opcode(handler
)) {
9382 /* opc2 is 5 bits long */
9383 for (opc2
= 0; opc2
< PPC_CPU_INDIRECT_OPCODES_LEN
; opc2
++) {
9384 table
= env
->opcodes
;
9385 handler
= env
->opcodes
[opc1
];
9386 table
= ind_table(handler
);
9387 handler
= table
[opc2
];
9388 if (is_indirect_opcode(handler
)) {
9389 table
= ind_table(handler
);
9390 /* opc3 is 5 bits long */
9391 for (opc3
= 0; opc3
< PPC_CPU_INDIRECT_OPCODES_LEN
;
9393 handler
= table
[opc3
];
9394 if (is_indirect_opcode(handler
)) {
9395 table
= ind_table(handler
);
9396 /* opc4 is 5 bits long */
9397 for (opc4
= 0; opc4
< PPC_CPU_INDIRECT_OPCODES_LEN
;
9399 handler
= table
[opc4
];
9400 if (handler
->handler
!= &gen_invalid
) {
9401 printf("INSN: %02x %02x %02x %02x -- "
9402 "(%02d %04d %02d) : %s\n",
9403 opc1
, opc2
, opc3
, opc4
,
9404 opc1
, (opc3
<< 5) | opc2
, opc4
,
9409 if (handler
->handler
!= &gen_invalid
) {
9410 /* Special hack to properly dump SPE insns */
9411 p
= strchr(handler
->oname
, '_');
9413 printf("INSN: %02x %02x %02x (%02d %04d) : "
9415 opc1
, opc2
, opc3
, opc1
,
9420 if ((p
- handler
->oname
) != strlen(q
)
9421 || (memcmp(handler
->oname
, q
, strlen(q
))
9423 /* First instruction */
9424 printf("INSN: %02x %02x %02x"
9425 "(%02d %04d) : %.*s\n",
9426 opc1
, opc2
<< 1, opc3
, opc1
,
9427 (opc3
<< 6) | (opc2
<< 1),
9428 (int)(p
- handler
->oname
),
9431 if (strcmp(p
+ 1, q
) != 0) {
9432 /* Second instruction */
9433 printf("INSN: %02x %02x %02x "
9434 "(%02d %04d) : %s\n", opc1
,
9435 (opc2
<< 1) | 1, opc3
, opc1
,
9436 (opc3
<< 6) | (opc2
<< 1) | 1,
9444 if (handler
->handler
!= &gen_invalid
) {
9445 printf("INSN: %02x %02x -- (%02d %04d) : %s\n",
9446 opc1
, opc2
, opc1
, opc2
, handler
->oname
);
9451 if (handler
->handler
!= &gen_invalid
) {
9452 printf("INSN: %02x -- -- (%02d ----) : %s\n",
9453 opc1
, opc1
, handler
->oname
);
9460 static bool avr_need_swap(CPUPPCState
*env
)
9462 #ifdef HOST_WORDS_BIGENDIAN
9469 static int gdb_get_float_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9472 stfq_p(mem_buf
, env
->fpr
[n
]);
9473 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9477 stl_p(mem_buf
, env
->fpscr
);
9478 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9484 static int gdb_set_float_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9487 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9488 env
->fpr
[n
] = ldfq_p(mem_buf
);
9492 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9493 helper_store_fpscr(env
, ldl_p(mem_buf
), 0xffffffff);
9499 static int gdb_get_avr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9502 if (!avr_need_swap(env
)) {
9503 stq_p(mem_buf
, env
->avr
[n
].u64
[0]);
9504 stq_p(mem_buf
+8, env
->avr
[n
].u64
[1]);
9506 stq_p(mem_buf
, env
->avr
[n
].u64
[1]);
9507 stq_p(mem_buf
+8, env
->avr
[n
].u64
[0]);
9509 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9510 ppc_maybe_bswap_register(env
, mem_buf
+ 8, 8);
9514 stl_p(mem_buf
, env
->vscr
);
9515 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9519 stl_p(mem_buf
, (uint32_t)env
->spr
[SPR_VRSAVE
]);
9520 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9526 static int gdb_set_avr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9529 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9530 ppc_maybe_bswap_register(env
, mem_buf
+ 8, 8);
9531 if (!avr_need_swap(env
)) {
9532 env
->avr
[n
].u64
[0] = ldq_p(mem_buf
);
9533 env
->avr
[n
].u64
[1] = ldq_p(mem_buf
+8);
9535 env
->avr
[n
].u64
[1] = ldq_p(mem_buf
);
9536 env
->avr
[n
].u64
[0] = ldq_p(mem_buf
+8);
9541 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9542 env
->vscr
= ldl_p(mem_buf
);
9546 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9547 env
->spr
[SPR_VRSAVE
] = (target_ulong
)ldl_p(mem_buf
);
9553 static int gdb_get_spe_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9556 #if defined(TARGET_PPC64)
9557 stl_p(mem_buf
, env
->gpr
[n
] >> 32);
9558 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9560 stl_p(mem_buf
, env
->gprh
[n
]);
9565 stq_p(mem_buf
, env
->spe_acc
);
9566 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9570 stl_p(mem_buf
, env
->spe_fscr
);
9571 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9577 static int gdb_set_spe_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9580 #if defined(TARGET_PPC64)
9581 target_ulong lo
= (uint32_t)env
->gpr
[n
];
9584 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9586 hi
= (target_ulong
)ldl_p(mem_buf
) << 32;
9587 env
->gpr
[n
] = lo
| hi
;
9589 env
->gprh
[n
] = ldl_p(mem_buf
);
9594 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9595 env
->spe_acc
= ldq_p(mem_buf
);
9599 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9600 env
->spe_fscr
= ldl_p(mem_buf
);
9606 static int gdb_get_vsx_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9609 stq_p(mem_buf
, env
->vsr
[n
]);
9610 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9616 static int gdb_set_vsx_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9619 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9620 env
->vsr
[n
] = ldq_p(mem_buf
);
9626 static int ppc_fixup_cpu(PowerPCCPU
*cpu
)
9628 CPUPPCState
*env
= &cpu
->env
;
9630 /* TCG doesn't (yet) emulate some groups of instructions that
9631 * are implemented on some otherwise supported CPUs (e.g. VSX
9632 * and decimal floating point instructions on POWER7). We
9633 * remove unsupported instruction groups from the cpu state's
9634 * instruction masks and hope the guest can cope. For at
9635 * least the pseries machine, the unavailability of these
9636 * instructions can be advertised to the guest via the device
9638 if ((env
->insns_flags
& ~PPC_TCG_INSNS
)
9639 || (env
->insns_flags2
& ~PPC_TCG_INSNS2
)) {
9640 warn_report("Disabling some instructions which are not "
9641 "emulated by TCG (0x%" PRIx64
", 0x%" PRIx64
")",
9642 env
->insns_flags
& ~PPC_TCG_INSNS
,
9643 env
->insns_flags2
& ~PPC_TCG_INSNS2
);
9645 env
->insns_flags
&= PPC_TCG_INSNS
;
9646 env
->insns_flags2
&= PPC_TCG_INSNS2
;
9650 static void ppc_cpu_realize(DeviceState
*dev
, Error
**errp
)
9652 CPUState
*cs
= CPU(dev
);
9653 PowerPCCPU
*cpu
= POWERPC_CPU(dev
);
9654 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9655 Error
*local_err
= NULL
;
9657 cpu_exec_realizefn(cs
, &local_err
);
9658 if (local_err
!= NULL
) {
9659 error_propagate(errp
, local_err
);
9662 if (cpu
->vcpu_id
== UNASSIGNED_CPU_INDEX
) {
9663 cpu
->vcpu_id
= cs
->cpu_index
;
9666 if (tcg_enabled()) {
9667 if (ppc_fixup_cpu(cpu
) != 0) {
9668 error_setg(errp
, "Unable to emulate selected CPU with TCG");
9673 create_ppc_opcodes(cpu
, &local_err
);
9674 if (local_err
!= NULL
) {
9675 error_propagate(errp
, local_err
);
9680 if (pcc
->insns_flags
& PPC_FLOAT
) {
9681 gdb_register_coprocessor(cs
, gdb_get_float_reg
, gdb_set_float_reg
,
9682 33, "power-fpu.xml", 0);
9684 if (pcc
->insns_flags
& PPC_ALTIVEC
) {
9685 gdb_register_coprocessor(cs
, gdb_get_avr_reg
, gdb_set_avr_reg
,
9686 34, "power-altivec.xml", 0);
9688 if (pcc
->insns_flags
& PPC_SPE
) {
9689 gdb_register_coprocessor(cs
, gdb_get_spe_reg
, gdb_set_spe_reg
,
9690 34, "power-spe.xml", 0);
9692 if (pcc
->insns_flags2
& PPC2_VSX
) {
9693 gdb_register_coprocessor(cs
, gdb_get_vsx_reg
, gdb_set_vsx_reg
,
9694 32, "power-vsx.xml", 0);
9699 pcc
->parent_realize(dev
, errp
);
9701 #if defined(PPC_DUMP_CPU)
9703 CPUPPCState
*env
= &cpu
->env
;
9704 const char *mmu_model
, *excp_model
, *bus_model
;
9705 switch (env
->mmu_model
) {
9706 case POWERPC_MMU_32B
:
9707 mmu_model
= "PowerPC 32";
9709 case POWERPC_MMU_SOFT_6xx
:
9710 mmu_model
= "PowerPC 6xx/7xx with software driven TLBs";
9712 case POWERPC_MMU_SOFT_74xx
:
9713 mmu_model
= "PowerPC 74xx with software driven TLBs";
9715 case POWERPC_MMU_SOFT_4xx
:
9716 mmu_model
= "PowerPC 4xx with software driven TLBs";
9718 case POWERPC_MMU_SOFT_4xx_Z
:
9719 mmu_model
= "PowerPC 4xx with software driven TLBs "
9720 "and zones protections";
9722 case POWERPC_MMU_REAL
:
9723 mmu_model
= "PowerPC real mode only";
9725 case POWERPC_MMU_MPC8xx
:
9726 mmu_model
= "PowerPC MPC8xx";
9728 case POWERPC_MMU_BOOKE
:
9729 mmu_model
= "PowerPC BookE";
9731 case POWERPC_MMU_BOOKE206
:
9732 mmu_model
= "PowerPC BookE 2.06";
9734 case POWERPC_MMU_601
:
9735 mmu_model
= "PowerPC 601";
9737 #if defined(TARGET_PPC64)
9738 case POWERPC_MMU_64B
:
9739 mmu_model
= "PowerPC 64";
9743 mmu_model
= "Unknown or invalid";
9746 switch (env
->excp_model
) {
9747 case POWERPC_EXCP_STD
:
9748 excp_model
= "PowerPC";
9750 case POWERPC_EXCP_40x
:
9751 excp_model
= "PowerPC 40x";
9753 case POWERPC_EXCP_601
:
9754 excp_model
= "PowerPC 601";
9756 case POWERPC_EXCP_602
:
9757 excp_model
= "PowerPC 602";
9759 case POWERPC_EXCP_603
:
9760 excp_model
= "PowerPC 603";
9762 case POWERPC_EXCP_603E
:
9763 excp_model
= "PowerPC 603e";
9765 case POWERPC_EXCP_604
:
9766 excp_model
= "PowerPC 604";
9768 case POWERPC_EXCP_7x0
:
9769 excp_model
= "PowerPC 740/750";
9771 case POWERPC_EXCP_7x5
:
9772 excp_model
= "PowerPC 745/755";
9774 case POWERPC_EXCP_74xx
:
9775 excp_model
= "PowerPC 74xx";
9777 case POWERPC_EXCP_BOOKE
:
9778 excp_model
= "PowerPC BookE";
9780 #if defined(TARGET_PPC64)
9781 case POWERPC_EXCP_970
:
9782 excp_model
= "PowerPC 970";
9786 excp_model
= "Unknown or invalid";
9789 switch (env
->bus_model
) {
9790 case PPC_FLAGS_INPUT_6xx
:
9791 bus_model
= "PowerPC 6xx";
9793 case PPC_FLAGS_INPUT_BookE
:
9794 bus_model
= "PowerPC BookE";
9796 case PPC_FLAGS_INPUT_405
:
9797 bus_model
= "PowerPC 405";
9799 case PPC_FLAGS_INPUT_401
:
9800 bus_model
= "PowerPC 401/403";
9802 case PPC_FLAGS_INPUT_RCPU
:
9803 bus_model
= "RCPU / MPC8xx";
9805 #if defined(TARGET_PPC64)
9806 case PPC_FLAGS_INPUT_970
:
9807 bus_model
= "PowerPC 970";
9811 bus_model
= "Unknown or invalid";
9814 printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64
"\n"
9815 " MMU model : %s\n",
9816 object_class_get_name(OBJECT_CLASS(pcc
)),
9817 pcc
->pvr
, pcc
->msr_mask
, mmu_model
);
9818 #if !defined(CONFIG_USER_ONLY)
9819 if (env
->tlb
.tlb6
) {
9820 printf(" %d %s TLB in %d ways\n",
9821 env
->nb_tlb
, env
->id_tlbs
? "splitted" : "merged",
9825 printf(" Exceptions model : %s\n"
9826 " Bus model : %s\n",
9827 excp_model
, bus_model
);
9828 printf(" MSR features :\n");
9829 if (env
->flags
& POWERPC_FLAG_SPE
)
9830 printf(" signal processing engine enable"
9832 else if (env
->flags
& POWERPC_FLAG_VRE
)
9833 printf(" vector processor enable\n");
9834 if (env
->flags
& POWERPC_FLAG_TGPR
)
9835 printf(" temporary GPRs\n");
9836 else if (env
->flags
& POWERPC_FLAG_CE
)
9837 printf(" critical input enable\n");
9838 if (env
->flags
& POWERPC_FLAG_SE
)
9839 printf(" single-step trace mode\n");
9840 else if (env
->flags
& POWERPC_FLAG_DWE
)
9841 printf(" debug wait enable\n");
9842 else if (env
->flags
& POWERPC_FLAG_UBLE
)
9843 printf(" user BTB lock enable\n");
9844 if (env
->flags
& POWERPC_FLAG_BE
)
9845 printf(" branch-step trace mode\n");
9846 else if (env
->flags
& POWERPC_FLAG_DE
)
9847 printf(" debug interrupt enable\n");
9848 if (env
->flags
& POWERPC_FLAG_PX
)
9849 printf(" inclusive protection\n");
9850 else if (env
->flags
& POWERPC_FLAG_PMM
)
9851 printf(" performance monitor mark\n");
9852 if (env
->flags
== POWERPC_FLAG_NONE
)
9854 printf(" Time-base/decrementer clock source: %s\n",
9855 env
->flags
& POWERPC_FLAG_RTC_CLK
? "RTC clock" : "bus clock");
9856 dump_ppc_insns(env
);
9864 cpu_exec_unrealizefn(cs
);
9867 static void ppc_cpu_unrealize(DeviceState
*dev
, Error
**errp
)
9869 PowerPCCPU
*cpu
= POWERPC_CPU(dev
);
9870 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9871 CPUPPCState
*env
= &cpu
->env
;
9872 Error
*local_err
= NULL
;
9873 opc_handler_t
**table
, **table_2
;
9876 pcc
->parent_unrealize(dev
, &local_err
);
9877 if (local_err
!= NULL
) {
9878 error_propagate(errp
, local_err
);
9882 for (i
= 0; i
< PPC_CPU_OPCODES_LEN
; i
++) {
9883 if (env
->opcodes
[i
] == &invalid_handler
) {
9886 if (is_indirect_opcode(env
->opcodes
[i
])) {
9887 table
= ind_table(env
->opcodes
[i
]);
9888 for (j
= 0; j
< PPC_CPU_INDIRECT_OPCODES_LEN
; j
++) {
9889 if (table
[j
] == &invalid_handler
) {
9892 if (is_indirect_opcode(table
[j
])) {
9893 table_2
= ind_table(table
[j
]);
9894 for (k
= 0; k
< PPC_CPU_INDIRECT_OPCODES_LEN
; k
++) {
9895 if (table_2
[k
] != &invalid_handler
&&
9896 is_indirect_opcode(table_2
[k
])) {
9897 g_free((opc_handler_t
*)((uintptr_t)table_2
[k
] &
9901 g_free((opc_handler_t
*)((uintptr_t)table
[j
] &
9905 g_free((opc_handler_t
*)((uintptr_t)env
->opcodes
[i
] &
9911 static gint
ppc_cpu_compare_class_pvr(gconstpointer a
, gconstpointer b
)
9913 ObjectClass
*oc
= (ObjectClass
*)a
;
9914 uint32_t pvr
= *(uint32_t *)b
;
9915 PowerPCCPUClass
*pcc
= (PowerPCCPUClass
*)a
;
9917 /* -cpu host does a PVR lookup during construction */
9918 if (unlikely(strcmp(object_class_get_name(oc
),
9919 TYPE_HOST_POWERPC_CPU
) == 0)) {
9923 return pcc
->pvr
== pvr
? 0 : -1;
9926 PowerPCCPUClass
*ppc_cpu_class_by_pvr(uint32_t pvr
)
9928 GSList
*list
, *item
;
9929 PowerPCCPUClass
*pcc
= NULL
;
9931 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
9932 item
= g_slist_find_custom(list
, &pvr
, ppc_cpu_compare_class_pvr
);
9934 pcc
= POWERPC_CPU_CLASS(item
->data
);
9941 static gint
ppc_cpu_compare_class_pvr_mask(gconstpointer a
, gconstpointer b
)
9943 ObjectClass
*oc
= (ObjectClass
*)a
;
9944 uint32_t pvr
= *(uint32_t *)b
;
9945 PowerPCCPUClass
*pcc
= (PowerPCCPUClass
*)a
;
9947 /* -cpu host does a PVR lookup during construction */
9948 if (unlikely(strcmp(object_class_get_name(oc
),
9949 TYPE_HOST_POWERPC_CPU
) == 0)) {
9953 if (pcc
->pvr_match(pcc
, pvr
)) {
9960 PowerPCCPUClass
*ppc_cpu_class_by_pvr_mask(uint32_t pvr
)
9962 GSList
*list
, *item
;
9963 PowerPCCPUClass
*pcc
= NULL
;
9965 list
= object_class_get_list(TYPE_POWERPC_CPU
, true);
9966 item
= g_slist_find_custom(list
, &pvr
, ppc_cpu_compare_class_pvr_mask
);
9968 pcc
= POWERPC_CPU_CLASS(item
->data
);
9975 static const char *ppc_cpu_lookup_alias(const char *alias
)
9979 for (ai
= 0; ppc_cpu_aliases
[ai
].alias
!= NULL
; ai
++) {
9980 if (strcmp(ppc_cpu_aliases
[ai
].alias
, alias
) == 0) {
9981 return ppc_cpu_aliases
[ai
].model
;
9988 static ObjectClass
*ppc_cpu_class_by_name(const char *name
)
9990 char *cpu_model
, *typename
;
9995 /* Lookup by PVR if cpu_model is valid 8 digit hex number
9996 * (excl: 0x prefix if present)
9998 if (!qemu_strtoul(name
, &p
, 16, &pvr
)) {
10000 len
= (len
== 10) && (name
[1] == 'x') ? len
- 2 : len
;
10001 if ((len
== 8) && (*p
== '\0')) {
10002 return OBJECT_CLASS(ppc_cpu_class_by_pvr(pvr
));
10006 cpu_model
= g_ascii_strdown(name
, -1);
10007 p
= ppc_cpu_lookup_alias(cpu_model
);
10010 cpu_model
= g_strdup(p
);
10013 typename
= g_strdup_printf("%s" POWERPC_CPU_TYPE_SUFFIX
, cpu_model
);
10014 oc
= object_class_by_name(typename
);
10021 static void ppc_cpu_parse_featurestr(const char *type
, char *features
,
10024 Object
*machine
= qdev_get_machine();
10025 const PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(object_class_by_name(type
));
10031 if (object_property_find(machine
, "max-cpu-compat", NULL
)) {
10034 char *s
= features
;
10035 Error
*local_err
= NULL
;
10036 char *compat_str
= NULL
;
10039 * Backwards compatibility hack:
10041 * CPUs had a "compat=" property which didn't make sense for
10042 * anything except pseries. It was replaced by "max-cpu-compat"
10043 * machine option. This supports old command lines like
10044 * -cpu POWER8,compat=power7
10045 * By stripping the compat option and applying it to the machine
10046 * before passing it on to the cpu level parser.
10048 inpieces
= g_strsplit(features
, ",", 0);
10050 for (i
= 0; inpieces
[i
]; i
++) {
10051 if (g_str_has_prefix(inpieces
[i
], "compat=")) {
10052 compat_str
= inpieces
[i
];
10055 if ((i
!= 0) && (s
!= features
)) {
10056 s
= g_stpcpy(s
, ",");
10058 s
= g_stpcpy(s
, inpieces
[i
]);
10062 char *v
= compat_str
+ strlen("compat=");
10063 object_property_set_str(machine
, v
, "max-cpu-compat", &local_err
);
10065 g_strfreev(inpieces
);
10067 error_propagate(errp
, local_err
);
10072 /* do property processing with generic handler */
10073 pcc
->parent_parse_features(type
, features
, errp
);
10076 PowerPCCPUClass
*ppc_cpu_get_family_class(PowerPCCPUClass
*pcc
)
10078 ObjectClass
*oc
= OBJECT_CLASS(pcc
);
10080 while (oc
&& !object_class_is_abstract(oc
)) {
10081 oc
= object_class_get_parent(oc
);
10085 return POWERPC_CPU_CLASS(oc
);
10088 /* Sort by PVR, ordering special case "host" last. */
10089 static gint
ppc_cpu_list_compare(gconstpointer a
, gconstpointer b
)
10091 ObjectClass
*oc_a
= (ObjectClass
*)a
;
10092 ObjectClass
*oc_b
= (ObjectClass
*)b
;
10093 PowerPCCPUClass
*pcc_a
= POWERPC_CPU_CLASS(oc_a
);
10094 PowerPCCPUClass
*pcc_b
= POWERPC_CPU_CLASS(oc_b
);
10095 const char *name_a
= object_class_get_name(oc_a
);
10096 const char *name_b
= object_class_get_name(oc_b
);
10098 if (strcmp(name_a
, TYPE_HOST_POWERPC_CPU
) == 0) {
10100 } else if (strcmp(name_b
, TYPE_HOST_POWERPC_CPU
) == 0) {
10103 /* Avoid an integer overflow during subtraction */
10104 if (pcc_a
->pvr
< pcc_b
->pvr
) {
10106 } else if (pcc_a
->pvr
> pcc_b
->pvr
) {
10114 static void ppc_cpu_list_entry(gpointer data
, gpointer user_data
)
10116 ObjectClass
*oc
= data
;
10117 CPUListState
*s
= user_data
;
10118 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10119 DeviceClass
*family
= DEVICE_CLASS(ppc_cpu_get_family_class(pcc
));
10120 const char *typename
= object_class_get_name(oc
);
10124 if (unlikely(strcmp(typename
, TYPE_HOST_POWERPC_CPU
) == 0)) {
10128 name
= g_strndup(typename
,
10129 strlen(typename
) - strlen(POWERPC_CPU_TYPE_SUFFIX
));
10130 (*s
->cpu_fprintf
)(s
->file
, "PowerPC %-16s PVR %08x\n",
10132 for (i
= 0; ppc_cpu_aliases
[i
].alias
!= NULL
; i
++) {
10133 PowerPCCPUAlias
*alias
= &ppc_cpu_aliases
[i
];
10134 ObjectClass
*alias_oc
= ppc_cpu_class_by_name(alias
->model
);
10136 if (alias_oc
!= oc
) {
10140 * If running with KVM, we might update the family alias later, so
10141 * avoid printing the wrong alias here and use "preferred" instead
10143 if (strcmp(alias
->alias
, family
->desc
) == 0) {
10144 (*s
->cpu_fprintf
)(s
->file
,
10145 "PowerPC %-16s (alias for preferred %s CPU)\n",
10146 alias
->alias
, family
->desc
);
10148 (*s
->cpu_fprintf
)(s
->file
, "PowerPC %-16s (alias for %s)\n",
10149 alias
->alias
, name
);
10155 void ppc_cpu_list(FILE *f
, fprintf_function cpu_fprintf
)
10159 .cpu_fprintf
= cpu_fprintf
,
10163 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10164 list
= g_slist_sort(list
, ppc_cpu_list_compare
);
10165 g_slist_foreach(list
, ppc_cpu_list_entry
, &s
);
10166 g_slist_free(list
);
10169 cpu_fprintf(f
, "\n");
10170 cpu_fprintf(f
, "PowerPC %-16s\n", "host");
10174 static void ppc_cpu_defs_entry(gpointer data
, gpointer user_data
)
10176 ObjectClass
*oc
= data
;
10177 CpuDefinitionInfoList
**first
= user_data
;
10178 const char *typename
;
10179 CpuDefinitionInfoList
*entry
;
10180 CpuDefinitionInfo
*info
;
10182 typename
= object_class_get_name(oc
);
10183 info
= g_malloc0(sizeof(*info
));
10184 info
->name
= g_strndup(typename
,
10185 strlen(typename
) - strlen(POWERPC_CPU_TYPE_SUFFIX
));
10187 entry
= g_malloc0(sizeof(*entry
));
10188 entry
->value
= info
;
10189 entry
->next
= *first
;
10193 CpuDefinitionInfoList
*arch_query_cpu_definitions(Error
**errp
)
10195 CpuDefinitionInfoList
*cpu_list
= NULL
;
10199 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10200 g_slist_foreach(list
, ppc_cpu_defs_entry
, &cpu_list
);
10201 g_slist_free(list
);
10203 for (i
= 0; ppc_cpu_aliases
[i
].alias
!= NULL
; i
++) {
10204 PowerPCCPUAlias
*alias
= &ppc_cpu_aliases
[i
];
10206 CpuDefinitionInfoList
*entry
;
10207 CpuDefinitionInfo
*info
;
10209 oc
= ppc_cpu_class_by_name(alias
->model
);
10214 info
= g_malloc0(sizeof(*info
));
10215 info
->name
= g_strdup(alias
->alias
);
10216 info
->q_typename
= g_strdup(object_class_get_name(oc
));
10218 entry
= g_malloc0(sizeof(*entry
));
10219 entry
->value
= info
;
10220 entry
->next
= cpu_list
;
10227 static void ppc_cpu_set_pc(CPUState
*cs
, vaddr value
)
10229 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10231 cpu
->env
.nip
= value
;
10234 static bool ppc_cpu_has_work(CPUState
*cs
)
10236 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10237 CPUPPCState
*env
= &cpu
->env
;
10239 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
10242 /* CPUClass::reset() */
10243 static void ppc_cpu_reset(CPUState
*s
)
10245 PowerPCCPU
*cpu
= POWERPC_CPU(s
);
10246 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10247 CPUPPCState
*env
= &cpu
->env
;
10251 pcc
->parent_reset(s
);
10253 msr
= (target_ulong
)0;
10254 msr
|= (target_ulong
)MSR_HVB
;
10255 msr
|= (target_ulong
)0 << MSR_AP
; /* TO BE CHECKED */
10256 msr
|= (target_ulong
)0 << MSR_SA
; /* TO BE CHECKED */
10257 msr
|= (target_ulong
)1 << MSR_EP
;
10258 #if defined(DO_SINGLE_STEP) && 0
10259 /* Single step trace mode */
10260 msr
|= (target_ulong
)1 << MSR_SE
;
10261 msr
|= (target_ulong
)1 << MSR_BE
;
10263 #if defined(CONFIG_USER_ONLY)
10264 msr
|= (target_ulong
)1 << MSR_FP
; /* Allow floating point usage */
10265 msr
|= (target_ulong
)1 << MSR_FE0
; /* Allow floating point exceptions */
10266 msr
|= (target_ulong
)1 << MSR_FE1
;
10267 msr
|= (target_ulong
)1 << MSR_VR
; /* Allow altivec usage */
10268 msr
|= (target_ulong
)1 << MSR_VSX
; /* Allow VSX usage */
10269 msr
|= (target_ulong
)1 << MSR_SPE
; /* Allow SPE usage */
10270 msr
|= (target_ulong
)1 << MSR_PR
;
10271 #if defined(TARGET_PPC64)
10272 msr
|= (target_ulong
)1 << MSR_TM
; /* Transactional memory */
10274 #if !defined(TARGET_WORDS_BIGENDIAN)
10275 msr
|= (target_ulong
)1 << MSR_LE
; /* Little-endian user mode */
10276 if (!((env
->msr_mask
>> MSR_LE
) & 1)) {
10277 fprintf(stderr
, "Selected CPU does not support little-endian.\n");
10283 #if defined(TARGET_PPC64)
10284 if (env
->mmu_model
& POWERPC_MMU_64
) {
10285 msr
|= (1ULL << MSR_SF
);
10289 hreg_store_msr(env
, msr
, 1);
10291 #if !defined(CONFIG_USER_ONLY)
10292 env
->nip
= env
->hreset_vector
| env
->excp_prefix
;
10293 if (env
->mmu_model
!= POWERPC_MMU_REAL
) {
10294 ppc_tlb_invalidate_all(env
);
10298 hreg_compute_hflags(env
);
10299 env
->reserve_addr
= (target_ulong
)-1ULL;
10300 /* Be sure no exception or interrupt is pending */
10301 env
->pending_interrupts
= 0;
10302 s
->exception_index
= POWERPC_EXCP_NONE
;
10303 env
->error_code
= 0;
10305 for (i
= 0; i
< ARRAY_SIZE(env
->spr_cb
); i
++) {
10306 ppc_spr_t
*spr
= &env
->spr_cb
[i
];
10311 env
->spr
[i
] = spr
->default_value
;
10315 #ifndef CONFIG_USER_ONLY
10316 static bool ppc_cpu_is_big_endian(CPUState
*cs
)
10318 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10319 CPUPPCState
*env
= &cpu
->env
;
10321 cpu_synchronize_state(cs
);
10327 static void ppc_cpu_instance_init(Object
*obj
)
10329 CPUState
*cs
= CPU(obj
);
10330 PowerPCCPU
*cpu
= POWERPC_CPU(obj
);
10331 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10332 CPUPPCState
*env
= &cpu
->env
;
10335 cpu
->vcpu_id
= UNASSIGNED_CPU_INDEX
;
10337 env
->msr_mask
= pcc
->msr_mask
;
10338 env
->mmu_model
= pcc
->mmu_model
;
10339 env
->excp_model
= pcc
->excp_model
;
10340 env
->bus_model
= pcc
->bus_model
;
10341 env
->insns_flags
= pcc
->insns_flags
;
10342 env
->insns_flags2
= pcc
->insns_flags2
;
10343 env
->flags
= pcc
->flags
;
10344 env
->bfd_mach
= pcc
->bfd_mach
;
10345 env
->check_pow
= pcc
->check_pow
;
10347 /* Mark HV mode as supported if the CPU has an MSR_HV bit
10348 * in the msr_mask. The mask can later be cleared by PAPR
10349 * mode but the hv mode support will remain, thus enforcing
10350 * that we cannot use priv. instructions in guest in PAPR
10351 * mode. For 970 we currently simply don't set HV in msr_mask
10352 * thus simulating an "Apple mode" 970. If we ever want to
10353 * support 970 HV mode, we'll have to add a processor attribute
10356 #if !defined(CONFIG_USER_ONLY)
10357 env
->has_hv_mode
= !!(env
->msr_mask
& MSR_HVB
);
10360 ppc_hash64_init(cpu
);
10363 static void ppc_cpu_instance_finalize(Object
*obj
)
10365 PowerPCCPU
*cpu
= POWERPC_CPU(obj
);
10367 ppc_hash64_finalize(cpu
);
10370 static bool ppc_pvr_match_default(PowerPCCPUClass
*pcc
, uint32_t pvr
)
10372 return pcc
->pvr
== pvr
;
10375 static gchar
*ppc_gdb_arch_name(CPUState
*cs
)
10377 #if defined(TARGET_PPC64)
10378 return g_strdup("powerpc:common64");
10380 return g_strdup("powerpc:common");
10384 static void ppc_disas_set_info(CPUState
*cs
, disassemble_info
*info
)
10386 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10387 CPUPPCState
*env
= &cpu
->env
;
10389 if ((env
->hflags
>> MSR_LE
) & 1) {
10390 info
->endian
= BFD_ENDIAN_LITTLE
;
10392 info
->mach
= env
->bfd_mach
;
10393 if (!env
->bfd_mach
) {
10394 #ifdef TARGET_PPC64
10395 info
->mach
= bfd_mach_ppc64
;
10397 info
->mach
= bfd_mach_ppc
;
10400 info
->disassembler_options
= (char *)"any";
10401 info
->print_insn
= print_insn_ppc
;
10403 info
->cap_arch
= CS_ARCH_PPC
;
10404 #ifdef TARGET_PPC64
10405 info
->cap_mode
= CS_MODE_64
;
10409 static Property ppc_cpu_properties
[] = {
10410 DEFINE_PROP_BOOL("pre-2.8-migration", PowerPCCPU
, pre_2_8_migration
, false),
10411 DEFINE_PROP_BOOL("pre-2.10-migration", PowerPCCPU
, pre_2_10_migration
,
10413 DEFINE_PROP_BOOL("pre-3.0-migration", PowerPCCPU
, pre_3_0_migration
,
10415 DEFINE_PROP_END_OF_LIST(),
10418 static void ppc_cpu_class_init(ObjectClass
*oc
, void *data
)
10420 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10421 CPUClass
*cc
= CPU_CLASS(oc
);
10422 DeviceClass
*dc
= DEVICE_CLASS(oc
);
10424 device_class_set_parent_realize(dc
, ppc_cpu_realize
,
10425 &pcc
->parent_realize
);
10426 device_class_set_parent_unrealize(dc
, ppc_cpu_unrealize
,
10427 &pcc
->parent_unrealize
);
10428 pcc
->pvr_match
= ppc_pvr_match_default
;
10429 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_always
;
10430 dc
->props
= ppc_cpu_properties
;
10432 pcc
->parent_reset
= cc
->reset
;
10433 cc
->reset
= ppc_cpu_reset
;
10435 cc
->class_by_name
= ppc_cpu_class_by_name
;
10436 pcc
->parent_parse_features
= cc
->parse_features
;
10437 cc
->parse_features
= ppc_cpu_parse_featurestr
;
10438 cc
->has_work
= ppc_cpu_has_work
;
10439 cc
->do_interrupt
= ppc_cpu_do_interrupt
;
10440 cc
->cpu_exec_interrupt
= ppc_cpu_exec_interrupt
;
10441 cc
->dump_state
= ppc_cpu_dump_state
;
10442 cc
->dump_statistics
= ppc_cpu_dump_statistics
;
10443 cc
->set_pc
= ppc_cpu_set_pc
;
10444 cc
->gdb_read_register
= ppc_cpu_gdb_read_register
;
10445 cc
->gdb_write_register
= ppc_cpu_gdb_write_register
;
10446 cc
->do_unaligned_access
= ppc_cpu_do_unaligned_access
;
10447 #ifdef CONFIG_USER_ONLY
10448 cc
->handle_mmu_fault
= ppc_cpu_handle_mmu_fault
;
10450 cc
->get_phys_page_debug
= ppc_cpu_get_phys_page_debug
;
10451 cc
->vmsd
= &vmstate_ppc_cpu
;
10453 #if defined(CONFIG_SOFTMMU)
10454 cc
->write_elf64_note
= ppc64_cpu_write_elf64_note
;
10455 cc
->write_elf32_note
= ppc32_cpu_write_elf32_note
;
10458 cc
->gdb_num_core_regs
= 71;
10460 #ifdef USE_APPLE_GDB
10461 cc
->gdb_read_register
= ppc_cpu_gdb_read_register_apple
;
10462 cc
->gdb_write_register
= ppc_cpu_gdb_write_register_apple
;
10463 cc
->gdb_num_core_regs
= 71 + 32;
10466 cc
->gdb_arch_name
= ppc_gdb_arch_name
;
10467 #if defined(TARGET_PPC64)
10468 cc
->gdb_core_xml_file
= "power64-core.xml";
10470 cc
->gdb_core_xml_file
= "power-core.xml";
10472 #ifndef CONFIG_USER_ONLY
10473 cc
->virtio_is_big_endian
= ppc_cpu_is_big_endian
;
10476 cc
->tcg_initialize
= ppc_translate_init
;
10478 cc
->disas_set_info
= ppc_disas_set_info
;
10480 dc
->fw_name
= "PowerPC,UNKNOWN";
10483 static const TypeInfo ppc_cpu_type_info
= {
10484 .name
= TYPE_POWERPC_CPU
,
10485 .parent
= TYPE_CPU
,
10486 .instance_size
= sizeof(PowerPCCPU
),
10487 .instance_init
= ppc_cpu_instance_init
,
10488 .instance_finalize
= ppc_cpu_instance_finalize
,
10490 .class_size
= sizeof(PowerPCCPUClass
),
10491 .class_init
= ppc_cpu_class_init
,
10494 static const TypeInfo ppc_vhyp_type_info
= {
10495 .name
= TYPE_PPC_VIRTUAL_HYPERVISOR
,
10496 .parent
= TYPE_INTERFACE
,
10497 .class_size
= sizeof(PPCVirtualHypervisorClass
),
10500 static void ppc_cpu_register_types(void)
10502 type_register_static(&ppc_cpu_type_info
);
10503 type_register_static(&ppc_vhyp_type_info
);
10506 type_init(ppc_cpu_register_types
)