2 * PowerPC CPU initialization for qemu.
4 * Copyright (c) 2003-2007 Jocelyn Mayer
5 * Copyright 2011 Freescale Semiconductor, Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "qemu/osdep.h"
22 #include "disas/bfd.h"
23 #include "exec/gdbstub.h"
25 #include "sysemu/arch_init.h"
26 #include "sysemu/cpus.h"
27 #include "sysemu/hw_accel.h"
28 #include "cpu-models.h"
29 #include "mmu-hash32.h"
30 #include "mmu-hash64.h"
31 #include "qemu/error-report.h"
32 #include "qapi/visitor.h"
33 #include "hw/qdev-properties.h"
34 #include "hw/ppc/ppc.h"
35 #include "mmu-book3s-v3.h"
37 //#define PPC_DUMP_CPU
38 //#define PPC_DEBUG_SPR
39 //#define PPC_DUMP_SPR_ACCESSES
40 /* #define USE_APPLE_GDB */
43 * do nothing but store/retrieve spr value
45 static void spr_load_dump_spr(int sprn
)
47 #ifdef PPC_DUMP_SPR_ACCESSES
48 TCGv_i32 t0
= tcg_const_i32(sprn
);
49 gen_helper_load_dump_spr(cpu_env
, t0
);
50 tcg_temp_free_i32(t0
);
54 static void spr_read_generic (DisasContext
*ctx
, int gprn
, int sprn
)
56 gen_load_spr(cpu_gpr
[gprn
], sprn
);
57 spr_load_dump_spr(sprn
);
60 static void spr_store_dump_spr(int sprn
)
62 #ifdef PPC_DUMP_SPR_ACCESSES
63 TCGv_i32 t0
= tcg_const_i32(sprn
);
64 gen_helper_store_dump_spr(cpu_env
, t0
);
65 tcg_temp_free_i32(t0
);
69 static void spr_write_generic(DisasContext
*ctx
, int sprn
, int gprn
)
71 gen_store_spr(sprn
, cpu_gpr
[gprn
]);
72 spr_store_dump_spr(sprn
);
75 #if !defined(CONFIG_USER_ONLY)
76 static void spr_write_generic32(DisasContext
*ctx
, int sprn
, int gprn
)
79 TCGv t0
= tcg_temp_new();
80 tcg_gen_ext32u_tl(t0
, cpu_gpr
[gprn
]);
81 gen_store_spr(sprn
, t0
);
83 spr_store_dump_spr(sprn
);
85 spr_write_generic(ctx
, sprn
, gprn
);
89 static void spr_write_clear(DisasContext
*ctx
, int sprn
, int gprn
)
91 TCGv t0
= tcg_temp_new();
92 TCGv t1
= tcg_temp_new();
93 gen_load_spr(t0
, sprn
);
94 tcg_gen_neg_tl(t1
, cpu_gpr
[gprn
]);
95 tcg_gen_and_tl(t0
, t0
, t1
);
96 gen_store_spr(sprn
, t0
);
101 static void spr_access_nop(DisasContext
*ctx
, int sprn
, int gprn
)
107 /* SPR common to all PowerPC */
109 static void spr_read_xer(DisasContext
*ctx
, int gprn
, int sprn
)
111 gen_read_xer(ctx
, cpu_gpr
[gprn
]);
114 static void spr_write_xer(DisasContext
*ctx
, int sprn
, int gprn
)
116 gen_write_xer(cpu_gpr
[gprn
]);
120 static void spr_read_lr(DisasContext
*ctx
, int gprn
, int sprn
)
122 tcg_gen_mov_tl(cpu_gpr
[gprn
], cpu_lr
);
125 static void spr_write_lr(DisasContext
*ctx
, int sprn
, int gprn
)
127 tcg_gen_mov_tl(cpu_lr
, cpu_gpr
[gprn
]);
131 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
132 static void spr_read_cfar(DisasContext
*ctx
, int gprn
, int sprn
)
134 tcg_gen_mov_tl(cpu_gpr
[gprn
], cpu_cfar
);
137 static void spr_write_cfar(DisasContext
*ctx
, int sprn
, int gprn
)
139 tcg_gen_mov_tl(cpu_cfar
, cpu_gpr
[gprn
]);
141 #endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
144 static void spr_read_ctr(DisasContext
*ctx
, int gprn
, int sprn
)
146 tcg_gen_mov_tl(cpu_gpr
[gprn
], cpu_ctr
);
149 static void spr_write_ctr(DisasContext
*ctx
, int sprn
, int gprn
)
151 tcg_gen_mov_tl(cpu_ctr
, cpu_gpr
[gprn
]);
154 /* User read access to SPR */
160 static void spr_read_ureg(DisasContext
*ctx
, int gprn
, int sprn
)
162 gen_load_spr(cpu_gpr
[gprn
], sprn
+ 0x10);
165 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
166 static void spr_write_ureg(DisasContext
*ctx
, int sprn
, int gprn
)
168 gen_store_spr(sprn
+ 0x10, cpu_gpr
[gprn
]);
172 /* SPR common to all non-embedded PowerPC */
174 #if !defined(CONFIG_USER_ONLY)
175 static void spr_read_decr(DisasContext
*ctx
, int gprn
, int sprn
)
177 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
180 gen_helper_load_decr(cpu_gpr
[gprn
], cpu_env
);
181 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
183 gen_stop_exception(ctx
);
187 static void spr_write_decr(DisasContext
*ctx
, int sprn
, int gprn
)
189 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
192 gen_helper_store_decr(cpu_env
, cpu_gpr
[gprn
]);
193 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
195 gen_stop_exception(ctx
);
200 /* SPR common to all non-embedded PowerPC, except 601 */
202 static void spr_read_tbl(DisasContext
*ctx
, int gprn
, int sprn
)
204 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
207 gen_helper_load_tbl(cpu_gpr
[gprn
], cpu_env
);
208 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
210 gen_stop_exception(ctx
);
214 static void spr_read_tbu(DisasContext
*ctx
, int gprn
, int sprn
)
216 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
219 gen_helper_load_tbu(cpu_gpr
[gprn
], cpu_env
);
220 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
222 gen_stop_exception(ctx
);
226 __attribute__ (( unused
))
227 static void spr_read_atbl(DisasContext
*ctx
, int gprn
, int sprn
)
229 gen_helper_load_atbl(cpu_gpr
[gprn
], cpu_env
);
232 __attribute__ (( unused
))
233 static void spr_read_atbu(DisasContext
*ctx
, int gprn
, int sprn
)
235 gen_helper_load_atbu(cpu_gpr
[gprn
], cpu_env
);
238 #if !defined(CONFIG_USER_ONLY)
239 static void spr_write_tbl(DisasContext
*ctx
, int sprn
, int gprn
)
241 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
244 gen_helper_store_tbl(cpu_env
, cpu_gpr
[gprn
]);
245 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
247 gen_stop_exception(ctx
);
251 static void spr_write_tbu(DisasContext
*ctx
, int sprn
, int gprn
)
253 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
256 gen_helper_store_tbu(cpu_env
, cpu_gpr
[gprn
]);
257 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
259 gen_stop_exception(ctx
);
263 __attribute__ (( unused
))
264 static void spr_write_atbl(DisasContext
*ctx
, int sprn
, int gprn
)
266 gen_helper_store_atbl(cpu_env
, cpu_gpr
[gprn
]);
269 __attribute__ (( unused
))
270 static void spr_write_atbu(DisasContext
*ctx
, int sprn
, int gprn
)
272 gen_helper_store_atbu(cpu_env
, cpu_gpr
[gprn
]);
275 #if defined(TARGET_PPC64)
276 __attribute__ (( unused
))
277 static void spr_read_purr(DisasContext
*ctx
, int gprn
, int sprn
)
279 gen_helper_load_purr(cpu_gpr
[gprn
], cpu_env
);
283 static void spr_read_hdecr(DisasContext
*ctx
, int gprn
, int sprn
)
285 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
288 gen_helper_load_hdecr(cpu_gpr
[gprn
], cpu_env
);
289 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
291 gen_stop_exception(ctx
);
295 static void spr_write_hdecr(DisasContext
*ctx
, int sprn
, int gprn
)
297 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
300 gen_helper_store_hdecr(cpu_env
, cpu_gpr
[gprn
]);
301 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
303 gen_stop_exception(ctx
);
310 #if !defined(CONFIG_USER_ONLY)
311 /* IBAT0U...IBAT0U */
312 /* IBAT0L...IBAT7L */
313 static void spr_read_ibat(DisasContext
*ctx
, int gprn
, int sprn
)
315 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, IBAT
[sprn
& 1][(sprn
- SPR_IBAT0U
) / 2]));
318 static void spr_read_ibat_h(DisasContext
*ctx
, int gprn
, int sprn
)
320 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, IBAT
[sprn
& 1][((sprn
- SPR_IBAT4U
) / 2) + 4]));
323 static void spr_write_ibatu(DisasContext
*ctx
, int sprn
, int gprn
)
325 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0U
) / 2);
326 gen_helper_store_ibatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
327 tcg_temp_free_i32(t0
);
330 static void spr_write_ibatu_h(DisasContext
*ctx
, int sprn
, int gprn
)
332 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_IBAT4U
) / 2) + 4);
333 gen_helper_store_ibatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
334 tcg_temp_free_i32(t0
);
337 static void spr_write_ibatl(DisasContext
*ctx
, int sprn
, int gprn
)
339 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0L
) / 2);
340 gen_helper_store_ibatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
341 tcg_temp_free_i32(t0
);
344 static void spr_write_ibatl_h(DisasContext
*ctx
, int sprn
, int gprn
)
346 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_IBAT4L
) / 2) + 4);
347 gen_helper_store_ibatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
348 tcg_temp_free_i32(t0
);
351 /* DBAT0U...DBAT7U */
352 /* DBAT0L...DBAT7L */
353 static void spr_read_dbat(DisasContext
*ctx
, int gprn
, int sprn
)
355 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, DBAT
[sprn
& 1][(sprn
- SPR_DBAT0U
) / 2]));
358 static void spr_read_dbat_h(DisasContext
*ctx
, int gprn
, int sprn
)
360 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, DBAT
[sprn
& 1][((sprn
- SPR_DBAT4U
) / 2) + 4]));
363 static void spr_write_dbatu(DisasContext
*ctx
, int sprn
, int gprn
)
365 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_DBAT0U
) / 2);
366 gen_helper_store_dbatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
367 tcg_temp_free_i32(t0
);
370 static void spr_write_dbatu_h(DisasContext
*ctx
, int sprn
, int gprn
)
372 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_DBAT4U
) / 2) + 4);
373 gen_helper_store_dbatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
374 tcg_temp_free_i32(t0
);
377 static void spr_write_dbatl(DisasContext
*ctx
, int sprn
, int gprn
)
379 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_DBAT0L
) / 2);
380 gen_helper_store_dbatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
381 tcg_temp_free_i32(t0
);
384 static void spr_write_dbatl_h(DisasContext
*ctx
, int sprn
, int gprn
)
386 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_DBAT4L
) / 2) + 4);
387 gen_helper_store_dbatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
388 tcg_temp_free_i32(t0
);
392 static void spr_write_sdr1(DisasContext
*ctx
, int sprn
, int gprn
)
394 gen_helper_store_sdr1(cpu_env
, cpu_gpr
[gprn
]);
397 #if defined(TARGET_PPC64)
398 /* 64 bits PowerPC specific SPRs */
400 static void spr_write_pidr(DisasContext
*ctx
, int sprn
, int gprn
)
402 gen_helper_store_pidr(cpu_env
, cpu_gpr
[gprn
]);
405 static void spr_read_hior(DisasContext
*ctx
, int gprn
, int sprn
)
407 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, excp_prefix
));
410 static void spr_write_hior(DisasContext
*ctx
, int sprn
, int gprn
)
412 TCGv t0
= tcg_temp_new();
413 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], 0x3FFFFF00000ULL
);
414 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_prefix
));
420 /* PowerPC 601 specific registers */
422 static void spr_read_601_rtcl(DisasContext
*ctx
, int gprn
, int sprn
)
424 gen_helper_load_601_rtcl(cpu_gpr
[gprn
], cpu_env
);
427 static void spr_read_601_rtcu(DisasContext
*ctx
, int gprn
, int sprn
)
429 gen_helper_load_601_rtcu(cpu_gpr
[gprn
], cpu_env
);
432 #if !defined(CONFIG_USER_ONLY)
433 static void spr_write_601_rtcu(DisasContext
*ctx
, int sprn
, int gprn
)
435 gen_helper_store_601_rtcu(cpu_env
, cpu_gpr
[gprn
]);
438 static void spr_write_601_rtcl(DisasContext
*ctx
, int sprn
, int gprn
)
440 gen_helper_store_601_rtcl(cpu_env
, cpu_gpr
[gprn
]);
443 static void spr_write_hid0_601(DisasContext
*ctx
, int sprn
, int gprn
)
445 gen_helper_store_hid0_601(cpu_env
, cpu_gpr
[gprn
]);
446 /* Must stop the translation as endianness may have changed */
447 gen_stop_exception(ctx
);
452 #if !defined(CONFIG_USER_ONLY)
453 static void spr_read_601_ubat(DisasContext
*ctx
, int gprn
, int sprn
)
455 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, IBAT
[sprn
& 1][(sprn
- SPR_IBAT0U
) / 2]));
458 static void spr_write_601_ubatu(DisasContext
*ctx
, int sprn
, int gprn
)
460 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0U
) / 2);
461 gen_helper_store_601_batl(cpu_env
, t0
, cpu_gpr
[gprn
]);
462 tcg_temp_free_i32(t0
);
465 static void spr_write_601_ubatl(DisasContext
*ctx
, int sprn
, int gprn
)
467 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0U
) / 2);
468 gen_helper_store_601_batu(cpu_env
, t0
, cpu_gpr
[gprn
]);
469 tcg_temp_free_i32(t0
);
473 /* PowerPC 40x specific registers */
474 #if !defined(CONFIG_USER_ONLY)
475 static void spr_read_40x_pit(DisasContext
*ctx
, int gprn
, int sprn
)
477 gen_helper_load_40x_pit(cpu_gpr
[gprn
], cpu_env
);
480 static void spr_write_40x_pit(DisasContext
*ctx
, int sprn
, int gprn
)
482 gen_helper_store_40x_pit(cpu_env
, cpu_gpr
[gprn
]);
485 static void spr_write_40x_dbcr0(DisasContext
*ctx
, int sprn
, int gprn
)
487 gen_helper_store_40x_dbcr0(cpu_env
, cpu_gpr
[gprn
]);
488 /* We must stop translation as we may have rebooted */
489 gen_stop_exception(ctx
);
492 static void spr_write_40x_sler(DisasContext
*ctx
, int sprn
, int gprn
)
494 gen_helper_store_40x_sler(cpu_env
, cpu_gpr
[gprn
]);
497 static void spr_write_booke_tcr(DisasContext
*ctx
, int sprn
, int gprn
)
499 gen_helper_store_booke_tcr(cpu_env
, cpu_gpr
[gprn
]);
502 static void spr_write_booke_tsr(DisasContext
*ctx
, int sprn
, int gprn
)
504 gen_helper_store_booke_tsr(cpu_env
, cpu_gpr
[gprn
]);
508 /* PowerPC 403 specific registers */
509 /* PBL1 / PBU1 / PBL2 / PBU2 */
510 #if !defined(CONFIG_USER_ONLY)
511 static void spr_read_403_pbr(DisasContext
*ctx
, int gprn
, int sprn
)
513 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, pb
[sprn
- SPR_403_PBL1
]));
516 static void spr_write_403_pbr(DisasContext
*ctx
, int sprn
, int gprn
)
518 TCGv_i32 t0
= tcg_const_i32(sprn
- SPR_403_PBL1
);
519 gen_helper_store_403_pbr(cpu_env
, t0
, cpu_gpr
[gprn
]);
520 tcg_temp_free_i32(t0
);
523 static void spr_write_pir(DisasContext
*ctx
, int sprn
, int gprn
)
525 TCGv t0
= tcg_temp_new();
526 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], 0xF);
527 gen_store_spr(SPR_PIR
, t0
);
532 /* SPE specific registers */
533 static void spr_read_spefscr(DisasContext
*ctx
, int gprn
, int sprn
)
535 TCGv_i32 t0
= tcg_temp_new_i32();
536 tcg_gen_ld_i32(t0
, cpu_env
, offsetof(CPUPPCState
, spe_fscr
));
537 tcg_gen_extu_i32_tl(cpu_gpr
[gprn
], t0
);
538 tcg_temp_free_i32(t0
);
541 static void spr_write_spefscr(DisasContext
*ctx
, int sprn
, int gprn
)
543 TCGv_i32 t0
= tcg_temp_new_i32();
544 tcg_gen_trunc_tl_i32(t0
, cpu_gpr
[gprn
]);
545 tcg_gen_st_i32(t0
, cpu_env
, offsetof(CPUPPCState
, spe_fscr
));
546 tcg_temp_free_i32(t0
);
549 #if !defined(CONFIG_USER_ONLY)
550 /* Callback used to write the exception vector base */
551 static void spr_write_excp_prefix(DisasContext
*ctx
, int sprn
, int gprn
)
553 TCGv t0
= tcg_temp_new();
554 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUPPCState
, ivpr_mask
));
555 tcg_gen_and_tl(t0
, t0
, cpu_gpr
[gprn
]);
556 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_prefix
));
557 gen_store_spr(sprn
, t0
);
561 static void spr_write_excp_vector(DisasContext
*ctx
, int sprn
, int gprn
)
565 if (sprn
>= SPR_BOOKE_IVOR0
&& sprn
<= SPR_BOOKE_IVOR15
) {
566 sprn_offs
= sprn
- SPR_BOOKE_IVOR0
;
567 } else if (sprn
>= SPR_BOOKE_IVOR32
&& sprn
<= SPR_BOOKE_IVOR37
) {
568 sprn_offs
= sprn
- SPR_BOOKE_IVOR32
+ 32;
569 } else if (sprn
>= SPR_BOOKE_IVOR38
&& sprn
<= SPR_BOOKE_IVOR42
) {
570 sprn_offs
= sprn
- SPR_BOOKE_IVOR38
+ 38;
572 printf("Trying to write an unknown exception vector %d %03x\n",
574 gen_inval_exception(ctx
, POWERPC_EXCP_PRIV_REG
);
578 TCGv t0
= tcg_temp_new();
579 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUPPCState
, ivor_mask
));
580 tcg_gen_and_tl(t0
, t0
, cpu_gpr
[gprn
]);
581 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_vectors
[sprn_offs
]));
582 gen_store_spr(sprn
, t0
);
587 static inline void vscr_init(CPUPPCState
*env
, uint32_t val
)
590 /* Altivec always uses round-to-nearest */
591 set_float_rounding_mode(float_round_nearest_even
, &env
->vec_status
);
592 set_flush_to_zero(vscr_nj
, &env
->vec_status
);
595 #ifdef CONFIG_USER_ONLY
596 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
597 oea_read, oea_write, one_reg_id, initial_value) \
598 _spr_register(env, num, name, uea_read, uea_write, initial_value)
599 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
600 oea_read, oea_write, hea_read, hea_write, \
601 one_reg_id, initial_value) \
602 _spr_register(env, num, name, uea_read, uea_write, initial_value)
604 #if !defined(CONFIG_KVM)
605 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
606 oea_read, oea_write, one_reg_id, initial_value) \
607 _spr_register(env, num, name, uea_read, uea_write, \
608 oea_read, oea_write, oea_read, oea_write, initial_value)
609 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
610 oea_read, oea_write, hea_read, hea_write, \
611 one_reg_id, initial_value) \
612 _spr_register(env, num, name, uea_read, uea_write, \
613 oea_read, oea_write, hea_read, hea_write, initial_value)
615 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
616 oea_read, oea_write, one_reg_id, initial_value) \
617 _spr_register(env, num, name, uea_read, uea_write, \
618 oea_read, oea_write, oea_read, oea_write, \
619 one_reg_id, initial_value)
620 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
621 oea_read, oea_write, hea_read, hea_write, \
622 one_reg_id, initial_value) \
623 _spr_register(env, num, name, uea_read, uea_write, \
624 oea_read, oea_write, hea_read, hea_write, \
625 one_reg_id, initial_value)
629 #define spr_register(env, num, name, uea_read, uea_write, \
630 oea_read, oea_write, initial_value) \
631 spr_register_kvm(env, num, name, uea_read, uea_write, \
632 oea_read, oea_write, 0, initial_value)
634 #define spr_register_hv(env, num, name, uea_read, uea_write, \
635 oea_read, oea_write, hea_read, hea_write, \
637 spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
638 oea_read, oea_write, hea_read, hea_write, \
641 static inline void _spr_register(CPUPPCState
*env
, int num
,
643 void (*uea_read
)(DisasContext
*ctx
, int gprn
, int sprn
),
644 void (*uea_write
)(DisasContext
*ctx
, int sprn
, int gprn
),
645 #if !defined(CONFIG_USER_ONLY)
647 void (*oea_read
)(DisasContext
*ctx
, int gprn
, int sprn
),
648 void (*oea_write
)(DisasContext
*ctx
, int sprn
, int gprn
),
649 void (*hea_read
)(DisasContext
*opaque
, int gprn
, int sprn
),
650 void (*hea_write
)(DisasContext
*opaque
, int sprn
, int gprn
),
652 #if defined(CONFIG_KVM)
655 target_ulong initial_value
)
659 spr
= &env
->spr_cb
[num
];
660 if (spr
->name
!= NULL
||env
-> spr
[num
] != 0x00000000 ||
661 #if !defined(CONFIG_USER_ONLY)
662 spr
->oea_read
!= NULL
|| spr
->oea_write
!= NULL
||
664 spr
->uea_read
!= NULL
|| spr
->uea_write
!= NULL
) {
665 printf("Error: Trying to register SPR %d (%03x) twice !\n", num
, num
);
668 #if defined(PPC_DEBUG_SPR)
669 printf("*** register spr %d (%03x) %s val " TARGET_FMT_lx
"\n", num
, num
,
670 name
, initial_value
);
673 spr
->uea_read
= uea_read
;
674 spr
->uea_write
= uea_write
;
675 #if !defined(CONFIG_USER_ONLY)
676 spr
->oea_read
= oea_read
;
677 spr
->oea_write
= oea_write
;
678 spr
->hea_read
= hea_read
;
679 spr
->hea_write
= hea_write
;
681 #if defined(CONFIG_KVM)
682 spr
->one_reg_id
= one_reg_id
,
684 env
->spr
[num
] = spr
->default_value
= initial_value
;
687 /* Generic PowerPC SPRs */
688 static void gen_spr_generic(CPUPPCState
*env
)
690 /* Integer processing */
691 spr_register(env
, SPR_XER
, "XER",
692 &spr_read_xer
, &spr_write_xer
,
693 &spr_read_xer
, &spr_write_xer
,
696 spr_register(env
, SPR_LR
, "LR",
697 &spr_read_lr
, &spr_write_lr
,
698 &spr_read_lr
, &spr_write_lr
,
700 spr_register(env
, SPR_CTR
, "CTR",
701 &spr_read_ctr
, &spr_write_ctr
,
702 &spr_read_ctr
, &spr_write_ctr
,
704 /* Interrupt processing */
705 spr_register(env
, SPR_SRR0
, "SRR0",
706 SPR_NOACCESS
, SPR_NOACCESS
,
707 &spr_read_generic
, &spr_write_generic
,
709 spr_register(env
, SPR_SRR1
, "SRR1",
710 SPR_NOACCESS
, SPR_NOACCESS
,
711 &spr_read_generic
, &spr_write_generic
,
713 /* Processor control */
714 spr_register(env
, SPR_SPRG0
, "SPRG0",
715 SPR_NOACCESS
, SPR_NOACCESS
,
716 &spr_read_generic
, &spr_write_generic
,
718 spr_register(env
, SPR_SPRG1
, "SPRG1",
719 SPR_NOACCESS
, SPR_NOACCESS
,
720 &spr_read_generic
, &spr_write_generic
,
722 spr_register(env
, SPR_SPRG2
, "SPRG2",
723 SPR_NOACCESS
, SPR_NOACCESS
,
724 &spr_read_generic
, &spr_write_generic
,
726 spr_register(env
, SPR_SPRG3
, "SPRG3",
727 SPR_NOACCESS
, SPR_NOACCESS
,
728 &spr_read_generic
, &spr_write_generic
,
732 /* SPR common to all non-embedded PowerPC, including 601 */
733 static void gen_spr_ne_601(CPUPPCState
*env
)
735 /* Exception processing */
736 spr_register_kvm(env
, SPR_DSISR
, "DSISR",
737 SPR_NOACCESS
, SPR_NOACCESS
,
738 &spr_read_generic
, &spr_write_generic
,
739 KVM_REG_PPC_DSISR
, 0x00000000);
740 spr_register_kvm(env
, SPR_DAR
, "DAR",
741 SPR_NOACCESS
, SPR_NOACCESS
,
742 &spr_read_generic
, &spr_write_generic
,
743 KVM_REG_PPC_DAR
, 0x00000000);
745 spr_register(env
, SPR_DECR
, "DECR",
746 SPR_NOACCESS
, SPR_NOACCESS
,
747 &spr_read_decr
, &spr_write_decr
,
751 /* Storage Description Register 1 */
752 static void gen_spr_sdr1(CPUPPCState
*env
)
754 #ifndef CONFIG_USER_ONLY
755 if (env
->has_hv_mode
) {
756 /* SDR1 is a hypervisor resource on CPUs which have a
758 spr_register_hv(env
, SPR_SDR1
, "SDR1",
759 SPR_NOACCESS
, SPR_NOACCESS
,
760 SPR_NOACCESS
, SPR_NOACCESS
,
761 &spr_read_generic
, &spr_write_sdr1
,
764 spr_register(env
, SPR_SDR1
, "SDR1",
765 SPR_NOACCESS
, SPR_NOACCESS
,
766 &spr_read_generic
, &spr_write_sdr1
,
773 static void gen_low_BATs(CPUPPCState
*env
)
775 #if !defined(CONFIG_USER_ONLY)
776 spr_register(env
, SPR_IBAT0U
, "IBAT0U",
777 SPR_NOACCESS
, SPR_NOACCESS
,
778 &spr_read_ibat
, &spr_write_ibatu
,
780 spr_register(env
, SPR_IBAT0L
, "IBAT0L",
781 SPR_NOACCESS
, SPR_NOACCESS
,
782 &spr_read_ibat
, &spr_write_ibatl
,
784 spr_register(env
, SPR_IBAT1U
, "IBAT1U",
785 SPR_NOACCESS
, SPR_NOACCESS
,
786 &spr_read_ibat
, &spr_write_ibatu
,
788 spr_register(env
, SPR_IBAT1L
, "IBAT1L",
789 SPR_NOACCESS
, SPR_NOACCESS
,
790 &spr_read_ibat
, &spr_write_ibatl
,
792 spr_register(env
, SPR_IBAT2U
, "IBAT2U",
793 SPR_NOACCESS
, SPR_NOACCESS
,
794 &spr_read_ibat
, &spr_write_ibatu
,
796 spr_register(env
, SPR_IBAT2L
, "IBAT2L",
797 SPR_NOACCESS
, SPR_NOACCESS
,
798 &spr_read_ibat
, &spr_write_ibatl
,
800 spr_register(env
, SPR_IBAT3U
, "IBAT3U",
801 SPR_NOACCESS
, SPR_NOACCESS
,
802 &spr_read_ibat
, &spr_write_ibatu
,
804 spr_register(env
, SPR_IBAT3L
, "IBAT3L",
805 SPR_NOACCESS
, SPR_NOACCESS
,
806 &spr_read_ibat
, &spr_write_ibatl
,
808 spr_register(env
, SPR_DBAT0U
, "DBAT0U",
809 SPR_NOACCESS
, SPR_NOACCESS
,
810 &spr_read_dbat
, &spr_write_dbatu
,
812 spr_register(env
, SPR_DBAT0L
, "DBAT0L",
813 SPR_NOACCESS
, SPR_NOACCESS
,
814 &spr_read_dbat
, &spr_write_dbatl
,
816 spr_register(env
, SPR_DBAT1U
, "DBAT1U",
817 SPR_NOACCESS
, SPR_NOACCESS
,
818 &spr_read_dbat
, &spr_write_dbatu
,
820 spr_register(env
, SPR_DBAT1L
, "DBAT1L",
821 SPR_NOACCESS
, SPR_NOACCESS
,
822 &spr_read_dbat
, &spr_write_dbatl
,
824 spr_register(env
, SPR_DBAT2U
, "DBAT2U",
825 SPR_NOACCESS
, SPR_NOACCESS
,
826 &spr_read_dbat
, &spr_write_dbatu
,
828 spr_register(env
, SPR_DBAT2L
, "DBAT2L",
829 SPR_NOACCESS
, SPR_NOACCESS
,
830 &spr_read_dbat
, &spr_write_dbatl
,
832 spr_register(env
, SPR_DBAT3U
, "DBAT3U",
833 SPR_NOACCESS
, SPR_NOACCESS
,
834 &spr_read_dbat
, &spr_write_dbatu
,
836 spr_register(env
, SPR_DBAT3L
, "DBAT3L",
837 SPR_NOACCESS
, SPR_NOACCESS
,
838 &spr_read_dbat
, &spr_write_dbatl
,
845 static void gen_high_BATs(CPUPPCState
*env
)
847 #if !defined(CONFIG_USER_ONLY)
848 spr_register(env
, SPR_IBAT4U
, "IBAT4U",
849 SPR_NOACCESS
, SPR_NOACCESS
,
850 &spr_read_ibat_h
, &spr_write_ibatu_h
,
852 spr_register(env
, SPR_IBAT4L
, "IBAT4L",
853 SPR_NOACCESS
, SPR_NOACCESS
,
854 &spr_read_ibat_h
, &spr_write_ibatl_h
,
856 spr_register(env
, SPR_IBAT5U
, "IBAT5U",
857 SPR_NOACCESS
, SPR_NOACCESS
,
858 &spr_read_ibat_h
, &spr_write_ibatu_h
,
860 spr_register(env
, SPR_IBAT5L
, "IBAT5L",
861 SPR_NOACCESS
, SPR_NOACCESS
,
862 &spr_read_ibat_h
, &spr_write_ibatl_h
,
864 spr_register(env
, SPR_IBAT6U
, "IBAT6U",
865 SPR_NOACCESS
, SPR_NOACCESS
,
866 &spr_read_ibat_h
, &spr_write_ibatu_h
,
868 spr_register(env
, SPR_IBAT6L
, "IBAT6L",
869 SPR_NOACCESS
, SPR_NOACCESS
,
870 &spr_read_ibat_h
, &spr_write_ibatl_h
,
872 spr_register(env
, SPR_IBAT7U
, "IBAT7U",
873 SPR_NOACCESS
, SPR_NOACCESS
,
874 &spr_read_ibat_h
, &spr_write_ibatu_h
,
876 spr_register(env
, SPR_IBAT7L
, "IBAT7L",
877 SPR_NOACCESS
, SPR_NOACCESS
,
878 &spr_read_ibat_h
, &spr_write_ibatl_h
,
880 spr_register(env
, SPR_DBAT4U
, "DBAT4U",
881 SPR_NOACCESS
, SPR_NOACCESS
,
882 &spr_read_dbat_h
, &spr_write_dbatu_h
,
884 spr_register(env
, SPR_DBAT4L
, "DBAT4L",
885 SPR_NOACCESS
, SPR_NOACCESS
,
886 &spr_read_dbat_h
, &spr_write_dbatl_h
,
888 spr_register(env
, SPR_DBAT5U
, "DBAT5U",
889 SPR_NOACCESS
, SPR_NOACCESS
,
890 &spr_read_dbat_h
, &spr_write_dbatu_h
,
892 spr_register(env
, SPR_DBAT5L
, "DBAT5L",
893 SPR_NOACCESS
, SPR_NOACCESS
,
894 &spr_read_dbat_h
, &spr_write_dbatl_h
,
896 spr_register(env
, SPR_DBAT6U
, "DBAT6U",
897 SPR_NOACCESS
, SPR_NOACCESS
,
898 &spr_read_dbat_h
, &spr_write_dbatu_h
,
900 spr_register(env
, SPR_DBAT6L
, "DBAT6L",
901 SPR_NOACCESS
, SPR_NOACCESS
,
902 &spr_read_dbat_h
, &spr_write_dbatl_h
,
904 spr_register(env
, SPR_DBAT7U
, "DBAT7U",
905 SPR_NOACCESS
, SPR_NOACCESS
,
906 &spr_read_dbat_h
, &spr_write_dbatu_h
,
908 spr_register(env
, SPR_DBAT7L
, "DBAT7L",
909 SPR_NOACCESS
, SPR_NOACCESS
,
910 &spr_read_dbat_h
, &spr_write_dbatl_h
,
916 /* Generic PowerPC time base */
917 static void gen_tbl(CPUPPCState
*env
)
919 spr_register(env
, SPR_VTBL
, "TBL",
920 &spr_read_tbl
, SPR_NOACCESS
,
921 &spr_read_tbl
, SPR_NOACCESS
,
923 spr_register(env
, SPR_TBL
, "TBL",
924 &spr_read_tbl
, SPR_NOACCESS
,
925 &spr_read_tbl
, &spr_write_tbl
,
927 spr_register(env
, SPR_VTBU
, "TBU",
928 &spr_read_tbu
, SPR_NOACCESS
,
929 &spr_read_tbu
, SPR_NOACCESS
,
931 spr_register(env
, SPR_TBU
, "TBU",
932 &spr_read_tbu
, SPR_NOACCESS
,
933 &spr_read_tbu
, &spr_write_tbu
,
937 /* Softare table search registers */
938 static void gen_6xx_7xx_soft_tlb(CPUPPCState
*env
, int nb_tlbs
, int nb_ways
)
940 #if !defined(CONFIG_USER_ONLY)
941 env
->nb_tlb
= nb_tlbs
;
942 env
->nb_ways
= nb_ways
;
944 env
->tlb_type
= TLB_6XX
;
945 spr_register(env
, SPR_DMISS
, "DMISS",
946 SPR_NOACCESS
, SPR_NOACCESS
,
947 &spr_read_generic
, SPR_NOACCESS
,
949 spr_register(env
, SPR_DCMP
, "DCMP",
950 SPR_NOACCESS
, SPR_NOACCESS
,
951 &spr_read_generic
, SPR_NOACCESS
,
953 spr_register(env
, SPR_HASH1
, "HASH1",
954 SPR_NOACCESS
, SPR_NOACCESS
,
955 &spr_read_generic
, SPR_NOACCESS
,
957 spr_register(env
, SPR_HASH2
, "HASH2",
958 SPR_NOACCESS
, SPR_NOACCESS
,
959 &spr_read_generic
, SPR_NOACCESS
,
961 spr_register(env
, SPR_IMISS
, "IMISS",
962 SPR_NOACCESS
, SPR_NOACCESS
,
963 &spr_read_generic
, SPR_NOACCESS
,
965 spr_register(env
, SPR_ICMP
, "ICMP",
966 SPR_NOACCESS
, SPR_NOACCESS
,
967 &spr_read_generic
, SPR_NOACCESS
,
969 spr_register(env
, SPR_RPA
, "RPA",
970 SPR_NOACCESS
, SPR_NOACCESS
,
971 &spr_read_generic
, &spr_write_generic
,
976 /* SPR common to MPC755 and G2 */
977 static void gen_spr_G2_755(CPUPPCState
*env
)
980 spr_register(env
, SPR_SPRG4
, "SPRG4",
981 SPR_NOACCESS
, SPR_NOACCESS
,
982 &spr_read_generic
, &spr_write_generic
,
984 spr_register(env
, SPR_SPRG5
, "SPRG5",
985 SPR_NOACCESS
, SPR_NOACCESS
,
986 &spr_read_generic
, &spr_write_generic
,
988 spr_register(env
, SPR_SPRG6
, "SPRG6",
989 SPR_NOACCESS
, SPR_NOACCESS
,
990 &spr_read_generic
, &spr_write_generic
,
992 spr_register(env
, SPR_SPRG7
, "SPRG7",
993 SPR_NOACCESS
, SPR_NOACCESS
,
994 &spr_read_generic
, &spr_write_generic
,
998 /* SPR common to all 7xx PowerPC implementations */
999 static void gen_spr_7xx(CPUPPCState
*env
)
1002 /* XXX : not implemented */
1003 spr_register_kvm(env
, SPR_DABR
, "DABR",
1004 SPR_NOACCESS
, SPR_NOACCESS
,
1005 &spr_read_generic
, &spr_write_generic
,
1006 KVM_REG_PPC_DABR
, 0x00000000);
1007 /* XXX : not implemented */
1008 spr_register(env
, SPR_IABR
, "IABR",
1009 SPR_NOACCESS
, SPR_NOACCESS
,
1010 &spr_read_generic
, &spr_write_generic
,
1012 /* Cache management */
1013 /* XXX : not implemented */
1014 spr_register(env
, SPR_ICTC
, "ICTC",
1015 SPR_NOACCESS
, SPR_NOACCESS
,
1016 &spr_read_generic
, &spr_write_generic
,
1018 /* Performance monitors */
1019 /* XXX : not implemented */
1020 spr_register(env
, SPR_7XX_MMCR0
, "MMCR0",
1021 SPR_NOACCESS
, SPR_NOACCESS
,
1022 &spr_read_generic
, &spr_write_generic
,
1024 /* XXX : not implemented */
1025 spr_register(env
, SPR_7XX_MMCR1
, "MMCR1",
1026 SPR_NOACCESS
, SPR_NOACCESS
,
1027 &spr_read_generic
, &spr_write_generic
,
1029 /* XXX : not implemented */
1030 spr_register(env
, SPR_7XX_PMC1
, "PMC1",
1031 SPR_NOACCESS
, SPR_NOACCESS
,
1032 &spr_read_generic
, &spr_write_generic
,
1034 /* XXX : not implemented */
1035 spr_register(env
, SPR_7XX_PMC2
, "PMC2",
1036 SPR_NOACCESS
, SPR_NOACCESS
,
1037 &spr_read_generic
, &spr_write_generic
,
1039 /* XXX : not implemented */
1040 spr_register(env
, SPR_7XX_PMC3
, "PMC3",
1041 SPR_NOACCESS
, SPR_NOACCESS
,
1042 &spr_read_generic
, &spr_write_generic
,
1044 /* XXX : not implemented */
1045 spr_register(env
, SPR_7XX_PMC4
, "PMC4",
1046 SPR_NOACCESS
, SPR_NOACCESS
,
1047 &spr_read_generic
, &spr_write_generic
,
1049 /* XXX : not implemented */
1050 spr_register(env
, SPR_7XX_SIAR
, "SIAR",
1051 SPR_NOACCESS
, SPR_NOACCESS
,
1052 &spr_read_generic
, SPR_NOACCESS
,
1054 /* XXX : not implemented */
1055 spr_register(env
, SPR_7XX_UMMCR0
, "UMMCR0",
1056 &spr_read_ureg
, SPR_NOACCESS
,
1057 &spr_read_ureg
, SPR_NOACCESS
,
1059 /* XXX : not implemented */
1060 spr_register(env
, SPR_7XX_UMMCR1
, "UMMCR1",
1061 &spr_read_ureg
, SPR_NOACCESS
,
1062 &spr_read_ureg
, SPR_NOACCESS
,
1064 /* XXX : not implemented */
1065 spr_register(env
, SPR_7XX_UPMC1
, "UPMC1",
1066 &spr_read_ureg
, SPR_NOACCESS
,
1067 &spr_read_ureg
, SPR_NOACCESS
,
1069 /* XXX : not implemented */
1070 spr_register(env
, SPR_7XX_UPMC2
, "UPMC2",
1071 &spr_read_ureg
, SPR_NOACCESS
,
1072 &spr_read_ureg
, SPR_NOACCESS
,
1074 /* XXX : not implemented */
1075 spr_register(env
, SPR_7XX_UPMC3
, "UPMC3",
1076 &spr_read_ureg
, SPR_NOACCESS
,
1077 &spr_read_ureg
, SPR_NOACCESS
,
1079 /* XXX : not implemented */
1080 spr_register(env
, SPR_7XX_UPMC4
, "UPMC4",
1081 &spr_read_ureg
, SPR_NOACCESS
,
1082 &spr_read_ureg
, SPR_NOACCESS
,
1084 /* XXX : not implemented */
1085 spr_register(env
, SPR_7XX_USIAR
, "USIAR",
1086 &spr_read_ureg
, SPR_NOACCESS
,
1087 &spr_read_ureg
, SPR_NOACCESS
,
1089 /* External access control */
1090 /* XXX : not implemented */
1091 spr_register(env
, SPR_EAR
, "EAR",
1092 SPR_NOACCESS
, SPR_NOACCESS
,
1093 &spr_read_generic
, &spr_write_generic
,
1098 #ifndef CONFIG_USER_ONLY
1099 static void spr_write_amr(DisasContext
*ctx
, int sprn
, int gprn
)
1101 TCGv t0
= tcg_temp_new();
1102 TCGv t1
= tcg_temp_new();
1103 TCGv t2
= tcg_temp_new();
1105 /* Note, the HV=1 PR=0 case is handled earlier by simply using
1106 * spr_write_generic for HV mode in the SPR table
1109 /* Build insertion mask into t1 based on context */
1111 gen_load_spr(t1
, SPR_UAMOR
);
1113 gen_load_spr(t1
, SPR_AMOR
);
1116 /* Mask new bits into t2 */
1117 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1119 /* Load AMR and clear new bits in t0 */
1120 gen_load_spr(t0
, SPR_AMR
);
1121 tcg_gen_andc_tl(t0
, t0
, t1
);
1123 /* Or'in new bits and write it out */
1124 tcg_gen_or_tl(t0
, t0
, t2
);
1125 gen_store_spr(SPR_AMR
, t0
);
1126 spr_store_dump_spr(SPR_AMR
);
1133 static void spr_write_uamor(DisasContext
*ctx
, int sprn
, int gprn
)
1135 TCGv t0
= tcg_temp_new();
1136 TCGv t1
= tcg_temp_new();
1137 TCGv t2
= tcg_temp_new();
1139 /* Note, the HV=1 case is handled earlier by simply using
1140 * spr_write_generic for HV mode in the SPR table
1143 /* Build insertion mask into t1 based on context */
1144 gen_load_spr(t1
, SPR_AMOR
);
1146 /* Mask new bits into t2 */
1147 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1149 /* Load AMR and clear new bits in t0 */
1150 gen_load_spr(t0
, SPR_UAMOR
);
1151 tcg_gen_andc_tl(t0
, t0
, t1
);
1153 /* Or'in new bits and write it out */
1154 tcg_gen_or_tl(t0
, t0
, t2
);
1155 gen_store_spr(SPR_UAMOR
, t0
);
1156 spr_store_dump_spr(SPR_UAMOR
);
1163 static void spr_write_iamr(DisasContext
*ctx
, int sprn
, int gprn
)
1165 TCGv t0
= tcg_temp_new();
1166 TCGv t1
= tcg_temp_new();
1167 TCGv t2
= tcg_temp_new();
1169 /* Note, the HV=1 case is handled earlier by simply using
1170 * spr_write_generic for HV mode in the SPR table
1173 /* Build insertion mask into t1 based on context */
1174 gen_load_spr(t1
, SPR_AMOR
);
1176 /* Mask new bits into t2 */
1177 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1179 /* Load AMR and clear new bits in t0 */
1180 gen_load_spr(t0
, SPR_IAMR
);
1181 tcg_gen_andc_tl(t0
, t0
, t1
);
1183 /* Or'in new bits and write it out */
1184 tcg_gen_or_tl(t0
, t0
, t2
);
1185 gen_store_spr(SPR_IAMR
, t0
);
1186 spr_store_dump_spr(SPR_IAMR
);
1192 #endif /* CONFIG_USER_ONLY */
1194 static void gen_spr_amr(CPUPPCState
*env
)
1196 #ifndef CONFIG_USER_ONLY
1197 /* Virtual Page Class Key protection */
1198 /* The AMR is accessible either via SPR 13 or SPR 29. 13 is
1199 * userspace accessible, 29 is privileged. So we only need to set
1200 * the kvm ONE_REG id on one of them, we use 29 */
1201 spr_register(env
, SPR_UAMR
, "UAMR",
1202 &spr_read_generic
, &spr_write_amr
,
1203 &spr_read_generic
, &spr_write_amr
,
1205 spr_register_kvm_hv(env
, SPR_AMR
, "AMR",
1206 SPR_NOACCESS
, SPR_NOACCESS
,
1207 &spr_read_generic
, &spr_write_amr
,
1208 &spr_read_generic
, &spr_write_generic
,
1209 KVM_REG_PPC_AMR
, 0);
1210 spr_register_kvm_hv(env
, SPR_UAMOR
, "UAMOR",
1211 SPR_NOACCESS
, SPR_NOACCESS
,
1212 &spr_read_generic
, &spr_write_uamor
,
1213 &spr_read_generic
, &spr_write_generic
,
1214 KVM_REG_PPC_UAMOR
, 0);
1215 spr_register_hv(env
, SPR_AMOR
, "AMOR",
1216 SPR_NOACCESS
, SPR_NOACCESS
,
1217 SPR_NOACCESS
, SPR_NOACCESS
,
1218 &spr_read_generic
, &spr_write_generic
,
1220 #endif /* !CONFIG_USER_ONLY */
1223 static void gen_spr_iamr(CPUPPCState
*env
)
1225 #ifndef CONFIG_USER_ONLY
1226 spr_register_kvm_hv(env
, SPR_IAMR
, "IAMR",
1227 SPR_NOACCESS
, SPR_NOACCESS
,
1228 &spr_read_generic
, &spr_write_iamr
,
1229 &spr_read_generic
, &spr_write_generic
,
1230 KVM_REG_PPC_IAMR
, 0);
1231 #endif /* !CONFIG_USER_ONLY */
1233 #endif /* TARGET_PPC64 */
1235 #ifndef CONFIG_USER_ONLY
1236 static void spr_read_thrm(DisasContext
*ctx
, int gprn
, int sprn
)
1238 gen_helper_fixup_thrm(cpu_env
);
1239 gen_load_spr(cpu_gpr
[gprn
], sprn
);
1240 spr_load_dump_spr(sprn
);
1242 #endif /* !CONFIG_USER_ONLY */
1244 static void gen_spr_thrm(CPUPPCState
*env
)
1246 /* Thermal management */
1247 /* XXX : not implemented */
1248 spr_register(env
, SPR_THRM1
, "THRM1",
1249 SPR_NOACCESS
, SPR_NOACCESS
,
1250 &spr_read_thrm
, &spr_write_generic
,
1252 /* XXX : not implemented */
1253 spr_register(env
, SPR_THRM2
, "THRM2",
1254 SPR_NOACCESS
, SPR_NOACCESS
,
1255 &spr_read_thrm
, &spr_write_generic
,
1257 /* XXX : not implemented */
1258 spr_register(env
, SPR_THRM3
, "THRM3",
1259 SPR_NOACCESS
, SPR_NOACCESS
,
1260 &spr_read_thrm
, &spr_write_generic
,
1264 /* SPR specific to PowerPC 604 implementation */
1265 static void gen_spr_604(CPUPPCState
*env
)
1267 /* Processor identification */
1268 spr_register(env
, SPR_PIR
, "PIR",
1269 SPR_NOACCESS
, SPR_NOACCESS
,
1270 &spr_read_generic
, &spr_write_pir
,
1273 /* XXX : not implemented */
1274 spr_register(env
, SPR_IABR
, "IABR",
1275 SPR_NOACCESS
, SPR_NOACCESS
,
1276 &spr_read_generic
, &spr_write_generic
,
1278 /* XXX : not implemented */
1279 spr_register_kvm(env
, SPR_DABR
, "DABR",
1280 SPR_NOACCESS
, SPR_NOACCESS
,
1281 &spr_read_generic
, &spr_write_generic
,
1282 KVM_REG_PPC_DABR
, 0x00000000);
1283 /* Performance counters */
1284 /* XXX : not implemented */
1285 spr_register(env
, SPR_7XX_MMCR0
, "MMCR0",
1286 SPR_NOACCESS
, SPR_NOACCESS
,
1287 &spr_read_generic
, &spr_write_generic
,
1289 /* XXX : not implemented */
1290 spr_register(env
, SPR_7XX_PMC1
, "PMC1",
1291 SPR_NOACCESS
, SPR_NOACCESS
,
1292 &spr_read_generic
, &spr_write_generic
,
1294 /* XXX : not implemented */
1295 spr_register(env
, SPR_7XX_PMC2
, "PMC2",
1296 SPR_NOACCESS
, SPR_NOACCESS
,
1297 &spr_read_generic
, &spr_write_generic
,
1299 /* XXX : not implemented */
1300 spr_register(env
, SPR_7XX_SIAR
, "SIAR",
1301 SPR_NOACCESS
, SPR_NOACCESS
,
1302 &spr_read_generic
, SPR_NOACCESS
,
1304 /* XXX : not implemented */
1305 spr_register(env
, SPR_SDA
, "SDA",
1306 SPR_NOACCESS
, SPR_NOACCESS
,
1307 &spr_read_generic
, SPR_NOACCESS
,
1309 /* External access control */
1310 /* XXX : not implemented */
1311 spr_register(env
, SPR_EAR
, "EAR",
1312 SPR_NOACCESS
, SPR_NOACCESS
,
1313 &spr_read_generic
, &spr_write_generic
,
1317 /* SPR specific to PowerPC 603 implementation */
1318 static void gen_spr_603(CPUPPCState
*env
)
1320 /* External access control */
1321 /* XXX : not implemented */
1322 spr_register(env
, SPR_EAR
, "EAR",
1323 SPR_NOACCESS
, SPR_NOACCESS
,
1324 &spr_read_generic
, &spr_write_generic
,
1327 /* XXX : not implemented */
1328 spr_register(env
, SPR_IABR
, "IABR",
1329 SPR_NOACCESS
, SPR_NOACCESS
,
1330 &spr_read_generic
, &spr_write_generic
,
1335 /* SPR specific to PowerPC G2 implementation */
1336 static void gen_spr_G2(CPUPPCState
*env
)
1338 /* Memory base address */
1340 /* XXX : not implemented */
1341 spr_register(env
, SPR_MBAR
, "MBAR",
1342 SPR_NOACCESS
, SPR_NOACCESS
,
1343 &spr_read_generic
, &spr_write_generic
,
1345 /* Exception processing */
1346 spr_register(env
, SPR_BOOKE_CSRR0
, "CSRR0",
1347 SPR_NOACCESS
, SPR_NOACCESS
,
1348 &spr_read_generic
, &spr_write_generic
,
1350 spr_register(env
, SPR_BOOKE_CSRR1
, "CSRR1",
1351 SPR_NOACCESS
, SPR_NOACCESS
,
1352 &spr_read_generic
, &spr_write_generic
,
1355 /* XXX : not implemented */
1356 spr_register(env
, SPR_DABR
, "DABR",
1357 SPR_NOACCESS
, SPR_NOACCESS
,
1358 &spr_read_generic
, &spr_write_generic
,
1360 /* XXX : not implemented */
1361 spr_register(env
, SPR_DABR2
, "DABR2",
1362 SPR_NOACCESS
, SPR_NOACCESS
,
1363 &spr_read_generic
, &spr_write_generic
,
1365 /* XXX : not implemented */
1366 spr_register(env
, SPR_IABR
, "IABR",
1367 SPR_NOACCESS
, SPR_NOACCESS
,
1368 &spr_read_generic
, &spr_write_generic
,
1370 /* XXX : not implemented */
1371 spr_register(env
, SPR_IABR2
, "IABR2",
1372 SPR_NOACCESS
, SPR_NOACCESS
,
1373 &spr_read_generic
, &spr_write_generic
,
1375 /* XXX : not implemented */
1376 spr_register(env
, SPR_IBCR
, "IBCR",
1377 SPR_NOACCESS
, SPR_NOACCESS
,
1378 &spr_read_generic
, &spr_write_generic
,
1380 /* XXX : not implemented */
1381 spr_register(env
, SPR_DBCR
, "DBCR",
1382 SPR_NOACCESS
, SPR_NOACCESS
,
1383 &spr_read_generic
, &spr_write_generic
,
1387 /* SPR specific to PowerPC 602 implementation */
1388 static void gen_spr_602(CPUPPCState
*env
)
1391 /* XXX : not implemented */
1392 spr_register(env
, SPR_SER
, "SER",
1393 SPR_NOACCESS
, SPR_NOACCESS
,
1394 &spr_read_generic
, &spr_write_generic
,
1396 /* XXX : not implemented */
1397 spr_register(env
, SPR_SEBR
, "SEBR",
1398 SPR_NOACCESS
, SPR_NOACCESS
,
1399 &spr_read_generic
, &spr_write_generic
,
1401 /* XXX : not implemented */
1402 spr_register(env
, SPR_ESASRR
, "ESASRR",
1403 SPR_NOACCESS
, SPR_NOACCESS
,
1404 &spr_read_generic
, &spr_write_generic
,
1406 /* Floating point status */
1407 /* XXX : not implemented */
1408 spr_register(env
, SPR_SP
, "SP",
1409 SPR_NOACCESS
, SPR_NOACCESS
,
1410 &spr_read_generic
, &spr_write_generic
,
1412 /* XXX : not implemented */
1413 spr_register(env
, SPR_LT
, "LT",
1414 SPR_NOACCESS
, SPR_NOACCESS
,
1415 &spr_read_generic
, &spr_write_generic
,
1417 /* Watchdog timer */
1418 /* XXX : not implemented */
1419 spr_register(env
, SPR_TCR
, "TCR",
1420 SPR_NOACCESS
, SPR_NOACCESS
,
1421 &spr_read_generic
, &spr_write_generic
,
1423 /* Interrupt base */
1424 spr_register(env
, SPR_IBR
, "IBR",
1425 SPR_NOACCESS
, SPR_NOACCESS
,
1426 &spr_read_generic
, &spr_write_generic
,
1428 /* XXX : not implemented */
1429 spr_register(env
, SPR_IABR
, "IABR",
1430 SPR_NOACCESS
, SPR_NOACCESS
,
1431 &spr_read_generic
, &spr_write_generic
,
1435 /* SPR specific to PowerPC 601 implementation */
1436 static void gen_spr_601(CPUPPCState
*env
)
1438 /* Multiplication/division register */
1440 spr_register(env
, SPR_MQ
, "MQ",
1441 &spr_read_generic
, &spr_write_generic
,
1442 &spr_read_generic
, &spr_write_generic
,
1445 spr_register(env
, SPR_601_RTCU
, "RTCU",
1446 SPR_NOACCESS
, SPR_NOACCESS
,
1447 SPR_NOACCESS
, &spr_write_601_rtcu
,
1449 spr_register(env
, SPR_601_VRTCU
, "RTCU",
1450 &spr_read_601_rtcu
, SPR_NOACCESS
,
1451 &spr_read_601_rtcu
, SPR_NOACCESS
,
1453 spr_register(env
, SPR_601_RTCL
, "RTCL",
1454 SPR_NOACCESS
, SPR_NOACCESS
,
1455 SPR_NOACCESS
, &spr_write_601_rtcl
,
1457 spr_register(env
, SPR_601_VRTCL
, "RTCL",
1458 &spr_read_601_rtcl
, SPR_NOACCESS
,
1459 &spr_read_601_rtcl
, SPR_NOACCESS
,
1463 spr_register(env
, SPR_601_UDECR
, "UDECR",
1464 &spr_read_decr
, SPR_NOACCESS
,
1465 &spr_read_decr
, SPR_NOACCESS
,
1468 /* External access control */
1469 /* XXX : not implemented */
1470 spr_register(env
, SPR_EAR
, "EAR",
1471 SPR_NOACCESS
, SPR_NOACCESS
,
1472 &spr_read_generic
, &spr_write_generic
,
1474 /* Memory management */
1475 #if !defined(CONFIG_USER_ONLY)
1476 spr_register(env
, SPR_IBAT0U
, "IBAT0U",
1477 SPR_NOACCESS
, SPR_NOACCESS
,
1478 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1480 spr_register(env
, SPR_IBAT0L
, "IBAT0L",
1481 SPR_NOACCESS
, SPR_NOACCESS
,
1482 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1484 spr_register(env
, SPR_IBAT1U
, "IBAT1U",
1485 SPR_NOACCESS
, SPR_NOACCESS
,
1486 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1488 spr_register(env
, SPR_IBAT1L
, "IBAT1L",
1489 SPR_NOACCESS
, SPR_NOACCESS
,
1490 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1492 spr_register(env
, SPR_IBAT2U
, "IBAT2U",
1493 SPR_NOACCESS
, SPR_NOACCESS
,
1494 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1496 spr_register(env
, SPR_IBAT2L
, "IBAT2L",
1497 SPR_NOACCESS
, SPR_NOACCESS
,
1498 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1500 spr_register(env
, SPR_IBAT3U
, "IBAT3U",
1501 SPR_NOACCESS
, SPR_NOACCESS
,
1502 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1504 spr_register(env
, SPR_IBAT3L
, "IBAT3L",
1505 SPR_NOACCESS
, SPR_NOACCESS
,
1506 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1512 static void gen_spr_74xx(CPUPPCState
*env
)
1514 /* Processor identification */
1515 spr_register(env
, SPR_PIR
, "PIR",
1516 SPR_NOACCESS
, SPR_NOACCESS
,
1517 &spr_read_generic
, &spr_write_pir
,
1519 /* XXX : not implemented */
1520 spr_register(env
, SPR_74XX_MMCR2
, "MMCR2",
1521 SPR_NOACCESS
, SPR_NOACCESS
,
1522 &spr_read_generic
, &spr_write_generic
,
1524 /* XXX : not implemented */
1525 spr_register(env
, SPR_74XX_UMMCR2
, "UMMCR2",
1526 &spr_read_ureg
, SPR_NOACCESS
,
1527 &spr_read_ureg
, SPR_NOACCESS
,
1529 /* XXX: not implemented */
1530 spr_register(env
, SPR_BAMR
, "BAMR",
1531 SPR_NOACCESS
, SPR_NOACCESS
,
1532 &spr_read_generic
, &spr_write_generic
,
1534 /* XXX : not implemented */
1535 spr_register(env
, SPR_MSSCR0
, "MSSCR0",
1536 SPR_NOACCESS
, SPR_NOACCESS
,
1537 &spr_read_generic
, &spr_write_generic
,
1539 /* Hardware implementation registers */
1540 /* XXX : not implemented */
1541 spr_register(env
, SPR_HID0
, "HID0",
1542 SPR_NOACCESS
, SPR_NOACCESS
,
1543 &spr_read_generic
, &spr_write_generic
,
1545 /* XXX : not implemented */
1546 spr_register(env
, SPR_HID1
, "HID1",
1547 SPR_NOACCESS
, SPR_NOACCESS
,
1548 &spr_read_generic
, &spr_write_generic
,
1551 spr_register(env
, SPR_VRSAVE
, "VRSAVE",
1552 &spr_read_generic
, &spr_write_generic
,
1553 &spr_read_generic
, &spr_write_generic
,
1555 /* XXX : not implemented */
1556 spr_register(env
, SPR_L2CR
, "L2CR",
1557 SPR_NOACCESS
, SPR_NOACCESS
,
1558 &spr_read_generic
, spr_access_nop
,
1560 /* Not strictly an SPR */
1561 vscr_init(env
, 0x00010000);
1564 static void gen_l3_ctrl(CPUPPCState
*env
)
1567 /* XXX : not implemented */
1568 spr_register(env
, SPR_L3CR
, "L3CR",
1569 SPR_NOACCESS
, SPR_NOACCESS
,
1570 &spr_read_generic
, &spr_write_generic
,
1573 /* XXX : not implemented */
1574 spr_register(env
, SPR_L3ITCR0
, "L3ITCR0",
1575 SPR_NOACCESS
, SPR_NOACCESS
,
1576 &spr_read_generic
, &spr_write_generic
,
1579 /* XXX : not implemented */
1580 spr_register(env
, SPR_L3PM
, "L3PM",
1581 SPR_NOACCESS
, SPR_NOACCESS
,
1582 &spr_read_generic
, &spr_write_generic
,
1586 static void gen_74xx_soft_tlb(CPUPPCState
*env
, int nb_tlbs
, int nb_ways
)
1588 #if !defined(CONFIG_USER_ONLY)
1589 env
->nb_tlb
= nb_tlbs
;
1590 env
->nb_ways
= nb_ways
;
1592 env
->tlb_type
= TLB_6XX
;
1593 /* XXX : not implemented */
1594 spr_register(env
, SPR_PTEHI
, "PTEHI",
1595 SPR_NOACCESS
, SPR_NOACCESS
,
1596 &spr_read_generic
, &spr_write_generic
,
1598 /* XXX : not implemented */
1599 spr_register(env
, SPR_PTELO
, "PTELO",
1600 SPR_NOACCESS
, SPR_NOACCESS
,
1601 &spr_read_generic
, &spr_write_generic
,
1603 /* XXX : not implemented */
1604 spr_register(env
, SPR_TLBMISS
, "TLBMISS",
1605 SPR_NOACCESS
, SPR_NOACCESS
,
1606 &spr_read_generic
, &spr_write_generic
,
1611 #if !defined(CONFIG_USER_ONLY)
1612 static void spr_write_e500_l1csr0(DisasContext
*ctx
, int sprn
, int gprn
)
1614 TCGv t0
= tcg_temp_new();
1616 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], L1CSR0_DCE
| L1CSR0_CPE
);
1617 gen_store_spr(sprn
, t0
);
1621 static void spr_write_e500_l1csr1(DisasContext
*ctx
, int sprn
, int gprn
)
1623 TCGv t0
= tcg_temp_new();
1625 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], L1CSR1_ICE
| L1CSR1_CPE
);
1626 gen_store_spr(sprn
, t0
);
1630 static void spr_write_booke206_mmucsr0(DisasContext
*ctx
, int sprn
, int gprn
)
1632 gen_helper_booke206_tlbflush(cpu_env
, cpu_gpr
[gprn
]);
1635 static void spr_write_booke_pid(DisasContext
*ctx
, int sprn
, int gprn
)
1637 TCGv_i32 t0
= tcg_const_i32(sprn
);
1638 gen_helper_booke_setpid(cpu_env
, t0
, cpu_gpr
[gprn
]);
1639 tcg_temp_free_i32(t0
);
1643 static void gen_spr_usprg3(CPUPPCState
*env
)
1645 spr_register(env
, SPR_USPRG3
, "USPRG3",
1646 &spr_read_ureg
, SPR_NOACCESS
,
1647 &spr_read_ureg
, SPR_NOACCESS
,
1651 static void gen_spr_usprgh(CPUPPCState
*env
)
1653 spr_register(env
, SPR_USPRG4
, "USPRG4",
1654 &spr_read_ureg
, SPR_NOACCESS
,
1655 &spr_read_ureg
, SPR_NOACCESS
,
1657 spr_register(env
, SPR_USPRG5
, "USPRG5",
1658 &spr_read_ureg
, SPR_NOACCESS
,
1659 &spr_read_ureg
, SPR_NOACCESS
,
1661 spr_register(env
, SPR_USPRG6
, "USPRG6",
1662 &spr_read_ureg
, SPR_NOACCESS
,
1663 &spr_read_ureg
, SPR_NOACCESS
,
1665 spr_register(env
, SPR_USPRG7
, "USPRG7",
1666 &spr_read_ureg
, SPR_NOACCESS
,
1667 &spr_read_ureg
, SPR_NOACCESS
,
1671 /* PowerPC BookE SPR */
1672 static void gen_spr_BookE(CPUPPCState
*env
, uint64_t ivor_mask
)
1674 const char *ivor_names
[64] = {
1675 "IVOR0", "IVOR1", "IVOR2", "IVOR3",
1676 "IVOR4", "IVOR5", "IVOR6", "IVOR7",
1677 "IVOR8", "IVOR9", "IVOR10", "IVOR11",
1678 "IVOR12", "IVOR13", "IVOR14", "IVOR15",
1679 "IVOR16", "IVOR17", "IVOR18", "IVOR19",
1680 "IVOR20", "IVOR21", "IVOR22", "IVOR23",
1681 "IVOR24", "IVOR25", "IVOR26", "IVOR27",
1682 "IVOR28", "IVOR29", "IVOR30", "IVOR31",
1683 "IVOR32", "IVOR33", "IVOR34", "IVOR35",
1684 "IVOR36", "IVOR37", "IVOR38", "IVOR39",
1685 "IVOR40", "IVOR41", "IVOR42", "IVOR43",
1686 "IVOR44", "IVOR45", "IVOR46", "IVOR47",
1687 "IVOR48", "IVOR49", "IVOR50", "IVOR51",
1688 "IVOR52", "IVOR53", "IVOR54", "IVOR55",
1689 "IVOR56", "IVOR57", "IVOR58", "IVOR59",
1690 "IVOR60", "IVOR61", "IVOR62", "IVOR63",
1692 #define SPR_BOOKE_IVORxx (-1)
1693 int ivor_sprn
[64] = {
1694 SPR_BOOKE_IVOR0
, SPR_BOOKE_IVOR1
, SPR_BOOKE_IVOR2
, SPR_BOOKE_IVOR3
,
1695 SPR_BOOKE_IVOR4
, SPR_BOOKE_IVOR5
, SPR_BOOKE_IVOR6
, SPR_BOOKE_IVOR7
,
1696 SPR_BOOKE_IVOR8
, SPR_BOOKE_IVOR9
, SPR_BOOKE_IVOR10
, SPR_BOOKE_IVOR11
,
1697 SPR_BOOKE_IVOR12
, SPR_BOOKE_IVOR13
, SPR_BOOKE_IVOR14
, SPR_BOOKE_IVOR15
,
1698 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1699 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1700 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1701 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1702 SPR_BOOKE_IVOR32
, SPR_BOOKE_IVOR33
, SPR_BOOKE_IVOR34
, SPR_BOOKE_IVOR35
,
1703 SPR_BOOKE_IVOR36
, SPR_BOOKE_IVOR37
, SPR_BOOKE_IVOR38
, SPR_BOOKE_IVOR39
,
1704 SPR_BOOKE_IVOR40
, SPR_BOOKE_IVOR41
, SPR_BOOKE_IVOR42
, SPR_BOOKE_IVORxx
,
1705 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1706 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1707 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1708 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1709 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1713 /* Interrupt processing */
1714 spr_register(env
, SPR_BOOKE_CSRR0
, "CSRR0",
1715 SPR_NOACCESS
, SPR_NOACCESS
,
1716 &spr_read_generic
, &spr_write_generic
,
1718 spr_register(env
, SPR_BOOKE_CSRR1
, "CSRR1",
1719 SPR_NOACCESS
, SPR_NOACCESS
,
1720 &spr_read_generic
, &spr_write_generic
,
1723 /* XXX : not implemented */
1724 spr_register(env
, SPR_BOOKE_IAC1
, "IAC1",
1725 SPR_NOACCESS
, SPR_NOACCESS
,
1726 &spr_read_generic
, &spr_write_generic
,
1728 /* XXX : not implemented */
1729 spr_register(env
, SPR_BOOKE_IAC2
, "IAC2",
1730 SPR_NOACCESS
, SPR_NOACCESS
,
1731 &spr_read_generic
, &spr_write_generic
,
1733 /* XXX : not implemented */
1734 spr_register(env
, SPR_BOOKE_DAC1
, "DAC1",
1735 SPR_NOACCESS
, SPR_NOACCESS
,
1736 &spr_read_generic
, &spr_write_generic
,
1738 /* XXX : not implemented */
1739 spr_register(env
, SPR_BOOKE_DAC2
, "DAC2",
1740 SPR_NOACCESS
, SPR_NOACCESS
,
1741 &spr_read_generic
, &spr_write_generic
,
1743 /* XXX : not implemented */
1744 spr_register(env
, SPR_BOOKE_DBCR0
, "DBCR0",
1745 SPR_NOACCESS
, SPR_NOACCESS
,
1746 &spr_read_generic
, &spr_write_40x_dbcr0
,
1748 /* XXX : not implemented */
1749 spr_register(env
, SPR_BOOKE_DBCR1
, "DBCR1",
1750 SPR_NOACCESS
, SPR_NOACCESS
,
1751 &spr_read_generic
, &spr_write_generic
,
1753 /* XXX : not implemented */
1754 spr_register(env
, SPR_BOOKE_DBCR2
, "DBCR2",
1755 SPR_NOACCESS
, SPR_NOACCESS
,
1756 &spr_read_generic
, &spr_write_generic
,
1758 /* XXX : not implemented */
1759 spr_register(env
, SPR_BOOKE_DBSR
, "DBSR",
1760 SPR_NOACCESS
, SPR_NOACCESS
,
1761 &spr_read_generic
, &spr_write_clear
,
1763 spr_register(env
, SPR_BOOKE_DEAR
, "DEAR",
1764 SPR_NOACCESS
, SPR_NOACCESS
,
1765 &spr_read_generic
, &spr_write_generic
,
1767 spr_register(env
, SPR_BOOKE_ESR
, "ESR",
1768 SPR_NOACCESS
, SPR_NOACCESS
,
1769 &spr_read_generic
, &spr_write_generic
,
1771 spr_register(env
, SPR_BOOKE_IVPR
, "IVPR",
1772 SPR_NOACCESS
, SPR_NOACCESS
,
1773 &spr_read_generic
, &spr_write_excp_prefix
,
1775 /* Exception vectors */
1776 for (i
= 0; i
< 64; i
++) {
1777 if (ivor_mask
& (1ULL << i
)) {
1778 if (ivor_sprn
[i
] == SPR_BOOKE_IVORxx
) {
1779 fprintf(stderr
, "ERROR: IVOR %d SPR is not defined\n", i
);
1782 spr_register(env
, ivor_sprn
[i
], ivor_names
[i
],
1783 SPR_NOACCESS
, SPR_NOACCESS
,
1784 &spr_read_generic
, &spr_write_excp_vector
,
1788 spr_register(env
, SPR_BOOKE_PID
, "PID",
1789 SPR_NOACCESS
, SPR_NOACCESS
,
1790 &spr_read_generic
, &spr_write_booke_pid
,
1792 spr_register(env
, SPR_BOOKE_TCR
, "TCR",
1793 SPR_NOACCESS
, SPR_NOACCESS
,
1794 &spr_read_generic
, &spr_write_booke_tcr
,
1796 spr_register(env
, SPR_BOOKE_TSR
, "TSR",
1797 SPR_NOACCESS
, SPR_NOACCESS
,
1798 &spr_read_generic
, &spr_write_booke_tsr
,
1801 spr_register(env
, SPR_DECR
, "DECR",
1802 SPR_NOACCESS
, SPR_NOACCESS
,
1803 &spr_read_decr
, &spr_write_decr
,
1805 spr_register(env
, SPR_BOOKE_DECAR
, "DECAR",
1806 SPR_NOACCESS
, SPR_NOACCESS
,
1807 SPR_NOACCESS
, &spr_write_generic
,
1810 spr_register(env
, SPR_USPRG0
, "USPRG0",
1811 &spr_read_generic
, &spr_write_generic
,
1812 &spr_read_generic
, &spr_write_generic
,
1814 spr_register(env
, SPR_SPRG4
, "SPRG4",
1815 SPR_NOACCESS
, SPR_NOACCESS
,
1816 &spr_read_generic
, &spr_write_generic
,
1818 spr_register(env
, SPR_SPRG5
, "SPRG5",
1819 SPR_NOACCESS
, SPR_NOACCESS
,
1820 &spr_read_generic
, &spr_write_generic
,
1822 spr_register(env
, SPR_SPRG6
, "SPRG6",
1823 SPR_NOACCESS
, SPR_NOACCESS
,
1824 &spr_read_generic
, &spr_write_generic
,
1826 spr_register(env
, SPR_SPRG7
, "SPRG7",
1827 SPR_NOACCESS
, SPR_NOACCESS
,
1828 &spr_read_generic
, &spr_write_generic
,
1832 static inline uint32_t gen_tlbncfg(uint32_t assoc
, uint32_t minsize
,
1833 uint32_t maxsize
, uint32_t flags
,
1836 return (assoc
<< TLBnCFG_ASSOC_SHIFT
) |
1837 (minsize
<< TLBnCFG_MINSIZE_SHIFT
) |
1838 (maxsize
<< TLBnCFG_MAXSIZE_SHIFT
) |
1842 /* BookE 2.06 storage control registers */
1843 static void gen_spr_BookE206(CPUPPCState
*env
, uint32_t mas_mask
,
1846 #if !defined(CONFIG_USER_ONLY)
1847 const char *mas_names
[8] = {
1848 "MAS0", "MAS1", "MAS2", "MAS3", "MAS4", "MAS5", "MAS6", "MAS7",
1851 SPR_BOOKE_MAS0
, SPR_BOOKE_MAS1
, SPR_BOOKE_MAS2
, SPR_BOOKE_MAS3
,
1852 SPR_BOOKE_MAS4
, SPR_BOOKE_MAS5
, SPR_BOOKE_MAS6
, SPR_BOOKE_MAS7
,
1856 /* TLB assist registers */
1857 /* XXX : not implemented */
1858 for (i
= 0; i
< 8; i
++) {
1859 void (*uea_write
)(DisasContext
*ctx
, int sprn
, int gprn
) = &spr_write_generic32
;
1860 if (i
== 2 && (mas_mask
& (1 << i
)) && (env
->insns_flags
& PPC_64B
)) {
1861 uea_write
= &spr_write_generic
;
1863 if (mas_mask
& (1 << i
)) {
1864 spr_register(env
, mas_sprn
[i
], mas_names
[i
],
1865 SPR_NOACCESS
, SPR_NOACCESS
,
1866 &spr_read_generic
, uea_write
,
1870 if (env
->nb_pids
> 1) {
1871 /* XXX : not implemented */
1872 spr_register(env
, SPR_BOOKE_PID1
, "PID1",
1873 SPR_NOACCESS
, SPR_NOACCESS
,
1874 &spr_read_generic
, &spr_write_booke_pid
,
1877 if (env
->nb_pids
> 2) {
1878 /* XXX : not implemented */
1879 spr_register(env
, SPR_BOOKE_PID2
, "PID2",
1880 SPR_NOACCESS
, SPR_NOACCESS
,
1881 &spr_read_generic
, &spr_write_booke_pid
,
1884 /* XXX : not implemented */
1885 spr_register(env
, SPR_MMUCFG
, "MMUCFG",
1886 SPR_NOACCESS
, SPR_NOACCESS
,
1887 &spr_read_generic
, SPR_NOACCESS
,
1888 0x00000000); /* TOFIX */
1889 switch (env
->nb_ways
) {
1891 spr_register(env
, SPR_BOOKE_TLB3CFG
, "TLB3CFG",
1892 SPR_NOACCESS
, SPR_NOACCESS
,
1893 &spr_read_generic
, SPR_NOACCESS
,
1897 spr_register(env
, SPR_BOOKE_TLB2CFG
, "TLB2CFG",
1898 SPR_NOACCESS
, SPR_NOACCESS
,
1899 &spr_read_generic
, SPR_NOACCESS
,
1903 spr_register(env
, SPR_BOOKE_TLB1CFG
, "TLB1CFG",
1904 SPR_NOACCESS
, SPR_NOACCESS
,
1905 &spr_read_generic
, SPR_NOACCESS
,
1909 spr_register(env
, SPR_BOOKE_TLB0CFG
, "TLB0CFG",
1910 SPR_NOACCESS
, SPR_NOACCESS
,
1911 &spr_read_generic
, SPR_NOACCESS
,
1920 gen_spr_usprgh(env
);
1923 /* SPR specific to PowerPC 440 implementation */
1924 static void gen_spr_440(CPUPPCState
*env
)
1927 /* XXX : not implemented */
1928 spr_register(env
, SPR_440_DNV0
, "DNV0",
1929 SPR_NOACCESS
, SPR_NOACCESS
,
1930 &spr_read_generic
, &spr_write_generic
,
1932 /* XXX : not implemented */
1933 spr_register(env
, SPR_440_DNV1
, "DNV1",
1934 SPR_NOACCESS
, SPR_NOACCESS
,
1935 &spr_read_generic
, &spr_write_generic
,
1937 /* XXX : not implemented */
1938 spr_register(env
, SPR_440_DNV2
, "DNV2",
1939 SPR_NOACCESS
, SPR_NOACCESS
,
1940 &spr_read_generic
, &spr_write_generic
,
1942 /* XXX : not implemented */
1943 spr_register(env
, SPR_440_DNV3
, "DNV3",
1944 SPR_NOACCESS
, SPR_NOACCESS
,
1945 &spr_read_generic
, &spr_write_generic
,
1947 /* XXX : not implemented */
1948 spr_register(env
, SPR_440_DTV0
, "DTV0",
1949 SPR_NOACCESS
, SPR_NOACCESS
,
1950 &spr_read_generic
, &spr_write_generic
,
1952 /* XXX : not implemented */
1953 spr_register(env
, SPR_440_DTV1
, "DTV1",
1954 SPR_NOACCESS
, SPR_NOACCESS
,
1955 &spr_read_generic
, &spr_write_generic
,
1957 /* XXX : not implemented */
1958 spr_register(env
, SPR_440_DTV2
, "DTV2",
1959 SPR_NOACCESS
, SPR_NOACCESS
,
1960 &spr_read_generic
, &spr_write_generic
,
1962 /* XXX : not implemented */
1963 spr_register(env
, SPR_440_DTV3
, "DTV3",
1964 SPR_NOACCESS
, SPR_NOACCESS
,
1965 &spr_read_generic
, &spr_write_generic
,
1967 /* XXX : not implemented */
1968 spr_register(env
, SPR_440_DVLIM
, "DVLIM",
1969 SPR_NOACCESS
, SPR_NOACCESS
,
1970 &spr_read_generic
, &spr_write_generic
,
1972 /* XXX : not implemented */
1973 spr_register(env
, SPR_440_INV0
, "INV0",
1974 SPR_NOACCESS
, SPR_NOACCESS
,
1975 &spr_read_generic
, &spr_write_generic
,
1977 /* XXX : not implemented */
1978 spr_register(env
, SPR_440_INV1
, "INV1",
1979 SPR_NOACCESS
, SPR_NOACCESS
,
1980 &spr_read_generic
, &spr_write_generic
,
1982 /* XXX : not implemented */
1983 spr_register(env
, SPR_440_INV2
, "INV2",
1984 SPR_NOACCESS
, SPR_NOACCESS
,
1985 &spr_read_generic
, &spr_write_generic
,
1987 /* XXX : not implemented */
1988 spr_register(env
, SPR_440_INV3
, "INV3",
1989 SPR_NOACCESS
, SPR_NOACCESS
,
1990 &spr_read_generic
, &spr_write_generic
,
1992 /* XXX : not implemented */
1993 spr_register(env
, SPR_440_ITV0
, "ITV0",
1994 SPR_NOACCESS
, SPR_NOACCESS
,
1995 &spr_read_generic
, &spr_write_generic
,
1997 /* XXX : not implemented */
1998 spr_register(env
, SPR_440_ITV1
, "ITV1",
1999 SPR_NOACCESS
, SPR_NOACCESS
,
2000 &spr_read_generic
, &spr_write_generic
,
2002 /* XXX : not implemented */
2003 spr_register(env
, SPR_440_ITV2
, "ITV2",
2004 SPR_NOACCESS
, SPR_NOACCESS
,
2005 &spr_read_generic
, &spr_write_generic
,
2007 /* XXX : not implemented */
2008 spr_register(env
, SPR_440_ITV3
, "ITV3",
2009 SPR_NOACCESS
, SPR_NOACCESS
,
2010 &spr_read_generic
, &spr_write_generic
,
2012 /* XXX : not implemented */
2013 spr_register(env
, SPR_440_IVLIM
, "IVLIM",
2014 SPR_NOACCESS
, SPR_NOACCESS
,
2015 &spr_read_generic
, &spr_write_generic
,
2018 /* XXX : not implemented */
2019 spr_register(env
, SPR_BOOKE_DCDBTRH
, "DCDBTRH",
2020 SPR_NOACCESS
, SPR_NOACCESS
,
2021 &spr_read_generic
, SPR_NOACCESS
,
2023 /* XXX : not implemented */
2024 spr_register(env
, SPR_BOOKE_DCDBTRL
, "DCDBTRL",
2025 SPR_NOACCESS
, SPR_NOACCESS
,
2026 &spr_read_generic
, SPR_NOACCESS
,
2028 /* XXX : not implemented */
2029 spr_register(env
, SPR_BOOKE_ICDBDR
, "ICDBDR",
2030 SPR_NOACCESS
, SPR_NOACCESS
,
2031 &spr_read_generic
, SPR_NOACCESS
,
2033 /* XXX : not implemented */
2034 spr_register(env
, SPR_BOOKE_ICDBTRH
, "ICDBTRH",
2035 SPR_NOACCESS
, SPR_NOACCESS
,
2036 &spr_read_generic
, SPR_NOACCESS
,
2038 /* XXX : not implemented */
2039 spr_register(env
, SPR_BOOKE_ICDBTRL
, "ICDBTRL",
2040 SPR_NOACCESS
, SPR_NOACCESS
,
2041 &spr_read_generic
, SPR_NOACCESS
,
2043 /* XXX : not implemented */
2044 spr_register(env
, SPR_440_DBDR
, "DBDR",
2045 SPR_NOACCESS
, SPR_NOACCESS
,
2046 &spr_read_generic
, &spr_write_generic
,
2048 /* Processor control */
2049 spr_register(env
, SPR_4xx_CCR0
, "CCR0",
2050 SPR_NOACCESS
, SPR_NOACCESS
,
2051 &spr_read_generic
, &spr_write_generic
,
2053 spr_register(env
, SPR_440_RSTCFG
, "RSTCFG",
2054 SPR_NOACCESS
, SPR_NOACCESS
,
2055 &spr_read_generic
, SPR_NOACCESS
,
2057 /* Storage control */
2058 spr_register(env
, SPR_440_MMUCR
, "MMUCR",
2059 SPR_NOACCESS
, SPR_NOACCESS
,
2060 &spr_read_generic
, &spr_write_generic
,
2064 /* SPR shared between PowerPC 40x implementations */
2065 static void gen_spr_40x(CPUPPCState
*env
)
2068 /* not emulated, as QEMU do not emulate caches */
2069 spr_register(env
, SPR_40x_DCCR
, "DCCR",
2070 SPR_NOACCESS
, SPR_NOACCESS
,
2071 &spr_read_generic
, &spr_write_generic
,
2073 /* not emulated, as QEMU do not emulate caches */
2074 spr_register(env
, SPR_40x_ICCR
, "ICCR",
2075 SPR_NOACCESS
, SPR_NOACCESS
,
2076 &spr_read_generic
, &spr_write_generic
,
2078 /* not emulated, as QEMU do not emulate caches */
2079 spr_register(env
, SPR_BOOKE_ICDBDR
, "ICDBDR",
2080 SPR_NOACCESS
, SPR_NOACCESS
,
2081 &spr_read_generic
, SPR_NOACCESS
,
2084 spr_register(env
, SPR_40x_DEAR
, "DEAR",
2085 SPR_NOACCESS
, SPR_NOACCESS
,
2086 &spr_read_generic
, &spr_write_generic
,
2088 spr_register(env
, SPR_40x_ESR
, "ESR",
2089 SPR_NOACCESS
, SPR_NOACCESS
,
2090 &spr_read_generic
, &spr_write_generic
,
2092 spr_register(env
, SPR_40x_EVPR
, "EVPR",
2093 SPR_NOACCESS
, SPR_NOACCESS
,
2094 &spr_read_generic
, &spr_write_excp_prefix
,
2096 spr_register(env
, SPR_40x_SRR2
, "SRR2",
2097 &spr_read_generic
, &spr_write_generic
,
2098 &spr_read_generic
, &spr_write_generic
,
2100 spr_register(env
, SPR_40x_SRR3
, "SRR3",
2101 &spr_read_generic
, &spr_write_generic
,
2102 &spr_read_generic
, &spr_write_generic
,
2105 spr_register(env
, SPR_40x_PIT
, "PIT",
2106 SPR_NOACCESS
, SPR_NOACCESS
,
2107 &spr_read_40x_pit
, &spr_write_40x_pit
,
2109 spr_register(env
, SPR_40x_TCR
, "TCR",
2110 SPR_NOACCESS
, SPR_NOACCESS
,
2111 &spr_read_generic
, &spr_write_booke_tcr
,
2113 spr_register(env
, SPR_40x_TSR
, "TSR",
2114 SPR_NOACCESS
, SPR_NOACCESS
,
2115 &spr_read_generic
, &spr_write_booke_tsr
,
2119 /* SPR specific to PowerPC 405 implementation */
2120 static void gen_spr_405(CPUPPCState
*env
)
2123 spr_register(env
, SPR_40x_PID
, "PID",
2124 SPR_NOACCESS
, SPR_NOACCESS
,
2125 &spr_read_generic
, &spr_write_generic
,
2127 spr_register(env
, SPR_4xx_CCR0
, "CCR0",
2128 SPR_NOACCESS
, SPR_NOACCESS
,
2129 &spr_read_generic
, &spr_write_generic
,
2131 /* Debug interface */
2132 /* XXX : not implemented */
2133 spr_register(env
, SPR_40x_DBCR0
, "DBCR0",
2134 SPR_NOACCESS
, SPR_NOACCESS
,
2135 &spr_read_generic
, &spr_write_40x_dbcr0
,
2137 /* XXX : not implemented */
2138 spr_register(env
, SPR_405_DBCR1
, "DBCR1",
2139 SPR_NOACCESS
, SPR_NOACCESS
,
2140 &spr_read_generic
, &spr_write_generic
,
2142 /* XXX : not implemented */
2143 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2144 SPR_NOACCESS
, SPR_NOACCESS
,
2145 &spr_read_generic
, &spr_write_clear
,
2146 /* Last reset was system reset */
2148 /* XXX : not implemented */
2149 spr_register(env
, SPR_40x_DAC1
, "DAC1",
2150 SPR_NOACCESS
, SPR_NOACCESS
,
2151 &spr_read_generic
, &spr_write_generic
,
2153 spr_register(env
, SPR_40x_DAC2
, "DAC2",
2154 SPR_NOACCESS
, SPR_NOACCESS
,
2155 &spr_read_generic
, &spr_write_generic
,
2157 /* XXX : not implemented */
2158 spr_register(env
, SPR_405_DVC1
, "DVC1",
2159 SPR_NOACCESS
, SPR_NOACCESS
,
2160 &spr_read_generic
, &spr_write_generic
,
2162 /* XXX : not implemented */
2163 spr_register(env
, SPR_405_DVC2
, "DVC2",
2164 SPR_NOACCESS
, SPR_NOACCESS
,
2165 &spr_read_generic
, &spr_write_generic
,
2167 /* XXX : not implemented */
2168 spr_register(env
, SPR_40x_IAC1
, "IAC1",
2169 SPR_NOACCESS
, SPR_NOACCESS
,
2170 &spr_read_generic
, &spr_write_generic
,
2172 spr_register(env
, SPR_40x_IAC2
, "IAC2",
2173 SPR_NOACCESS
, SPR_NOACCESS
,
2174 &spr_read_generic
, &spr_write_generic
,
2176 /* XXX : not implemented */
2177 spr_register(env
, SPR_405_IAC3
, "IAC3",
2178 SPR_NOACCESS
, SPR_NOACCESS
,
2179 &spr_read_generic
, &spr_write_generic
,
2181 /* XXX : not implemented */
2182 spr_register(env
, SPR_405_IAC4
, "IAC4",
2183 SPR_NOACCESS
, SPR_NOACCESS
,
2184 &spr_read_generic
, &spr_write_generic
,
2186 /* Storage control */
2187 /* XXX: TODO: not implemented */
2188 spr_register(env
, SPR_405_SLER
, "SLER",
2189 SPR_NOACCESS
, SPR_NOACCESS
,
2190 &spr_read_generic
, &spr_write_40x_sler
,
2192 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2193 SPR_NOACCESS
, SPR_NOACCESS
,
2194 &spr_read_generic
, &spr_write_generic
,
2196 /* XXX : not implemented */
2197 spr_register(env
, SPR_405_SU0R
, "SU0R",
2198 SPR_NOACCESS
, SPR_NOACCESS
,
2199 &spr_read_generic
, &spr_write_generic
,
2202 spr_register(env
, SPR_USPRG0
, "USPRG0",
2203 &spr_read_ureg
, SPR_NOACCESS
,
2204 &spr_read_ureg
, SPR_NOACCESS
,
2206 spr_register(env
, SPR_SPRG4
, "SPRG4",
2207 SPR_NOACCESS
, SPR_NOACCESS
,
2208 &spr_read_generic
, &spr_write_generic
,
2210 spr_register(env
, SPR_SPRG5
, "SPRG5",
2211 SPR_NOACCESS
, SPR_NOACCESS
,
2212 spr_read_generic
, &spr_write_generic
,
2214 spr_register(env
, SPR_SPRG6
, "SPRG6",
2215 SPR_NOACCESS
, SPR_NOACCESS
,
2216 spr_read_generic
, &spr_write_generic
,
2218 spr_register(env
, SPR_SPRG7
, "SPRG7",
2219 SPR_NOACCESS
, SPR_NOACCESS
,
2220 spr_read_generic
, &spr_write_generic
,
2222 gen_spr_usprgh(env
);
2225 /* SPR shared between PowerPC 401 & 403 implementations */
2226 static void gen_spr_401_403(CPUPPCState
*env
)
2229 spr_register(env
, SPR_403_VTBL
, "TBL",
2230 &spr_read_tbl
, SPR_NOACCESS
,
2231 &spr_read_tbl
, SPR_NOACCESS
,
2233 spr_register(env
, SPR_403_TBL
, "TBL",
2234 SPR_NOACCESS
, SPR_NOACCESS
,
2235 SPR_NOACCESS
, &spr_write_tbl
,
2237 spr_register(env
, SPR_403_VTBU
, "TBU",
2238 &spr_read_tbu
, SPR_NOACCESS
,
2239 &spr_read_tbu
, SPR_NOACCESS
,
2241 spr_register(env
, SPR_403_TBU
, "TBU",
2242 SPR_NOACCESS
, SPR_NOACCESS
,
2243 SPR_NOACCESS
, &spr_write_tbu
,
2246 /* not emulated, as QEMU do not emulate caches */
2247 spr_register(env
, SPR_403_CDBCR
, "CDBCR",
2248 SPR_NOACCESS
, SPR_NOACCESS
,
2249 &spr_read_generic
, &spr_write_generic
,
2253 /* SPR specific to PowerPC 401 implementation */
2254 static void gen_spr_401(CPUPPCState
*env
)
2256 /* Debug interface */
2257 /* XXX : not implemented */
2258 spr_register(env
, SPR_40x_DBCR0
, "DBCR",
2259 SPR_NOACCESS
, SPR_NOACCESS
,
2260 &spr_read_generic
, &spr_write_40x_dbcr0
,
2262 /* XXX : not implemented */
2263 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2264 SPR_NOACCESS
, SPR_NOACCESS
,
2265 &spr_read_generic
, &spr_write_clear
,
2266 /* Last reset was system reset */
2268 /* XXX : not implemented */
2269 spr_register(env
, SPR_40x_DAC1
, "DAC",
2270 SPR_NOACCESS
, SPR_NOACCESS
,
2271 &spr_read_generic
, &spr_write_generic
,
2273 /* XXX : not implemented */
2274 spr_register(env
, SPR_40x_IAC1
, "IAC",
2275 SPR_NOACCESS
, SPR_NOACCESS
,
2276 &spr_read_generic
, &spr_write_generic
,
2278 /* Storage control */
2279 /* XXX: TODO: not implemented */
2280 spr_register(env
, SPR_405_SLER
, "SLER",
2281 SPR_NOACCESS
, SPR_NOACCESS
,
2282 &spr_read_generic
, &spr_write_40x_sler
,
2284 /* not emulated, as QEMU never does speculative access */
2285 spr_register(env
, SPR_40x_SGR
, "SGR",
2286 SPR_NOACCESS
, SPR_NOACCESS
,
2287 &spr_read_generic
, &spr_write_generic
,
2289 /* not emulated, as QEMU do not emulate caches */
2290 spr_register(env
, SPR_40x_DCWR
, "DCWR",
2291 SPR_NOACCESS
, SPR_NOACCESS
,
2292 &spr_read_generic
, &spr_write_generic
,
2296 static void gen_spr_401x2(CPUPPCState
*env
)
2299 spr_register(env
, SPR_40x_PID
, "PID",
2300 SPR_NOACCESS
, SPR_NOACCESS
,
2301 &spr_read_generic
, &spr_write_generic
,
2303 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2304 SPR_NOACCESS
, SPR_NOACCESS
,
2305 &spr_read_generic
, &spr_write_generic
,
2309 /* SPR specific to PowerPC 403 implementation */
2310 static void gen_spr_403(CPUPPCState
*env
)
2312 /* Debug interface */
2313 /* XXX : not implemented */
2314 spr_register(env
, SPR_40x_DBCR0
, "DBCR0",
2315 SPR_NOACCESS
, SPR_NOACCESS
,
2316 &spr_read_generic
, &spr_write_40x_dbcr0
,
2318 /* XXX : not implemented */
2319 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2320 SPR_NOACCESS
, SPR_NOACCESS
,
2321 &spr_read_generic
, &spr_write_clear
,
2322 /* Last reset was system reset */
2324 /* XXX : not implemented */
2325 spr_register(env
, SPR_40x_DAC1
, "DAC1",
2326 SPR_NOACCESS
, SPR_NOACCESS
,
2327 &spr_read_generic
, &spr_write_generic
,
2329 /* XXX : not implemented */
2330 spr_register(env
, SPR_40x_DAC2
, "DAC2",
2331 SPR_NOACCESS
, SPR_NOACCESS
,
2332 &spr_read_generic
, &spr_write_generic
,
2334 /* XXX : not implemented */
2335 spr_register(env
, SPR_40x_IAC1
, "IAC1",
2336 SPR_NOACCESS
, SPR_NOACCESS
,
2337 &spr_read_generic
, &spr_write_generic
,
2339 /* XXX : not implemented */
2340 spr_register(env
, SPR_40x_IAC2
, "IAC2",
2341 SPR_NOACCESS
, SPR_NOACCESS
,
2342 &spr_read_generic
, &spr_write_generic
,
2346 static void gen_spr_403_real(CPUPPCState
*env
)
2348 spr_register(env
, SPR_403_PBL1
, "PBL1",
2349 SPR_NOACCESS
, SPR_NOACCESS
,
2350 &spr_read_403_pbr
, &spr_write_403_pbr
,
2352 spr_register(env
, SPR_403_PBU1
, "PBU1",
2353 SPR_NOACCESS
, SPR_NOACCESS
,
2354 &spr_read_403_pbr
, &spr_write_403_pbr
,
2356 spr_register(env
, SPR_403_PBL2
, "PBL2",
2357 SPR_NOACCESS
, SPR_NOACCESS
,
2358 &spr_read_403_pbr
, &spr_write_403_pbr
,
2360 spr_register(env
, SPR_403_PBU2
, "PBU2",
2361 SPR_NOACCESS
, SPR_NOACCESS
,
2362 &spr_read_403_pbr
, &spr_write_403_pbr
,
2366 static void gen_spr_403_mmu(CPUPPCState
*env
)
2369 spr_register(env
, SPR_40x_PID
, "PID",
2370 SPR_NOACCESS
, SPR_NOACCESS
,
2371 &spr_read_generic
, &spr_write_generic
,
2373 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2374 SPR_NOACCESS
, SPR_NOACCESS
,
2375 &spr_read_generic
, &spr_write_generic
,
2379 /* SPR specific to PowerPC compression coprocessor extension */
2380 static void gen_spr_compress(CPUPPCState
*env
)
2382 /* XXX : not implemented */
2383 spr_register(env
, SPR_401_SKR
, "SKR",
2384 SPR_NOACCESS
, SPR_NOACCESS
,
2385 &spr_read_generic
, &spr_write_generic
,
2389 static void gen_spr_5xx_8xx(CPUPPCState
*env
)
2391 /* Exception processing */
2392 spr_register_kvm(env
, SPR_DSISR
, "DSISR",
2393 SPR_NOACCESS
, SPR_NOACCESS
,
2394 &spr_read_generic
, &spr_write_generic
,
2395 KVM_REG_PPC_DSISR
, 0x00000000);
2396 spr_register_kvm(env
, SPR_DAR
, "DAR",
2397 SPR_NOACCESS
, SPR_NOACCESS
,
2398 &spr_read_generic
, &spr_write_generic
,
2399 KVM_REG_PPC_DAR
, 0x00000000);
2401 spr_register(env
, SPR_DECR
, "DECR",
2402 SPR_NOACCESS
, SPR_NOACCESS
,
2403 &spr_read_decr
, &spr_write_decr
,
2405 /* XXX : not implemented */
2406 spr_register(env
, SPR_MPC_EIE
, "EIE",
2407 SPR_NOACCESS
, SPR_NOACCESS
,
2408 &spr_read_generic
, &spr_write_generic
,
2410 /* XXX : not implemented */
2411 spr_register(env
, SPR_MPC_EID
, "EID",
2412 SPR_NOACCESS
, SPR_NOACCESS
,
2413 &spr_read_generic
, &spr_write_generic
,
2415 /* XXX : not implemented */
2416 spr_register(env
, SPR_MPC_NRI
, "NRI",
2417 SPR_NOACCESS
, SPR_NOACCESS
,
2418 &spr_read_generic
, &spr_write_generic
,
2420 /* XXX : not implemented */
2421 spr_register(env
, SPR_MPC_CMPA
, "CMPA",
2422 SPR_NOACCESS
, SPR_NOACCESS
,
2423 &spr_read_generic
, &spr_write_generic
,
2425 /* XXX : not implemented */
2426 spr_register(env
, SPR_MPC_CMPB
, "CMPB",
2427 SPR_NOACCESS
, SPR_NOACCESS
,
2428 &spr_read_generic
, &spr_write_generic
,
2430 /* XXX : not implemented */
2431 spr_register(env
, SPR_MPC_CMPC
, "CMPC",
2432 SPR_NOACCESS
, SPR_NOACCESS
,
2433 &spr_read_generic
, &spr_write_generic
,
2435 /* XXX : not implemented */
2436 spr_register(env
, SPR_MPC_CMPD
, "CMPD",
2437 SPR_NOACCESS
, SPR_NOACCESS
,
2438 &spr_read_generic
, &spr_write_generic
,
2440 /* XXX : not implemented */
2441 spr_register(env
, SPR_MPC_ECR
, "ECR",
2442 SPR_NOACCESS
, SPR_NOACCESS
,
2443 &spr_read_generic
, &spr_write_generic
,
2445 /* XXX : not implemented */
2446 spr_register(env
, SPR_MPC_DER
, "DER",
2447 SPR_NOACCESS
, SPR_NOACCESS
,
2448 &spr_read_generic
, &spr_write_generic
,
2450 /* XXX : not implemented */
2451 spr_register(env
, SPR_MPC_COUNTA
, "COUNTA",
2452 SPR_NOACCESS
, SPR_NOACCESS
,
2453 &spr_read_generic
, &spr_write_generic
,
2455 /* XXX : not implemented */
2456 spr_register(env
, SPR_MPC_COUNTB
, "COUNTB",
2457 SPR_NOACCESS
, SPR_NOACCESS
,
2458 &spr_read_generic
, &spr_write_generic
,
2460 /* XXX : not implemented */
2461 spr_register(env
, SPR_MPC_CMPE
, "CMPE",
2462 SPR_NOACCESS
, SPR_NOACCESS
,
2463 &spr_read_generic
, &spr_write_generic
,
2465 /* XXX : not implemented */
2466 spr_register(env
, SPR_MPC_CMPF
, "CMPF",
2467 SPR_NOACCESS
, SPR_NOACCESS
,
2468 &spr_read_generic
, &spr_write_generic
,
2470 /* XXX : not implemented */
2471 spr_register(env
, SPR_MPC_CMPG
, "CMPG",
2472 SPR_NOACCESS
, SPR_NOACCESS
,
2473 &spr_read_generic
, &spr_write_generic
,
2475 /* XXX : not implemented */
2476 spr_register(env
, SPR_MPC_CMPH
, "CMPH",
2477 SPR_NOACCESS
, SPR_NOACCESS
,
2478 &spr_read_generic
, &spr_write_generic
,
2480 /* XXX : not implemented */
2481 spr_register(env
, SPR_MPC_LCTRL1
, "LCTRL1",
2482 SPR_NOACCESS
, SPR_NOACCESS
,
2483 &spr_read_generic
, &spr_write_generic
,
2485 /* XXX : not implemented */
2486 spr_register(env
, SPR_MPC_LCTRL2
, "LCTRL2",
2487 SPR_NOACCESS
, SPR_NOACCESS
,
2488 &spr_read_generic
, &spr_write_generic
,
2490 /* XXX : not implemented */
2491 spr_register(env
, SPR_MPC_BAR
, "BAR",
2492 SPR_NOACCESS
, SPR_NOACCESS
,
2493 &spr_read_generic
, &spr_write_generic
,
2495 /* XXX : not implemented */
2496 spr_register(env
, SPR_MPC_DPDR
, "DPDR",
2497 SPR_NOACCESS
, SPR_NOACCESS
,
2498 &spr_read_generic
, &spr_write_generic
,
2500 /* XXX : not implemented */
2501 spr_register(env
, SPR_MPC_IMMR
, "IMMR",
2502 SPR_NOACCESS
, SPR_NOACCESS
,
2503 &spr_read_generic
, &spr_write_generic
,
2507 static void gen_spr_5xx(CPUPPCState
*env
)
2509 /* XXX : not implemented */
2510 spr_register(env
, SPR_RCPU_MI_GRA
, "MI_GRA",
2511 SPR_NOACCESS
, SPR_NOACCESS
,
2512 &spr_read_generic
, &spr_write_generic
,
2514 /* XXX : not implemented */
2515 spr_register(env
, SPR_RCPU_L2U_GRA
, "L2U_GRA",
2516 SPR_NOACCESS
, SPR_NOACCESS
,
2517 &spr_read_generic
, &spr_write_generic
,
2519 /* XXX : not implemented */
2520 spr_register(env
, SPR_RPCU_BBCMCR
, "L2U_BBCMCR",
2521 SPR_NOACCESS
, SPR_NOACCESS
,
2522 &spr_read_generic
, &spr_write_generic
,
2524 /* XXX : not implemented */
2525 spr_register(env
, SPR_RCPU_L2U_MCR
, "L2U_MCR",
2526 SPR_NOACCESS
, SPR_NOACCESS
,
2527 &spr_read_generic
, &spr_write_generic
,
2529 /* XXX : not implemented */
2530 spr_register(env
, SPR_RCPU_MI_RBA0
, "MI_RBA0",
2531 SPR_NOACCESS
, SPR_NOACCESS
,
2532 &spr_read_generic
, &spr_write_generic
,
2534 /* XXX : not implemented */
2535 spr_register(env
, SPR_RCPU_MI_RBA1
, "MI_RBA1",
2536 SPR_NOACCESS
, SPR_NOACCESS
,
2537 &spr_read_generic
, &spr_write_generic
,
2539 /* XXX : not implemented */
2540 spr_register(env
, SPR_RCPU_MI_RBA2
, "MI_RBA2",
2541 SPR_NOACCESS
, SPR_NOACCESS
,
2542 &spr_read_generic
, &spr_write_generic
,
2544 /* XXX : not implemented */
2545 spr_register(env
, SPR_RCPU_MI_RBA3
, "MI_RBA3",
2546 SPR_NOACCESS
, SPR_NOACCESS
,
2547 &spr_read_generic
, &spr_write_generic
,
2549 /* XXX : not implemented */
2550 spr_register(env
, SPR_RCPU_L2U_RBA0
, "L2U_RBA0",
2551 SPR_NOACCESS
, SPR_NOACCESS
,
2552 &spr_read_generic
, &spr_write_generic
,
2554 /* XXX : not implemented */
2555 spr_register(env
, SPR_RCPU_L2U_RBA1
, "L2U_RBA1",
2556 SPR_NOACCESS
, SPR_NOACCESS
,
2557 &spr_read_generic
, &spr_write_generic
,
2559 /* XXX : not implemented */
2560 spr_register(env
, SPR_RCPU_L2U_RBA2
, "L2U_RBA2",
2561 SPR_NOACCESS
, SPR_NOACCESS
,
2562 &spr_read_generic
, &spr_write_generic
,
2564 /* XXX : not implemented */
2565 spr_register(env
, SPR_RCPU_L2U_RBA3
, "L2U_RBA3",
2566 SPR_NOACCESS
, SPR_NOACCESS
,
2567 &spr_read_generic
, &spr_write_generic
,
2569 /* XXX : not implemented */
2570 spr_register(env
, SPR_RCPU_MI_RA0
, "MI_RA0",
2571 SPR_NOACCESS
, SPR_NOACCESS
,
2572 &spr_read_generic
, &spr_write_generic
,
2574 /* XXX : not implemented */
2575 spr_register(env
, SPR_RCPU_MI_RA1
, "MI_RA1",
2576 SPR_NOACCESS
, SPR_NOACCESS
,
2577 &spr_read_generic
, &spr_write_generic
,
2579 /* XXX : not implemented */
2580 spr_register(env
, SPR_RCPU_MI_RA2
, "MI_RA2",
2581 SPR_NOACCESS
, SPR_NOACCESS
,
2582 &spr_read_generic
, &spr_write_generic
,
2584 /* XXX : not implemented */
2585 spr_register(env
, SPR_RCPU_MI_RA3
, "MI_RA3",
2586 SPR_NOACCESS
, SPR_NOACCESS
,
2587 &spr_read_generic
, &spr_write_generic
,
2589 /* XXX : not implemented */
2590 spr_register(env
, SPR_RCPU_L2U_RA0
, "L2U_RA0",
2591 SPR_NOACCESS
, SPR_NOACCESS
,
2592 &spr_read_generic
, &spr_write_generic
,
2594 /* XXX : not implemented */
2595 spr_register(env
, SPR_RCPU_L2U_RA1
, "L2U_RA1",
2596 SPR_NOACCESS
, SPR_NOACCESS
,
2597 &spr_read_generic
, &spr_write_generic
,
2599 /* XXX : not implemented */
2600 spr_register(env
, SPR_RCPU_L2U_RA2
, "L2U_RA2",
2601 SPR_NOACCESS
, SPR_NOACCESS
,
2602 &spr_read_generic
, &spr_write_generic
,
2604 /* XXX : not implemented */
2605 spr_register(env
, SPR_RCPU_L2U_RA3
, "L2U_RA3",
2606 SPR_NOACCESS
, SPR_NOACCESS
,
2607 &spr_read_generic
, &spr_write_generic
,
2609 /* XXX : not implemented */
2610 spr_register(env
, SPR_RCPU_FPECR
, "FPECR",
2611 SPR_NOACCESS
, SPR_NOACCESS
,
2612 &spr_read_generic
, &spr_write_generic
,
2616 static void gen_spr_8xx(CPUPPCState
*env
)
2618 /* XXX : not implemented */
2619 spr_register(env
, SPR_MPC_IC_CST
, "IC_CST",
2620 SPR_NOACCESS
, SPR_NOACCESS
,
2621 &spr_read_generic
, &spr_write_generic
,
2623 /* XXX : not implemented */
2624 spr_register(env
, SPR_MPC_IC_ADR
, "IC_ADR",
2625 SPR_NOACCESS
, SPR_NOACCESS
,
2626 &spr_read_generic
, &spr_write_generic
,
2628 /* XXX : not implemented */
2629 spr_register(env
, SPR_MPC_IC_DAT
, "IC_DAT",
2630 SPR_NOACCESS
, SPR_NOACCESS
,
2631 &spr_read_generic
, &spr_write_generic
,
2633 /* XXX : not implemented */
2634 spr_register(env
, SPR_MPC_DC_CST
, "DC_CST",
2635 SPR_NOACCESS
, SPR_NOACCESS
,
2636 &spr_read_generic
, &spr_write_generic
,
2638 /* XXX : not implemented */
2639 spr_register(env
, SPR_MPC_DC_ADR
, "DC_ADR",
2640 SPR_NOACCESS
, SPR_NOACCESS
,
2641 &spr_read_generic
, &spr_write_generic
,
2643 /* XXX : not implemented */
2644 spr_register(env
, SPR_MPC_DC_DAT
, "DC_DAT",
2645 SPR_NOACCESS
, SPR_NOACCESS
,
2646 &spr_read_generic
, &spr_write_generic
,
2648 /* XXX : not implemented */
2649 spr_register(env
, SPR_MPC_MI_CTR
, "MI_CTR",
2650 SPR_NOACCESS
, SPR_NOACCESS
,
2651 &spr_read_generic
, &spr_write_generic
,
2653 /* XXX : not implemented */
2654 spr_register(env
, SPR_MPC_MI_AP
, "MI_AP",
2655 SPR_NOACCESS
, SPR_NOACCESS
,
2656 &spr_read_generic
, &spr_write_generic
,
2658 /* XXX : not implemented */
2659 spr_register(env
, SPR_MPC_MI_EPN
, "MI_EPN",
2660 SPR_NOACCESS
, SPR_NOACCESS
,
2661 &spr_read_generic
, &spr_write_generic
,
2663 /* XXX : not implemented */
2664 spr_register(env
, SPR_MPC_MI_TWC
, "MI_TWC",
2665 SPR_NOACCESS
, SPR_NOACCESS
,
2666 &spr_read_generic
, &spr_write_generic
,
2668 /* XXX : not implemented */
2669 spr_register(env
, SPR_MPC_MI_RPN
, "MI_RPN",
2670 SPR_NOACCESS
, SPR_NOACCESS
,
2671 &spr_read_generic
, &spr_write_generic
,
2673 /* XXX : not implemented */
2674 spr_register(env
, SPR_MPC_MI_DBCAM
, "MI_DBCAM",
2675 SPR_NOACCESS
, SPR_NOACCESS
,
2676 &spr_read_generic
, &spr_write_generic
,
2678 /* XXX : not implemented */
2679 spr_register(env
, SPR_MPC_MI_DBRAM0
, "MI_DBRAM0",
2680 SPR_NOACCESS
, SPR_NOACCESS
,
2681 &spr_read_generic
, &spr_write_generic
,
2683 /* XXX : not implemented */
2684 spr_register(env
, SPR_MPC_MI_DBRAM1
, "MI_DBRAM1",
2685 SPR_NOACCESS
, SPR_NOACCESS
,
2686 &spr_read_generic
, &spr_write_generic
,
2688 /* XXX : not implemented */
2689 spr_register(env
, SPR_MPC_MD_CTR
, "MD_CTR",
2690 SPR_NOACCESS
, SPR_NOACCESS
,
2691 &spr_read_generic
, &spr_write_generic
,
2693 /* XXX : not implemented */
2694 spr_register(env
, SPR_MPC_MD_CASID
, "MD_CASID",
2695 SPR_NOACCESS
, SPR_NOACCESS
,
2696 &spr_read_generic
, &spr_write_generic
,
2698 /* XXX : not implemented */
2699 spr_register(env
, SPR_MPC_MD_AP
, "MD_AP",
2700 SPR_NOACCESS
, SPR_NOACCESS
,
2701 &spr_read_generic
, &spr_write_generic
,
2703 /* XXX : not implemented */
2704 spr_register(env
, SPR_MPC_MD_EPN
, "MD_EPN",
2705 SPR_NOACCESS
, SPR_NOACCESS
,
2706 &spr_read_generic
, &spr_write_generic
,
2708 /* XXX : not implemented */
2709 spr_register(env
, SPR_MPC_MD_TWB
, "MD_TWB",
2710 SPR_NOACCESS
, SPR_NOACCESS
,
2711 &spr_read_generic
, &spr_write_generic
,
2713 /* XXX : not implemented */
2714 spr_register(env
, SPR_MPC_MD_TWC
, "MD_TWC",
2715 SPR_NOACCESS
, SPR_NOACCESS
,
2716 &spr_read_generic
, &spr_write_generic
,
2718 /* XXX : not implemented */
2719 spr_register(env
, SPR_MPC_MD_RPN
, "MD_RPN",
2720 SPR_NOACCESS
, SPR_NOACCESS
,
2721 &spr_read_generic
, &spr_write_generic
,
2723 /* XXX : not implemented */
2724 spr_register(env
, SPR_MPC_MD_TW
, "MD_TW",
2725 SPR_NOACCESS
, SPR_NOACCESS
,
2726 &spr_read_generic
, &spr_write_generic
,
2728 /* XXX : not implemented */
2729 spr_register(env
, SPR_MPC_MD_DBCAM
, "MD_DBCAM",
2730 SPR_NOACCESS
, SPR_NOACCESS
,
2731 &spr_read_generic
, &spr_write_generic
,
2733 /* XXX : not implemented */
2734 spr_register(env
, SPR_MPC_MD_DBRAM0
, "MD_DBRAM0",
2735 SPR_NOACCESS
, SPR_NOACCESS
,
2736 &spr_read_generic
, &spr_write_generic
,
2738 /* XXX : not implemented */
2739 spr_register(env
, SPR_MPC_MD_DBRAM1
, "MD_DBRAM1",
2740 SPR_NOACCESS
, SPR_NOACCESS
,
2741 &spr_read_generic
, &spr_write_generic
,
2747 * AMR => SPR 29 (Power 2.04)
2748 * CTRL => SPR 136 (Power 2.04)
2749 * CTRL => SPR 152 (Power 2.04)
2750 * SCOMC => SPR 276 (64 bits ?)
2751 * SCOMD => SPR 277 (64 bits ?)
2752 * TBU40 => SPR 286 (Power 2.04 hypv)
2753 * HSPRG0 => SPR 304 (Power 2.04 hypv)
2754 * HSPRG1 => SPR 305 (Power 2.04 hypv)
2755 * HDSISR => SPR 306 (Power 2.04 hypv)
2756 * HDAR => SPR 307 (Power 2.04 hypv)
2757 * PURR => SPR 309 (Power 2.04 hypv)
2758 * HDEC => SPR 310 (Power 2.04 hypv)
2759 * HIOR => SPR 311 (hypv)
2760 * RMOR => SPR 312 (970)
2761 * HRMOR => SPR 313 (Power 2.04 hypv)
2762 * HSRR0 => SPR 314 (Power 2.04 hypv)
2763 * HSRR1 => SPR 315 (Power 2.04 hypv)
2764 * LPIDR => SPR 317 (970)
2765 * EPR => SPR 702 (Power 2.04 emb)
2766 * perf => 768-783 (Power 2.04)
2767 * perf => 784-799 (Power 2.04)
2768 * PPR => SPR 896 (Power 2.04)
2769 * EPLC => SPR 947 (Power 2.04 emb)
2770 * EPSC => SPR 948 (Power 2.04 emb)
2771 * DABRX => 1015 (Power 2.04 hypv)
2772 * FPECR => SPR 1022 (?)
2773 * ... and more (thermal management, performance counters, ...)
2776 /*****************************************************************************/
2777 /* Exception vectors models */
2778 static void init_excp_4xx_real(CPUPPCState
*env
)
2780 #if !defined(CONFIG_USER_ONLY)
2781 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000100;
2782 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2783 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2784 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2785 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2786 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2787 env
->excp_vectors
[POWERPC_EXCP_PIT
] = 0x00001000;
2788 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00001010;
2789 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001020;
2790 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00002000;
2791 env
->ivor_mask
= 0x0000FFF0UL
;
2792 env
->ivpr_mask
= 0xFFFF0000UL
;
2793 /* Hardware reset vector */
2794 env
->hreset_vector
= 0xFFFFFFFCUL
;
2798 static void init_excp_4xx_softmmu(CPUPPCState
*env
)
2800 #if !defined(CONFIG_USER_ONLY)
2801 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000100;
2802 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2803 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2804 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2805 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2806 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2807 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2808 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2809 env
->excp_vectors
[POWERPC_EXCP_PIT
] = 0x00001000;
2810 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00001010;
2811 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001020;
2812 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00001100;
2813 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00001200;
2814 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00002000;
2815 env
->ivor_mask
= 0x0000FFF0UL
;
2816 env
->ivpr_mask
= 0xFFFF0000UL
;
2817 /* Hardware reset vector */
2818 env
->hreset_vector
= 0xFFFFFFFCUL
;
2822 static void init_excp_MPC5xx(CPUPPCState
*env
)
2824 #if !defined(CONFIG_USER_ONLY)
2825 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2826 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2827 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2828 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2829 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2830 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000900;
2831 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2832 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2833 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2834 env
->excp_vectors
[POWERPC_EXCP_FPA
] = 0x00000E00;
2835 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001000;
2836 env
->excp_vectors
[POWERPC_EXCP_DABR
] = 0x00001C00;
2837 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001C00;
2838 env
->excp_vectors
[POWERPC_EXCP_MEXTBR
] = 0x00001E00;
2839 env
->excp_vectors
[POWERPC_EXCP_NMEXTBR
] = 0x00001F00;
2840 env
->ivor_mask
= 0x0000FFF0UL
;
2841 env
->ivpr_mask
= 0xFFFF0000UL
;
2842 /* Hardware reset vector */
2843 env
->hreset_vector
= 0x00000100UL
;
2847 static void init_excp_MPC8xx(CPUPPCState
*env
)
2849 #if !defined(CONFIG_USER_ONLY)
2850 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2851 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2852 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2853 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2854 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2855 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2856 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2857 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000900;
2858 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2859 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2860 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2861 env
->excp_vectors
[POWERPC_EXCP_FPA
] = 0x00000E00;
2862 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001000;
2863 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00001100;
2864 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00001200;
2865 env
->excp_vectors
[POWERPC_EXCP_ITLBE
] = 0x00001300;
2866 env
->excp_vectors
[POWERPC_EXCP_DTLBE
] = 0x00001400;
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_G2(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
] = 0x00000800;
2889 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2890 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000A00;
2891 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2892 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2893 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
2894 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
2895 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
2896 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
2897 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
2898 /* Hardware reset vector */
2899 env
->hreset_vector
= 0x00000100UL
;
2903 static void init_excp_e200(CPUPPCState
*env
, target_ulong ivpr_mask
)
2905 #if !defined(CONFIG_USER_ONLY)
2906 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000FFC;
2907 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000000;
2908 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000000;
2909 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000000;
2910 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000000;
2911 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000000;
2912 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000000;
2913 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000000;
2914 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000000;
2915 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000000;
2916 env
->excp_vectors
[POWERPC_EXCP_APU
] = 0x00000000;
2917 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000000;
2918 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00000000;
2919 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00000000;
2920 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00000000;
2921 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00000000;
2922 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00000000;
2923 env
->excp_vectors
[POWERPC_EXCP_SPEU
] = 0x00000000;
2924 env
->excp_vectors
[POWERPC_EXCP_EFPDI
] = 0x00000000;
2925 env
->excp_vectors
[POWERPC_EXCP_EFPRI
] = 0x00000000;
2926 env
->ivor_mask
= 0x0000FFF7UL
;
2927 env
->ivpr_mask
= ivpr_mask
;
2928 /* Hardware reset vector */
2929 env
->hreset_vector
= 0xFFFFFFFCUL
;
2933 static void init_excp_BookE(CPUPPCState
*env
)
2935 #if !defined(CONFIG_USER_ONLY)
2936 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000000;
2937 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000000;
2938 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000000;
2939 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000000;
2940 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000000;
2941 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000000;
2942 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000000;
2943 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000000;
2944 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000000;
2945 env
->excp_vectors
[POWERPC_EXCP_APU
] = 0x00000000;
2946 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000000;
2947 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00000000;
2948 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00000000;
2949 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00000000;
2950 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00000000;
2951 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00000000;
2952 env
->ivor_mask
= 0x0000FFF0UL
;
2953 env
->ivpr_mask
= 0xFFFF0000UL
;
2954 /* Hardware reset vector */
2955 env
->hreset_vector
= 0xFFFFFFFCUL
;
2959 static void init_excp_601(CPUPPCState
*env
)
2961 #if !defined(CONFIG_USER_ONLY)
2962 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2963 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2964 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2965 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2966 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2967 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2968 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2969 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
2970 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2971 env
->excp_vectors
[POWERPC_EXCP_IO
] = 0x00000A00;
2972 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2973 env
->excp_vectors
[POWERPC_EXCP_RUNM
] = 0x00002000;
2974 /* Hardware reset vector */
2975 env
->hreset_vector
= 0x00000100UL
;
2979 static void init_excp_602(CPUPPCState
*env
)
2981 #if !defined(CONFIG_USER_ONLY)
2982 /* XXX: exception prefix has a special behavior on 602 */
2983 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2984 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2985 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2986 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2987 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2988 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2989 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2990 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
2991 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2992 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2993 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2994 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
2995 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
2996 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
2997 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
2998 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
2999 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001500;
3000 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001600;
3001 /* Hardware reset vector */
3002 env
->hreset_vector
= 0x00000100UL
;
3006 static void init_excp_603(CPUPPCState
*env
)
3008 #if !defined(CONFIG_USER_ONLY)
3009 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3010 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3011 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3012 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3013 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3014 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3015 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3016 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3017 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3018 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3019 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3020 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3021 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3022 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3023 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3024 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3025 /* Hardware reset vector */
3026 env
->hreset_vector
= 0x00000100UL
;
3030 static void init_excp_604(CPUPPCState
*env
)
3032 #if !defined(CONFIG_USER_ONLY)
3033 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3034 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3035 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3036 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3037 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3038 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3039 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3040 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3041 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3042 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3043 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3044 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3045 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3046 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3047 /* Hardware reset vector */
3048 env
->hreset_vector
= 0x00000100UL
;
3052 static void init_excp_7x0(CPUPPCState
*env
)
3054 #if !defined(CONFIG_USER_ONLY)
3055 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3056 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3057 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3058 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3059 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3060 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3061 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3062 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3063 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3064 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3065 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3066 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3067 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3068 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3069 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3070 /* Hardware reset vector */
3071 env
->hreset_vector
= 0x00000100UL
;
3075 static void init_excp_750cl(CPUPPCState
*env
)
3077 #if !defined(CONFIG_USER_ONLY)
3078 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3079 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3080 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3081 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3082 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3083 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3084 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3085 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3086 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3087 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3088 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3089 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3090 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3091 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3092 /* Hardware reset vector */
3093 env
->hreset_vector
= 0x00000100UL
;
3097 static void init_excp_750cx(CPUPPCState
*env
)
3099 #if !defined(CONFIG_USER_ONLY)
3100 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3101 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3102 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3103 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3104 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3105 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3106 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3107 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3108 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3109 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3110 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3111 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3112 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3113 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3114 /* Hardware reset vector */
3115 env
->hreset_vector
= 0x00000100UL
;
3119 /* XXX: Check if this is correct */
3120 static void init_excp_7x5(CPUPPCState
*env
)
3122 #if !defined(CONFIG_USER_ONLY)
3123 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3124 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3125 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3126 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3127 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3128 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3129 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3130 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3131 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3132 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3133 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3134 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3135 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3136 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3137 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3138 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3139 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3140 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3141 /* Hardware reset vector */
3142 env
->hreset_vector
= 0x00000100UL
;
3146 static void init_excp_7400(CPUPPCState
*env
)
3148 #if !defined(CONFIG_USER_ONLY)
3149 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3150 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3151 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3152 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3153 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3154 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3155 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3156 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3157 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3158 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3159 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3160 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3161 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3162 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3163 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3164 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001600;
3165 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3166 /* Hardware reset vector */
3167 env
->hreset_vector
= 0x00000100UL
;
3171 static void init_excp_7450(CPUPPCState
*env
)
3173 #if !defined(CONFIG_USER_ONLY)
3174 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3175 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3176 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3177 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3178 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3179 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3180 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3181 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3182 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3183 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3184 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3185 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3186 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3187 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3188 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3189 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3190 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3191 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3192 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001600;
3193 /* Hardware reset vector */
3194 env
->hreset_vector
= 0x00000100UL
;
3198 #if defined(TARGET_PPC64)
3199 static void init_excp_970(CPUPPCState
*env
)
3201 #if !defined(CONFIG_USER_ONLY)
3202 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3203 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3204 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3205 env
->excp_vectors
[POWERPC_EXCP_DSEG
] = 0x00000380;
3206 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3207 env
->excp_vectors
[POWERPC_EXCP_ISEG
] = 0x00000480;
3208 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3209 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3210 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3211 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3212 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3213 env
->excp_vectors
[POWERPC_EXCP_HDECR
] = 0x00000980;
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_IABR
] = 0x00001300;
3219 env
->excp_vectors
[POWERPC_EXCP_MAINT
] = 0x00001600;
3220 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001700;
3221 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001800;
3222 /* Hardware reset vector */
3223 env
->hreset_vector
= 0x0000000000000100ULL
;
3227 static void init_excp_POWER7(CPUPPCState
*env
)
3229 #if !defined(CONFIG_USER_ONLY)
3230 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3231 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3232 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3233 env
->excp_vectors
[POWERPC_EXCP_DSEG
] = 0x00000380;
3234 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3235 env
->excp_vectors
[POWERPC_EXCP_ISEG
] = 0x00000480;
3236 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3237 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3238 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3239 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3240 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3241 env
->excp_vectors
[POWERPC_EXCP_HDECR
] = 0x00000980;
3242 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3243 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3244 env
->excp_vectors
[POWERPC_EXCP_HDSI
] = 0x00000E00;
3245 env
->excp_vectors
[POWERPC_EXCP_HISI
] = 0x00000E20;
3246 env
->excp_vectors
[POWERPC_EXCP_HV_EMU
] = 0x00000E40;
3247 env
->excp_vectors
[POWERPC_EXCP_HV_MAINT
] = 0x00000E60;
3248 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3249 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3250 env
->excp_vectors
[POWERPC_EXCP_VSXU
] = 0x00000F40;
3251 /* Hardware reset vector */
3252 env
->hreset_vector
= 0x0000000000000100ULL
;
3256 static void init_excp_POWER8(CPUPPCState
*env
)
3258 init_excp_POWER7(env
);
3260 #if !defined(CONFIG_USER_ONLY)
3261 env
->excp_vectors
[POWERPC_EXCP_SDOOR
] = 0x00000A00;
3262 env
->excp_vectors
[POWERPC_EXCP_FU
] = 0x00000F60;
3263 env
->excp_vectors
[POWERPC_EXCP_HV_FU
] = 0x00000F80;
3264 env
->excp_vectors
[POWERPC_EXCP_SDOOR_HV
] = 0x00000E80;
3270 /*****************************************************************************/
3271 /* Power management enable checks */
3272 static int check_pow_none(CPUPPCState
*env
)
3277 static int check_pow_nocheck(CPUPPCState
*env
)
3282 static int check_pow_hid0(CPUPPCState
*env
)
3284 if (env
->spr
[SPR_HID0
] & 0x00E00000)
3290 static int check_pow_hid0_74xx(CPUPPCState
*env
)
3292 if (env
->spr
[SPR_HID0
] & 0x00600000)
3298 static bool ppc_cpu_interrupts_big_endian_always(PowerPCCPU
*cpu
)
3304 static bool ppc_cpu_interrupts_big_endian_lpcr(PowerPCCPU
*cpu
)
3306 return !(cpu
->env
.spr
[SPR_LPCR
] & LPCR_ILE
);
3310 /*****************************************************************************/
3311 /* PowerPC implementations definitions */
3313 #define POWERPC_FAMILY(_name) \
3315 glue(glue(ppc_, _name), _cpu_family_class_init)(ObjectClass *, void *); \
3317 static const TypeInfo \
3318 glue(glue(ppc_, _name), _cpu_family_type_info) = { \
3319 .name = stringify(_name) "-family-" TYPE_POWERPC_CPU, \
3320 .parent = TYPE_POWERPC_CPU, \
3322 .class_init = glue(glue(ppc_, _name), _cpu_family_class_init), \
3325 static void glue(glue(ppc_, _name), _cpu_family_register_types)(void) \
3327 type_register_static( \
3328 &glue(glue(ppc_, _name), _cpu_family_type_info)); \
3331 type_init(glue(glue(ppc_, _name), _cpu_family_register_types)) \
3333 static void glue(glue(ppc_, _name), _cpu_family_class_init)
3335 static void init_proc_401(CPUPPCState
*env
)
3338 gen_spr_401_403(env
);
3340 init_excp_4xx_real(env
);
3341 env
->dcache_line_size
= 32;
3342 env
->icache_line_size
= 32;
3343 /* Allocate hardware IRQ controller */
3344 ppc40x_irq_init(ppc_env_get_cpu(env
));
3346 SET_FIT_PERIOD(12, 16, 20, 24);
3347 SET_WDT_PERIOD(16, 20, 24, 28);
3350 POWERPC_FAMILY(401)(ObjectClass
*oc
, void *data
)
3352 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3353 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3355 dc
->desc
= "PowerPC 401";
3356 pcc
->init_proc
= init_proc_401
;
3357 pcc
->check_pow
= check_pow_nocheck
;
3358 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3359 PPC_WRTEE
| PPC_DCR
|
3360 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3362 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3363 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3364 pcc
->msr_mask
= (1ull << MSR_KEY
) |
3373 pcc
->mmu_model
= POWERPC_MMU_REAL
;
3374 pcc
->excp_model
= POWERPC_EXCP_40x
;
3375 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3376 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3377 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3378 POWERPC_FLAG_BUS_CLK
;
3381 static void init_proc_401x2(CPUPPCState
*env
)
3384 gen_spr_401_403(env
);
3386 gen_spr_compress(env
);
3387 /* Memory management */
3388 #if !defined(CONFIG_USER_ONLY)
3392 env
->tlb_type
= TLB_EMB
;
3394 init_excp_4xx_softmmu(env
);
3395 env
->dcache_line_size
= 32;
3396 env
->icache_line_size
= 32;
3397 /* Allocate hardware IRQ controller */
3398 ppc40x_irq_init(ppc_env_get_cpu(env
));
3400 SET_FIT_PERIOD(12, 16, 20, 24);
3401 SET_WDT_PERIOD(16, 20, 24, 28);
3404 POWERPC_FAMILY(401x2
)(ObjectClass
*oc
, void *data
)
3406 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3407 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3409 dc
->desc
= "PowerPC 401x2";
3410 pcc
->init_proc
= init_proc_401x2
;
3411 pcc
->check_pow
= check_pow_nocheck
;
3412 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3413 PPC_DCR
| PPC_WRTEE
|
3414 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3415 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3416 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3417 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3418 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3419 pcc
->msr_mask
= (1ull << 20) |
3431 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3432 pcc
->excp_model
= POWERPC_EXCP_40x
;
3433 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3434 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3435 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3436 POWERPC_FLAG_BUS_CLK
;
3439 static void init_proc_401x3(CPUPPCState
*env
)
3442 gen_spr_401_403(env
);
3445 gen_spr_compress(env
);
3446 init_excp_4xx_softmmu(env
);
3447 env
->dcache_line_size
= 32;
3448 env
->icache_line_size
= 32;
3449 /* Allocate hardware IRQ controller */
3450 ppc40x_irq_init(ppc_env_get_cpu(env
));
3452 SET_FIT_PERIOD(12, 16, 20, 24);
3453 SET_WDT_PERIOD(16, 20, 24, 28);
3456 POWERPC_FAMILY(401x3
)(ObjectClass
*oc
, void *data
)
3458 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3459 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3461 dc
->desc
= "PowerPC 401x3";
3462 pcc
->init_proc
= init_proc_401x3
;
3463 pcc
->check_pow
= check_pow_nocheck
;
3464 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3465 PPC_DCR
| PPC_WRTEE
|
3466 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3467 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3468 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3469 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3470 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3471 pcc
->msr_mask
= (1ull << 20) |
3484 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3485 pcc
->excp_model
= POWERPC_EXCP_40x
;
3486 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3487 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3488 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3489 POWERPC_FLAG_BUS_CLK
;
3492 static void init_proc_IOP480(CPUPPCState
*env
)
3495 gen_spr_401_403(env
);
3497 gen_spr_compress(env
);
3498 /* Memory management */
3499 #if !defined(CONFIG_USER_ONLY)
3503 env
->tlb_type
= TLB_EMB
;
3505 init_excp_4xx_softmmu(env
);
3506 env
->dcache_line_size
= 32;
3507 env
->icache_line_size
= 32;
3508 /* Allocate hardware IRQ controller */
3509 ppc40x_irq_init(ppc_env_get_cpu(env
));
3511 SET_FIT_PERIOD(8, 12, 16, 20);
3512 SET_WDT_PERIOD(16, 20, 24, 28);
3515 POWERPC_FAMILY(IOP480
)(ObjectClass
*oc
, void *data
)
3517 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3518 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3520 dc
->desc
= "IOP480";
3521 pcc
->init_proc
= init_proc_IOP480
;
3522 pcc
->check_pow
= check_pow_nocheck
;
3523 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3524 PPC_DCR
| PPC_WRTEE
|
3525 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3526 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3527 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3528 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3529 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3530 pcc
->msr_mask
= (1ull << 20) |
3542 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3543 pcc
->excp_model
= POWERPC_EXCP_40x
;
3544 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3545 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3546 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3547 POWERPC_FLAG_BUS_CLK
;
3550 static void init_proc_403(CPUPPCState
*env
)
3553 gen_spr_401_403(env
);
3555 gen_spr_403_real(env
);
3556 init_excp_4xx_real(env
);
3557 env
->dcache_line_size
= 32;
3558 env
->icache_line_size
= 32;
3559 /* Allocate hardware IRQ controller */
3560 ppc40x_irq_init(ppc_env_get_cpu(env
));
3562 SET_FIT_PERIOD(8, 12, 16, 20);
3563 SET_WDT_PERIOD(16, 20, 24, 28);
3566 POWERPC_FAMILY(403)(ObjectClass
*oc
, void *data
)
3568 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3569 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3571 dc
->desc
= "PowerPC 403";
3572 pcc
->init_proc
= init_proc_403
;
3573 pcc
->check_pow
= check_pow_nocheck
;
3574 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3575 PPC_DCR
| PPC_WRTEE
|
3576 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3578 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3579 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3580 pcc
->msr_mask
= (1ull << MSR_POW
) |
3589 pcc
->mmu_model
= POWERPC_MMU_REAL
;
3590 pcc
->excp_model
= POWERPC_EXCP_40x
;
3591 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3592 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3593 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_PX
|
3594 POWERPC_FLAG_BUS_CLK
;
3597 static void init_proc_403GCX(CPUPPCState
*env
)
3600 gen_spr_401_403(env
);
3602 gen_spr_403_real(env
);
3603 gen_spr_403_mmu(env
);
3604 /* Bus access control */
3605 /* not emulated, as QEMU never does speculative access */
3606 spr_register(env
, SPR_40x_SGR
, "SGR",
3607 SPR_NOACCESS
, SPR_NOACCESS
,
3608 &spr_read_generic
, &spr_write_generic
,
3610 /* not emulated, as QEMU do not emulate caches */
3611 spr_register(env
, SPR_40x_DCWR
, "DCWR",
3612 SPR_NOACCESS
, SPR_NOACCESS
,
3613 &spr_read_generic
, &spr_write_generic
,
3615 /* Memory management */
3616 #if !defined(CONFIG_USER_ONLY)
3620 env
->tlb_type
= TLB_EMB
;
3622 init_excp_4xx_softmmu(env
);
3623 env
->dcache_line_size
= 32;
3624 env
->icache_line_size
= 32;
3625 /* Allocate hardware IRQ controller */
3626 ppc40x_irq_init(ppc_env_get_cpu(env
));
3628 SET_FIT_PERIOD(8, 12, 16, 20);
3629 SET_WDT_PERIOD(16, 20, 24, 28);
3632 POWERPC_FAMILY(403GCX
)(ObjectClass
*oc
, void *data
)
3634 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3635 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3637 dc
->desc
= "PowerPC 403 GCX";
3638 pcc
->init_proc
= init_proc_403GCX
;
3639 pcc
->check_pow
= check_pow_nocheck
;
3640 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3641 PPC_DCR
| PPC_WRTEE
|
3642 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3644 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3645 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3646 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3647 pcc
->msr_mask
= (1ull << MSR_POW
) |
3656 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3657 pcc
->excp_model
= POWERPC_EXCP_40x
;
3658 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3659 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3660 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_PX
|
3661 POWERPC_FLAG_BUS_CLK
;
3664 static void init_proc_405(CPUPPCState
*env
)
3670 /* Bus access control */
3671 /* not emulated, as QEMU never does speculative access */
3672 spr_register(env
, SPR_40x_SGR
, "SGR",
3673 SPR_NOACCESS
, SPR_NOACCESS
,
3674 &spr_read_generic
, &spr_write_generic
,
3676 /* not emulated, as QEMU do not emulate caches */
3677 spr_register(env
, SPR_40x_DCWR
, "DCWR",
3678 SPR_NOACCESS
, SPR_NOACCESS
,
3679 &spr_read_generic
, &spr_write_generic
,
3681 /* Memory management */
3682 #if !defined(CONFIG_USER_ONLY)
3686 env
->tlb_type
= TLB_EMB
;
3688 init_excp_4xx_softmmu(env
);
3689 env
->dcache_line_size
= 32;
3690 env
->icache_line_size
= 32;
3691 /* Allocate hardware IRQ controller */
3692 ppc40x_irq_init(ppc_env_get_cpu(env
));
3694 SET_FIT_PERIOD(8, 12, 16, 20);
3695 SET_WDT_PERIOD(16, 20, 24, 28);
3698 POWERPC_FAMILY(405)(ObjectClass
*oc
, void *data
)
3700 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3701 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3703 dc
->desc
= "PowerPC 405";
3704 pcc
->init_proc
= init_proc_405
;
3705 pcc
->check_pow
= check_pow_nocheck
;
3706 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3707 PPC_DCR
| PPC_WRTEE
|
3708 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3709 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3710 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3711 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3712 PPC_4xx_COMMON
| PPC_405_MAC
| PPC_40x_EXCP
;
3713 pcc
->msr_mask
= (1ull << MSR_POW
) |
3722 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx
;
3723 pcc
->excp_model
= POWERPC_EXCP_40x
;
3724 pcc
->bus_model
= PPC_FLAGS_INPUT_405
;
3725 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3726 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3727 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3730 static void init_proc_440EP(CPUPPCState
*env
)
3734 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3736 gen_spr_usprgh(env
);
3737 /* Processor identification */
3738 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3739 SPR_NOACCESS
, SPR_NOACCESS
,
3740 &spr_read_generic
, &spr_write_pir
,
3742 /* XXX : not implemented */
3743 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
3744 SPR_NOACCESS
, SPR_NOACCESS
,
3745 &spr_read_generic
, &spr_write_generic
,
3747 /* XXX : not implemented */
3748 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
3749 SPR_NOACCESS
, SPR_NOACCESS
,
3750 &spr_read_generic
, &spr_write_generic
,
3752 /* XXX : not implemented */
3753 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
3754 SPR_NOACCESS
, SPR_NOACCESS
,
3755 &spr_read_generic
, &spr_write_generic
,
3757 /* XXX : not implemented */
3758 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
3759 SPR_NOACCESS
, SPR_NOACCESS
,
3760 &spr_read_generic
, &spr_write_generic
,
3762 /* XXX : not implemented */
3763 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
3764 SPR_NOACCESS
, SPR_NOACCESS
,
3765 &spr_read_generic
, &spr_write_generic
,
3767 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
3768 SPR_NOACCESS
, SPR_NOACCESS
,
3769 &spr_read_generic
, &spr_write_generic
,
3771 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
3772 SPR_NOACCESS
, SPR_NOACCESS
,
3773 &spr_read_generic
, &spr_write_generic
,
3775 /* XXX : not implemented */
3776 spr_register(env
, SPR_440_CCR1
, "CCR1",
3777 SPR_NOACCESS
, SPR_NOACCESS
,
3778 &spr_read_generic
, &spr_write_generic
,
3780 /* Memory management */
3781 #if !defined(CONFIG_USER_ONLY)
3785 env
->tlb_type
= TLB_EMB
;
3787 init_excp_BookE(env
);
3788 env
->dcache_line_size
= 32;
3789 env
->icache_line_size
= 32;
3790 ppc40x_irq_init(ppc_env_get_cpu(env
));
3792 SET_FIT_PERIOD(12, 16, 20, 24);
3793 SET_WDT_PERIOD(20, 24, 28, 32);
3796 POWERPC_FAMILY(440EP
)(ObjectClass
*oc
, void *data
)
3798 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3799 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3801 dc
->desc
= "PowerPC 440 EP";
3802 pcc
->init_proc
= init_proc_440EP
;
3803 pcc
->check_pow
= check_pow_nocheck
;
3804 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3805 PPC_FLOAT
| PPC_FLOAT_FRES
| PPC_FLOAT_FSEL
|
3806 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
3808 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
3809 PPC_CACHE
| PPC_CACHE_ICBI
|
3810 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3811 PPC_MEM_TLBSYNC
| PPC_MFTB
|
3812 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3814 pcc
->msr_mask
= (1ull << MSR_POW
) |
3826 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3827 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3828 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3829 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3830 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3831 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3834 static void init_proc_440GP(CPUPPCState
*env
)
3838 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3840 gen_spr_usprgh(env
);
3841 /* Processor identification */
3842 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3843 SPR_NOACCESS
, SPR_NOACCESS
,
3844 &spr_read_generic
, &spr_write_pir
,
3846 /* XXX : not implemented */
3847 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
3848 SPR_NOACCESS
, SPR_NOACCESS
,
3849 &spr_read_generic
, &spr_write_generic
,
3851 /* XXX : not implemented */
3852 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
3853 SPR_NOACCESS
, SPR_NOACCESS
,
3854 &spr_read_generic
, &spr_write_generic
,
3856 /* XXX : not implemented */
3857 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
3858 SPR_NOACCESS
, SPR_NOACCESS
,
3859 &spr_read_generic
, &spr_write_generic
,
3861 /* XXX : not implemented */
3862 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
3863 SPR_NOACCESS
, SPR_NOACCESS
,
3864 &spr_read_generic
, &spr_write_generic
,
3866 /* Memory management */
3867 #if !defined(CONFIG_USER_ONLY)
3871 env
->tlb_type
= TLB_EMB
;
3873 init_excp_BookE(env
);
3874 env
->dcache_line_size
= 32;
3875 env
->icache_line_size
= 32;
3876 /* XXX: TODO: allocate internal IRQ controller */
3878 SET_FIT_PERIOD(12, 16, 20, 24);
3879 SET_WDT_PERIOD(20, 24, 28, 32);
3882 POWERPC_FAMILY(440GP
)(ObjectClass
*oc
, void *data
)
3884 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3885 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3887 dc
->desc
= "PowerPC 440 GP";
3888 pcc
->init_proc
= init_proc_440GP
;
3889 pcc
->check_pow
= check_pow_nocheck
;
3890 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3891 PPC_DCR
| PPC_DCRX
| PPC_WRTEE
| PPC_MFAPIDI
|
3892 PPC_CACHE
| PPC_CACHE_ICBI
|
3893 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3894 PPC_MEM_TLBSYNC
| PPC_TLBIVA
| PPC_MFTB
|
3895 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3897 pcc
->msr_mask
= (1ull << MSR_POW
) |
3909 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3910 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3911 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3912 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3913 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3914 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3917 static void init_proc_440x4(CPUPPCState
*env
)
3921 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3923 gen_spr_usprgh(env
);
3924 /* Processor identification */
3925 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3926 SPR_NOACCESS
, SPR_NOACCESS
,
3927 &spr_read_generic
, &spr_write_pir
,
3929 /* XXX : not implemented */
3930 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
3931 SPR_NOACCESS
, SPR_NOACCESS
,
3932 &spr_read_generic
, &spr_write_generic
,
3934 /* XXX : not implemented */
3935 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
3936 SPR_NOACCESS
, SPR_NOACCESS
,
3937 &spr_read_generic
, &spr_write_generic
,
3939 /* XXX : not implemented */
3940 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
3941 SPR_NOACCESS
, SPR_NOACCESS
,
3942 &spr_read_generic
, &spr_write_generic
,
3944 /* XXX : not implemented */
3945 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
3946 SPR_NOACCESS
, SPR_NOACCESS
,
3947 &spr_read_generic
, &spr_write_generic
,
3949 /* Memory management */
3950 #if !defined(CONFIG_USER_ONLY)
3954 env
->tlb_type
= TLB_EMB
;
3956 init_excp_BookE(env
);
3957 env
->dcache_line_size
= 32;
3958 env
->icache_line_size
= 32;
3959 /* XXX: TODO: allocate internal IRQ controller */
3961 SET_FIT_PERIOD(12, 16, 20, 24);
3962 SET_WDT_PERIOD(20, 24, 28, 32);
3965 POWERPC_FAMILY(440x4
)(ObjectClass
*oc
, void *data
)
3967 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3968 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3970 dc
->desc
= "PowerPC 440x4";
3971 pcc
->init_proc
= init_proc_440x4
;
3972 pcc
->check_pow
= check_pow_nocheck
;
3973 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3974 PPC_DCR
| PPC_WRTEE
|
3975 PPC_CACHE
| PPC_CACHE_ICBI
|
3976 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3977 PPC_MEM_TLBSYNC
| PPC_MFTB
|
3978 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3980 pcc
->msr_mask
= (1ull << MSR_POW
) |
3992 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3993 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3994 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3995 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3996 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3997 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4000 static void init_proc_440x5(CPUPPCState
*env
)
4004 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
4006 gen_spr_usprgh(env
);
4007 /* Processor identification */
4008 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4009 SPR_NOACCESS
, SPR_NOACCESS
,
4010 &spr_read_generic
, &spr_write_pir
,
4012 /* XXX : not implemented */
4013 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4014 SPR_NOACCESS
, SPR_NOACCESS
,
4015 &spr_read_generic
, &spr_write_generic
,
4017 /* XXX : not implemented */
4018 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4019 SPR_NOACCESS
, SPR_NOACCESS
,
4020 &spr_read_generic
, &spr_write_generic
,
4022 /* XXX : not implemented */
4023 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
4024 SPR_NOACCESS
, SPR_NOACCESS
,
4025 &spr_read_generic
, &spr_write_generic
,
4027 /* XXX : not implemented */
4028 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
4029 SPR_NOACCESS
, SPR_NOACCESS
,
4030 &spr_read_generic
, &spr_write_generic
,
4032 /* XXX : not implemented */
4033 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
4034 SPR_NOACCESS
, SPR_NOACCESS
,
4035 &spr_read_generic
, &spr_write_generic
,
4037 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
4038 SPR_NOACCESS
, SPR_NOACCESS
,
4039 &spr_read_generic
, &spr_write_generic
,
4041 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
4042 SPR_NOACCESS
, SPR_NOACCESS
,
4043 &spr_read_generic
, &spr_write_generic
,
4045 /* XXX : not implemented */
4046 spr_register(env
, SPR_440_CCR1
, "CCR1",
4047 SPR_NOACCESS
, SPR_NOACCESS
,
4048 &spr_read_generic
, &spr_write_generic
,
4050 /* Memory management */
4051 #if !defined(CONFIG_USER_ONLY)
4055 env
->tlb_type
= TLB_EMB
;
4057 init_excp_BookE(env
);
4058 env
->dcache_line_size
= 32;
4059 env
->icache_line_size
= 32;
4060 ppc40x_irq_init(ppc_env_get_cpu(env
));
4062 SET_FIT_PERIOD(12, 16, 20, 24);
4063 SET_WDT_PERIOD(20, 24, 28, 32);
4066 POWERPC_FAMILY(440x5
)(ObjectClass
*oc
, void *data
)
4068 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4069 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4071 dc
->desc
= "PowerPC 440x5";
4072 pcc
->init_proc
= init_proc_440x5
;
4073 pcc
->check_pow
= check_pow_nocheck
;
4074 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4075 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
4076 PPC_CACHE
| PPC_CACHE_ICBI
|
4077 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4078 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4079 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4081 pcc
->msr_mask
= (1ull << MSR_POW
) |
4093 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4094 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4095 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4096 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4097 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4098 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4101 POWERPC_FAMILY(440x5wDFPU
)(ObjectClass
*oc
, void *data
)
4103 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4104 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4106 dc
->desc
= "PowerPC 440x5 with double precision FPU";
4107 pcc
->init_proc
= init_proc_440x5
;
4108 pcc
->check_pow
= check_pow_nocheck
;
4109 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4110 PPC_FLOAT
| PPC_FLOAT_FSQRT
|
4112 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
4113 PPC_CACHE
| PPC_CACHE_ICBI
|
4114 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4115 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4116 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4118 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
4119 pcc
->msr_mask
= (1ull << MSR_POW
) |
4131 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4132 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4133 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4134 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4135 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4136 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4139 static void init_proc_460 (CPUPPCState
*env
)
4143 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
4145 gen_spr_usprgh(env
);
4146 /* Processor identification */
4147 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4148 SPR_NOACCESS
, SPR_NOACCESS
,
4149 &spr_read_generic
, &spr_write_pir
,
4151 /* XXX : not implemented */
4152 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4153 SPR_NOACCESS
, SPR_NOACCESS
,
4154 &spr_read_generic
, &spr_write_generic
,
4156 /* XXX : not implemented */
4157 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4158 SPR_NOACCESS
, SPR_NOACCESS
,
4159 &spr_read_generic
, &spr_write_generic
,
4161 /* XXX : not implemented */
4162 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
4163 SPR_NOACCESS
, SPR_NOACCESS
,
4164 &spr_read_generic
, &spr_write_generic
,
4166 /* XXX : not implemented */
4167 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
4168 SPR_NOACCESS
, SPR_NOACCESS
,
4169 &spr_read_generic
, &spr_write_generic
,
4171 /* XXX : not implemented */
4172 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
4173 SPR_NOACCESS
, SPR_NOACCESS
,
4174 &spr_read_generic
, &spr_write_generic
,
4176 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
4177 SPR_NOACCESS
, SPR_NOACCESS
,
4178 &spr_read_generic
, &spr_write_generic
,
4180 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
4181 SPR_NOACCESS
, SPR_NOACCESS
,
4182 &spr_read_generic
, &spr_write_generic
,
4184 /* XXX : not implemented */
4185 spr_register(env
, SPR_440_CCR1
, "CCR1",
4186 SPR_NOACCESS
, SPR_NOACCESS
,
4187 &spr_read_generic
, &spr_write_generic
,
4189 /* XXX : not implemented */
4190 spr_register(env
, SPR_DCRIPR
, "SPR_DCRIPR",
4191 &spr_read_generic
, &spr_write_generic
,
4192 &spr_read_generic
, &spr_write_generic
,
4194 /* Memory management */
4195 #if !defined(CONFIG_USER_ONLY)
4199 env
->tlb_type
= TLB_EMB
;
4201 init_excp_BookE(env
);
4202 env
->dcache_line_size
= 32;
4203 env
->icache_line_size
= 32;
4204 /* XXX: TODO: allocate internal IRQ controller */
4206 SET_FIT_PERIOD(12, 16, 20, 24);
4207 SET_WDT_PERIOD(20, 24, 28, 32);
4210 POWERPC_FAMILY(460)(ObjectClass
*oc
, void *data
)
4212 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4213 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4215 dc
->desc
= "PowerPC 460 (guessed)";
4216 pcc
->init_proc
= init_proc_460
;
4217 pcc
->check_pow
= check_pow_nocheck
;
4218 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4219 PPC_DCR
| PPC_DCRX
| PPC_DCRUX
|
4220 PPC_WRTEE
| PPC_MFAPIDI
| PPC_MFTB
|
4221 PPC_CACHE
| PPC_CACHE_ICBI
|
4222 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4223 PPC_MEM_TLBSYNC
| PPC_TLBIVA
|
4224 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4226 pcc
->msr_mask
= (1ull << MSR_POW
) |
4238 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4239 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4240 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4241 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4242 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4243 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4246 static void init_proc_460F(CPUPPCState
*env
)
4250 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
4252 gen_spr_usprgh(env
);
4253 /* Processor identification */
4254 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4255 SPR_NOACCESS
, SPR_NOACCESS
,
4256 &spr_read_generic
, &spr_write_pir
,
4258 /* XXX : not implemented */
4259 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4260 SPR_NOACCESS
, SPR_NOACCESS
,
4261 &spr_read_generic
, &spr_write_generic
,
4263 /* XXX : not implemented */
4264 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4265 SPR_NOACCESS
, SPR_NOACCESS
,
4266 &spr_read_generic
, &spr_write_generic
,
4268 /* XXX : not implemented */
4269 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
4270 SPR_NOACCESS
, SPR_NOACCESS
,
4271 &spr_read_generic
, &spr_write_generic
,
4273 /* XXX : not implemented */
4274 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
4275 SPR_NOACCESS
, SPR_NOACCESS
,
4276 &spr_read_generic
, &spr_write_generic
,
4278 /* XXX : not implemented */
4279 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
4280 SPR_NOACCESS
, SPR_NOACCESS
,
4281 &spr_read_generic
, &spr_write_generic
,
4283 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
4284 SPR_NOACCESS
, SPR_NOACCESS
,
4285 &spr_read_generic
, &spr_write_generic
,
4287 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
4288 SPR_NOACCESS
, SPR_NOACCESS
,
4289 &spr_read_generic
, &spr_write_generic
,
4291 /* XXX : not implemented */
4292 spr_register(env
, SPR_440_CCR1
, "CCR1",
4293 SPR_NOACCESS
, SPR_NOACCESS
,
4294 &spr_read_generic
, &spr_write_generic
,
4296 /* XXX : not implemented */
4297 spr_register(env
, SPR_DCRIPR
, "SPR_DCRIPR",
4298 &spr_read_generic
, &spr_write_generic
,
4299 &spr_read_generic
, &spr_write_generic
,
4301 /* Memory management */
4302 #if !defined(CONFIG_USER_ONLY)
4306 env
->tlb_type
= TLB_EMB
;
4308 init_excp_BookE(env
);
4309 env
->dcache_line_size
= 32;
4310 env
->icache_line_size
= 32;
4311 /* XXX: TODO: allocate internal IRQ controller */
4313 SET_FIT_PERIOD(12, 16, 20, 24);
4314 SET_WDT_PERIOD(20, 24, 28, 32);
4317 POWERPC_FAMILY(460F
)(ObjectClass
*oc
, void *data
)
4319 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4320 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4322 dc
->desc
= "PowerPC 460F (guessed)";
4323 pcc
->init_proc
= init_proc_460F
;
4324 pcc
->check_pow
= check_pow_nocheck
;
4325 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4326 PPC_FLOAT
| PPC_FLOAT_FRES
| PPC_FLOAT_FSEL
|
4327 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
4328 PPC_FLOAT_STFIWX
| PPC_MFTB
|
4329 PPC_DCR
| PPC_DCRX
| PPC_DCRUX
|
4330 PPC_WRTEE
| PPC_MFAPIDI
|
4331 PPC_CACHE
| PPC_CACHE_ICBI
|
4332 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4333 PPC_MEM_TLBSYNC
| PPC_TLBIVA
|
4334 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4336 pcc
->msr_mask
= (1ull << MSR_POW
) |
4348 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4349 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4350 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4351 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4352 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4353 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4356 static void init_proc_MPC5xx(CPUPPCState
*env
)
4360 gen_spr_5xx_8xx(env
);
4362 init_excp_MPC5xx(env
);
4363 env
->dcache_line_size
= 32;
4364 env
->icache_line_size
= 32;
4365 /* XXX: TODO: allocate internal IRQ controller */
4368 POWERPC_FAMILY(MPC5xx
)(ObjectClass
*oc
, void *data
)
4370 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4371 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4373 dc
->desc
= "Freescale 5xx cores (aka RCPU)";
4374 pcc
->init_proc
= init_proc_MPC5xx
;
4375 pcc
->check_pow
= check_pow_none
;
4376 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4377 PPC_MEM_EIEIO
| PPC_MEM_SYNC
|
4378 PPC_CACHE_ICBI
| PPC_FLOAT
| PPC_FLOAT_STFIWX
|
4380 pcc
->msr_mask
= (1ull << MSR_ILE
) |
4392 pcc
->mmu_model
= POWERPC_MMU_REAL
;
4393 pcc
->excp_model
= POWERPC_EXCP_603
;
4394 pcc
->bus_model
= PPC_FLAGS_INPUT_RCPU
;
4395 pcc
->bfd_mach
= bfd_mach_ppc_505
;
4396 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
4397 POWERPC_FLAG_BUS_CLK
;
4400 static void init_proc_MPC8xx(CPUPPCState
*env
)
4404 gen_spr_5xx_8xx(env
);
4406 init_excp_MPC8xx(env
);
4407 env
->dcache_line_size
= 32;
4408 env
->icache_line_size
= 32;
4409 /* XXX: TODO: allocate internal IRQ controller */
4412 POWERPC_FAMILY(MPC8xx
)(ObjectClass
*oc
, void *data
)
4414 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4415 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4417 dc
->desc
= "Freescale 8xx cores (aka PowerQUICC)";
4418 pcc
->init_proc
= init_proc_MPC8xx
;
4419 pcc
->check_pow
= check_pow_none
;
4420 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4421 PPC_MEM_EIEIO
| PPC_MEM_SYNC
|
4422 PPC_CACHE_ICBI
| PPC_MFTB
;
4423 pcc
->msr_mask
= (1ull << MSR_ILE
) |
4435 pcc
->mmu_model
= POWERPC_MMU_MPC8xx
;
4436 pcc
->excp_model
= POWERPC_EXCP_603
;
4437 pcc
->bus_model
= PPC_FLAGS_INPUT_RCPU
;
4438 pcc
->bfd_mach
= bfd_mach_ppc_860
;
4439 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
4440 POWERPC_FLAG_BUS_CLK
;
4443 /* Freescale 82xx cores (aka PowerQUICC-II) */
4445 static void init_proc_G2(CPUPPCState
*env
)
4447 gen_spr_ne_601(env
);
4449 gen_spr_G2_755(env
);
4453 /* External access control */
4454 /* XXX : not implemented */
4455 spr_register(env
, SPR_EAR
, "EAR",
4456 SPR_NOACCESS
, SPR_NOACCESS
,
4457 &spr_read_generic
, &spr_write_generic
,
4459 /* Hardware implementation register */
4460 /* XXX : not implemented */
4461 spr_register(env
, SPR_HID0
, "HID0",
4462 SPR_NOACCESS
, SPR_NOACCESS
,
4463 &spr_read_generic
, &spr_write_generic
,
4465 /* XXX : not implemented */
4466 spr_register(env
, SPR_HID1
, "HID1",
4467 SPR_NOACCESS
, SPR_NOACCESS
,
4468 &spr_read_generic
, &spr_write_generic
,
4470 /* XXX : not implemented */
4471 spr_register(env
, SPR_HID2
, "HID2",
4472 SPR_NOACCESS
, SPR_NOACCESS
,
4473 &spr_read_generic
, &spr_write_generic
,
4475 /* Memory management */
4478 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4480 env
->dcache_line_size
= 32;
4481 env
->icache_line_size
= 32;
4482 /* Allocate hardware IRQ controller */
4483 ppc6xx_irq_init(ppc_env_get_cpu(env
));
4486 POWERPC_FAMILY(G2
)(ObjectClass
*oc
, void *data
)
4488 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4489 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4491 dc
->desc
= "PowerPC G2";
4492 pcc
->init_proc
= init_proc_G2
;
4493 pcc
->check_pow
= check_pow_hid0
;
4494 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4495 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4497 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4498 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4499 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4500 PPC_SEGMENT
| PPC_EXTERN
;
4501 pcc
->msr_mask
= (1ull << MSR_POW
) |
4502 (1ull << MSR_TGPR
) |
4516 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4517 pcc
->excp_model
= POWERPC_EXCP_G2
;
4518 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4519 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
4520 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4521 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4524 static void init_proc_G2LE(CPUPPCState
*env
)
4526 gen_spr_ne_601(env
);
4528 gen_spr_G2_755(env
);
4532 /* External access control */
4533 /* XXX : not implemented */
4534 spr_register(env
, SPR_EAR
, "EAR",
4535 SPR_NOACCESS
, SPR_NOACCESS
,
4536 &spr_read_generic
, &spr_write_generic
,
4538 /* Hardware implementation register */
4539 /* XXX : not implemented */
4540 spr_register(env
, SPR_HID0
, "HID0",
4541 SPR_NOACCESS
, SPR_NOACCESS
,
4542 &spr_read_generic
, &spr_write_generic
,
4544 /* XXX : not implemented */
4545 spr_register(env
, SPR_HID1
, "HID1",
4546 SPR_NOACCESS
, SPR_NOACCESS
,
4547 &spr_read_generic
, &spr_write_generic
,
4549 /* XXX : not implemented */
4550 spr_register(env
, SPR_HID2
, "HID2",
4551 SPR_NOACCESS
, SPR_NOACCESS
,
4552 &spr_read_generic
, &spr_write_generic
,
4555 /* Memory management */
4558 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4560 env
->dcache_line_size
= 32;
4561 env
->icache_line_size
= 32;
4562 /* Allocate hardware IRQ controller */
4563 ppc6xx_irq_init(ppc_env_get_cpu(env
));
4566 POWERPC_FAMILY(G2LE
)(ObjectClass
*oc
, void *data
)
4568 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4569 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4571 dc
->desc
= "PowerPC G2LE";
4572 pcc
->init_proc
= init_proc_G2LE
;
4573 pcc
->check_pow
= check_pow_hid0
;
4574 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4575 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4577 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4578 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4579 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4580 PPC_SEGMENT
| PPC_EXTERN
;
4581 pcc
->msr_mask
= (1ull << MSR_POW
) |
4582 (1ull << MSR_TGPR
) |
4598 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4599 pcc
->excp_model
= POWERPC_EXCP_G2
;
4600 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4601 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
4602 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4603 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4606 static void init_proc_e200(CPUPPCState
*env
)
4610 gen_spr_BookE(env
, 0x000000070000FFFFULL
);
4611 /* XXX : not implemented */
4612 spr_register(env
, SPR_BOOKE_SPEFSCR
, "SPEFSCR",
4613 &spr_read_spefscr
, &spr_write_spefscr
,
4614 &spr_read_spefscr
, &spr_write_spefscr
,
4616 /* Memory management */
4617 gen_spr_BookE206(env
, 0x0000005D, NULL
);
4618 /* XXX : not implemented */
4619 spr_register(env
, SPR_HID0
, "HID0",
4620 SPR_NOACCESS
, SPR_NOACCESS
,
4621 &spr_read_generic
, &spr_write_generic
,
4623 /* XXX : not implemented */
4624 spr_register(env
, SPR_HID1
, "HID1",
4625 SPR_NOACCESS
, SPR_NOACCESS
,
4626 &spr_read_generic
, &spr_write_generic
,
4628 /* XXX : not implemented */
4629 spr_register(env
, SPR_Exxx_ALTCTXCR
, "ALTCTXCR",
4630 SPR_NOACCESS
, SPR_NOACCESS
,
4631 &spr_read_generic
, &spr_write_generic
,
4633 /* XXX : not implemented */
4634 spr_register(env
, SPR_Exxx_BUCSR
, "BUCSR",
4635 SPR_NOACCESS
, SPR_NOACCESS
,
4636 &spr_read_generic
, &spr_write_generic
,
4638 /* XXX : not implemented */
4639 spr_register(env
, SPR_Exxx_CTXCR
, "CTXCR",
4640 SPR_NOACCESS
, SPR_NOACCESS
,
4641 &spr_read_generic
, &spr_write_generic
,
4643 /* XXX : not implemented */
4644 spr_register(env
, SPR_Exxx_DBCNT
, "DBCNT",
4645 SPR_NOACCESS
, SPR_NOACCESS
,
4646 &spr_read_generic
, &spr_write_generic
,
4648 /* XXX : not implemented */
4649 spr_register(env
, SPR_Exxx_DBCR3
, "DBCR3",
4650 SPR_NOACCESS
, SPR_NOACCESS
,
4651 &spr_read_generic
, &spr_write_generic
,
4653 /* XXX : not implemented */
4654 spr_register(env
, SPR_Exxx_L1CFG0
, "L1CFG0",
4655 &spr_read_generic
, SPR_NOACCESS
,
4656 &spr_read_generic
, SPR_NOACCESS
,
4658 /* XXX : not implemented */
4659 spr_register(env
, SPR_Exxx_L1CSR0
, "L1CSR0",
4660 SPR_NOACCESS
, SPR_NOACCESS
,
4661 &spr_read_generic
, &spr_write_generic
,
4663 /* XXX : not implemented */
4664 spr_register(env
, SPR_Exxx_L1FINV0
, "L1FINV0",
4665 SPR_NOACCESS
, SPR_NOACCESS
,
4666 &spr_read_generic
, &spr_write_generic
,
4668 /* XXX : not implemented */
4669 spr_register(env
, SPR_BOOKE_TLB0CFG
, "TLB0CFG",
4670 SPR_NOACCESS
, SPR_NOACCESS
,
4671 &spr_read_generic
, &spr_write_generic
,
4673 /* XXX : not implemented */
4674 spr_register(env
, SPR_BOOKE_TLB1CFG
, "TLB1CFG",
4675 SPR_NOACCESS
, SPR_NOACCESS
,
4676 &spr_read_generic
, &spr_write_generic
,
4678 /* XXX : not implemented */
4679 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4680 SPR_NOACCESS
, SPR_NOACCESS
,
4681 &spr_read_generic
, &spr_write_generic
,
4683 /* XXX : not implemented */
4684 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4685 SPR_NOACCESS
, SPR_NOACCESS
,
4686 &spr_read_generic
, &spr_write_generic
,
4688 /* XXX : not implemented */
4689 spr_register(env
, SPR_MMUCSR0
, "MMUCSR0",
4690 SPR_NOACCESS
, SPR_NOACCESS
,
4691 &spr_read_generic
, &spr_write_generic
,
4692 0x00000000); /* TOFIX */
4693 spr_register(env
, SPR_BOOKE_DSRR0
, "DSRR0",
4694 SPR_NOACCESS
, SPR_NOACCESS
,
4695 &spr_read_generic
, &spr_write_generic
,
4697 spr_register(env
, SPR_BOOKE_DSRR1
, "DSRR1",
4698 SPR_NOACCESS
, SPR_NOACCESS
,
4699 &spr_read_generic
, &spr_write_generic
,
4701 #if !defined(CONFIG_USER_ONLY)
4705 env
->tlb_type
= TLB_EMB
;
4707 init_excp_e200(env
, 0xFFFF0000UL
);
4708 env
->dcache_line_size
= 32;
4709 env
->icache_line_size
= 32;
4710 /* XXX: TODO: allocate internal IRQ controller */
4713 POWERPC_FAMILY(e200
)(ObjectClass
*oc
, void *data
)
4715 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4716 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4718 dc
->desc
= "e200 core";
4719 pcc
->init_proc
= init_proc_e200
;
4720 pcc
->check_pow
= check_pow_hid0
;
4721 /* XXX: unimplemented instructions:
4728 * all SPE multiply-accumulate instructions
4730 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
4731 PPC_SPE
| PPC_SPE_SINGLE
|
4732 PPC_WRTEE
| PPC_RFDI
|
4733 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
4734 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4735 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
|
4737 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
4751 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
4752 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4753 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4754 pcc
->bfd_mach
= bfd_mach_ppc_860
;
4755 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
4756 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
4757 POWERPC_FLAG_BUS_CLK
;
4760 static void init_proc_e300(CPUPPCState
*env
)
4762 gen_spr_ne_601(env
);
4767 /* hardware implementation registers */
4768 /* XXX : not implemented */
4769 spr_register(env
, SPR_HID0
, "HID0",
4770 SPR_NOACCESS
, SPR_NOACCESS
,
4771 &spr_read_generic
, &spr_write_generic
,
4773 /* XXX : not implemented */
4774 spr_register(env
, SPR_HID1
, "HID1",
4775 SPR_NOACCESS
, SPR_NOACCESS
,
4776 &spr_read_generic
, &spr_write_generic
,
4778 /* XXX : not implemented */
4779 spr_register(env
, SPR_HID2
, "HID2",
4780 SPR_NOACCESS
, SPR_NOACCESS
,
4781 &spr_read_generic
, &spr_write_generic
,
4784 /* XXX : not implemented */
4785 spr_register(env
, SPR_DABR
, "DABR",
4786 SPR_NOACCESS
, SPR_NOACCESS
,
4787 &spr_read_generic
, &spr_write_generic
,
4789 /* XXX : not implemented */
4790 spr_register(env
, SPR_DABR2
, "DABR2",
4791 SPR_NOACCESS
, SPR_NOACCESS
,
4792 &spr_read_generic
, &spr_write_generic
,
4794 /* XXX : not implemented */
4795 spr_register(env
, SPR_IABR2
, "IABR2",
4796 SPR_NOACCESS
, SPR_NOACCESS
,
4797 &spr_read_generic
, &spr_write_generic
,
4799 /* XXX : not implemented */
4800 spr_register(env
, SPR_IBCR
, "IBCR",
4801 SPR_NOACCESS
, SPR_NOACCESS
,
4802 &spr_read_generic
, &spr_write_generic
,
4804 /* XXX : not implemented */
4805 spr_register(env
, SPR_DBCR
, "DBCR",
4806 SPR_NOACCESS
, SPR_NOACCESS
,
4807 &spr_read_generic
, &spr_write_generic
,
4809 /* Memory management */
4812 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4814 env
->dcache_line_size
= 32;
4815 env
->icache_line_size
= 32;
4816 /* Allocate hardware IRQ controller */
4817 ppc6xx_irq_init(ppc_env_get_cpu(env
));
4820 POWERPC_FAMILY(e300
)(ObjectClass
*oc
, void *data
)
4822 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4823 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4825 dc
->desc
= "e300 core";
4826 pcc
->init_proc
= init_proc_e300
;
4827 pcc
->check_pow
= check_pow_hid0
;
4828 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4829 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4831 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4832 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4833 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4834 PPC_SEGMENT
| PPC_EXTERN
;
4835 pcc
->msr_mask
= (1ull << MSR_POW
) |
4836 (1ull << MSR_TGPR
) |
4852 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4853 pcc
->excp_model
= POWERPC_EXCP_603
;
4854 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4855 pcc
->bfd_mach
= bfd_mach_ppc_603
;
4856 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4857 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4860 #if !defined(CONFIG_USER_ONLY)
4861 static void spr_write_mas73(DisasContext
*ctx
, int sprn
, int gprn
)
4863 TCGv val
= tcg_temp_new();
4864 tcg_gen_ext32u_tl(val
, cpu_gpr
[gprn
]);
4865 gen_store_spr(SPR_BOOKE_MAS3
, val
);
4866 tcg_gen_shri_tl(val
, cpu_gpr
[gprn
], 32);
4867 gen_store_spr(SPR_BOOKE_MAS7
, val
);
4871 static void spr_read_mas73(DisasContext
*ctx
, int gprn
, int sprn
)
4873 TCGv mas7
= tcg_temp_new();
4874 TCGv mas3
= tcg_temp_new();
4875 gen_load_spr(mas7
, SPR_BOOKE_MAS7
);
4876 tcg_gen_shli_tl(mas7
, mas7
, 32);
4877 gen_load_spr(mas3
, SPR_BOOKE_MAS3
);
4878 tcg_gen_or_tl(cpu_gpr
[gprn
], mas3
, mas7
);
4879 tcg_temp_free(mas3
);
4880 tcg_temp_free(mas7
);
4885 enum fsl_e500_version
{
4892 static void init_proc_e500(CPUPPCState
*env
, int version
)
4894 PowerPCCPU
*cpu
= ppc_env_get_cpu(env
);
4895 uint32_t tlbncfg
[2];
4897 uint64_t ivpr_mask
= 0xFFFF0000ULL
;
4898 uint32_t l1cfg0
= 0x3800 /* 8 ways */
4899 | 0x0020; /* 32 kb */
4900 uint32_t l1cfg1
= 0x3800 /* 8 ways */
4901 | 0x0020; /* 32 kb */
4902 #if !defined(CONFIG_USER_ONLY)
4909 * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't
4910 * complain when accessing them.
4911 * gen_spr_BookE(env, 0x0000000F0000FD7FULL);
4917 ivor_mask
= 0x0000000F0000FFFFULL
;
4921 ivor_mask
= 0x000003FE0000FFFFULL
;
4924 gen_spr_BookE(env
, ivor_mask
);
4925 gen_spr_usprg3(env
);
4926 /* Processor identification */
4927 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4928 SPR_NOACCESS
, SPR_NOACCESS
,
4929 &spr_read_generic
, &spr_write_pir
,
4931 /* XXX : not implemented */
4932 spr_register(env
, SPR_BOOKE_SPEFSCR
, "SPEFSCR",
4933 &spr_read_spefscr
, &spr_write_spefscr
,
4934 &spr_read_spefscr
, &spr_write_spefscr
,
4936 #if !defined(CONFIG_USER_ONLY)
4937 /* Memory management */
4943 tlbncfg
[0] = gen_tlbncfg(2, 1, 1, 0, 256);
4944 tlbncfg
[1] = gen_tlbncfg(16, 1, 9, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 16);
4947 tlbncfg
[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4948 tlbncfg
[1] = gen_tlbncfg(16, 1, 12, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 16);
4952 tlbncfg
[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4953 tlbncfg
[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 64);
4956 cpu_abort(CPU(cpu
), "Unknown CPU: " TARGET_FMT_lx
"\n", env
->spr
[SPR_PVR
]);
4963 env
->dcache_line_size
= 32;
4964 env
->icache_line_size
= 32;
4968 env
->dcache_line_size
= 64;
4969 env
->icache_line_size
= 64;
4970 l1cfg0
|= 0x1000000; /* 64 byte cache block size */
4971 l1cfg1
|= 0x1000000; /* 64 byte cache block size */
4974 cpu_abort(CPU(cpu
), "Unknown CPU: " TARGET_FMT_lx
"\n", env
->spr
[SPR_PVR
]);
4976 gen_spr_BookE206(env
, 0x000000DF, tlbncfg
);
4977 /* XXX : not implemented */
4978 spr_register(env
, SPR_HID0
, "HID0",
4979 SPR_NOACCESS
, SPR_NOACCESS
,
4980 &spr_read_generic
, &spr_write_generic
,
4982 /* XXX : not implemented */
4983 spr_register(env
, SPR_HID1
, "HID1",
4984 SPR_NOACCESS
, SPR_NOACCESS
,
4985 &spr_read_generic
, &spr_write_generic
,
4987 /* XXX : not implemented */
4988 spr_register(env
, SPR_Exxx_BBEAR
, "BBEAR",
4989 SPR_NOACCESS
, SPR_NOACCESS
,
4990 &spr_read_generic
, &spr_write_generic
,
4992 /* XXX : not implemented */
4993 spr_register(env
, SPR_Exxx_BBTAR
, "BBTAR",
4994 SPR_NOACCESS
, SPR_NOACCESS
,
4995 &spr_read_generic
, &spr_write_generic
,
4997 /* XXX : not implemented */
4998 spr_register(env
, SPR_Exxx_MCAR
, "MCAR",
4999 SPR_NOACCESS
, SPR_NOACCESS
,
5000 &spr_read_generic
, &spr_write_generic
,
5002 /* XXX : not implemented */
5003 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
5004 SPR_NOACCESS
, SPR_NOACCESS
,
5005 &spr_read_generic
, &spr_write_generic
,
5007 /* XXX : not implemented */
5008 spr_register(env
, SPR_Exxx_NPIDR
, "NPIDR",
5009 SPR_NOACCESS
, SPR_NOACCESS
,
5010 &spr_read_generic
, &spr_write_generic
,
5012 /* XXX : not implemented */
5013 spr_register(env
, SPR_Exxx_BUCSR
, "BUCSR",
5014 SPR_NOACCESS
, SPR_NOACCESS
,
5015 &spr_read_generic
, &spr_write_generic
,
5017 /* XXX : not implemented */
5018 spr_register(env
, SPR_Exxx_L1CFG0
, "L1CFG0",
5019 &spr_read_generic
, SPR_NOACCESS
,
5020 &spr_read_generic
, SPR_NOACCESS
,
5022 spr_register(env
, SPR_Exxx_L1CFG1
, "L1CFG1",
5023 &spr_read_generic
, SPR_NOACCESS
,
5024 &spr_read_generic
, SPR_NOACCESS
,
5026 spr_register(env
, SPR_Exxx_L1CSR0
, "L1CSR0",
5027 SPR_NOACCESS
, SPR_NOACCESS
,
5028 &spr_read_generic
, &spr_write_e500_l1csr0
,
5030 spr_register(env
, SPR_Exxx_L1CSR1
, "L1CSR1",
5031 SPR_NOACCESS
, SPR_NOACCESS
,
5032 &spr_read_generic
, &spr_write_e500_l1csr1
,
5034 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
5035 SPR_NOACCESS
, SPR_NOACCESS
,
5036 &spr_read_generic
, &spr_write_generic
,
5038 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
5039 SPR_NOACCESS
, SPR_NOACCESS
,
5040 &spr_read_generic
, &spr_write_generic
,
5042 spr_register(env
, SPR_MMUCSR0
, "MMUCSR0",
5043 SPR_NOACCESS
, SPR_NOACCESS
,
5044 &spr_read_generic
, &spr_write_booke206_mmucsr0
,
5046 spr_register(env
, SPR_BOOKE_EPR
, "EPR",
5047 SPR_NOACCESS
, SPR_NOACCESS
,
5048 &spr_read_generic
, SPR_NOACCESS
,
5050 /* XXX better abstract into Emb.xxx features */
5051 if (version
== fsl_e5500
) {
5052 spr_register(env
, SPR_BOOKE_EPCR
, "EPCR",
5053 SPR_NOACCESS
, SPR_NOACCESS
,
5054 &spr_read_generic
, &spr_write_generic
,
5056 spr_register(env
, SPR_BOOKE_MAS7_MAS3
, "MAS7_MAS3",
5057 SPR_NOACCESS
, SPR_NOACCESS
,
5058 &spr_read_mas73
, &spr_write_mas73
,
5060 ivpr_mask
= (target_ulong
)~0xFFFFULL
;
5063 #if !defined(CONFIG_USER_ONLY)
5065 env
->tlb_type
= TLB_MAS
;
5066 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
5067 env
->nb_tlb
+= booke206_tlb_size(env
, i
);
5071 init_excp_e200(env
, ivpr_mask
);
5072 /* Allocate hardware IRQ controller */
5073 ppce500_irq_init(ppc_env_get_cpu(env
));
5076 static void init_proc_e500v1(CPUPPCState
*env
)
5078 init_proc_e500(env
, fsl_e500v1
);
5081 POWERPC_FAMILY(e500v1
)(ObjectClass
*oc
, void *data
)
5083 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5084 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5086 dc
->desc
= "e500v1 core";
5087 pcc
->init_proc
= init_proc_e500v1
;
5088 pcc
->check_pow
= check_pow_hid0
;
5089 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
5090 PPC_SPE
| PPC_SPE_SINGLE
|
5091 PPC_WRTEE
| PPC_RFDI
|
5092 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5093 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5094 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5095 pcc
->insns_flags2
= PPC2_BOOKE206
;
5096 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
5110 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5111 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5112 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5113 pcc
->bfd_mach
= bfd_mach_ppc_860
;
5114 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
5115 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
5116 POWERPC_FLAG_BUS_CLK
;
5119 static void init_proc_e500v2(CPUPPCState
*env
)
5121 init_proc_e500(env
, fsl_e500v2
);
5124 POWERPC_FAMILY(e500v2
)(ObjectClass
*oc
, void *data
)
5126 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5127 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5129 dc
->desc
= "e500v2 core";
5130 pcc
->init_proc
= init_proc_e500v2
;
5131 pcc
->check_pow
= check_pow_hid0
;
5132 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
5133 PPC_SPE
| PPC_SPE_SINGLE
| PPC_SPE_DOUBLE
|
5134 PPC_WRTEE
| PPC_RFDI
|
5135 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5136 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5137 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5138 pcc
->insns_flags2
= PPC2_BOOKE206
;
5139 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
5153 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5154 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5155 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5156 pcc
->bfd_mach
= bfd_mach_ppc_860
;
5157 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
5158 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
5159 POWERPC_FLAG_BUS_CLK
;
5162 static void init_proc_e500mc(CPUPPCState
*env
)
5164 init_proc_e500(env
, fsl_e500mc
);
5167 POWERPC_FAMILY(e500mc
)(ObjectClass
*oc
, void *data
)
5169 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5170 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5172 dc
->desc
= "e500mc core";
5173 pcc
->init_proc
= init_proc_e500mc
;
5174 pcc
->check_pow
= check_pow_none
;
5175 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5176 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5177 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5178 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5179 PPC_FLOAT
| PPC_FLOAT_FRES
|
5180 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5181 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5182 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5183 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
;
5184 pcc
->msr_mask
= (1ull << MSR_GS
) |
5185 (1ull << MSR_UCLE
) |
5198 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5199 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5200 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5201 /* FIXME: figure out the correct flag for e500mc */
5202 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5203 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5204 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5208 static void init_proc_e5500(CPUPPCState
*env
)
5210 init_proc_e500(env
, fsl_e5500
);
5213 POWERPC_FAMILY(e5500
)(ObjectClass
*oc
, void *data
)
5215 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5216 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5218 dc
->desc
= "e5500 core";
5219 pcc
->init_proc
= init_proc_e5500
;
5220 pcc
->check_pow
= check_pow_none
;
5221 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5222 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5223 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5224 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5225 PPC_FLOAT
| PPC_FLOAT_FRES
|
5226 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5227 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5228 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
|
5229 PPC_64B
| PPC_POPCNTB
| PPC_POPCNTWD
;
5230 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
| PPC2_PERM_ISA206
| \
5232 pcc
->msr_mask
= (1ull << MSR_CM
) |
5234 (1ull << MSR_UCLE
) |
5247 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5248 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5249 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5250 /* FIXME: figure out the correct flag for e5500 */
5251 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5252 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5253 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5257 /* Non-embedded PowerPC */
5259 #define POWERPC_MSRR_601 (0x0000000000001040ULL)
5261 static void init_proc_601(CPUPPCState
*env
)
5263 gen_spr_ne_601(env
);
5266 /* Hardware implementation registers */
5267 /* XXX : not implemented */
5268 spr_register(env
, SPR_HID0
, "HID0",
5269 SPR_NOACCESS
, SPR_NOACCESS
,
5270 &spr_read_generic
, &spr_write_hid0_601
,
5272 /* XXX : not implemented */
5273 spr_register(env
, SPR_HID1
, "HID1",
5274 SPR_NOACCESS
, SPR_NOACCESS
,
5275 &spr_read_generic
, &spr_write_generic
,
5277 /* XXX : not implemented */
5278 spr_register(env
, SPR_601_HID2
, "HID2",
5279 SPR_NOACCESS
, SPR_NOACCESS
,
5280 &spr_read_generic
, &spr_write_generic
,
5282 /* XXX : not implemented */
5283 spr_register(env
, SPR_601_HID5
, "HID5",
5284 SPR_NOACCESS
, SPR_NOACCESS
,
5285 &spr_read_generic
, &spr_write_generic
,
5287 /* Memory management */
5289 /* XXX: beware that dcache line size is 64
5290 * but dcbz uses 32 bytes "sectors"
5291 * XXX: this breaks clcs instruction !
5293 env
->dcache_line_size
= 32;
5294 env
->icache_line_size
= 64;
5295 /* Allocate hardware IRQ controller */
5296 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5299 POWERPC_FAMILY(601)(ObjectClass
*oc
, void *data
)
5301 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5302 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5304 dc
->desc
= "PowerPC 601";
5305 pcc
->init_proc
= init_proc_601
;
5306 pcc
->check_pow
= check_pow_none
;
5307 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_POWER_BR
|
5309 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5310 PPC_MEM_SYNC
| PPC_MEM_EIEIO
| PPC_MEM_TLBIE
|
5311 PPC_SEGMENT
| PPC_EXTERN
;
5312 pcc
->msr_mask
= (1ull << MSR_EE
) |
5322 pcc
->mmu_model
= POWERPC_MMU_601
;
5323 #if defined(CONFIG_SOFTMMU)
5324 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5326 pcc
->excp_model
= POWERPC_EXCP_601
;
5327 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5328 pcc
->bfd_mach
= bfd_mach_ppc_601
;
5329 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_RTC_CLK
;
5332 #define POWERPC_MSRR_601v (0x0000000000001040ULL)
5334 static void init_proc_601v(CPUPPCState
*env
)
5337 /* XXX : not implemented */
5338 spr_register(env
, SPR_601_HID15
, "HID15",
5339 SPR_NOACCESS
, SPR_NOACCESS
,
5340 &spr_read_generic
, &spr_write_generic
,
5344 POWERPC_FAMILY(601v
)(ObjectClass
*oc
, void *data
)
5346 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5347 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5349 dc
->desc
= "PowerPC 601v";
5350 pcc
->init_proc
= init_proc_601v
;
5351 pcc
->check_pow
= check_pow_none
;
5352 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_POWER_BR
|
5354 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5355 PPC_MEM_SYNC
| PPC_MEM_EIEIO
| PPC_MEM_TLBIE
|
5356 PPC_SEGMENT
| PPC_EXTERN
;
5357 pcc
->msr_mask
= (1ull << MSR_EE
) |
5367 pcc
->mmu_model
= POWERPC_MMU_601
;
5368 #if defined(CONFIG_SOFTMMU)
5369 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5371 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5372 pcc
->bfd_mach
= bfd_mach_ppc_601
;
5373 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_RTC_CLK
;
5376 static void init_proc_602(CPUPPCState
*env
)
5378 gen_spr_ne_601(env
);
5383 /* hardware implementation registers */
5384 /* XXX : not implemented */
5385 spr_register(env
, SPR_HID0
, "HID0",
5386 SPR_NOACCESS
, SPR_NOACCESS
,
5387 &spr_read_generic
, &spr_write_generic
,
5389 /* XXX : not implemented */
5390 spr_register(env
, SPR_HID1
, "HID1",
5391 SPR_NOACCESS
, SPR_NOACCESS
,
5392 &spr_read_generic
, &spr_write_generic
,
5394 /* Memory management */
5396 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5398 env
->dcache_line_size
= 32;
5399 env
->icache_line_size
= 32;
5400 /* Allocate hardware IRQ controller */
5401 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5404 POWERPC_FAMILY(602)(ObjectClass
*oc
, void *data
)
5406 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5407 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5409 dc
->desc
= "PowerPC 602";
5410 pcc
->init_proc
= init_proc_602
;
5411 pcc
->check_pow
= check_pow_hid0
;
5412 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5413 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5414 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5415 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5416 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5417 PPC_MEM_TLBIE
| PPC_6xx_TLB
| PPC_MEM_TLBSYNC
|
5418 PPC_SEGMENT
| PPC_602_SPEC
;
5419 pcc
->msr_mask
= (1ull << MSR_VSX
) |
5422 (1ull << MSR_TGPR
) |
5437 /* XXX: 602 MMU is quite specific. Should add a special case */
5438 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5439 pcc
->excp_model
= POWERPC_EXCP_602
;
5440 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5441 pcc
->bfd_mach
= bfd_mach_ppc_602
;
5442 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5443 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5446 static void init_proc_603(CPUPPCState
*env
)
5448 gen_spr_ne_601(env
);
5453 /* hardware implementation registers */
5454 /* XXX : not implemented */
5455 spr_register(env
, SPR_HID0
, "HID0",
5456 SPR_NOACCESS
, SPR_NOACCESS
,
5457 &spr_read_generic
, &spr_write_generic
,
5459 /* XXX : not implemented */
5460 spr_register(env
, SPR_HID1
, "HID1",
5461 SPR_NOACCESS
, SPR_NOACCESS
,
5462 &spr_read_generic
, &spr_write_generic
,
5464 /* Memory management */
5466 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5468 env
->dcache_line_size
= 32;
5469 env
->icache_line_size
= 32;
5470 /* Allocate hardware IRQ controller */
5471 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5474 POWERPC_FAMILY(603)(ObjectClass
*oc
, void *data
)
5476 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5477 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5479 dc
->desc
= "PowerPC 603";
5480 pcc
->init_proc
= init_proc_603
;
5481 pcc
->check_pow
= check_pow_hid0
;
5482 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5483 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5484 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5485 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5486 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5487 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
5488 PPC_SEGMENT
| PPC_EXTERN
;
5489 pcc
->msr_mask
= (1ull << MSR_POW
) |
5490 (1ull << MSR_TGPR
) |
5505 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5506 pcc
->excp_model
= POWERPC_EXCP_603
;
5507 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5508 pcc
->bfd_mach
= bfd_mach_ppc_603
;
5509 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5510 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5513 static void init_proc_603E(CPUPPCState
*env
)
5515 gen_spr_ne_601(env
);
5520 /* hardware implementation registers */
5521 /* XXX : not implemented */
5522 spr_register(env
, SPR_HID0
, "HID0",
5523 SPR_NOACCESS
, SPR_NOACCESS
,
5524 &spr_read_generic
, &spr_write_generic
,
5526 /* XXX : not implemented */
5527 spr_register(env
, SPR_HID1
, "HID1",
5528 SPR_NOACCESS
, SPR_NOACCESS
,
5529 &spr_read_generic
, &spr_write_generic
,
5531 /* Memory management */
5533 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5535 env
->dcache_line_size
= 32;
5536 env
->icache_line_size
= 32;
5537 /* Allocate hardware IRQ controller */
5538 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5541 POWERPC_FAMILY(603E
)(ObjectClass
*oc
, void *data
)
5543 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5544 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5546 dc
->desc
= "PowerPC 603e";
5547 pcc
->init_proc
= init_proc_603E
;
5548 pcc
->check_pow
= check_pow_hid0
;
5549 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5550 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5551 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5552 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5553 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5554 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
5555 PPC_SEGMENT
| PPC_EXTERN
;
5556 pcc
->msr_mask
= (1ull << MSR_POW
) |
5557 (1ull << MSR_TGPR
) |
5572 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5573 pcc
->excp_model
= POWERPC_EXCP_603E
;
5574 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5575 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
5576 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5577 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5580 static void init_proc_604(CPUPPCState
*env
)
5582 gen_spr_ne_601(env
);
5587 /* Hardware implementation registers */
5588 /* XXX : not implemented */
5589 spr_register(env
, SPR_HID0
, "HID0",
5590 SPR_NOACCESS
, SPR_NOACCESS
,
5591 &spr_read_generic
, &spr_write_generic
,
5593 /* Memory management */
5596 env
->dcache_line_size
= 32;
5597 env
->icache_line_size
= 32;
5598 /* Allocate hardware IRQ controller */
5599 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5602 POWERPC_FAMILY(604)(ObjectClass
*oc
, void *data
)
5604 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5605 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5607 dc
->desc
= "PowerPC 604";
5608 pcc
->init_proc
= init_proc_604
;
5609 pcc
->check_pow
= check_pow_nocheck
;
5610 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5611 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5612 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5613 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5614 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5615 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5616 PPC_SEGMENT
| PPC_EXTERN
;
5617 pcc
->msr_mask
= (1ull << MSR_POW
) |
5633 pcc
->mmu_model
= POWERPC_MMU_32B
;
5634 #if defined(CONFIG_SOFTMMU)
5635 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5637 pcc
->excp_model
= POWERPC_EXCP_604
;
5638 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5639 pcc
->bfd_mach
= bfd_mach_ppc_604
;
5640 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5641 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5644 static void init_proc_604E(CPUPPCState
*env
)
5646 gen_spr_ne_601(env
);
5649 /* XXX : not implemented */
5650 spr_register(env
, SPR_7XX_MMCR1
, "MMCR1",
5651 SPR_NOACCESS
, SPR_NOACCESS
,
5652 &spr_read_generic
, &spr_write_generic
,
5654 /* XXX : not implemented */
5655 spr_register(env
, SPR_7XX_PMC3
, "PMC3",
5656 SPR_NOACCESS
, SPR_NOACCESS
,
5657 &spr_read_generic
, &spr_write_generic
,
5659 /* XXX : not implemented */
5660 spr_register(env
, SPR_7XX_PMC4
, "PMC4",
5661 SPR_NOACCESS
, SPR_NOACCESS
,
5662 &spr_read_generic
, &spr_write_generic
,
5666 /* Hardware implementation registers */
5667 /* XXX : not implemented */
5668 spr_register(env
, SPR_HID0
, "HID0",
5669 SPR_NOACCESS
, SPR_NOACCESS
,
5670 &spr_read_generic
, &spr_write_generic
,
5672 /* XXX : not implemented */
5673 spr_register(env
, SPR_HID1
, "HID1",
5674 SPR_NOACCESS
, SPR_NOACCESS
,
5675 &spr_read_generic
, &spr_write_generic
,
5677 /* Memory management */
5680 env
->dcache_line_size
= 32;
5681 env
->icache_line_size
= 32;
5682 /* Allocate hardware IRQ controller */
5683 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5686 POWERPC_FAMILY(604E
)(ObjectClass
*oc
, void *data
)
5688 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5689 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5691 dc
->desc
= "PowerPC 604E";
5692 pcc
->init_proc
= init_proc_604E
;
5693 pcc
->check_pow
= check_pow_nocheck
;
5694 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5695 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5696 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5697 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5698 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5699 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5700 PPC_SEGMENT
| PPC_EXTERN
;
5701 pcc
->msr_mask
= (1ull << MSR_POW
) |
5717 pcc
->mmu_model
= POWERPC_MMU_32B
;
5718 #if defined(CONFIG_SOFTMMU)
5719 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5721 pcc
->excp_model
= POWERPC_EXCP_604
;
5722 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5723 pcc
->bfd_mach
= bfd_mach_ppc_604
;
5724 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5725 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5728 static void init_proc_740(CPUPPCState
*env
)
5730 gen_spr_ne_601(env
);
5735 /* Thermal management */
5737 /* Hardware implementation registers */
5738 /* XXX : not implemented */
5739 spr_register(env
, SPR_HID0
, "HID0",
5740 SPR_NOACCESS
, SPR_NOACCESS
,
5741 &spr_read_generic
, &spr_write_generic
,
5743 /* XXX : not implemented */
5744 spr_register(env
, SPR_HID1
, "HID1",
5745 SPR_NOACCESS
, SPR_NOACCESS
,
5746 &spr_read_generic
, &spr_write_generic
,
5748 /* Memory management */
5751 env
->dcache_line_size
= 32;
5752 env
->icache_line_size
= 32;
5753 /* Allocate hardware IRQ controller */
5754 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5757 POWERPC_FAMILY(740)(ObjectClass
*oc
, void *data
)
5759 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5760 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5762 dc
->desc
= "PowerPC 740";
5763 pcc
->init_proc
= init_proc_740
;
5764 pcc
->check_pow
= check_pow_hid0
;
5765 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5766 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5767 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5768 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5769 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5770 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5771 PPC_SEGMENT
| PPC_EXTERN
;
5772 pcc
->msr_mask
= (1ull << MSR_POW
) |
5788 pcc
->mmu_model
= POWERPC_MMU_32B
;
5789 #if defined(CONFIG_SOFTMMU)
5790 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5792 pcc
->excp_model
= POWERPC_EXCP_7x0
;
5793 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5794 pcc
->bfd_mach
= bfd_mach_ppc_750
;
5795 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5796 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5799 static void init_proc_750(CPUPPCState
*env
)
5801 gen_spr_ne_601(env
);
5804 /* XXX : not implemented */
5805 spr_register(env
, SPR_L2CR
, "L2CR",
5806 SPR_NOACCESS
, SPR_NOACCESS
,
5807 &spr_read_generic
, spr_access_nop
,
5811 /* Thermal management */
5813 /* Hardware implementation registers */
5814 /* XXX : not implemented */
5815 spr_register(env
, SPR_HID0
, "HID0",
5816 SPR_NOACCESS
, SPR_NOACCESS
,
5817 &spr_read_generic
, &spr_write_generic
,
5819 /* XXX : not implemented */
5820 spr_register(env
, SPR_HID1
, "HID1",
5821 SPR_NOACCESS
, SPR_NOACCESS
,
5822 &spr_read_generic
, &spr_write_generic
,
5824 /* Memory management */
5826 /* XXX: high BATs are also present but are known to be bugged on
5830 env
->dcache_line_size
= 32;
5831 env
->icache_line_size
= 32;
5832 /* Allocate hardware IRQ controller */
5833 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5836 POWERPC_FAMILY(750)(ObjectClass
*oc
, void *data
)
5838 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5839 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5841 dc
->desc
= "PowerPC 750";
5842 pcc
->init_proc
= init_proc_750
;
5843 pcc
->check_pow
= check_pow_hid0
;
5844 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5845 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5846 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5847 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5848 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5849 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5850 PPC_SEGMENT
| PPC_EXTERN
;
5851 pcc
->msr_mask
= (1ull << MSR_POW
) |
5867 pcc
->mmu_model
= POWERPC_MMU_32B
;
5868 #if defined(CONFIG_SOFTMMU)
5869 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5871 pcc
->excp_model
= POWERPC_EXCP_7x0
;
5872 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5873 pcc
->bfd_mach
= bfd_mach_ppc_750
;
5874 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5875 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5878 static void init_proc_750cl(CPUPPCState
*env
)
5880 gen_spr_ne_601(env
);
5883 /* XXX : not implemented */
5884 spr_register(env
, SPR_L2CR
, "L2CR",
5885 SPR_NOACCESS
, SPR_NOACCESS
,
5886 &spr_read_generic
, spr_access_nop
,
5890 /* Thermal management */
5891 /* Those registers are fake on 750CL */
5892 spr_register(env
, SPR_THRM1
, "THRM1",
5893 SPR_NOACCESS
, SPR_NOACCESS
,
5894 &spr_read_generic
, &spr_write_generic
,
5896 spr_register(env
, SPR_THRM2
, "THRM2",
5897 SPR_NOACCESS
, SPR_NOACCESS
,
5898 &spr_read_generic
, &spr_write_generic
,
5900 spr_register(env
, SPR_THRM3
, "THRM3",
5901 SPR_NOACCESS
, SPR_NOACCESS
,
5902 &spr_read_generic
, &spr_write_generic
,
5904 /* XXX: not implemented */
5905 spr_register(env
, SPR_750_TDCL
, "TDCL",
5906 SPR_NOACCESS
, SPR_NOACCESS
,
5907 &spr_read_generic
, &spr_write_generic
,
5909 spr_register(env
, SPR_750_TDCH
, "TDCH",
5910 SPR_NOACCESS
, SPR_NOACCESS
,
5911 &spr_read_generic
, &spr_write_generic
,
5914 /* XXX : not implemented */
5915 spr_register(env
, SPR_750_WPAR
, "WPAR",
5916 SPR_NOACCESS
, SPR_NOACCESS
,
5917 &spr_read_generic
, &spr_write_generic
,
5919 spr_register(env
, SPR_750_DMAL
, "DMAL",
5920 SPR_NOACCESS
, SPR_NOACCESS
,
5921 &spr_read_generic
, &spr_write_generic
,
5923 spr_register(env
, SPR_750_DMAU
, "DMAU",
5924 SPR_NOACCESS
, SPR_NOACCESS
,
5925 &spr_read_generic
, &spr_write_generic
,
5927 /* Hardware implementation registers */
5928 /* XXX : not implemented */
5929 spr_register(env
, SPR_HID0
, "HID0",
5930 SPR_NOACCESS
, SPR_NOACCESS
,
5931 &spr_read_generic
, &spr_write_generic
,
5933 /* XXX : not implemented */
5934 spr_register(env
, SPR_HID1
, "HID1",
5935 SPR_NOACCESS
, SPR_NOACCESS
,
5936 &spr_read_generic
, &spr_write_generic
,
5938 /* XXX : not implemented */
5939 spr_register(env
, SPR_750CL_HID2
, "HID2",
5940 SPR_NOACCESS
, SPR_NOACCESS
,
5941 &spr_read_generic
, &spr_write_generic
,
5943 /* XXX : not implemented */
5944 spr_register(env
, SPR_750CL_HID4
, "HID4",
5945 SPR_NOACCESS
, SPR_NOACCESS
,
5946 &spr_read_generic
, &spr_write_generic
,
5948 /* Quantization registers */
5949 /* XXX : not implemented */
5950 spr_register(env
, SPR_750_GQR0
, "GQR0",
5951 SPR_NOACCESS
, SPR_NOACCESS
,
5952 &spr_read_generic
, &spr_write_generic
,
5954 /* XXX : not implemented */
5955 spr_register(env
, SPR_750_GQR1
, "GQR1",
5956 SPR_NOACCESS
, SPR_NOACCESS
,
5957 &spr_read_generic
, &spr_write_generic
,
5959 /* XXX : not implemented */
5960 spr_register(env
, SPR_750_GQR2
, "GQR2",
5961 SPR_NOACCESS
, SPR_NOACCESS
,
5962 &spr_read_generic
, &spr_write_generic
,
5964 /* XXX : not implemented */
5965 spr_register(env
, SPR_750_GQR3
, "GQR3",
5966 SPR_NOACCESS
, SPR_NOACCESS
,
5967 &spr_read_generic
, &spr_write_generic
,
5969 /* XXX : not implemented */
5970 spr_register(env
, SPR_750_GQR4
, "GQR4",
5971 SPR_NOACCESS
, SPR_NOACCESS
,
5972 &spr_read_generic
, &spr_write_generic
,
5974 /* XXX : not implemented */
5975 spr_register(env
, SPR_750_GQR5
, "GQR5",
5976 SPR_NOACCESS
, SPR_NOACCESS
,
5977 &spr_read_generic
, &spr_write_generic
,
5979 /* XXX : not implemented */
5980 spr_register(env
, SPR_750_GQR6
, "GQR6",
5981 SPR_NOACCESS
, SPR_NOACCESS
,
5982 &spr_read_generic
, &spr_write_generic
,
5984 /* XXX : not implemented */
5985 spr_register(env
, SPR_750_GQR7
, "GQR7",
5986 SPR_NOACCESS
, SPR_NOACCESS
,
5987 &spr_read_generic
, &spr_write_generic
,
5989 /* Memory management */
5991 /* PowerPC 750cl has 8 DBATs and 8 IBATs */
5993 init_excp_750cl(env
);
5994 env
->dcache_line_size
= 32;
5995 env
->icache_line_size
= 32;
5996 /* Allocate hardware IRQ controller */
5997 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6000 POWERPC_FAMILY(750cl
)(ObjectClass
*oc
, void *data
)
6002 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6003 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6005 dc
->desc
= "PowerPC 750 CL";
6006 pcc
->init_proc
= init_proc_750cl
;
6007 pcc
->check_pow
= check_pow_hid0
;
6008 /* XXX: not implemented:
6009 * cache lock instructions:
6011 * floating point paired instructions
6046 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6047 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6048 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6049 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6050 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6051 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6052 PPC_SEGMENT
| PPC_EXTERN
;
6053 pcc
->msr_mask
= (1ull << MSR_POW
) |
6069 pcc
->mmu_model
= POWERPC_MMU_32B
;
6070 #if defined(CONFIG_SOFTMMU)
6071 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6073 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6074 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6075 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6076 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6077 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6080 static void init_proc_750cx(CPUPPCState
*env
)
6082 gen_spr_ne_601(env
);
6085 /* XXX : not implemented */
6086 spr_register(env
, SPR_L2CR
, "L2CR",
6087 SPR_NOACCESS
, SPR_NOACCESS
,
6088 &spr_read_generic
, spr_access_nop
,
6092 /* Thermal management */
6094 /* This register is not implemented but is present for compatibility */
6095 spr_register(env
, SPR_SDA
, "SDA",
6096 SPR_NOACCESS
, SPR_NOACCESS
,
6097 &spr_read_generic
, &spr_write_generic
,
6099 /* Hardware implementation registers */
6100 /* XXX : not implemented */
6101 spr_register(env
, SPR_HID0
, "HID0",
6102 SPR_NOACCESS
, SPR_NOACCESS
,
6103 &spr_read_generic
, &spr_write_generic
,
6105 /* XXX : not implemented */
6106 spr_register(env
, SPR_HID1
, "HID1",
6107 SPR_NOACCESS
, SPR_NOACCESS
,
6108 &spr_read_generic
, &spr_write_generic
,
6110 /* Memory management */
6112 /* PowerPC 750cx has 8 DBATs and 8 IBATs */
6114 init_excp_750cx(env
);
6115 env
->dcache_line_size
= 32;
6116 env
->icache_line_size
= 32;
6117 /* Allocate hardware IRQ controller */
6118 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6121 POWERPC_FAMILY(750cx
)(ObjectClass
*oc
, void *data
)
6123 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6124 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6126 dc
->desc
= "PowerPC 750CX";
6127 pcc
->init_proc
= init_proc_750cx
;
6128 pcc
->check_pow
= check_pow_hid0
;
6129 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6130 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6131 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6132 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6133 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6134 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6135 PPC_SEGMENT
| PPC_EXTERN
;
6136 pcc
->msr_mask
= (1ull << MSR_POW
) |
6152 pcc
->mmu_model
= POWERPC_MMU_32B
;
6153 #if defined(CONFIG_SOFTMMU)
6154 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6156 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6157 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6158 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6159 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6160 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6163 static void init_proc_750fx(CPUPPCState
*env
)
6165 gen_spr_ne_601(env
);
6168 /* XXX : not implemented */
6169 spr_register(env
, SPR_L2CR
, "L2CR",
6170 SPR_NOACCESS
, SPR_NOACCESS
,
6171 &spr_read_generic
, spr_access_nop
,
6175 /* Thermal management */
6177 /* XXX : not implemented */
6178 spr_register(env
, SPR_750_THRM4
, "THRM4",
6179 SPR_NOACCESS
, SPR_NOACCESS
,
6180 &spr_read_generic
, &spr_write_generic
,
6182 /* Hardware implementation registers */
6183 /* XXX : not implemented */
6184 spr_register(env
, SPR_HID0
, "HID0",
6185 SPR_NOACCESS
, SPR_NOACCESS
,
6186 &spr_read_generic
, &spr_write_generic
,
6188 /* XXX : not implemented */
6189 spr_register(env
, SPR_HID1
, "HID1",
6190 SPR_NOACCESS
, SPR_NOACCESS
,
6191 &spr_read_generic
, &spr_write_generic
,
6193 /* XXX : not implemented */
6194 spr_register(env
, SPR_750FX_HID2
, "HID2",
6195 SPR_NOACCESS
, SPR_NOACCESS
,
6196 &spr_read_generic
, &spr_write_generic
,
6198 /* Memory management */
6200 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6203 env
->dcache_line_size
= 32;
6204 env
->icache_line_size
= 32;
6205 /* Allocate hardware IRQ controller */
6206 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6209 POWERPC_FAMILY(750fx
)(ObjectClass
*oc
, void *data
)
6211 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6212 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6214 dc
->desc
= "PowerPC 750FX";
6215 pcc
->init_proc
= init_proc_750fx
;
6216 pcc
->check_pow
= check_pow_hid0
;
6217 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6218 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6219 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6220 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6221 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6222 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6223 PPC_SEGMENT
| PPC_EXTERN
;
6224 pcc
->msr_mask
= (1ull << MSR_POW
) |
6240 pcc
->mmu_model
= POWERPC_MMU_32B
;
6241 #if defined(CONFIG_SOFTMMU)
6242 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6244 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6245 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6246 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6247 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6248 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6251 static void init_proc_750gx(CPUPPCState
*env
)
6253 gen_spr_ne_601(env
);
6256 /* XXX : not implemented (XXX: different from 750fx) */
6257 spr_register(env
, SPR_L2CR
, "L2CR",
6258 SPR_NOACCESS
, SPR_NOACCESS
,
6259 &spr_read_generic
, spr_access_nop
,
6263 /* Thermal management */
6265 /* XXX : not implemented */
6266 spr_register(env
, SPR_750_THRM4
, "THRM4",
6267 SPR_NOACCESS
, SPR_NOACCESS
,
6268 &spr_read_generic
, &spr_write_generic
,
6270 /* Hardware implementation registers */
6271 /* XXX : not implemented (XXX: different from 750fx) */
6272 spr_register(env
, SPR_HID0
, "HID0",
6273 SPR_NOACCESS
, SPR_NOACCESS
,
6274 &spr_read_generic
, &spr_write_generic
,
6276 /* XXX : not implemented */
6277 spr_register(env
, SPR_HID1
, "HID1",
6278 SPR_NOACCESS
, SPR_NOACCESS
,
6279 &spr_read_generic
, &spr_write_generic
,
6281 /* XXX : not implemented (XXX: different from 750fx) */
6282 spr_register(env
, SPR_750FX_HID2
, "HID2",
6283 SPR_NOACCESS
, SPR_NOACCESS
,
6284 &spr_read_generic
, &spr_write_generic
,
6286 /* Memory management */
6288 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6291 env
->dcache_line_size
= 32;
6292 env
->icache_line_size
= 32;
6293 /* Allocate hardware IRQ controller */
6294 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6297 POWERPC_FAMILY(750gx
)(ObjectClass
*oc
, void *data
)
6299 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6300 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6302 dc
->desc
= "PowerPC 750GX";
6303 pcc
->init_proc
= init_proc_750gx
;
6304 pcc
->check_pow
= check_pow_hid0
;
6305 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6306 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6307 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6308 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6309 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6310 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6311 PPC_SEGMENT
| PPC_EXTERN
;
6312 pcc
->msr_mask
= (1ull << MSR_POW
) |
6328 pcc
->mmu_model
= POWERPC_MMU_32B
;
6329 #if defined(CONFIG_SOFTMMU)
6330 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6332 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6333 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6334 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6335 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6336 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6339 static void init_proc_745(CPUPPCState
*env
)
6341 gen_spr_ne_601(env
);
6344 gen_spr_G2_755(env
);
6347 /* Thermal management */
6349 /* Hardware implementation registers */
6350 /* XXX : not implemented */
6351 spr_register(env
, SPR_HID0
, "HID0",
6352 SPR_NOACCESS
, SPR_NOACCESS
,
6353 &spr_read_generic
, &spr_write_generic
,
6355 /* XXX : not implemented */
6356 spr_register(env
, SPR_HID1
, "HID1",
6357 SPR_NOACCESS
, SPR_NOACCESS
,
6358 &spr_read_generic
, &spr_write_generic
,
6360 /* XXX : not implemented */
6361 spr_register(env
, SPR_HID2
, "HID2",
6362 SPR_NOACCESS
, SPR_NOACCESS
,
6363 &spr_read_generic
, &spr_write_generic
,
6365 /* Memory management */
6368 gen_6xx_7xx_soft_tlb(env
, 64, 2);
6370 env
->dcache_line_size
= 32;
6371 env
->icache_line_size
= 32;
6372 /* Allocate hardware IRQ controller */
6373 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6376 POWERPC_FAMILY(745)(ObjectClass
*oc
, void *data
)
6378 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6379 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6381 dc
->desc
= "PowerPC 745";
6382 pcc
->init_proc
= init_proc_745
;
6383 pcc
->check_pow
= check_pow_hid0
;
6384 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6385 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6386 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6387 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6388 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6389 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
6390 PPC_SEGMENT
| PPC_EXTERN
;
6391 pcc
->msr_mask
= (1ull << MSR_POW
) |
6407 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
6408 pcc
->excp_model
= POWERPC_EXCP_7x5
;
6409 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6410 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6411 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6412 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6415 static void init_proc_755(CPUPPCState
*env
)
6417 gen_spr_ne_601(env
);
6420 gen_spr_G2_755(env
);
6423 /* L2 cache control */
6424 /* XXX : not implemented */
6425 spr_register(env
, SPR_L2CR
, "L2CR",
6426 SPR_NOACCESS
, SPR_NOACCESS
,
6427 &spr_read_generic
, spr_access_nop
,
6429 /* XXX : not implemented */
6430 spr_register(env
, SPR_L2PMCR
, "L2PMCR",
6431 SPR_NOACCESS
, SPR_NOACCESS
,
6432 &spr_read_generic
, &spr_write_generic
,
6434 /* Thermal management */
6436 /* Hardware implementation registers */
6437 /* XXX : not implemented */
6438 spr_register(env
, SPR_HID0
, "HID0",
6439 SPR_NOACCESS
, SPR_NOACCESS
,
6440 &spr_read_generic
, &spr_write_generic
,
6442 /* XXX : not implemented */
6443 spr_register(env
, SPR_HID1
, "HID1",
6444 SPR_NOACCESS
, SPR_NOACCESS
,
6445 &spr_read_generic
, &spr_write_generic
,
6447 /* XXX : not implemented */
6448 spr_register(env
, SPR_HID2
, "HID2",
6449 SPR_NOACCESS
, SPR_NOACCESS
,
6450 &spr_read_generic
, &spr_write_generic
,
6452 /* Memory management */
6455 gen_6xx_7xx_soft_tlb(env
, 64, 2);
6457 env
->dcache_line_size
= 32;
6458 env
->icache_line_size
= 32;
6459 /* Allocate hardware IRQ controller */
6460 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6463 POWERPC_FAMILY(755)(ObjectClass
*oc
, void *data
)
6465 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6466 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6468 dc
->desc
= "PowerPC 755";
6469 pcc
->init_proc
= init_proc_755
;
6470 pcc
->check_pow
= check_pow_hid0
;
6471 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6472 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6473 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6474 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6475 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6476 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
6477 PPC_SEGMENT
| PPC_EXTERN
;
6478 pcc
->msr_mask
= (1ull << MSR_POW
) |
6494 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
6495 pcc
->excp_model
= POWERPC_EXCP_7x5
;
6496 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6497 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6498 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6499 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6502 static void init_proc_7400(CPUPPCState
*env
)
6504 gen_spr_ne_601(env
);
6509 /* 74xx specific SPR */
6511 /* XXX : not implemented */
6512 spr_register(env
, SPR_UBAMR
, "UBAMR",
6513 &spr_read_ureg
, SPR_NOACCESS
,
6514 &spr_read_ureg
, SPR_NOACCESS
,
6516 /* XXX: this seems not implemented on all revisions. */
6517 /* XXX : not implemented */
6518 spr_register(env
, SPR_MSSCR1
, "MSSCR1",
6519 SPR_NOACCESS
, SPR_NOACCESS
,
6520 &spr_read_generic
, &spr_write_generic
,
6522 /* Thermal management */
6524 /* Memory management */
6526 init_excp_7400(env
);
6527 env
->dcache_line_size
= 32;
6528 env
->icache_line_size
= 32;
6529 /* Allocate hardware IRQ controller */
6530 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6533 POWERPC_FAMILY(7400)(ObjectClass
*oc
, void *data
)
6535 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6536 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6538 dc
->desc
= "PowerPC 7400 (aka G4)";
6539 pcc
->init_proc
= init_proc_7400
;
6540 pcc
->check_pow
= check_pow_hid0
;
6541 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6542 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6543 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6545 PPC_CACHE
| PPC_CACHE_ICBI
|
6546 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6547 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6548 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6550 PPC_SEGMENT
| PPC_EXTERN
|
6552 pcc
->msr_mask
= (1ull << MSR_VR
) |
6569 pcc
->mmu_model
= POWERPC_MMU_32B
;
6570 #if defined(CONFIG_SOFTMMU)
6571 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6573 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6574 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6575 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6576 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6577 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6578 POWERPC_FLAG_BUS_CLK
;
6581 static void init_proc_7410(CPUPPCState
*env
)
6583 gen_spr_ne_601(env
);
6588 /* 74xx specific SPR */
6590 /* XXX : not implemented */
6591 spr_register(env
, SPR_UBAMR
, "UBAMR",
6592 &spr_read_ureg
, SPR_NOACCESS
,
6593 &spr_read_ureg
, SPR_NOACCESS
,
6595 /* Thermal management */
6598 /* XXX : not implemented */
6599 spr_register(env
, SPR_L2PMCR
, "L2PMCR",
6600 SPR_NOACCESS
, SPR_NOACCESS
,
6601 &spr_read_generic
, &spr_write_generic
,
6604 /* XXX : not implemented */
6605 spr_register(env
, SPR_LDSTDB
, "LDSTDB",
6606 SPR_NOACCESS
, SPR_NOACCESS
,
6607 &spr_read_generic
, &spr_write_generic
,
6609 /* Memory management */
6611 init_excp_7400(env
);
6612 env
->dcache_line_size
= 32;
6613 env
->icache_line_size
= 32;
6614 /* Allocate hardware IRQ controller */
6615 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6618 POWERPC_FAMILY(7410)(ObjectClass
*oc
, void *data
)
6620 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6621 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6623 dc
->desc
= "PowerPC 7410 (aka G4)";
6624 pcc
->init_proc
= init_proc_7410
;
6625 pcc
->check_pow
= check_pow_hid0
;
6626 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6627 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6628 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6630 PPC_CACHE
| PPC_CACHE_ICBI
|
6631 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6632 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6633 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6635 PPC_SEGMENT
| PPC_EXTERN
|
6637 pcc
->msr_mask
= (1ull << MSR_VR
) |
6654 pcc
->mmu_model
= POWERPC_MMU_32B
;
6655 #if defined(CONFIG_SOFTMMU)
6656 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6658 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6659 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6660 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6661 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6662 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6663 POWERPC_FLAG_BUS_CLK
;
6666 static void init_proc_7440(CPUPPCState
*env
)
6668 gen_spr_ne_601(env
);
6673 /* 74xx specific SPR */
6675 /* XXX : not implemented */
6676 spr_register(env
, SPR_UBAMR
, "UBAMR",
6677 &spr_read_ureg
, SPR_NOACCESS
,
6678 &spr_read_ureg
, SPR_NOACCESS
,
6681 /* XXX : not implemented */
6682 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6683 SPR_NOACCESS
, SPR_NOACCESS
,
6684 &spr_read_generic
, &spr_write_generic
,
6687 /* XXX : not implemented */
6688 spr_register(env
, SPR_ICTRL
, "ICTRL",
6689 SPR_NOACCESS
, SPR_NOACCESS
,
6690 &spr_read_generic
, &spr_write_generic
,
6693 /* XXX : not implemented */
6694 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6695 SPR_NOACCESS
, SPR_NOACCESS
,
6696 &spr_read_generic
, &spr_write_generic
,
6699 /* XXX : not implemented */
6700 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6701 SPR_NOACCESS
, SPR_NOACCESS
,
6702 &spr_read_generic
, &spr_write_generic
,
6704 /* XXX : not implemented */
6705 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6706 &spr_read_ureg
, SPR_NOACCESS
,
6707 &spr_read_ureg
, SPR_NOACCESS
,
6709 /* XXX : not implemented */
6710 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6711 SPR_NOACCESS
, SPR_NOACCESS
,
6712 &spr_read_generic
, &spr_write_generic
,
6714 /* XXX : not implemented */
6715 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6716 &spr_read_ureg
, SPR_NOACCESS
,
6717 &spr_read_ureg
, SPR_NOACCESS
,
6719 /* Memory management */
6721 gen_74xx_soft_tlb(env
, 128, 2);
6722 init_excp_7450(env
);
6723 env
->dcache_line_size
= 32;
6724 env
->icache_line_size
= 32;
6725 /* Allocate hardware IRQ controller */
6726 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6729 POWERPC_FAMILY(7440)(ObjectClass
*oc
, void *data
)
6731 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6732 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6734 dc
->desc
= "PowerPC 7440 (aka G4)";
6735 pcc
->init_proc
= init_proc_7440
;
6736 pcc
->check_pow
= check_pow_hid0_74xx
;
6737 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6738 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6739 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6741 PPC_CACHE
| PPC_CACHE_ICBI
|
6742 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6743 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6744 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6745 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6746 PPC_SEGMENT
| PPC_EXTERN
|
6748 pcc
->msr_mask
= (1ull << MSR_VR
) |
6765 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6766 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6767 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6768 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6769 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6770 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6771 POWERPC_FLAG_BUS_CLK
;
6774 static void init_proc_7450(CPUPPCState
*env
)
6776 gen_spr_ne_601(env
);
6781 /* 74xx specific SPR */
6783 /* Level 3 cache control */
6786 /* XXX : not implemented */
6787 spr_register(env
, SPR_L3ITCR1
, "L3ITCR1",
6788 SPR_NOACCESS
, SPR_NOACCESS
,
6789 &spr_read_generic
, &spr_write_generic
,
6792 /* XXX : not implemented */
6793 spr_register(env
, SPR_L3ITCR2
, "L3ITCR2",
6794 SPR_NOACCESS
, SPR_NOACCESS
,
6795 &spr_read_generic
, &spr_write_generic
,
6798 /* XXX : not implemented */
6799 spr_register(env
, SPR_L3ITCR3
, "L3ITCR3",
6800 SPR_NOACCESS
, SPR_NOACCESS
,
6801 &spr_read_generic
, &spr_write_generic
,
6804 /* XXX : not implemented */
6805 spr_register(env
, SPR_L3OHCR
, "L3OHCR",
6806 SPR_NOACCESS
, SPR_NOACCESS
,
6807 &spr_read_generic
, &spr_write_generic
,
6809 /* XXX : not implemented */
6810 spr_register(env
, SPR_UBAMR
, "UBAMR",
6811 &spr_read_ureg
, SPR_NOACCESS
,
6812 &spr_read_ureg
, SPR_NOACCESS
,
6815 /* XXX : not implemented */
6816 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6817 SPR_NOACCESS
, SPR_NOACCESS
,
6818 &spr_read_generic
, &spr_write_generic
,
6821 /* XXX : not implemented */
6822 spr_register(env
, SPR_ICTRL
, "ICTRL",
6823 SPR_NOACCESS
, SPR_NOACCESS
,
6824 &spr_read_generic
, &spr_write_generic
,
6827 /* XXX : not implemented */
6828 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6829 SPR_NOACCESS
, SPR_NOACCESS
,
6830 &spr_read_generic
, &spr_write_generic
,
6833 /* XXX : not implemented */
6834 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6835 SPR_NOACCESS
, SPR_NOACCESS
,
6836 &spr_read_generic
, &spr_write_generic
,
6838 /* XXX : not implemented */
6839 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6840 &spr_read_ureg
, SPR_NOACCESS
,
6841 &spr_read_ureg
, SPR_NOACCESS
,
6843 /* XXX : not implemented */
6844 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6845 SPR_NOACCESS
, SPR_NOACCESS
,
6846 &spr_read_generic
, &spr_write_generic
,
6848 /* XXX : not implemented */
6849 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6850 &spr_read_ureg
, SPR_NOACCESS
,
6851 &spr_read_ureg
, SPR_NOACCESS
,
6853 /* Memory management */
6855 gen_74xx_soft_tlb(env
, 128, 2);
6856 init_excp_7450(env
);
6857 env
->dcache_line_size
= 32;
6858 env
->icache_line_size
= 32;
6859 /* Allocate hardware IRQ controller */
6860 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6863 POWERPC_FAMILY(7450)(ObjectClass
*oc
, void *data
)
6865 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6866 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6868 dc
->desc
= "PowerPC 7450 (aka G4)";
6869 pcc
->init_proc
= init_proc_7450
;
6870 pcc
->check_pow
= check_pow_hid0_74xx
;
6871 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6872 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6873 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6875 PPC_CACHE
| PPC_CACHE_ICBI
|
6876 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6877 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6878 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6879 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6880 PPC_SEGMENT
| PPC_EXTERN
|
6882 pcc
->msr_mask
= (1ull << MSR_VR
) |
6899 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6900 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6901 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6902 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6903 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6904 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6905 POWERPC_FLAG_BUS_CLK
;
6908 static void init_proc_7445(CPUPPCState
*env
)
6910 gen_spr_ne_601(env
);
6915 /* 74xx specific SPR */
6918 /* XXX : not implemented */
6919 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6920 SPR_NOACCESS
, SPR_NOACCESS
,
6921 &spr_read_generic
, &spr_write_generic
,
6924 /* XXX : not implemented */
6925 spr_register(env
, SPR_ICTRL
, "ICTRL",
6926 SPR_NOACCESS
, SPR_NOACCESS
,
6927 &spr_read_generic
, &spr_write_generic
,
6930 /* XXX : not implemented */
6931 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6932 SPR_NOACCESS
, SPR_NOACCESS
,
6933 &spr_read_generic
, &spr_write_generic
,
6936 /* XXX : not implemented */
6937 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6938 SPR_NOACCESS
, SPR_NOACCESS
,
6939 &spr_read_generic
, &spr_write_generic
,
6941 /* XXX : not implemented */
6942 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6943 &spr_read_ureg
, SPR_NOACCESS
,
6944 &spr_read_ureg
, SPR_NOACCESS
,
6946 /* XXX : not implemented */
6947 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6948 SPR_NOACCESS
, SPR_NOACCESS
,
6949 &spr_read_generic
, &spr_write_generic
,
6951 /* XXX : not implemented */
6952 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6953 &spr_read_ureg
, SPR_NOACCESS
,
6954 &spr_read_ureg
, SPR_NOACCESS
,
6957 spr_register(env
, SPR_SPRG4
, "SPRG4",
6958 SPR_NOACCESS
, SPR_NOACCESS
,
6959 &spr_read_generic
, &spr_write_generic
,
6961 spr_register(env
, SPR_USPRG4
, "USPRG4",
6962 &spr_read_ureg
, SPR_NOACCESS
,
6963 &spr_read_ureg
, SPR_NOACCESS
,
6965 spr_register(env
, SPR_SPRG5
, "SPRG5",
6966 SPR_NOACCESS
, SPR_NOACCESS
,
6967 &spr_read_generic
, &spr_write_generic
,
6969 spr_register(env
, SPR_USPRG5
, "USPRG5",
6970 &spr_read_ureg
, SPR_NOACCESS
,
6971 &spr_read_ureg
, SPR_NOACCESS
,
6973 spr_register(env
, SPR_SPRG6
, "SPRG6",
6974 SPR_NOACCESS
, SPR_NOACCESS
,
6975 &spr_read_generic
, &spr_write_generic
,
6977 spr_register(env
, SPR_USPRG6
, "USPRG6",
6978 &spr_read_ureg
, SPR_NOACCESS
,
6979 &spr_read_ureg
, SPR_NOACCESS
,
6981 spr_register(env
, SPR_SPRG7
, "SPRG7",
6982 SPR_NOACCESS
, SPR_NOACCESS
,
6983 &spr_read_generic
, &spr_write_generic
,
6985 spr_register(env
, SPR_USPRG7
, "USPRG7",
6986 &spr_read_ureg
, SPR_NOACCESS
,
6987 &spr_read_ureg
, SPR_NOACCESS
,
6989 /* Memory management */
6992 gen_74xx_soft_tlb(env
, 128, 2);
6993 init_excp_7450(env
);
6994 env
->dcache_line_size
= 32;
6995 env
->icache_line_size
= 32;
6996 /* Allocate hardware IRQ controller */
6997 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7000 POWERPC_FAMILY(7445)(ObjectClass
*oc
, void *data
)
7002 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7003 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7005 dc
->desc
= "PowerPC 7445 (aka G4)";
7006 pcc
->init_proc
= init_proc_7445
;
7007 pcc
->check_pow
= check_pow_hid0_74xx
;
7008 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7009 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7010 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7012 PPC_CACHE
| PPC_CACHE_ICBI
|
7013 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7014 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7015 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7016 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7017 PPC_SEGMENT
| PPC_EXTERN
|
7019 pcc
->msr_mask
= (1ull << MSR_VR
) |
7036 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7037 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7038 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7039 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7040 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7041 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7042 POWERPC_FLAG_BUS_CLK
;
7045 static void init_proc_7455(CPUPPCState
*env
)
7047 gen_spr_ne_601(env
);
7052 /* 74xx specific SPR */
7054 /* Level 3 cache control */
7057 /* XXX : not implemented */
7058 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7059 SPR_NOACCESS
, SPR_NOACCESS
,
7060 &spr_read_generic
, &spr_write_generic
,
7063 /* XXX : not implemented */
7064 spr_register(env
, SPR_ICTRL
, "ICTRL",
7065 SPR_NOACCESS
, SPR_NOACCESS
,
7066 &spr_read_generic
, &spr_write_generic
,
7069 /* XXX : not implemented */
7070 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7071 SPR_NOACCESS
, SPR_NOACCESS
,
7072 &spr_read_generic
, &spr_write_generic
,
7075 /* XXX : not implemented */
7076 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7077 SPR_NOACCESS
, SPR_NOACCESS
,
7078 &spr_read_generic
, &spr_write_generic
,
7080 /* XXX : not implemented */
7081 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7082 &spr_read_ureg
, SPR_NOACCESS
,
7083 &spr_read_ureg
, SPR_NOACCESS
,
7085 /* XXX : not implemented */
7086 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7087 SPR_NOACCESS
, SPR_NOACCESS
,
7088 &spr_read_generic
, &spr_write_generic
,
7090 /* XXX : not implemented */
7091 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7092 &spr_read_ureg
, SPR_NOACCESS
,
7093 &spr_read_ureg
, SPR_NOACCESS
,
7096 spr_register(env
, SPR_SPRG4
, "SPRG4",
7097 SPR_NOACCESS
, SPR_NOACCESS
,
7098 &spr_read_generic
, &spr_write_generic
,
7100 spr_register(env
, SPR_USPRG4
, "USPRG4",
7101 &spr_read_ureg
, SPR_NOACCESS
,
7102 &spr_read_ureg
, SPR_NOACCESS
,
7104 spr_register(env
, SPR_SPRG5
, "SPRG5",
7105 SPR_NOACCESS
, SPR_NOACCESS
,
7106 &spr_read_generic
, &spr_write_generic
,
7108 spr_register(env
, SPR_USPRG5
, "USPRG5",
7109 &spr_read_ureg
, SPR_NOACCESS
,
7110 &spr_read_ureg
, SPR_NOACCESS
,
7112 spr_register(env
, SPR_SPRG6
, "SPRG6",
7113 SPR_NOACCESS
, SPR_NOACCESS
,
7114 &spr_read_generic
, &spr_write_generic
,
7116 spr_register(env
, SPR_USPRG6
, "USPRG6",
7117 &spr_read_ureg
, SPR_NOACCESS
,
7118 &spr_read_ureg
, SPR_NOACCESS
,
7120 spr_register(env
, SPR_SPRG7
, "SPRG7",
7121 SPR_NOACCESS
, SPR_NOACCESS
,
7122 &spr_read_generic
, &spr_write_generic
,
7124 spr_register(env
, SPR_USPRG7
, "USPRG7",
7125 &spr_read_ureg
, SPR_NOACCESS
,
7126 &spr_read_ureg
, SPR_NOACCESS
,
7128 /* Memory management */
7131 gen_74xx_soft_tlb(env
, 128, 2);
7132 init_excp_7450(env
);
7133 env
->dcache_line_size
= 32;
7134 env
->icache_line_size
= 32;
7135 /* Allocate hardware IRQ controller */
7136 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7139 POWERPC_FAMILY(7455)(ObjectClass
*oc
, void *data
)
7141 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7142 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7144 dc
->desc
= "PowerPC 7455 (aka G4)";
7145 pcc
->init_proc
= init_proc_7455
;
7146 pcc
->check_pow
= check_pow_hid0_74xx
;
7147 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7148 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7149 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7151 PPC_CACHE
| PPC_CACHE_ICBI
|
7152 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7153 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7154 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7155 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7156 PPC_SEGMENT
| PPC_EXTERN
|
7158 pcc
->msr_mask
= (1ull << MSR_VR
) |
7175 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7176 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7177 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7178 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7179 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7180 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7181 POWERPC_FLAG_BUS_CLK
;
7184 static void init_proc_7457(CPUPPCState
*env
)
7186 gen_spr_ne_601(env
);
7191 /* 74xx specific SPR */
7193 /* Level 3 cache control */
7196 /* XXX : not implemented */
7197 spr_register(env
, SPR_L3ITCR1
, "L3ITCR1",
7198 SPR_NOACCESS
, SPR_NOACCESS
,
7199 &spr_read_generic
, &spr_write_generic
,
7202 /* XXX : not implemented */
7203 spr_register(env
, SPR_L3ITCR2
, "L3ITCR2",
7204 SPR_NOACCESS
, SPR_NOACCESS
,
7205 &spr_read_generic
, &spr_write_generic
,
7208 /* XXX : not implemented */
7209 spr_register(env
, SPR_L3ITCR3
, "L3ITCR3",
7210 SPR_NOACCESS
, SPR_NOACCESS
,
7211 &spr_read_generic
, &spr_write_generic
,
7214 /* XXX : not implemented */
7215 spr_register(env
, SPR_L3OHCR
, "L3OHCR",
7216 SPR_NOACCESS
, SPR_NOACCESS
,
7217 &spr_read_generic
, &spr_write_generic
,
7220 /* XXX : not implemented */
7221 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7222 SPR_NOACCESS
, SPR_NOACCESS
,
7223 &spr_read_generic
, &spr_write_generic
,
7226 /* XXX : not implemented */
7227 spr_register(env
, SPR_ICTRL
, "ICTRL",
7228 SPR_NOACCESS
, SPR_NOACCESS
,
7229 &spr_read_generic
, &spr_write_generic
,
7232 /* XXX : not implemented */
7233 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7234 SPR_NOACCESS
, SPR_NOACCESS
,
7235 &spr_read_generic
, &spr_write_generic
,
7238 /* XXX : not implemented */
7239 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7240 SPR_NOACCESS
, SPR_NOACCESS
,
7241 &spr_read_generic
, &spr_write_generic
,
7243 /* XXX : not implemented */
7244 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7245 &spr_read_ureg
, SPR_NOACCESS
,
7246 &spr_read_ureg
, SPR_NOACCESS
,
7248 /* XXX : not implemented */
7249 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7250 SPR_NOACCESS
, SPR_NOACCESS
,
7251 &spr_read_generic
, &spr_write_generic
,
7253 /* XXX : not implemented */
7254 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7255 &spr_read_ureg
, SPR_NOACCESS
,
7256 &spr_read_ureg
, SPR_NOACCESS
,
7259 spr_register(env
, SPR_SPRG4
, "SPRG4",
7260 SPR_NOACCESS
, SPR_NOACCESS
,
7261 &spr_read_generic
, &spr_write_generic
,
7263 spr_register(env
, SPR_USPRG4
, "USPRG4",
7264 &spr_read_ureg
, SPR_NOACCESS
,
7265 &spr_read_ureg
, SPR_NOACCESS
,
7267 spr_register(env
, SPR_SPRG5
, "SPRG5",
7268 SPR_NOACCESS
, SPR_NOACCESS
,
7269 &spr_read_generic
, &spr_write_generic
,
7271 spr_register(env
, SPR_USPRG5
, "USPRG5",
7272 &spr_read_ureg
, SPR_NOACCESS
,
7273 &spr_read_ureg
, SPR_NOACCESS
,
7275 spr_register(env
, SPR_SPRG6
, "SPRG6",
7276 SPR_NOACCESS
, SPR_NOACCESS
,
7277 &spr_read_generic
, &spr_write_generic
,
7279 spr_register(env
, SPR_USPRG6
, "USPRG6",
7280 &spr_read_ureg
, SPR_NOACCESS
,
7281 &spr_read_ureg
, SPR_NOACCESS
,
7283 spr_register(env
, SPR_SPRG7
, "SPRG7",
7284 SPR_NOACCESS
, SPR_NOACCESS
,
7285 &spr_read_generic
, &spr_write_generic
,
7287 spr_register(env
, SPR_USPRG7
, "USPRG7",
7288 &spr_read_ureg
, SPR_NOACCESS
,
7289 &spr_read_ureg
, SPR_NOACCESS
,
7291 /* Memory management */
7294 gen_74xx_soft_tlb(env
, 128, 2);
7295 init_excp_7450(env
);
7296 env
->dcache_line_size
= 32;
7297 env
->icache_line_size
= 32;
7298 /* Allocate hardware IRQ controller */
7299 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7302 POWERPC_FAMILY(7457)(ObjectClass
*oc
, void *data
)
7304 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7305 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7307 dc
->desc
= "PowerPC 7457 (aka G4)";
7308 pcc
->init_proc
= init_proc_7457
;
7309 pcc
->check_pow
= check_pow_hid0_74xx
;
7310 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7311 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7312 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7314 PPC_CACHE
| PPC_CACHE_ICBI
|
7315 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7316 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7317 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7318 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7319 PPC_SEGMENT
| PPC_EXTERN
|
7321 pcc
->msr_mask
= (1ull << MSR_VR
) |
7338 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7339 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7340 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7341 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7342 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7343 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7344 POWERPC_FLAG_BUS_CLK
;
7347 static void init_proc_e600(CPUPPCState
*env
)
7349 gen_spr_ne_601(env
);
7354 /* 74xx specific SPR */
7356 /* XXX : not implemented */
7357 spr_register(env
, SPR_UBAMR
, "UBAMR",
7358 &spr_read_ureg
, SPR_NOACCESS
,
7359 &spr_read_ureg
, SPR_NOACCESS
,
7361 /* XXX : not implemented */
7362 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7363 SPR_NOACCESS
, SPR_NOACCESS
,
7364 &spr_read_generic
, &spr_write_generic
,
7366 /* XXX : not implemented */
7367 spr_register(env
, SPR_ICTRL
, "ICTRL",
7368 SPR_NOACCESS
, SPR_NOACCESS
,
7369 &spr_read_generic
, &spr_write_generic
,
7371 /* XXX : not implemented */
7372 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7373 SPR_NOACCESS
, SPR_NOACCESS
,
7374 &spr_read_generic
, &spr_write_generic
,
7376 /* XXX : not implemented */
7377 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7378 SPR_NOACCESS
, SPR_NOACCESS
,
7379 &spr_read_generic
, &spr_write_generic
,
7381 /* XXX : not implemented */
7382 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7383 &spr_read_ureg
, SPR_NOACCESS
,
7384 &spr_read_ureg
, SPR_NOACCESS
,
7386 /* XXX : not implemented */
7387 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7388 SPR_NOACCESS
, SPR_NOACCESS
,
7389 &spr_read_generic
, &spr_write_generic
,
7391 /* XXX : not implemented */
7392 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7393 &spr_read_ureg
, SPR_NOACCESS
,
7394 &spr_read_ureg
, SPR_NOACCESS
,
7397 spr_register(env
, SPR_SPRG4
, "SPRG4",
7398 SPR_NOACCESS
, SPR_NOACCESS
,
7399 &spr_read_generic
, &spr_write_generic
,
7401 spr_register(env
, SPR_USPRG4
, "USPRG4",
7402 &spr_read_ureg
, SPR_NOACCESS
,
7403 &spr_read_ureg
, SPR_NOACCESS
,
7405 spr_register(env
, SPR_SPRG5
, "SPRG5",
7406 SPR_NOACCESS
, SPR_NOACCESS
,
7407 &spr_read_generic
, &spr_write_generic
,
7409 spr_register(env
, SPR_USPRG5
, "USPRG5",
7410 &spr_read_ureg
, SPR_NOACCESS
,
7411 &spr_read_ureg
, SPR_NOACCESS
,
7413 spr_register(env
, SPR_SPRG6
, "SPRG6",
7414 SPR_NOACCESS
, SPR_NOACCESS
,
7415 &spr_read_generic
, &spr_write_generic
,
7417 spr_register(env
, SPR_USPRG6
, "USPRG6",
7418 &spr_read_ureg
, SPR_NOACCESS
,
7419 &spr_read_ureg
, SPR_NOACCESS
,
7421 spr_register(env
, SPR_SPRG7
, "SPRG7",
7422 SPR_NOACCESS
, SPR_NOACCESS
,
7423 &spr_read_generic
, &spr_write_generic
,
7425 spr_register(env
, SPR_USPRG7
, "USPRG7",
7426 &spr_read_ureg
, SPR_NOACCESS
,
7427 &spr_read_ureg
, SPR_NOACCESS
,
7429 /* Memory management */
7432 gen_74xx_soft_tlb(env
, 128, 2);
7433 init_excp_7450(env
);
7434 env
->dcache_line_size
= 32;
7435 env
->icache_line_size
= 32;
7436 /* Allocate hardware IRQ controller */
7437 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7440 POWERPC_FAMILY(e600
)(ObjectClass
*oc
, void *data
)
7442 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7443 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7445 dc
->desc
= "PowerPC e600";
7446 pcc
->init_proc
= init_proc_e600
;
7447 pcc
->check_pow
= check_pow_hid0_74xx
;
7448 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7449 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7450 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7452 PPC_CACHE
| PPC_CACHE_ICBI
|
7453 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7454 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7455 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7456 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7457 PPC_SEGMENT
| PPC_EXTERN
|
7459 pcc
->insns_flags2
= PPC_NONE
;
7460 pcc
->msr_mask
= (1ull << MSR_VR
) |
7477 pcc
->mmu_model
= POWERPC_MMU_32B
;
7478 #if defined(CONFIG_SOFTMMU)
7479 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
7481 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7482 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7483 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7484 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7485 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7486 POWERPC_FLAG_BUS_CLK
;
7489 #if defined(TARGET_PPC64)
7490 #if defined(CONFIG_USER_ONLY)
7491 #define POWERPC970_HID5_INIT 0x00000080
7493 #define POWERPC970_HID5_INIT 0x00000000
7496 static void gen_fscr_facility_check(DisasContext
*ctx
, int facility_sprn
,
7497 int bit
, int sprn
, int cause
)
7499 TCGv_i32 t1
= tcg_const_i32(bit
);
7500 TCGv_i32 t2
= tcg_const_i32(sprn
);
7501 TCGv_i32 t3
= tcg_const_i32(cause
);
7503 gen_helper_fscr_facility_check(cpu_env
, t1
, t2
, t3
);
7505 tcg_temp_free_i32(t3
);
7506 tcg_temp_free_i32(t2
);
7507 tcg_temp_free_i32(t1
);
7510 static void gen_msr_facility_check(DisasContext
*ctx
, int facility_sprn
,
7511 int bit
, int sprn
, int cause
)
7513 TCGv_i32 t1
= tcg_const_i32(bit
);
7514 TCGv_i32 t2
= tcg_const_i32(sprn
);
7515 TCGv_i32 t3
= tcg_const_i32(cause
);
7517 gen_helper_msr_facility_check(cpu_env
, t1
, t2
, t3
);
7519 tcg_temp_free_i32(t3
);
7520 tcg_temp_free_i32(t2
);
7521 tcg_temp_free_i32(t1
);
7524 static void spr_read_prev_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
7526 TCGv spr_up
= tcg_temp_new();
7527 TCGv spr
= tcg_temp_new();
7529 gen_load_spr(spr
, sprn
- 1);
7530 tcg_gen_shri_tl(spr_up
, spr
, 32);
7531 tcg_gen_ext32u_tl(cpu_gpr
[gprn
], spr_up
);
7534 tcg_temp_free(spr_up
);
7537 static void spr_write_prev_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
7539 TCGv spr
= tcg_temp_new();
7541 gen_load_spr(spr
, sprn
- 1);
7542 tcg_gen_deposit_tl(spr
, spr
, cpu_gpr
[gprn
], 32, 32);
7543 gen_store_spr(sprn
- 1, spr
);
7548 static int check_pow_970(CPUPPCState
*env
)
7550 if (env
->spr
[SPR_HID0
] & (HID0_DEEPNAP
| HID0_DOZE
| HID0_NAP
)) {
7557 static void gen_spr_970_hid(CPUPPCState
*env
)
7559 /* Hardware implementation registers */
7560 /* XXX : not implemented */
7561 spr_register(env
, SPR_HID0
, "HID0",
7562 SPR_NOACCESS
, SPR_NOACCESS
,
7563 &spr_read_generic
, &spr_write_clear
,
7565 spr_register(env
, SPR_HID1
, "HID1",
7566 SPR_NOACCESS
, SPR_NOACCESS
,
7567 &spr_read_generic
, &spr_write_generic
,
7569 spr_register(env
, SPR_970_HID5
, "HID5",
7570 SPR_NOACCESS
, SPR_NOACCESS
,
7571 &spr_read_generic
, &spr_write_generic
,
7572 POWERPC970_HID5_INIT
);
7575 static void gen_spr_970_hior(CPUPPCState
*env
)
7577 spr_register(env
, SPR_HIOR
, "SPR_HIOR",
7578 SPR_NOACCESS
, SPR_NOACCESS
,
7579 &spr_read_hior
, &spr_write_hior
,
7583 static void gen_spr_book3s_ctrl(CPUPPCState
*env
)
7585 spr_register(env
, SPR_CTRL
, "SPR_CTRL",
7586 SPR_NOACCESS
, SPR_NOACCESS
,
7587 SPR_NOACCESS
, &spr_write_generic
,
7589 spr_register(env
, SPR_UCTRL
, "SPR_UCTRL",
7590 &spr_read_ureg
, SPR_NOACCESS
,
7591 &spr_read_ureg
, SPR_NOACCESS
,
7595 static void gen_spr_book3s_altivec(CPUPPCState
*env
)
7597 if (!(env
->insns_flags
& PPC_ALTIVEC
)) {
7601 spr_register_kvm(env
, SPR_VRSAVE
, "VRSAVE",
7602 &spr_read_generic
, &spr_write_generic
,
7603 &spr_read_generic
, &spr_write_generic
,
7604 KVM_REG_PPC_VRSAVE
, 0x00000000);
7606 /* Can't find information on what this should be on reset. This
7607 * value is the one used by 74xx processors. */
7608 vscr_init(env
, 0x00010000);
7611 static void gen_spr_book3s_dbg(CPUPPCState
*env
)
7614 * TODO: different specs define different scopes for these,
7615 * will have to address this:
7616 * 970: super/write and super/read
7617 * powerisa 2.03..2.04: hypv/write and super/read.
7618 * powerisa 2.05 and newer: hypv/write and hypv/read.
7620 spr_register_kvm(env
, SPR_DABR
, "DABR",
7621 SPR_NOACCESS
, SPR_NOACCESS
,
7622 &spr_read_generic
, &spr_write_generic
,
7623 KVM_REG_PPC_DABR
, 0x00000000);
7624 spr_register_kvm(env
, SPR_DABRX
, "DABRX",
7625 SPR_NOACCESS
, SPR_NOACCESS
,
7626 &spr_read_generic
, &spr_write_generic
,
7627 KVM_REG_PPC_DABRX
, 0x00000000);
7630 static void gen_spr_book3s_207_dbg(CPUPPCState
*env
)
7632 spr_register_kvm_hv(env
, SPR_DAWR
, "DAWR",
7633 SPR_NOACCESS
, SPR_NOACCESS
,
7634 SPR_NOACCESS
, SPR_NOACCESS
,
7635 &spr_read_generic
, &spr_write_generic
,
7636 KVM_REG_PPC_DAWR
, 0x00000000);
7637 spr_register_kvm_hv(env
, SPR_DAWRX
, "DAWRX",
7638 SPR_NOACCESS
, SPR_NOACCESS
,
7639 SPR_NOACCESS
, SPR_NOACCESS
,
7640 &spr_read_generic
, &spr_write_generic
,
7641 KVM_REG_PPC_DAWRX
, 0x00000000);
7642 spr_register_kvm_hv(env
, SPR_CIABR
, "CIABR",
7643 SPR_NOACCESS
, SPR_NOACCESS
,
7644 SPR_NOACCESS
, SPR_NOACCESS
,
7645 &spr_read_generic
, &spr_write_generic
,
7646 KVM_REG_PPC_CIABR
, 0x00000000);
7649 static void gen_spr_970_dbg(CPUPPCState
*env
)
7652 spr_register(env
, SPR_IABR
, "IABR",
7653 SPR_NOACCESS
, SPR_NOACCESS
,
7654 &spr_read_generic
, &spr_write_generic
,
7658 static void gen_spr_book3s_pmu_sup(CPUPPCState
*env
)
7660 spr_register_kvm(env
, SPR_POWER_MMCR0
, "MMCR0",
7661 SPR_NOACCESS
, SPR_NOACCESS
,
7662 &spr_read_generic
, &spr_write_generic
,
7663 KVM_REG_PPC_MMCR0
, 0x00000000);
7664 spr_register_kvm(env
, SPR_POWER_MMCR1
, "MMCR1",
7665 SPR_NOACCESS
, SPR_NOACCESS
,
7666 &spr_read_generic
, &spr_write_generic
,
7667 KVM_REG_PPC_MMCR1
, 0x00000000);
7668 spr_register_kvm(env
, SPR_POWER_MMCRA
, "MMCRA",
7669 SPR_NOACCESS
, SPR_NOACCESS
,
7670 &spr_read_generic
, &spr_write_generic
,
7671 KVM_REG_PPC_MMCRA
, 0x00000000);
7672 spr_register_kvm(env
, SPR_POWER_PMC1
, "PMC1",
7673 SPR_NOACCESS
, SPR_NOACCESS
,
7674 &spr_read_generic
, &spr_write_generic
,
7675 KVM_REG_PPC_PMC1
, 0x00000000);
7676 spr_register_kvm(env
, SPR_POWER_PMC2
, "PMC2",
7677 SPR_NOACCESS
, SPR_NOACCESS
,
7678 &spr_read_generic
, &spr_write_generic
,
7679 KVM_REG_PPC_PMC2
, 0x00000000);
7680 spr_register_kvm(env
, SPR_POWER_PMC3
, "PMC3",
7681 SPR_NOACCESS
, SPR_NOACCESS
,
7682 &spr_read_generic
, &spr_write_generic
,
7683 KVM_REG_PPC_PMC3
, 0x00000000);
7684 spr_register_kvm(env
, SPR_POWER_PMC4
, "PMC4",
7685 SPR_NOACCESS
, SPR_NOACCESS
,
7686 &spr_read_generic
, &spr_write_generic
,
7687 KVM_REG_PPC_PMC4
, 0x00000000);
7688 spr_register_kvm(env
, SPR_POWER_PMC5
, "PMC5",
7689 SPR_NOACCESS
, SPR_NOACCESS
,
7690 &spr_read_generic
, &spr_write_generic
,
7691 KVM_REG_PPC_PMC5
, 0x00000000);
7692 spr_register_kvm(env
, SPR_POWER_PMC6
, "PMC6",
7693 SPR_NOACCESS
, SPR_NOACCESS
,
7694 &spr_read_generic
, &spr_write_generic
,
7695 KVM_REG_PPC_PMC6
, 0x00000000);
7696 spr_register_kvm(env
, SPR_POWER_SIAR
, "SIAR",
7697 SPR_NOACCESS
, SPR_NOACCESS
,
7698 &spr_read_generic
, &spr_write_generic
,
7699 KVM_REG_PPC_SIAR
, 0x00000000);
7700 spr_register_kvm(env
, SPR_POWER_SDAR
, "SDAR",
7701 SPR_NOACCESS
, SPR_NOACCESS
,
7702 &spr_read_generic
, &spr_write_generic
,
7703 KVM_REG_PPC_SDAR
, 0x00000000);
7706 static void gen_spr_book3s_pmu_user(CPUPPCState
*env
)
7708 spr_register(env
, SPR_POWER_UMMCR0
, "UMMCR0",
7709 &spr_read_ureg
, SPR_NOACCESS
,
7710 &spr_read_ureg
, &spr_write_ureg
,
7712 spr_register(env
, SPR_POWER_UMMCR1
, "UMMCR1",
7713 &spr_read_ureg
, SPR_NOACCESS
,
7714 &spr_read_ureg
, &spr_write_ureg
,
7716 spr_register(env
, SPR_POWER_UMMCRA
, "UMMCRA",
7717 &spr_read_ureg
, SPR_NOACCESS
,
7718 &spr_read_ureg
, &spr_write_ureg
,
7720 spr_register(env
, SPR_POWER_UPMC1
, "UPMC1",
7721 &spr_read_ureg
, SPR_NOACCESS
,
7722 &spr_read_ureg
, &spr_write_ureg
,
7724 spr_register(env
, SPR_POWER_UPMC2
, "UPMC2",
7725 &spr_read_ureg
, SPR_NOACCESS
,
7726 &spr_read_ureg
, &spr_write_ureg
,
7728 spr_register(env
, SPR_POWER_UPMC3
, "UPMC3",
7729 &spr_read_ureg
, SPR_NOACCESS
,
7730 &spr_read_ureg
, &spr_write_ureg
,
7732 spr_register(env
, SPR_POWER_UPMC4
, "UPMC4",
7733 &spr_read_ureg
, SPR_NOACCESS
,
7734 &spr_read_ureg
, &spr_write_ureg
,
7736 spr_register(env
, SPR_POWER_UPMC5
, "UPMC5",
7737 &spr_read_ureg
, SPR_NOACCESS
,
7738 &spr_read_ureg
, &spr_write_ureg
,
7740 spr_register(env
, SPR_POWER_UPMC6
, "UPMC6",
7741 &spr_read_ureg
, SPR_NOACCESS
,
7742 &spr_read_ureg
, &spr_write_ureg
,
7744 spr_register(env
, SPR_POWER_USIAR
, "USIAR",
7745 &spr_read_ureg
, SPR_NOACCESS
,
7746 &spr_read_ureg
, &spr_write_ureg
,
7748 spr_register(env
, SPR_POWER_USDAR
, "USDAR",
7749 &spr_read_ureg
, SPR_NOACCESS
,
7750 &spr_read_ureg
, &spr_write_ureg
,
7754 static void gen_spr_970_pmu_sup(CPUPPCState
*env
)
7756 spr_register_kvm(env
, SPR_970_PMC7
, "PMC7",
7757 SPR_NOACCESS
, SPR_NOACCESS
,
7758 &spr_read_generic
, &spr_write_generic
,
7759 KVM_REG_PPC_PMC7
, 0x00000000);
7760 spr_register_kvm(env
, SPR_970_PMC8
, "PMC8",
7761 SPR_NOACCESS
, SPR_NOACCESS
,
7762 &spr_read_generic
, &spr_write_generic
,
7763 KVM_REG_PPC_PMC8
, 0x00000000);
7766 static void gen_spr_970_pmu_user(CPUPPCState
*env
)
7768 spr_register(env
, SPR_970_UPMC7
, "UPMC7",
7769 &spr_read_ureg
, SPR_NOACCESS
,
7770 &spr_read_ureg
, &spr_write_ureg
,
7772 spr_register(env
, SPR_970_UPMC8
, "UPMC8",
7773 &spr_read_ureg
, SPR_NOACCESS
,
7774 &spr_read_ureg
, &spr_write_ureg
,
7778 static void gen_spr_power8_pmu_sup(CPUPPCState
*env
)
7780 spr_register_kvm(env
, SPR_POWER_MMCR2
, "MMCR2",
7781 SPR_NOACCESS
, SPR_NOACCESS
,
7782 &spr_read_generic
, &spr_write_generic
,
7783 KVM_REG_PPC_MMCR2
, 0x00000000);
7784 spr_register_kvm(env
, SPR_POWER_MMCRS
, "MMCRS",
7785 SPR_NOACCESS
, SPR_NOACCESS
,
7786 &spr_read_generic
, &spr_write_generic
,
7787 KVM_REG_PPC_MMCRS
, 0x00000000);
7788 spr_register_kvm(env
, SPR_POWER_SIER
, "SIER",
7789 SPR_NOACCESS
, SPR_NOACCESS
,
7790 &spr_read_generic
, &spr_write_generic
,
7791 KVM_REG_PPC_SIER
, 0x00000000);
7792 spr_register_kvm(env
, SPR_POWER_SPMC1
, "SPMC1",
7793 SPR_NOACCESS
, SPR_NOACCESS
,
7794 &spr_read_generic
, &spr_write_generic
,
7795 KVM_REG_PPC_SPMC1
, 0x00000000);
7796 spr_register_kvm(env
, SPR_POWER_SPMC2
, "SPMC2",
7797 SPR_NOACCESS
, SPR_NOACCESS
,
7798 &spr_read_generic
, &spr_write_generic
,
7799 KVM_REG_PPC_SPMC2
, 0x00000000);
7800 spr_register_kvm(env
, SPR_TACR
, "TACR",
7801 SPR_NOACCESS
, SPR_NOACCESS
,
7802 &spr_read_generic
, &spr_write_generic
,
7803 KVM_REG_PPC_TACR
, 0x00000000);
7804 spr_register_kvm(env
, SPR_TCSCR
, "TCSCR",
7805 SPR_NOACCESS
, SPR_NOACCESS
,
7806 &spr_read_generic
, &spr_write_generic
,
7807 KVM_REG_PPC_TCSCR
, 0x00000000);
7808 spr_register_kvm(env
, SPR_CSIGR
, "CSIGR",
7809 SPR_NOACCESS
, SPR_NOACCESS
,
7810 &spr_read_generic
, &spr_write_generic
,
7811 KVM_REG_PPC_CSIGR
, 0x00000000);
7814 static void gen_spr_power8_pmu_user(CPUPPCState
*env
)
7816 spr_register(env
, SPR_POWER_UMMCR2
, "UMMCR2",
7817 &spr_read_ureg
, SPR_NOACCESS
,
7818 &spr_read_ureg
, &spr_write_ureg
,
7820 spr_register(env
, SPR_POWER_USIER
, "USIER",
7821 &spr_read_generic
, SPR_NOACCESS
,
7822 &spr_read_generic
, &spr_write_generic
,
7826 static void gen_spr_power5p_ear(CPUPPCState
*env
)
7828 /* External access control */
7829 spr_register(env
, SPR_EAR
, "EAR",
7830 SPR_NOACCESS
, SPR_NOACCESS
,
7831 &spr_read_generic
, &spr_write_generic
,
7835 #if !defined(CONFIG_USER_ONLY)
7836 static void spr_write_hmer(DisasContext
*ctx
, int sprn
, int gprn
)
7838 TCGv hmer
= tcg_temp_new();
7840 gen_load_spr(hmer
, sprn
);
7841 tcg_gen_and_tl(hmer
, cpu_gpr
[gprn
], hmer
);
7842 gen_store_spr(sprn
, hmer
);
7843 spr_store_dump_spr(sprn
);
7844 tcg_temp_free(hmer
);
7847 static void spr_write_lpcr(DisasContext
*ctx
, int sprn
, int gprn
)
7849 gen_helper_store_lpcr(cpu_env
, cpu_gpr
[gprn
]);
7852 static void spr_write_970_hid4(DisasContext
*ctx
, int sprn
, int gprn
)
7854 #if defined(TARGET_PPC64)
7855 spr_write_generic(ctx
, sprn
, gprn
);
7856 gen_helper_store_lpcr(cpu_env
, cpu_gpr
[gprn
]);
7860 #endif /* !defined(CONFIG_USER_ONLY) */
7862 static void gen_spr_970_lpar(CPUPPCState
*env
)
7864 #if !defined(CONFIG_USER_ONLY)
7865 /* Logical partitionning */
7866 /* PPC970: HID4 is effectively the LPCR */
7867 spr_register(env
, SPR_970_HID4
, "HID4",
7868 SPR_NOACCESS
, SPR_NOACCESS
,
7869 &spr_read_generic
, &spr_write_970_hid4
,
7874 static void gen_spr_power5p_lpar(CPUPPCState
*env
)
7876 #if !defined(CONFIG_USER_ONLY)
7877 /* Logical partitionning */
7878 spr_register_kvm_hv(env
, SPR_LPCR
, "LPCR",
7879 SPR_NOACCESS
, SPR_NOACCESS
,
7880 SPR_NOACCESS
, SPR_NOACCESS
,
7881 &spr_read_generic
, &spr_write_lpcr
,
7882 KVM_REG_PPC_LPCR
, LPCR_LPES0
| LPCR_LPES1
);
7883 spr_register_hv(env
, SPR_HDEC
, "HDEC",
7884 SPR_NOACCESS
, SPR_NOACCESS
,
7885 SPR_NOACCESS
, SPR_NOACCESS
,
7886 &spr_read_hdecr
, &spr_write_hdecr
, 0);
7890 static void gen_spr_book3s_ids(CPUPPCState
*env
)
7892 /* FIXME: Will need to deal with thread vs core only SPRs */
7894 /* Processor identification */
7895 spr_register_hv(env
, SPR_PIR
, "PIR",
7896 SPR_NOACCESS
, SPR_NOACCESS
,
7897 SPR_NOACCESS
, SPR_NOACCESS
,
7898 &spr_read_generic
, NULL
,
7900 spr_register_hv(env
, SPR_HID0
, "HID0",
7901 SPR_NOACCESS
, SPR_NOACCESS
,
7902 SPR_NOACCESS
, SPR_NOACCESS
,
7903 &spr_read_generic
, &spr_write_generic
,
7905 spr_register_hv(env
, SPR_TSCR
, "TSCR",
7906 SPR_NOACCESS
, SPR_NOACCESS
,
7907 SPR_NOACCESS
, SPR_NOACCESS
,
7908 &spr_read_generic
, &spr_write_generic
,
7910 spr_register_hv(env
, SPR_HMER
, "HMER",
7911 SPR_NOACCESS
, SPR_NOACCESS
,
7912 SPR_NOACCESS
, SPR_NOACCESS
,
7913 &spr_read_generic
, &spr_write_hmer
,
7915 spr_register_hv(env
, SPR_HMEER
, "HMEER",
7916 SPR_NOACCESS
, SPR_NOACCESS
,
7917 SPR_NOACCESS
, SPR_NOACCESS
,
7918 &spr_read_generic
, &spr_write_generic
,
7920 spr_register_hv(env
, SPR_TFMR
, "TFMR",
7921 SPR_NOACCESS
, SPR_NOACCESS
,
7922 SPR_NOACCESS
, SPR_NOACCESS
,
7923 &spr_read_generic
, &spr_write_generic
,
7925 spr_register_hv(env
, SPR_LPIDR
, "LPIDR",
7926 SPR_NOACCESS
, SPR_NOACCESS
,
7927 SPR_NOACCESS
, SPR_NOACCESS
,
7928 &spr_read_generic
, &spr_write_generic
,
7930 spr_register_hv(env
, SPR_HFSCR
, "HFSCR",
7931 SPR_NOACCESS
, SPR_NOACCESS
,
7932 SPR_NOACCESS
, SPR_NOACCESS
,
7933 &spr_read_generic
, &spr_write_generic
,
7935 spr_register_hv(env
, SPR_MMCRC
, "MMCRC",
7936 SPR_NOACCESS
, SPR_NOACCESS
,
7937 SPR_NOACCESS
, SPR_NOACCESS
,
7938 &spr_read_generic
, &spr_write_generic
,
7940 spr_register_hv(env
, SPR_MMCRH
, "MMCRH",
7941 SPR_NOACCESS
, SPR_NOACCESS
,
7942 SPR_NOACCESS
, SPR_NOACCESS
,
7943 &spr_read_generic
, &spr_write_generic
,
7945 spr_register_hv(env
, SPR_HSPRG0
, "HSPRG0",
7946 SPR_NOACCESS
, SPR_NOACCESS
,
7947 SPR_NOACCESS
, SPR_NOACCESS
,
7948 &spr_read_generic
, &spr_write_generic
,
7950 spr_register_hv(env
, SPR_HSPRG1
, "HSPRG1",
7951 SPR_NOACCESS
, SPR_NOACCESS
,
7952 SPR_NOACCESS
, SPR_NOACCESS
,
7953 &spr_read_generic
, &spr_write_generic
,
7955 spr_register_hv(env
, SPR_HSRR0
, "HSRR0",
7956 SPR_NOACCESS
, SPR_NOACCESS
,
7957 SPR_NOACCESS
, SPR_NOACCESS
,
7958 &spr_read_generic
, &spr_write_generic
,
7960 spr_register_hv(env
, SPR_HSRR1
, "HSRR1",
7961 SPR_NOACCESS
, SPR_NOACCESS
,
7962 SPR_NOACCESS
, SPR_NOACCESS
,
7963 &spr_read_generic
, &spr_write_generic
,
7965 spr_register_hv(env
, SPR_HDAR
, "HDAR",
7966 SPR_NOACCESS
, SPR_NOACCESS
,
7967 SPR_NOACCESS
, SPR_NOACCESS
,
7968 &spr_read_generic
, &spr_write_generic
,
7970 spr_register_hv(env
, SPR_HDSISR
, "HDSISR",
7971 SPR_NOACCESS
, SPR_NOACCESS
,
7972 SPR_NOACCESS
, SPR_NOACCESS
,
7973 &spr_read_generic
, &spr_write_generic
,
7975 spr_register_hv(env
, SPR_RMOR
, "RMOR",
7976 SPR_NOACCESS
, SPR_NOACCESS
,
7977 SPR_NOACCESS
, SPR_NOACCESS
,
7978 &spr_read_generic
, &spr_write_generic
,
7980 spr_register_hv(env
, SPR_HRMOR
, "HRMOR",
7981 SPR_NOACCESS
, SPR_NOACCESS
,
7982 SPR_NOACCESS
, SPR_NOACCESS
,
7983 &spr_read_generic
, &spr_write_generic
,
7987 static void gen_spr_power8_ids(CPUPPCState
*env
)
7989 /* Thread identification */
7990 spr_register(env
, SPR_TIR
, "TIR",
7991 SPR_NOACCESS
, SPR_NOACCESS
,
7992 &spr_read_generic
, SPR_NOACCESS
,
7996 static void gen_spr_book3s_purr(CPUPPCState
*env
)
7998 #if !defined(CONFIG_USER_ONLY)
7999 /* PURR & SPURR: Hack - treat these as aliases for the TB for now */
8000 spr_register_kvm(env
, SPR_PURR
, "PURR",
8001 &spr_read_purr
, SPR_NOACCESS
,
8002 &spr_read_purr
, SPR_NOACCESS
,
8003 KVM_REG_PPC_PURR
, 0x00000000);
8004 spr_register_kvm(env
, SPR_SPURR
, "SPURR",
8005 &spr_read_purr
, SPR_NOACCESS
,
8006 &spr_read_purr
, SPR_NOACCESS
,
8007 KVM_REG_PPC_SPURR
, 0x00000000);
8011 static void gen_spr_power6_dbg(CPUPPCState
*env
)
8013 #if !defined(CONFIG_USER_ONLY)
8014 spr_register(env
, SPR_CFAR
, "SPR_CFAR",
8015 SPR_NOACCESS
, SPR_NOACCESS
,
8016 &spr_read_cfar
, &spr_write_cfar
,
8021 static void gen_spr_power5p_common(CPUPPCState
*env
)
8023 spr_register_kvm(env
, SPR_PPR
, "PPR",
8024 &spr_read_generic
, &spr_write_generic
,
8025 &spr_read_generic
, &spr_write_generic
,
8026 KVM_REG_PPC_PPR
, 0x00000000);
8029 static void gen_spr_power6_common(CPUPPCState
*env
)
8031 #if !defined(CONFIG_USER_ONLY)
8032 spr_register_kvm(env
, SPR_DSCR
, "SPR_DSCR",
8033 SPR_NOACCESS
, SPR_NOACCESS
,
8034 &spr_read_generic
, &spr_write_generic
,
8035 KVM_REG_PPC_DSCR
, 0x00000000);
8038 * Register PCR to report POWERPC_EXCP_PRIV_REG instead of
8039 * POWERPC_EXCP_INVAL_SPR.
8041 spr_register(env
, SPR_PCR
, "PCR",
8042 SPR_NOACCESS
, SPR_NOACCESS
,
8043 SPR_NOACCESS
, SPR_NOACCESS
,
8047 static void spr_read_tar(DisasContext
*ctx
, int gprn
, int sprn
)
8049 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_TAR
, sprn
, FSCR_IC_TAR
);
8050 spr_read_generic(ctx
, gprn
, sprn
);
8053 static void spr_write_tar(DisasContext
*ctx
, int sprn
, int gprn
)
8055 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_TAR
, sprn
, FSCR_IC_TAR
);
8056 spr_write_generic(ctx
, sprn
, gprn
);
8059 static void gen_spr_power8_tce_address_control(CPUPPCState
*env
)
8061 spr_register_kvm(env
, SPR_TAR
, "TAR",
8062 &spr_read_tar
, &spr_write_tar
,
8063 &spr_read_generic
, &spr_write_generic
,
8064 KVM_REG_PPC_TAR
, 0x00000000);
8067 static void spr_read_tm(DisasContext
*ctx
, int gprn
, int sprn
)
8069 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8070 spr_read_generic(ctx
, gprn
, sprn
);
8073 static void spr_write_tm(DisasContext
*ctx
, int sprn
, int gprn
)
8075 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8076 spr_write_generic(ctx
, sprn
, gprn
);
8079 static void spr_read_tm_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
8081 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8082 spr_read_prev_upper32(ctx
, gprn
, sprn
);
8085 static void spr_write_tm_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
8087 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8088 spr_write_prev_upper32(ctx
, sprn
, gprn
);
8091 static void gen_spr_power8_tm(CPUPPCState
*env
)
8093 spr_register_kvm(env
, SPR_TFHAR
, "TFHAR",
8094 &spr_read_tm
, &spr_write_tm
,
8095 &spr_read_tm
, &spr_write_tm
,
8096 KVM_REG_PPC_TFHAR
, 0x00000000);
8097 spr_register_kvm(env
, SPR_TFIAR
, "TFIAR",
8098 &spr_read_tm
, &spr_write_tm
,
8099 &spr_read_tm
, &spr_write_tm
,
8100 KVM_REG_PPC_TFIAR
, 0x00000000);
8101 spr_register_kvm(env
, SPR_TEXASR
, "TEXASR",
8102 &spr_read_tm
, &spr_write_tm
,
8103 &spr_read_tm
, &spr_write_tm
,
8104 KVM_REG_PPC_TEXASR
, 0x00000000);
8105 spr_register(env
, SPR_TEXASRU
, "TEXASRU",
8106 &spr_read_tm_upper32
, &spr_write_tm_upper32
,
8107 &spr_read_tm_upper32
, &spr_write_tm_upper32
,
8111 static void spr_read_ebb(DisasContext
*ctx
, int gprn
, int sprn
)
8113 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8114 spr_read_generic(ctx
, gprn
, sprn
);
8117 static void spr_write_ebb(DisasContext
*ctx
, int sprn
, int gprn
)
8119 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8120 spr_write_generic(ctx
, sprn
, gprn
);
8123 static void spr_read_ebb_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
8125 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8126 spr_read_prev_upper32(ctx
, gprn
, sprn
);
8129 static void spr_write_ebb_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
8131 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8132 spr_write_prev_upper32(ctx
, sprn
, gprn
);
8135 static void gen_spr_power8_ebb(CPUPPCState
*env
)
8137 spr_register(env
, SPR_BESCRS
, "BESCRS",
8138 &spr_read_ebb
, &spr_write_ebb
,
8139 &spr_read_generic
, &spr_write_generic
,
8141 spr_register(env
, SPR_BESCRSU
, "BESCRSU",
8142 &spr_read_ebb_upper32
, &spr_write_ebb_upper32
,
8143 &spr_read_prev_upper32
, &spr_write_prev_upper32
,
8145 spr_register(env
, SPR_BESCRR
, "BESCRR",
8146 &spr_read_ebb
, &spr_write_ebb
,
8147 &spr_read_generic
, &spr_write_generic
,
8149 spr_register(env
, SPR_BESCRRU
, "BESCRRU",
8150 &spr_read_ebb_upper32
, &spr_write_ebb_upper32
,
8151 &spr_read_prev_upper32
, &spr_write_prev_upper32
,
8153 spr_register_kvm(env
, SPR_EBBHR
, "EBBHR",
8154 &spr_read_ebb
, &spr_write_ebb
,
8155 &spr_read_generic
, &spr_write_generic
,
8156 KVM_REG_PPC_EBBHR
, 0x00000000);
8157 spr_register_kvm(env
, SPR_EBBRR
, "EBBRR",
8158 &spr_read_ebb
, &spr_write_ebb
,
8159 &spr_read_generic
, &spr_write_generic
,
8160 KVM_REG_PPC_EBBRR
, 0x00000000);
8161 spr_register_kvm(env
, SPR_BESCR
, "BESCR",
8162 &spr_read_ebb
, &spr_write_ebb
,
8163 &spr_read_generic
, &spr_write_generic
,
8164 KVM_REG_PPC_BESCR
, 0x00000000);
8167 /* Virtual Time Base */
8168 static void gen_spr_vtb(CPUPPCState
*env
)
8170 spr_register(env
, SPR_VTB
, "VTB",
8171 SPR_NOACCESS
, SPR_NOACCESS
,
8172 &spr_read_tbl
, SPR_NOACCESS
,
8176 static void gen_spr_power8_fscr(CPUPPCState
*env
)
8178 #if defined(CONFIG_USER_ONLY)
8179 target_ulong initval
= 1ULL << FSCR_TAR
;
8181 target_ulong initval
= 0;
8183 spr_register_kvm(env
, SPR_FSCR
, "FSCR",
8184 SPR_NOACCESS
, SPR_NOACCESS
,
8185 &spr_read_generic
, &spr_write_generic
,
8186 KVM_REG_PPC_FSCR
, initval
);
8189 static void gen_spr_power8_pspb(CPUPPCState
*env
)
8191 spr_register_kvm(env
, SPR_PSPB
, "PSPB",
8192 SPR_NOACCESS
, SPR_NOACCESS
,
8193 &spr_read_generic
, &spr_write_generic32
,
8194 KVM_REG_PPC_PSPB
, 0);
8197 static void gen_spr_power8_ic(CPUPPCState
*env
)
8199 #if !defined(CONFIG_USER_ONLY)
8200 spr_register_hv(env
, SPR_IC
, "IC",
8201 SPR_NOACCESS
, SPR_NOACCESS
,
8202 &spr_read_generic
, SPR_NOACCESS
,
8203 &spr_read_generic
, &spr_write_generic
,
8208 static void gen_spr_power8_book4(CPUPPCState
*env
)
8210 /* Add a number of P8 book4 registers */
8211 #if !defined(CONFIG_USER_ONLY)
8212 spr_register_kvm(env
, SPR_ACOP
, "ACOP",
8213 SPR_NOACCESS
, SPR_NOACCESS
,
8214 &spr_read_generic
, &spr_write_generic
,
8215 KVM_REG_PPC_ACOP
, 0);
8216 spr_register_kvm(env
, SPR_BOOKS_PID
, "PID",
8217 SPR_NOACCESS
, SPR_NOACCESS
,
8218 &spr_read_generic
, &spr_write_pidr
,
8219 KVM_REG_PPC_PID
, 0);
8220 spr_register_kvm(env
, SPR_WORT
, "WORT",
8221 SPR_NOACCESS
, SPR_NOACCESS
,
8222 &spr_read_generic
, &spr_write_generic
,
8223 KVM_REG_PPC_WORT
, 0);
8227 static void gen_spr_power7_book4(CPUPPCState
*env
)
8229 /* Add a number of P7 book4 registers */
8230 #if !defined(CONFIG_USER_ONLY)
8231 spr_register_kvm(env
, SPR_ACOP
, "ACOP",
8232 SPR_NOACCESS
, SPR_NOACCESS
,
8233 &spr_read_generic
, &spr_write_generic
,
8234 KVM_REG_PPC_ACOP
, 0);
8235 spr_register_kvm(env
, SPR_BOOKS_PID
, "PID",
8236 SPR_NOACCESS
, SPR_NOACCESS
,
8237 &spr_read_generic
, &spr_write_generic
,
8238 KVM_REG_PPC_PID
, 0);
8242 static void gen_spr_power8_rpr(CPUPPCState
*env
)
8244 #if !defined(CONFIG_USER_ONLY)
8245 spr_register_hv(env
, SPR_RPR
, "RPR",
8246 SPR_NOACCESS
, SPR_NOACCESS
,
8247 SPR_NOACCESS
, SPR_NOACCESS
,
8248 &spr_read_generic
, &spr_write_generic
,
8249 0x00000103070F1F3F);
8253 static void init_proc_book3s_common(CPUPPCState
*env
)
8255 gen_spr_ne_601(env
);
8257 gen_spr_usprg3(env
);
8258 gen_spr_book3s_altivec(env
);
8259 gen_spr_book3s_pmu_sup(env
);
8260 gen_spr_book3s_pmu_user(env
);
8261 gen_spr_book3s_ctrl(env
);
8264 static void init_proc_970(CPUPPCState
*env
)
8266 /* Common Registers */
8267 init_proc_book3s_common(env
);
8269 gen_spr_book3s_dbg(env
);
8271 /* 970 Specific Registers */
8272 gen_spr_970_hid(env
);
8273 gen_spr_970_hior(env
);
8275 gen_spr_970_pmu_sup(env
);
8276 gen_spr_970_pmu_user(env
);
8277 gen_spr_970_lpar(env
);
8278 gen_spr_970_dbg(env
);
8281 #if !defined(CONFIG_USER_ONLY)
8284 env
->dcache_line_size
= 128;
8285 env
->icache_line_size
= 128;
8287 /* Allocate hardware IRQ controller */
8289 ppc970_irq_init(ppc_env_get_cpu(env
));
8292 POWERPC_FAMILY(970)(ObjectClass
*oc
, void *data
)
8294 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8295 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8297 dc
->desc
= "PowerPC 970";
8298 pcc
->init_proc
= init_proc_970
;
8299 pcc
->check_pow
= check_pow_970
;
8300 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
8301 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8302 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8304 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8305 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8306 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8307 PPC_64B
| PPC_ALTIVEC
|
8308 PPC_SEGMENT_64B
| PPC_SLBI
;
8309 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
8310 pcc
->msr_mask
= (1ull << MSR_SF
) |
8325 pcc
->mmu_model
= POWERPC_MMU_64B
;
8326 #if defined(CONFIG_SOFTMMU)
8327 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8329 pcc
->excp_model
= POWERPC_EXCP_970
;
8330 pcc
->bus_model
= PPC_FLAGS_INPUT_970
;
8331 pcc
->bfd_mach
= bfd_mach_ppc64
;
8332 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8333 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8334 POWERPC_FLAG_BUS_CLK
;
8335 pcc
->l1_dcache_size
= 0x8000;
8336 pcc
->l1_icache_size
= 0x10000;
8339 static void init_proc_power5plus(CPUPPCState
*env
)
8341 /* Common Registers */
8342 init_proc_book3s_common(env
);
8344 gen_spr_book3s_dbg(env
);
8346 /* POWER5+ Specific Registers */
8347 gen_spr_970_hid(env
);
8348 gen_spr_970_hior(env
);
8350 gen_spr_970_pmu_sup(env
);
8351 gen_spr_970_pmu_user(env
);
8352 gen_spr_power5p_common(env
);
8353 gen_spr_power5p_lpar(env
);
8354 gen_spr_power5p_ear(env
);
8357 #if !defined(CONFIG_USER_ONLY)
8360 env
->dcache_line_size
= 128;
8361 env
->icache_line_size
= 128;
8363 /* Allocate hardware IRQ controller */
8365 ppc970_irq_init(ppc_env_get_cpu(env
));
8368 POWERPC_FAMILY(POWER5P
)(ObjectClass
*oc
, void *data
)
8370 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8371 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8373 dc
->fw_name
= "PowerPC,POWER5";
8374 dc
->desc
= "POWER5+";
8375 pcc
->init_proc
= init_proc_power5plus
;
8376 pcc
->check_pow
= check_pow_970
;
8377 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
8378 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8379 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8381 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8382 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8383 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8385 PPC_SEGMENT_64B
| PPC_SLBI
;
8386 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
8387 pcc
->msr_mask
= (1ull << MSR_SF
) |
8402 pcc
->mmu_model
= POWERPC_MMU_2_03
;
8403 #if defined(CONFIG_SOFTMMU)
8404 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8406 pcc
->excp_model
= POWERPC_EXCP_970
;
8407 pcc
->bus_model
= PPC_FLAGS_INPUT_970
;
8408 pcc
->bfd_mach
= bfd_mach_ppc64
;
8409 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8410 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8411 POWERPC_FLAG_BUS_CLK
;
8412 pcc
->l1_dcache_size
= 0x8000;
8413 pcc
->l1_icache_size
= 0x10000;
8416 static void powerpc_get_compat(Object
*obj
, Visitor
*v
, const char *name
,
8417 void *opaque
, Error
**errp
)
8419 char *value
= (char *)"";
8420 Property
*prop
= opaque
;
8421 uint32_t *max_compat
= qdev_get_prop_ptr(DEVICE(obj
), prop
);
8423 switch (*max_compat
) {
8424 case CPU_POWERPC_LOGICAL_2_05
:
8425 value
= (char *)"power6";
8427 case CPU_POWERPC_LOGICAL_2_06
:
8428 value
= (char *)"power7";
8430 case CPU_POWERPC_LOGICAL_2_07
:
8431 value
= (char *)"power8";
8436 error_report("Internal error: compat is set to %x", *max_compat
);
8441 visit_type_str(v
, name
, &value
, errp
);
8444 static void powerpc_set_compat(Object
*obj
, Visitor
*v
, const char *name
,
8445 void *opaque
, Error
**errp
)
8447 Error
*error
= NULL
;
8449 Property
*prop
= opaque
;
8450 uint32_t *max_compat
= qdev_get_prop_ptr(DEVICE(obj
), prop
);
8452 visit_type_str(v
, name
, &value
, &error
);
8454 error_propagate(errp
, error
);
8458 if (strcmp(value
, "power6") == 0) {
8459 *max_compat
= CPU_POWERPC_LOGICAL_2_05
;
8460 } else if (strcmp(value
, "power7") == 0) {
8461 *max_compat
= CPU_POWERPC_LOGICAL_2_06
;
8462 } else if (strcmp(value
, "power8") == 0) {
8463 *max_compat
= CPU_POWERPC_LOGICAL_2_07
;
8465 error_setg(errp
, "Invalid compatibility mode \"%s\"", value
);
8471 static PropertyInfo powerpc_compat_propinfo
= {
8473 .description
= "compatibility mode, power6/power7/power8",
8474 .get
= powerpc_get_compat
,
8475 .set
= powerpc_set_compat
,
8478 #define DEFINE_PROP_POWERPC_COMPAT(_n, _s, _f) \
8479 DEFINE_PROP(_n, _s, _f, powerpc_compat_propinfo, uint32_t)
8481 static Property powerpc_servercpu_properties
[] = {
8482 DEFINE_PROP_POWERPC_COMPAT("compat", PowerPCCPU
, max_compat
),
8483 DEFINE_PROP_END_OF_LIST(),
8486 #ifdef CONFIG_SOFTMMU
8487 static const struct ppc_segment_page_sizes POWER7_POWER8_sps
= {
8490 .page_shift
= 12, /* 4K */
8492 .enc
= { { .page_shift
= 12, .pte_enc
= 0 },
8493 { .page_shift
= 16, .pte_enc
= 0x7 },
8494 { .page_shift
= 24, .pte_enc
= 0x38 }, },
8497 .page_shift
= 16, /* 64K */
8498 .slb_enc
= SLB_VSID_64K
,
8499 .enc
= { { .page_shift
= 16, .pte_enc
= 0x1 },
8500 { .page_shift
= 24, .pte_enc
= 0x8 }, },
8503 .page_shift
= 24, /* 16M */
8504 .slb_enc
= SLB_VSID_16M
,
8505 .enc
= { { .page_shift
= 24, .pte_enc
= 0 }, },
8508 .page_shift
= 34, /* 16G */
8509 .slb_enc
= SLB_VSID_16G
,
8510 .enc
= { { .page_shift
= 34, .pte_enc
= 0x3 }, },
8514 #endif /* CONFIG_SOFTMMU */
8516 static void init_proc_POWER7(CPUPPCState
*env
)
8518 /* Common Registers */
8519 init_proc_book3s_common(env
);
8521 gen_spr_book3s_dbg(env
);
8523 /* POWER7 Specific Registers */
8524 gen_spr_book3s_ids(env
);
8526 gen_spr_book3s_purr(env
);
8527 gen_spr_power5p_common(env
);
8528 gen_spr_power5p_lpar(env
);
8529 gen_spr_power5p_ear(env
);
8530 gen_spr_power6_common(env
);
8531 gen_spr_power6_dbg(env
);
8532 gen_spr_power7_book4(env
);
8535 #if !defined(CONFIG_USER_ONLY)
8538 env
->ci_large_pages
= true;
8539 env
->dcache_line_size
= 128;
8540 env
->icache_line_size
= 128;
8542 /* Allocate hardware IRQ controller */
8543 init_excp_POWER7(env
);
8544 ppcPOWER7_irq_init(ppc_env_get_cpu(env
));
8547 static bool ppc_pvr_match_power7(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8549 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER7P_BASE
) {
8552 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER7_BASE
) {
8558 static bool cpu_has_work_POWER7(CPUState
*cs
)
8560 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8561 CPUPPCState
*env
= &cpu
->env
;
8564 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8567 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8568 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE0
)) {
8571 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8572 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE1
)) {
8575 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
)) &&
8576 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE2
)) {
8579 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HMI
)) &&
8580 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE2
)) {
8583 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8588 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8592 POWERPC_FAMILY(POWER7
)(ObjectClass
*oc
, void *data
)
8594 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8595 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8596 CPUClass
*cc
= CPU_CLASS(oc
);
8598 dc
->fw_name
= "PowerPC,POWER7";
8599 dc
->desc
= "POWER7";
8600 dc
->props
= powerpc_servercpu_properties
;
8601 pcc
->pvr_match
= ppc_pvr_match_power7
;
8602 pcc
->pcr_mask
= PCR_VEC_DIS
| PCR_VSX_DIS
| PCR_COMPAT_2_05
;
8603 pcc
->pcr_supported
= PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8604 pcc
->init_proc
= init_proc_POWER7
;
8605 pcc
->check_pow
= check_pow_nocheck
;
8606 cc
->has_work
= cpu_has_work_POWER7
;
8607 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8608 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8609 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8610 PPC_FLOAT_FRSQRTES
|
8613 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8614 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8615 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8616 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
8617 PPC_SEGMENT_64B
| PPC_SLBI
|
8618 PPC_POPCNTB
| PPC_POPCNTWD
|
8620 pcc
->insns_flags2
= PPC2_VSX
| PPC2_DFP
| PPC2_DBRX
| PPC2_ISA205
|
8621 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8622 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8623 PPC2_FP_TST_ISA206
| PPC2_FP_CVT_S64
|
8625 pcc
->msr_mask
= (1ull << MSR_SF
) |
8641 pcc
->mmu_model
= POWERPC_MMU_2_06
;
8642 #if defined(CONFIG_SOFTMMU)
8643 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8644 pcc
->sps
= &POWER7_POWER8_sps
;
8646 pcc
->excp_model
= POWERPC_EXCP_POWER7
;
8647 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8648 pcc
->bfd_mach
= bfd_mach_ppc64
;
8649 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8650 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8651 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8653 pcc
->l1_dcache_size
= 0x8000;
8654 pcc
->l1_icache_size
= 0x8000;
8655 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8658 static void init_proc_POWER8(CPUPPCState
*env
)
8660 /* Common Registers */
8661 init_proc_book3s_common(env
);
8663 gen_spr_book3s_207_dbg(env
);
8665 /* POWER8 Specific Registers */
8666 gen_spr_book3s_ids(env
);
8669 gen_spr_book3s_purr(env
);
8670 gen_spr_power5p_common(env
);
8671 gen_spr_power5p_lpar(env
);
8672 gen_spr_power5p_ear(env
);
8673 gen_spr_power6_common(env
);
8674 gen_spr_power6_dbg(env
);
8675 gen_spr_power8_tce_address_control(env
);
8676 gen_spr_power8_ids(env
);
8677 gen_spr_power8_ebb(env
);
8678 gen_spr_power8_fscr(env
);
8679 gen_spr_power8_pmu_sup(env
);
8680 gen_spr_power8_pmu_user(env
);
8681 gen_spr_power8_tm(env
);
8682 gen_spr_power8_pspb(env
);
8684 gen_spr_power8_ic(env
);
8685 gen_spr_power8_book4(env
);
8686 gen_spr_power8_rpr(env
);
8689 #if !defined(CONFIG_USER_ONLY)
8692 env
->ci_large_pages
= true;
8693 env
->dcache_line_size
= 128;
8694 env
->icache_line_size
= 128;
8696 /* Allocate hardware IRQ controller */
8697 init_excp_POWER8(env
);
8698 ppcPOWER7_irq_init(ppc_env_get_cpu(env
));
8701 static bool ppc_pvr_match_power8(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8703 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8NVL_BASE
) {
8706 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8E_BASE
) {
8709 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8_BASE
) {
8715 static bool cpu_has_work_POWER8(CPUState
*cs
)
8717 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8718 CPUPPCState
*env
= &cpu
->env
;
8721 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8724 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8725 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE2
)) {
8728 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8729 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE3
)) {
8732 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
)) &&
8733 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE4
)) {
8736 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HMI
)) &&
8737 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE4
)) {
8740 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DOORBELL
)) &&
8741 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE0
)) {
8744 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HDOORBELL
)) &&
8745 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE1
)) {
8748 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8753 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8757 POWERPC_FAMILY(POWER8
)(ObjectClass
*oc
, void *data
)
8759 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8760 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8761 CPUClass
*cc
= CPU_CLASS(oc
);
8763 dc
->fw_name
= "PowerPC,POWER8";
8764 dc
->desc
= "POWER8";
8765 dc
->props
= powerpc_servercpu_properties
;
8766 pcc
->pvr_match
= ppc_pvr_match_power8
;
8767 pcc
->pcr_mask
= PCR_TM_DIS
| PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8768 pcc
->pcr_supported
= PCR_COMPAT_2_07
| PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8769 pcc
->init_proc
= init_proc_POWER8
;
8770 pcc
->check_pow
= check_pow_nocheck
;
8771 cc
->has_work
= cpu_has_work_POWER8
;
8772 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8773 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8774 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8775 PPC_FLOAT_FRSQRTES
|
8778 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8779 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8780 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8781 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
8782 PPC_SEGMENT_64B
| PPC_SLBI
|
8783 PPC_POPCNTB
| PPC_POPCNTWD
|
8785 pcc
->insns_flags2
= PPC2_VSX
| PPC2_VSX207
| PPC2_DFP
| PPC2_DBRX
|
8786 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8787 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8788 PPC2_FP_TST_ISA206
| PPC2_BCTAR_ISA207
|
8789 PPC2_LSQ_ISA207
| PPC2_ALTIVEC_207
|
8790 PPC2_ISA205
| PPC2_ISA207S
| PPC2_FP_CVT_S64
|
8791 PPC2_TM
| PPC2_PM_ISA206
;
8792 pcc
->msr_mask
= (1ull << MSR_SF
) |
8810 pcc
->mmu_model
= POWERPC_MMU_2_07
;
8811 #if defined(CONFIG_SOFTMMU)
8812 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8813 pcc
->sps
= &POWER7_POWER8_sps
;
8815 pcc
->excp_model
= POWERPC_EXCP_POWER8
;
8816 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8817 pcc
->bfd_mach
= bfd_mach_ppc64
;
8818 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8819 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8820 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8821 POWERPC_FLAG_VSX
| POWERPC_FLAG_TM
;
8822 pcc
->l1_dcache_size
= 0x8000;
8823 pcc
->l1_icache_size
= 0x8000;
8824 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8827 #ifdef CONFIG_SOFTMMU
8829 * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
8830 * Encoded as array of int_32s in the form:
8831 * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
8833 * y -> radix mode supported page size (encoded as a shift)
8835 static struct ppc_radix_page_info POWER9_radix_page_info
= {
8838 0x0000000c, /* 4K - enc: 0x0 */
8839 0xa0000010, /* 64K - enc: 0x5 */
8840 0x20000015, /* 2M - enc: 0x1 */
8841 0x4000001e /* 1G - enc: 0x2 */
8844 #endif /* CONFIG_SOFTMMU */
8846 static void init_proc_POWER9(CPUPPCState
*env
)
8848 /* Common Registers */
8849 init_proc_book3s_common(env
);
8850 gen_spr_book3s_207_dbg(env
);
8852 /* POWER8 Specific Registers */
8853 gen_spr_book3s_ids(env
);
8856 gen_spr_book3s_purr(env
);
8857 gen_spr_power5p_common(env
);
8858 gen_spr_power5p_lpar(env
);
8859 gen_spr_power5p_ear(env
);
8860 gen_spr_power6_common(env
);
8861 gen_spr_power6_dbg(env
);
8862 gen_spr_power8_tce_address_control(env
);
8863 gen_spr_power8_ids(env
);
8864 gen_spr_power8_ebb(env
);
8865 gen_spr_power8_fscr(env
);
8866 gen_spr_power8_pmu_sup(env
);
8867 gen_spr_power8_pmu_user(env
);
8868 gen_spr_power8_tm(env
);
8869 gen_spr_power8_pspb(env
);
8871 gen_spr_power8_ic(env
);
8872 gen_spr_power8_book4(env
);
8873 gen_spr_power8_rpr(env
);
8876 #if !defined(CONFIG_USER_ONLY)
8879 env
->ci_large_pages
= true;
8880 env
->dcache_line_size
= 128;
8881 env
->icache_line_size
= 128;
8883 /* Allocate hardware IRQ controller */
8884 init_excp_POWER8(env
);
8885 ppcPOWER7_irq_init(ppc_env_get_cpu(env
));
8888 static bool ppc_pvr_match_power9(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8890 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER9_BASE
) {
8896 static bool cpu_has_work_POWER9(CPUState
*cs
)
8898 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8899 CPUPPCState
*env
= &cpu
->env
;
8902 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8905 /* External Exception */
8906 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8907 (env
->spr
[SPR_LPCR
] & LPCR_EEE
)) {
8910 /* Decrementer Exception */
8911 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8912 (env
->spr
[SPR_LPCR
] & LPCR_DEE
)) {
8915 /* Machine Check or Hypervisor Maintenance Exception */
8916 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
|
8917 1u << PPC_INTERRUPT_HMI
)) && (env
->spr
[SPR_LPCR
] & LPCR_OEE
)) {
8920 /* Privileged Doorbell Exception */
8921 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DOORBELL
)) &&
8922 (env
->spr
[SPR_LPCR
] & LPCR_PDEE
)) {
8925 /* Hypervisor Doorbell Exception */
8926 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HDOORBELL
)) &&
8927 (env
->spr
[SPR_LPCR
] & LPCR_HDEE
)) {
8930 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8935 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8939 POWERPC_FAMILY(POWER9
)(ObjectClass
*oc
, void *data
)
8941 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8942 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8943 CPUClass
*cc
= CPU_CLASS(oc
);
8945 dc
->fw_name
= "PowerPC,POWER9";
8946 dc
->desc
= "POWER9";
8947 dc
->props
= powerpc_servercpu_properties
;
8948 pcc
->pvr_match
= ppc_pvr_match_power9
;
8949 pcc
->pcr_mask
= PCR_COMPAT_2_05
| PCR_COMPAT_2_06
| PCR_COMPAT_2_07
;
8950 pcc
->pcr_supported
= PCR_COMPAT_3_00
| PCR_COMPAT_2_07
| PCR_COMPAT_2_06
|
8952 pcc
->init_proc
= init_proc_POWER9
;
8953 pcc
->check_pow
= check_pow_nocheck
;
8954 cc
->has_work
= cpu_has_work_POWER9
;
8955 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8956 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8957 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8958 PPC_FLOAT_FRSQRTES
|
8961 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8962 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8964 PPC_64B
| PPC_64BX
| PPC_ALTIVEC
|
8965 PPC_SEGMENT_64B
| PPC_SLBI
|
8966 PPC_POPCNTB
| PPC_POPCNTWD
|
8968 pcc
->insns_flags2
= PPC2_VSX
| PPC2_VSX207
| PPC2_DFP
| PPC2_DBRX
|
8969 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8970 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8971 PPC2_FP_TST_ISA206
| PPC2_BCTAR_ISA207
|
8972 PPC2_LSQ_ISA207
| PPC2_ALTIVEC_207
|
8973 PPC2_ISA205
| PPC2_ISA207S
| PPC2_FP_CVT_S64
|
8974 PPC2_TM
| PPC2_PM_ISA206
| PPC2_ISA300
;
8975 pcc
->msr_mask
= (1ull << MSR_SF
) |
8992 pcc
->mmu_model
= POWERPC_MMU_3_00
;
8993 #if defined(CONFIG_SOFTMMU)
8994 pcc
->handle_mmu_fault
= ppc64_v3_handle_mmu_fault
;
8995 /* segment page size remain the same */
8996 pcc
->sps
= &POWER7_POWER8_sps
;
8997 pcc
->radix_page_info
= &POWER9_radix_page_info
;
8999 pcc
->excp_model
= POWERPC_EXCP_POWER8
;
9000 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
9001 pcc
->bfd_mach
= bfd_mach_ppc64
;
9002 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
9003 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
9004 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
9005 POWERPC_FLAG_VSX
| POWERPC_FLAG_TM
;
9006 pcc
->l1_dcache_size
= 0x8000;
9007 pcc
->l1_icache_size
= 0x8000;
9008 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
9011 #if !defined(CONFIG_USER_ONLY)
9012 void cpu_ppc_set_papr(PowerPCCPU
*cpu
, PPCVirtualHypervisor
*vhyp
)
9014 CPUPPCState
*env
= &cpu
->env
;
9015 ppc_spr_t
*lpcr
= &env
->spr_cb
[SPR_LPCR
];
9016 ppc_spr_t
*amor
= &env
->spr_cb
[SPR_AMOR
];
9020 /* PAPR always has exception vectors in RAM not ROM. To ensure this,
9021 * MSR[IP] should never be set.
9023 * We also disallow setting of MSR_HV
9025 env
->msr_mask
&= ~((1ull << MSR_EP
) | MSR_HVB
);
9027 /* Set emulated LPCR to not send interrupts to hypervisor. Note that
9028 * under KVM, the actual HW LPCR will be set differently by KVM itself,
9029 * the settings below ensure proper operations with TCG in absence of
9030 * a real hypervisor.
9032 * Clearing VPM0 will also cause us to use RMOR in mmu-hash64.c for
9033 * real mode accesses, which thankfully defaults to 0 and isn't
9034 * accessible in guest mode.
9036 lpcr
->default_value
&= ~(LPCR_VPM0
| LPCR_VPM1
| LPCR_ISL
| LPCR_KBV
);
9037 lpcr
->default_value
|= LPCR_LPES0
| LPCR_LPES1
;
9039 /* Set RMLS to the max (ie, 16G) */
9040 lpcr
->default_value
&= ~LPCR_RMLS
;
9041 lpcr
->default_value
|= 1ull << LPCR_RMLS_SHIFT
;
9043 switch (env
->mmu_model
) {
9044 case POWERPC_MMU_3_00
:
9045 /* By default we choose legacy mode and switch to new hash or radix
9046 * when a register process table hcall is made. So disable process
9047 * tables and guest translation shootdown by default
9049 lpcr
->default_value
&= ~(LPCR_UPRT
| LPCR_GTSE
);
9050 lpcr
->default_value
|= LPCR_PDEE
| LPCR_HDEE
| LPCR_EEE
| LPCR_DEE
|
9054 /* P7 and P8 has slightly different PECE bits, mostly because P8 adds
9055 * bit 47 and 48 which are reserved on P7. Here we set them all, which
9056 * will work as expected for both implementations
9058 lpcr
->default_value
|= LPCR_P8_PECE0
| LPCR_P8_PECE1
| LPCR_P8_PECE2
|
9059 LPCR_P8_PECE3
| LPCR_P8_PECE4
;
9062 /* We should be followed by a CPU reset but update the active value
9065 env
->spr
[SPR_LPCR
] = lpcr
->default_value
;
9067 /* Set a full AMOR so guest can use the AMR as it sees fit */
9068 env
->spr
[SPR_AMOR
] = amor
->default_value
= 0xffffffffffffffffull
;
9070 /* Update some env bits based on new LPCR value */
9071 ppc_hash64_update_rmls(env
);
9072 ppc_hash64_update_vrma(env
);
9074 /* Tell KVM that we're in PAPR mode */
9075 if (kvm_enabled()) {
9076 kvmppc_set_papr(cpu
);
9080 #endif /* !defined(CONFIG_USER_ONLY) */
9082 #endif /* defined(TARGET_PPC64) */
9084 /*****************************************************************************/
9085 /* Generic CPU instantiation routine */
9086 static void init_ppc_proc(PowerPCCPU
*cpu
)
9088 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9089 CPUPPCState
*env
= &cpu
->env
;
9090 #if !defined(CONFIG_USER_ONLY)
9093 env
->irq_inputs
= NULL
;
9094 /* Set all exception vectors to an invalid address */
9095 for (i
= 0; i
< POWERPC_EXCP_NB
; i
++)
9096 env
->excp_vectors
[i
] = (target_ulong
)(-1ULL);
9097 env
->ivor_mask
= 0x00000000;
9098 env
->ivpr_mask
= 0x00000000;
9099 /* Default MMU definitions */
9103 env
->tlb_type
= TLB_NONE
;
9105 /* Register SPR common to all PowerPC implementations */
9106 gen_spr_generic(env
);
9107 spr_register(env
, SPR_PVR
, "PVR",
9108 /* Linux permits userspace to read PVR */
9109 #if defined(CONFIG_LINUX_USER)
9115 &spr_read_generic
, SPR_NOACCESS
,
9117 /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
9118 if (pcc
->svr
!= POWERPC_SVR_NONE
) {
9119 if (pcc
->svr
& POWERPC_SVR_E500
) {
9120 spr_register(env
, SPR_E500_SVR
, "SVR",
9121 SPR_NOACCESS
, SPR_NOACCESS
,
9122 &spr_read_generic
, SPR_NOACCESS
,
9123 pcc
->svr
& ~POWERPC_SVR_E500
);
9125 spr_register(env
, SPR_SVR
, "SVR",
9126 SPR_NOACCESS
, SPR_NOACCESS
,
9127 &spr_read_generic
, SPR_NOACCESS
,
9131 /* PowerPC implementation specific initialisations (SPRs, timers, ...) */
9132 (*pcc
->init_proc
)(env
);
9134 /* MSR bits & flags consistency checks */
9135 if (env
->msr_mask
& (1 << 25)) {
9136 switch (env
->flags
& (POWERPC_FLAG_SPE
| POWERPC_FLAG_VRE
)) {
9137 case POWERPC_FLAG_SPE
:
9138 case POWERPC_FLAG_VRE
:
9141 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9142 "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n");
9145 } else if (env
->flags
& (POWERPC_FLAG_SPE
| POWERPC_FLAG_VRE
)) {
9146 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9147 "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n");
9150 if (env
->msr_mask
& (1 << 17)) {
9151 switch (env
->flags
& (POWERPC_FLAG_TGPR
| POWERPC_FLAG_CE
)) {
9152 case POWERPC_FLAG_TGPR
:
9153 case POWERPC_FLAG_CE
:
9156 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9157 "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n");
9160 } else if (env
->flags
& (POWERPC_FLAG_TGPR
| POWERPC_FLAG_CE
)) {
9161 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9162 "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n");
9165 if (env
->msr_mask
& (1 << 10)) {
9166 switch (env
->flags
& (POWERPC_FLAG_SE
| POWERPC_FLAG_DWE
|
9167 POWERPC_FLAG_UBLE
)) {
9168 case POWERPC_FLAG_SE
:
9169 case POWERPC_FLAG_DWE
:
9170 case POWERPC_FLAG_UBLE
:
9173 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9174 "Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE or "
9175 "POWERPC_FLAG_UBLE\n");
9178 } else if (env
->flags
& (POWERPC_FLAG_SE
| POWERPC_FLAG_DWE
|
9179 POWERPC_FLAG_UBLE
)) {
9180 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9181 "Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE nor "
9182 "POWERPC_FLAG_UBLE\n");
9185 if (env
->msr_mask
& (1 << 9)) {
9186 switch (env
->flags
& (POWERPC_FLAG_BE
| POWERPC_FLAG_DE
)) {
9187 case POWERPC_FLAG_BE
:
9188 case POWERPC_FLAG_DE
:
9191 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9192 "Should define POWERPC_FLAG_BE or POWERPC_FLAG_DE\n");
9195 } else if (env
->flags
& (POWERPC_FLAG_BE
| POWERPC_FLAG_DE
)) {
9196 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9197 "Should not define POWERPC_FLAG_BE nor POWERPC_FLAG_DE\n");
9200 if (env
->msr_mask
& (1 << 2)) {
9201 switch (env
->flags
& (POWERPC_FLAG_PX
| POWERPC_FLAG_PMM
)) {
9202 case POWERPC_FLAG_PX
:
9203 case POWERPC_FLAG_PMM
:
9206 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9207 "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n");
9210 } else if (env
->flags
& (POWERPC_FLAG_PX
| POWERPC_FLAG_PMM
)) {
9211 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9212 "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
9215 if ((env
->flags
& (POWERPC_FLAG_RTC_CLK
| POWERPC_FLAG_BUS_CLK
)) == 0) {
9216 fprintf(stderr
, "PowerPC flags inconsistency\n"
9217 "Should define the time-base and decrementer clock source\n");
9220 /* Allocate TLBs buffer when needed */
9221 #if !defined(CONFIG_USER_ONLY)
9222 if (env
->nb_tlb
!= 0) {
9223 int nb_tlb
= env
->nb_tlb
;
9224 if (env
->id_tlbs
!= 0)
9226 switch (env
->tlb_type
) {
9228 env
->tlb
.tlb6
= g_malloc0(nb_tlb
* sizeof(ppc6xx_tlb_t
));
9231 env
->tlb
.tlbe
= g_malloc0(nb_tlb
* sizeof(ppcemb_tlb_t
));
9234 env
->tlb
.tlbm
= g_malloc0(nb_tlb
* sizeof(ppcmas_tlb_t
));
9237 /* Pre-compute some useful values */
9238 env
->tlb_per_way
= env
->nb_tlb
/ env
->nb_ways
;
9240 if (env
->irq_inputs
== NULL
) {
9241 fprintf(stderr
, "WARNING: no internal IRQ controller registered.\n"
9242 " Attempt QEMU to crash very soon !\n");
9245 if (env
->check_pow
== NULL
) {
9246 fprintf(stderr
, "WARNING: no power management check handler "
9248 " Attempt QEMU to crash very soon !\n");
9252 #if defined(PPC_DUMP_CPU)
9253 static void dump_ppc_sprs(CPUPPCState
*env
)
9256 #if !defined(CONFIG_USER_ONLY)
9262 printf("Special purpose registers:\n");
9263 for (i
= 0; i
< 32; i
++) {
9264 for (j
= 0; j
< 32; j
++) {
9266 spr
= &env
->spr_cb
[n
];
9267 uw
= spr
->uea_write
!= NULL
&& spr
->uea_write
!= SPR_NOACCESS
;
9268 ur
= spr
->uea_read
!= NULL
&& spr
->uea_read
!= SPR_NOACCESS
;
9269 #if !defined(CONFIG_USER_ONLY)
9270 sw
= spr
->oea_write
!= NULL
&& spr
->oea_write
!= SPR_NOACCESS
;
9271 sr
= spr
->oea_read
!= NULL
&& spr
->oea_read
!= SPR_NOACCESS
;
9272 if (sw
|| sr
|| uw
|| ur
) {
9273 printf("SPR: %4d (%03x) %-8s s%c%c u%c%c\n",
9274 (i
<< 5) | j
, (i
<< 5) | j
, spr
->name
,
9275 sw
? 'w' : '-', sr
? 'r' : '-',
9276 uw
? 'w' : '-', ur
? 'r' : '-');
9280 printf("SPR: %4d (%03x) %-8s u%c%c\n",
9281 (i
<< 5) | j
, (i
<< 5) | j
, spr
->name
,
9282 uw
? 'w' : '-', ur
? 'r' : '-');
9292 /*****************************************************************************/
9296 PPC_DIRECT
= 0, /* Opcode routine */
9297 PPC_INDIRECT
= 1, /* Indirect opcode table */
9300 #define PPC_OPCODE_MASK 0x3
9302 static inline int is_indirect_opcode(void *handler
)
9304 return ((uintptr_t)handler
& PPC_OPCODE_MASK
) == PPC_INDIRECT
;
9307 static inline opc_handler_t
**ind_table(void *handler
)
9309 return (opc_handler_t
**)((uintptr_t)handler
& ~PPC_OPCODE_MASK
);
9312 /* Instruction table creation */
9313 /* Opcodes tables creation */
9314 static void fill_new_table(opc_handler_t
**table
, int len
)
9318 for (i
= 0; i
< len
; i
++)
9319 table
[i
] = &invalid_handler
;
9322 static int create_new_table(opc_handler_t
**table
, unsigned char idx
)
9324 opc_handler_t
**tmp
;
9326 tmp
= g_new(opc_handler_t
*, PPC_CPU_INDIRECT_OPCODES_LEN
);
9327 fill_new_table(tmp
, PPC_CPU_INDIRECT_OPCODES_LEN
);
9328 table
[idx
] = (opc_handler_t
*)((uintptr_t)tmp
| PPC_INDIRECT
);
9333 static int insert_in_table(opc_handler_t
**table
, unsigned char idx
,
9334 opc_handler_t
*handler
)
9336 if (table
[idx
] != &invalid_handler
)
9338 table
[idx
] = handler
;
9343 static int register_direct_insn(opc_handler_t
**ppc_opcodes
,
9344 unsigned char idx
, opc_handler_t
*handler
)
9346 if (insert_in_table(ppc_opcodes
, idx
, handler
) < 0) {
9347 printf("*** ERROR: opcode %02x already assigned in main "
9348 "opcode table\n", idx
);
9349 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9350 printf(" Registered handler '%s' - new handler '%s'\n",
9351 ppc_opcodes
[idx
]->oname
, handler
->oname
);
9359 static int register_ind_in_table(opc_handler_t
**table
,
9360 unsigned char idx1
, unsigned char idx2
,
9361 opc_handler_t
*handler
)
9363 if (table
[idx1
] == &invalid_handler
) {
9364 if (create_new_table(table
, idx1
) < 0) {
9365 printf("*** ERROR: unable to create indirect table "
9366 "idx=%02x\n", idx1
);
9370 if (!is_indirect_opcode(table
[idx1
])) {
9371 printf("*** ERROR: idx %02x already assigned to a direct "
9373 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9374 printf(" Registered handler '%s' - new handler '%s'\n",
9375 ind_table(table
[idx1
])[idx2
]->oname
, handler
->oname
);
9380 if (handler
!= NULL
&&
9381 insert_in_table(ind_table(table
[idx1
]), idx2
, handler
) < 0) {
9382 printf("*** ERROR: opcode %02x already assigned in "
9383 "opcode table %02x\n", idx2
, idx1
);
9384 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9385 printf(" Registered handler '%s' - new handler '%s'\n",
9386 ind_table(table
[idx1
])[idx2
]->oname
, handler
->oname
);
9394 static int register_ind_insn(opc_handler_t
**ppc_opcodes
,
9395 unsigned char idx1
, unsigned char idx2
,
9396 opc_handler_t
*handler
)
9398 return register_ind_in_table(ppc_opcodes
, idx1
, idx2
, handler
);
9401 static int register_dblind_insn(opc_handler_t
**ppc_opcodes
,
9402 unsigned char idx1
, unsigned char idx2
,
9403 unsigned char idx3
, opc_handler_t
*handler
)
9405 if (register_ind_in_table(ppc_opcodes
, idx1
, idx2
, NULL
) < 0) {
9406 printf("*** ERROR: unable to join indirect table idx "
9407 "[%02x-%02x]\n", idx1
, idx2
);
9410 if (register_ind_in_table(ind_table(ppc_opcodes
[idx1
]), idx2
, idx3
,
9412 printf("*** ERROR: unable to insert opcode "
9413 "[%02x-%02x-%02x]\n", idx1
, idx2
, idx3
);
9420 static int register_trplind_insn(opc_handler_t
**ppc_opcodes
,
9421 unsigned char idx1
, unsigned char idx2
,
9422 unsigned char idx3
, unsigned char idx4
,
9423 opc_handler_t
*handler
)
9425 opc_handler_t
**table
;
9427 if (register_ind_in_table(ppc_opcodes
, idx1
, idx2
, NULL
) < 0) {
9428 printf("*** ERROR: unable to join indirect table idx "
9429 "[%02x-%02x]\n", idx1
, idx2
);
9432 table
= ind_table(ppc_opcodes
[idx1
]);
9433 if (register_ind_in_table(table
, idx2
, idx3
, NULL
) < 0) {
9434 printf("*** ERROR: unable to join 2nd-level indirect table idx "
9435 "[%02x-%02x-%02x]\n", idx1
, idx2
, idx3
);
9438 table
= ind_table(table
[idx2
]);
9439 if (register_ind_in_table(table
, idx3
, idx4
, handler
) < 0) {
9440 printf("*** ERROR: unable to insert opcode "
9441 "[%02x-%02x-%02x-%02x]\n", idx1
, idx2
, idx3
, idx4
);
9446 static int register_insn(opc_handler_t
**ppc_opcodes
, opcode_t
*insn
)
9448 if (insn
->opc2
!= 0xFF) {
9449 if (insn
->opc3
!= 0xFF) {
9450 if (insn
->opc4
!= 0xFF) {
9451 if (register_trplind_insn(ppc_opcodes
, insn
->opc1
, insn
->opc2
,
9452 insn
->opc3
, insn
->opc4
,
9453 &insn
->handler
) < 0) {
9457 if (register_dblind_insn(ppc_opcodes
, insn
->opc1
, insn
->opc2
,
9458 insn
->opc3
, &insn
->handler
) < 0)
9462 if (register_ind_insn(ppc_opcodes
, insn
->opc1
,
9463 insn
->opc2
, &insn
->handler
) < 0)
9467 if (register_direct_insn(ppc_opcodes
, insn
->opc1
, &insn
->handler
) < 0)
9474 static int test_opcode_table(opc_handler_t
**table
, int len
)
9478 for (i
= 0, count
= 0; i
< len
; i
++) {
9479 /* Consistency fixup */
9480 if (table
[i
] == NULL
)
9481 table
[i
] = &invalid_handler
;
9482 if (table
[i
] != &invalid_handler
) {
9483 if (is_indirect_opcode(table
[i
])) {
9484 tmp
= test_opcode_table(ind_table(table
[i
]),
9485 PPC_CPU_INDIRECT_OPCODES_LEN
);
9488 table
[i
] = &invalid_handler
;
9501 static void fix_opcode_tables(opc_handler_t
**ppc_opcodes
)
9503 if (test_opcode_table(ppc_opcodes
, PPC_CPU_OPCODES_LEN
) == 0)
9504 printf("*** WARNING: no opcode defined !\n");
9507 /*****************************************************************************/
9508 static void create_ppc_opcodes(PowerPCCPU
*cpu
, Error
**errp
)
9510 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9511 CPUPPCState
*env
= &cpu
->env
;
9514 fill_new_table(env
->opcodes
, PPC_CPU_OPCODES_LEN
);
9515 for (opc
= opcodes
; opc
< &opcodes
[ARRAY_SIZE(opcodes
)]; opc
++) {
9516 if (((opc
->handler
.type
& pcc
->insns_flags
) != 0) ||
9517 ((opc
->handler
.type2
& pcc
->insns_flags2
) != 0)) {
9518 if (register_insn(env
->opcodes
, opc
) < 0) {
9519 error_setg(errp
, "ERROR initializing PowerPC instruction "
9520 "0x%02x 0x%02x 0x%02x", opc
->opc1
, opc
->opc2
,
9526 fix_opcode_tables(env
->opcodes
);
9531 #if defined(PPC_DUMP_CPU)
9532 static void dump_ppc_insns(CPUPPCState
*env
)
9534 opc_handler_t
**table
, *handler
;
9536 uint8_t opc1
, opc2
, opc3
, opc4
;
9538 printf("Instructions set:\n");
9539 /* opc1 is 6 bits long */
9540 for (opc1
= 0x00; opc1
< PPC_CPU_OPCODES_LEN
; opc1
++) {
9541 table
= env
->opcodes
;
9542 handler
= table
[opc1
];
9543 if (is_indirect_opcode(handler
)) {
9544 /* opc2 is 5 bits long */
9545 for (opc2
= 0; opc2
< PPC_CPU_INDIRECT_OPCODES_LEN
; opc2
++) {
9546 table
= env
->opcodes
;
9547 handler
= env
->opcodes
[opc1
];
9548 table
= ind_table(handler
);
9549 handler
= table
[opc2
];
9550 if (is_indirect_opcode(handler
)) {
9551 table
= ind_table(handler
);
9552 /* opc3 is 5 bits long */
9553 for (opc3
= 0; opc3
< PPC_CPU_INDIRECT_OPCODES_LEN
;
9555 handler
= table
[opc3
];
9556 if (is_indirect_opcode(handler
)) {
9557 table
= ind_table(handler
);
9558 /* opc4 is 5 bits long */
9559 for (opc4
= 0; opc4
< PPC_CPU_INDIRECT_OPCODES_LEN
;
9561 handler
= table
[opc4
];
9562 if (handler
->handler
!= &gen_invalid
) {
9563 printf("INSN: %02x %02x %02x %02x -- "
9564 "(%02d %04d %02d) : %s\n",
9565 opc1
, opc2
, opc3
, opc4
,
9566 opc1
, (opc3
<< 5) | opc2
, opc4
,
9571 if (handler
->handler
!= &gen_invalid
) {
9572 /* Special hack to properly dump SPE insns */
9573 p
= strchr(handler
->oname
, '_');
9575 printf("INSN: %02x %02x %02x (%02d %04d) : "
9577 opc1
, opc2
, opc3
, opc1
,
9582 if ((p
- handler
->oname
) != strlen(q
)
9583 || (memcmp(handler
->oname
, q
, strlen(q
))
9585 /* First instruction */
9586 printf("INSN: %02x %02x %02x"
9587 "(%02d %04d) : %.*s\n",
9588 opc1
, opc2
<< 1, opc3
, opc1
,
9589 (opc3
<< 6) | (opc2
<< 1),
9590 (int)(p
- handler
->oname
),
9593 if (strcmp(p
+ 1, q
) != 0) {
9594 /* Second instruction */
9595 printf("INSN: %02x %02x %02x "
9596 "(%02d %04d) : %s\n", opc1
,
9597 (opc2
<< 1) | 1, opc3
, opc1
,
9598 (opc3
<< 6) | (opc2
<< 1) | 1,
9606 if (handler
->handler
!= &gen_invalid
) {
9607 printf("INSN: %02x %02x -- (%02d %04d) : %s\n",
9608 opc1
, opc2
, opc1
, opc2
, handler
->oname
);
9613 if (handler
->handler
!= &gen_invalid
) {
9614 printf("INSN: %02x -- -- (%02d ----) : %s\n",
9615 opc1
, opc1
, handler
->oname
);
9622 static bool avr_need_swap(CPUPPCState
*env
)
9624 #ifdef HOST_WORDS_BIGENDIAN
9631 static int gdb_get_float_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9634 stfq_p(mem_buf
, env
->fpr
[n
]);
9635 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9639 stl_p(mem_buf
, env
->fpscr
);
9640 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9646 static int gdb_set_float_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9649 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9650 env
->fpr
[n
] = ldfq_p(mem_buf
);
9654 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9655 helper_store_fpscr(env
, ldl_p(mem_buf
), 0xffffffff);
9661 static int gdb_get_avr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9664 if (!avr_need_swap(env
)) {
9665 stq_p(mem_buf
, env
->avr
[n
].u64
[0]);
9666 stq_p(mem_buf
+8, env
->avr
[n
].u64
[1]);
9668 stq_p(mem_buf
, env
->avr
[n
].u64
[1]);
9669 stq_p(mem_buf
+8, env
->avr
[n
].u64
[0]);
9671 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9672 ppc_maybe_bswap_register(env
, mem_buf
+ 8, 8);
9676 stl_p(mem_buf
, env
->vscr
);
9677 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9681 stl_p(mem_buf
, (uint32_t)env
->spr
[SPR_VRSAVE
]);
9682 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9688 static int gdb_set_avr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9691 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9692 ppc_maybe_bswap_register(env
, mem_buf
+ 8, 8);
9693 if (!avr_need_swap(env
)) {
9694 env
->avr
[n
].u64
[0] = ldq_p(mem_buf
);
9695 env
->avr
[n
].u64
[1] = ldq_p(mem_buf
+8);
9697 env
->avr
[n
].u64
[1] = ldq_p(mem_buf
);
9698 env
->avr
[n
].u64
[0] = ldq_p(mem_buf
+8);
9703 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9704 env
->vscr
= ldl_p(mem_buf
);
9708 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9709 env
->spr
[SPR_VRSAVE
] = (target_ulong
)ldl_p(mem_buf
);
9715 static int gdb_get_spe_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9718 #if defined(TARGET_PPC64)
9719 stl_p(mem_buf
, env
->gpr
[n
] >> 32);
9720 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9722 stl_p(mem_buf
, env
->gprh
[n
]);
9727 stq_p(mem_buf
, env
->spe_acc
);
9728 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9732 stl_p(mem_buf
, env
->spe_fscr
);
9733 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9739 static int gdb_set_spe_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9742 #if defined(TARGET_PPC64)
9743 target_ulong lo
= (uint32_t)env
->gpr
[n
];
9746 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9748 hi
= (target_ulong
)ldl_p(mem_buf
) << 32;
9749 env
->gpr
[n
] = lo
| hi
;
9751 env
->gprh
[n
] = ldl_p(mem_buf
);
9756 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9757 env
->spe_acc
= ldq_p(mem_buf
);
9761 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9762 env
->spe_fscr
= ldl_p(mem_buf
);
9768 static int gdb_get_vsx_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9771 stq_p(mem_buf
, env
->vsr
[n
]);
9772 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9778 static int gdb_set_vsx_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9781 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9782 env
->vsr
[n
] = ldq_p(mem_buf
);
9788 static int ppc_fixup_cpu(PowerPCCPU
*cpu
)
9790 CPUPPCState
*env
= &cpu
->env
;
9792 /* TCG doesn't (yet) emulate some groups of instructions that
9793 * are implemented on some otherwise supported CPUs (e.g. VSX
9794 * and decimal floating point instructions on POWER7). We
9795 * remove unsupported instruction groups from the cpu state's
9796 * instruction masks and hope the guest can cope. For at
9797 * least the pseries machine, the unavailability of these
9798 * instructions can be advertised to the guest via the device
9800 if ((env
->insns_flags
& ~PPC_TCG_INSNS
)
9801 || (env
->insns_flags2
& ~PPC_TCG_INSNS2
)) {
9802 fprintf(stderr
, "Warning: Disabling some instructions which are not "
9803 "emulated by TCG (0x%" PRIx64
", 0x%" PRIx64
")\n",
9804 env
->insns_flags
& ~PPC_TCG_INSNS
,
9805 env
->insns_flags2
& ~PPC_TCG_INSNS2
);
9807 env
->insns_flags
&= PPC_TCG_INSNS
;
9808 env
->insns_flags2
&= PPC_TCG_INSNS2
;
9812 static inline bool ppc_cpu_is_valid(PowerPCCPUClass
*pcc
)
9814 #ifdef TARGET_PPCEMB
9815 return pcc
->mmu_model
== POWERPC_MMU_BOOKE
||
9816 pcc
->mmu_model
== POWERPC_MMU_SOFT_4xx
||
9817 pcc
->mmu_model
== POWERPC_MMU_SOFT_4xx_Z
;
9823 static void ppc_cpu_realizefn(DeviceState
*dev
, Error
**errp
)
9825 CPUState
*cs
= CPU(dev
);
9826 PowerPCCPU
*cpu
= POWERPC_CPU(dev
);
9827 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9828 Error
*local_err
= NULL
;
9829 #if !defined(CONFIG_USER_ONLY)
9830 int max_smt
= kvmppc_smt_threads();
9833 #if !defined(CONFIG_USER_ONLY)
9834 if (smp_threads
> max_smt
) {
9835 error_setg(errp
, "Cannot support more than %d threads on PPC with %s",
9836 max_smt
, kvm_enabled() ? "KVM" : "TCG");
9839 if (!is_power_of_2(smp_threads
)) {
9840 error_setg(errp
, "Cannot support %d threads on PPC with %s, "
9841 "threads count must be a power of 2.",
9842 smp_threads
, kvm_enabled() ? "KVM" : "TCG");
9847 cpu_exec_realizefn(cs
, &local_err
);
9848 if (local_err
!= NULL
) {
9849 error_propagate(errp
, local_err
);
9853 #if !defined(CONFIG_USER_ONLY)
9854 cpu
->cpu_dt_id
= (cs
->cpu_index
/ smp_threads
) * max_smt
9855 + (cs
->cpu_index
% smp_threads
);
9857 if (kvm_enabled() && !kvm_vcpu_id_is_valid(cpu
->cpu_dt_id
)) {
9858 error_setg(errp
, "Can't create CPU with id %d in KVM", cpu
->cpu_dt_id
);
9859 error_append_hint(errp
, "Adjust the number of cpus to %d "
9860 "or try to raise the number of threads per core\n",
9861 cpu
->cpu_dt_id
* smp_threads
/ max_smt
);
9866 if (tcg_enabled()) {
9867 if (ppc_fixup_cpu(cpu
) != 0) {
9868 error_setg(errp
, "Unable to emulate selected CPU with TCG");
9873 #if defined(TARGET_PPCEMB)
9874 if (!ppc_cpu_is_valid(pcc
)) {
9875 error_setg(errp
, "CPU does not possess a BookE or 4xx MMU. "
9876 "Please use qemu-system-ppc or qemu-system-ppc64 instead "
9877 "or choose another CPU model.");
9882 create_ppc_opcodes(cpu
, &local_err
);
9883 if (local_err
!= NULL
) {
9884 error_propagate(errp
, local_err
);
9889 if (pcc
->insns_flags
& PPC_FLOAT
) {
9890 gdb_register_coprocessor(cs
, gdb_get_float_reg
, gdb_set_float_reg
,
9891 33, "power-fpu.xml", 0);
9893 if (pcc
->insns_flags
& PPC_ALTIVEC
) {
9894 gdb_register_coprocessor(cs
, gdb_get_avr_reg
, gdb_set_avr_reg
,
9895 34, "power-altivec.xml", 0);
9897 if (pcc
->insns_flags
& PPC_SPE
) {
9898 gdb_register_coprocessor(cs
, gdb_get_spe_reg
, gdb_set_spe_reg
,
9899 34, "power-spe.xml", 0);
9901 if (pcc
->insns_flags2
& PPC2_VSX
) {
9902 gdb_register_coprocessor(cs
, gdb_get_vsx_reg
, gdb_set_vsx_reg
,
9903 32, "power-vsx.xml", 0);
9908 pcc
->parent_realize(dev
, errp
);
9910 #if defined(PPC_DUMP_CPU)
9912 CPUPPCState
*env
= &cpu
->env
;
9913 const char *mmu_model
, *excp_model
, *bus_model
;
9914 switch (env
->mmu_model
) {
9915 case POWERPC_MMU_32B
:
9916 mmu_model
= "PowerPC 32";
9918 case POWERPC_MMU_SOFT_6xx
:
9919 mmu_model
= "PowerPC 6xx/7xx with software driven TLBs";
9921 case POWERPC_MMU_SOFT_74xx
:
9922 mmu_model
= "PowerPC 74xx with software driven TLBs";
9924 case POWERPC_MMU_SOFT_4xx
:
9925 mmu_model
= "PowerPC 4xx with software driven TLBs";
9927 case POWERPC_MMU_SOFT_4xx_Z
:
9928 mmu_model
= "PowerPC 4xx with software driven TLBs "
9929 "and zones protections";
9931 case POWERPC_MMU_REAL
:
9932 mmu_model
= "PowerPC real mode only";
9934 case POWERPC_MMU_MPC8xx
:
9935 mmu_model
= "PowerPC MPC8xx";
9937 case POWERPC_MMU_BOOKE
:
9938 mmu_model
= "PowerPC BookE";
9940 case POWERPC_MMU_BOOKE206
:
9941 mmu_model
= "PowerPC BookE 2.06";
9943 case POWERPC_MMU_601
:
9944 mmu_model
= "PowerPC 601";
9946 #if defined(TARGET_PPC64)
9947 case POWERPC_MMU_64B
:
9948 mmu_model
= "PowerPC 64";
9952 mmu_model
= "Unknown or invalid";
9955 switch (env
->excp_model
) {
9956 case POWERPC_EXCP_STD
:
9957 excp_model
= "PowerPC";
9959 case POWERPC_EXCP_40x
:
9960 excp_model
= "PowerPC 40x";
9962 case POWERPC_EXCP_601
:
9963 excp_model
= "PowerPC 601";
9965 case POWERPC_EXCP_602
:
9966 excp_model
= "PowerPC 602";
9968 case POWERPC_EXCP_603
:
9969 excp_model
= "PowerPC 603";
9971 case POWERPC_EXCP_603E
:
9972 excp_model
= "PowerPC 603e";
9974 case POWERPC_EXCP_604
:
9975 excp_model
= "PowerPC 604";
9977 case POWERPC_EXCP_7x0
:
9978 excp_model
= "PowerPC 740/750";
9980 case POWERPC_EXCP_7x5
:
9981 excp_model
= "PowerPC 745/755";
9983 case POWERPC_EXCP_74xx
:
9984 excp_model
= "PowerPC 74xx";
9986 case POWERPC_EXCP_BOOKE
:
9987 excp_model
= "PowerPC BookE";
9989 #if defined(TARGET_PPC64)
9990 case POWERPC_EXCP_970
:
9991 excp_model
= "PowerPC 970";
9995 excp_model
= "Unknown or invalid";
9998 switch (env
->bus_model
) {
9999 case PPC_FLAGS_INPUT_6xx
:
10000 bus_model
= "PowerPC 6xx";
10002 case PPC_FLAGS_INPUT_BookE
:
10003 bus_model
= "PowerPC BookE";
10005 case PPC_FLAGS_INPUT_405
:
10006 bus_model
= "PowerPC 405";
10008 case PPC_FLAGS_INPUT_401
:
10009 bus_model
= "PowerPC 401/403";
10011 case PPC_FLAGS_INPUT_RCPU
:
10012 bus_model
= "RCPU / MPC8xx";
10014 #if defined(TARGET_PPC64)
10015 case PPC_FLAGS_INPUT_970
:
10016 bus_model
= "PowerPC 970";
10020 bus_model
= "Unknown or invalid";
10023 printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64
"\n"
10024 " MMU model : %s\n",
10025 object_class_get_name(OBJECT_CLASS(pcc
)),
10026 pcc
->pvr
, pcc
->msr_mask
, mmu_model
);
10027 #if !defined(CONFIG_USER_ONLY)
10028 if (env
->tlb
.tlb6
) {
10029 printf(" %d %s TLB in %d ways\n",
10030 env
->nb_tlb
, env
->id_tlbs
? "splitted" : "merged",
10034 printf(" Exceptions model : %s\n"
10035 " Bus model : %s\n",
10036 excp_model
, bus_model
);
10037 printf(" MSR features :\n");
10038 if (env
->flags
& POWERPC_FLAG_SPE
)
10039 printf(" signal processing engine enable"
10041 else if (env
->flags
& POWERPC_FLAG_VRE
)
10042 printf(" vector processor enable\n");
10043 if (env
->flags
& POWERPC_FLAG_TGPR
)
10044 printf(" temporary GPRs\n");
10045 else if (env
->flags
& POWERPC_FLAG_CE
)
10046 printf(" critical input enable\n");
10047 if (env
->flags
& POWERPC_FLAG_SE
)
10048 printf(" single-step trace mode\n");
10049 else if (env
->flags
& POWERPC_FLAG_DWE
)
10050 printf(" debug wait enable\n");
10051 else if (env
->flags
& POWERPC_FLAG_UBLE
)
10052 printf(" user BTB lock enable\n");
10053 if (env
->flags
& POWERPC_FLAG_BE
)
10054 printf(" branch-step trace mode\n");
10055 else if (env
->flags
& POWERPC_FLAG_DE
)
10056 printf(" debug interrupt enable\n");
10057 if (env
->flags
& POWERPC_FLAG_PX
)
10058 printf(" inclusive protection\n");
10059 else if (env
->flags
& POWERPC_FLAG_PMM
)
10060 printf(" performance monitor mark\n");
10061 if (env
->flags
== POWERPC_FLAG_NONE
)
10063 printf(" Time-base/decrementer clock source: %s\n",
10064 env
->flags
& POWERPC_FLAG_RTC_CLK
? "RTC clock" : "bus clock");
10065 dump_ppc_insns(env
);
10066 dump_ppc_sprs(env
);
10072 static void ppc_cpu_unrealizefn(DeviceState
*dev
, Error
**errp
)
10074 PowerPCCPU
*cpu
= POWERPC_CPU(dev
);
10075 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10076 CPUPPCState
*env
= &cpu
->env
;
10077 Error
*local_err
= NULL
;
10078 opc_handler_t
**table
, **table_2
;
10081 pcc
->parent_unrealize(dev
, &local_err
);
10082 if (local_err
!= NULL
) {
10083 error_propagate(errp
, local_err
);
10087 for (i
= 0; i
< PPC_CPU_OPCODES_LEN
; i
++) {
10088 if (env
->opcodes
[i
] == &invalid_handler
) {
10091 if (is_indirect_opcode(env
->opcodes
[i
])) {
10092 table
= ind_table(env
->opcodes
[i
]);
10093 for (j
= 0; j
< PPC_CPU_INDIRECT_OPCODES_LEN
; j
++) {
10094 if (table
[j
] == &invalid_handler
) {
10097 if (is_indirect_opcode(table
[j
])) {
10098 table_2
= ind_table(table
[j
]);
10099 for (k
= 0; k
< PPC_CPU_INDIRECT_OPCODES_LEN
; k
++) {
10100 if (table_2
[k
] != &invalid_handler
&&
10101 is_indirect_opcode(table_2
[k
])) {
10102 g_free((opc_handler_t
*)((uintptr_t)table_2
[k
] &
10106 g_free((opc_handler_t
*)((uintptr_t)table
[j
] &
10110 g_free((opc_handler_t
*)((uintptr_t)env
->opcodes
[i
] &
10116 static gint
ppc_cpu_compare_class_pvr(gconstpointer a
, gconstpointer b
)
10118 ObjectClass
*oc
= (ObjectClass
*)a
;
10119 uint32_t pvr
= *(uint32_t *)b
;
10120 PowerPCCPUClass
*pcc
= (PowerPCCPUClass
*)a
;
10122 /* -cpu host does a PVR lookup during construction */
10123 if (unlikely(strcmp(object_class_get_name(oc
),
10124 TYPE_HOST_POWERPC_CPU
) == 0)) {
10128 if (!ppc_cpu_is_valid(pcc
)) {
10132 return pcc
->pvr
== pvr
? 0 : -1;
10135 PowerPCCPUClass
*ppc_cpu_class_by_pvr(uint32_t pvr
)
10137 GSList
*list
, *item
;
10138 PowerPCCPUClass
*pcc
= NULL
;
10140 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10141 item
= g_slist_find_custom(list
, &pvr
, ppc_cpu_compare_class_pvr
);
10142 if (item
!= NULL
) {
10143 pcc
= POWERPC_CPU_CLASS(item
->data
);
10145 g_slist_free(list
);
10150 static gint
ppc_cpu_compare_class_pvr_mask(gconstpointer a
, gconstpointer b
)
10152 ObjectClass
*oc
= (ObjectClass
*)a
;
10153 uint32_t pvr
= *(uint32_t *)b
;
10154 PowerPCCPUClass
*pcc
= (PowerPCCPUClass
*)a
;
10156 /* -cpu host does a PVR lookup during construction */
10157 if (unlikely(strcmp(object_class_get_name(oc
),
10158 TYPE_HOST_POWERPC_CPU
) == 0)) {
10162 if (!ppc_cpu_is_valid(pcc
)) {
10166 if (pcc
->pvr_match(pcc
, pvr
)) {
10173 PowerPCCPUClass
*ppc_cpu_class_by_pvr_mask(uint32_t pvr
)
10175 GSList
*list
, *item
;
10176 PowerPCCPUClass
*pcc
= NULL
;
10178 list
= object_class_get_list(TYPE_POWERPC_CPU
, true);
10179 item
= g_slist_find_custom(list
, &pvr
, ppc_cpu_compare_class_pvr_mask
);
10180 if (item
!= NULL
) {
10181 pcc
= POWERPC_CPU_CLASS(item
->data
);
10183 g_slist_free(list
);
10188 static gint
ppc_cpu_compare_class_name(gconstpointer a
, gconstpointer b
)
10190 ObjectClass
*oc
= (ObjectClass
*)a
;
10191 const char *name
= b
;
10192 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10194 if (strncasecmp(name
, object_class_get_name(oc
), strlen(name
)) == 0 &&
10195 ppc_cpu_is_valid(pcc
) &&
10196 strcmp(object_class_get_name(oc
) + strlen(name
),
10197 "-" TYPE_POWERPC_CPU
) == 0) {
10204 static ObjectClass
*ppc_cpu_class_by_name(const char *name
);
10206 static ObjectClass
*ppc_cpu_class_by_alias(PowerPCCPUAlias
*alias
)
10208 ObjectClass
*invalid_class
= (void*)ppc_cpu_class_by_alias
;
10210 /* Cache target class lookups in the alias table */
10212 alias
->oc
= ppc_cpu_class_by_name(alias
->model
);
10214 /* Fast check for non-existing aliases */
10215 alias
->oc
= invalid_class
;
10219 if (alias
->oc
== invalid_class
) {
10226 static ObjectClass
*ppc_cpu_class_by_name(const char *name
)
10228 GSList
*list
, *item
;
10229 ObjectClass
*ret
= NULL
;
10233 /* Check if the given name is a PVR */
10234 len
= strlen(name
);
10235 if (len
== 10 && name
[0] == '0' && name
[1] == 'x') {
10238 } else if (len
== 8) {
10241 for (i
= 0; i
< 8; i
++) {
10242 if (!qemu_isxdigit(*p
++))
10246 return OBJECT_CLASS(ppc_cpu_class_by_pvr(strtoul(name
, NULL
, 16)));
10250 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10251 item
= g_slist_find_custom(list
, name
, ppc_cpu_compare_class_name
);
10252 if (item
!= NULL
) {
10253 ret
= OBJECT_CLASS(item
->data
);
10255 g_slist_free(list
);
10261 for (i
= 0; ppc_cpu_aliases
[i
].alias
!= NULL
; i
++) {
10262 if (strcmp(ppc_cpu_aliases
[i
].alias
, name
) == 0) {
10263 return ppc_cpu_class_by_alias(&ppc_cpu_aliases
[i
]);
10270 const char *ppc_cpu_lookup_alias(const char *alias
)
10274 for (ai
= 0; ppc_cpu_aliases
[ai
].alias
!= NULL
; ai
++) {
10275 if (strcmp(ppc_cpu_aliases
[ai
].alias
, alias
) == 0) {
10276 return ppc_cpu_aliases
[ai
].model
;
10283 PowerPCCPU
*cpu_ppc_init(const char *cpu_model
)
10285 return POWERPC_CPU(cpu_generic_init(TYPE_POWERPC_CPU
, cpu_model
));
10288 PowerPCCPUClass
*ppc_cpu_get_family_class(PowerPCCPUClass
*pcc
)
10290 ObjectClass
*oc
= OBJECT_CLASS(pcc
);
10292 while (oc
&& !object_class_is_abstract(oc
)) {
10293 oc
= object_class_get_parent(oc
);
10297 return POWERPC_CPU_CLASS(oc
);
10300 /* Sort by PVR, ordering special case "host" last. */
10301 static gint
ppc_cpu_list_compare(gconstpointer a
, gconstpointer b
)
10303 ObjectClass
*oc_a
= (ObjectClass
*)a
;
10304 ObjectClass
*oc_b
= (ObjectClass
*)b
;
10305 PowerPCCPUClass
*pcc_a
= POWERPC_CPU_CLASS(oc_a
);
10306 PowerPCCPUClass
*pcc_b
= POWERPC_CPU_CLASS(oc_b
);
10307 const char *name_a
= object_class_get_name(oc_a
);
10308 const char *name_b
= object_class_get_name(oc_b
);
10310 if (strcmp(name_a
, TYPE_HOST_POWERPC_CPU
) == 0) {
10312 } else if (strcmp(name_b
, TYPE_HOST_POWERPC_CPU
) == 0) {
10315 /* Avoid an integer overflow during subtraction */
10316 if (pcc_a
->pvr
< pcc_b
->pvr
) {
10318 } else if (pcc_a
->pvr
> pcc_b
->pvr
) {
10326 static void ppc_cpu_list_entry(gpointer data
, gpointer user_data
)
10328 ObjectClass
*oc
= data
;
10329 CPUListState
*s
= user_data
;
10330 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10331 DeviceClass
*family
= DEVICE_CLASS(ppc_cpu_get_family_class(pcc
));
10332 const char *typename
= object_class_get_name(oc
);
10336 if (!ppc_cpu_is_valid(pcc
)) {
10339 if (unlikely(strcmp(typename
, TYPE_HOST_POWERPC_CPU
) == 0)) {
10343 name
= g_strndup(typename
,
10344 strlen(typename
) - strlen("-" TYPE_POWERPC_CPU
));
10345 (*s
->cpu_fprintf
)(s
->file
, "PowerPC %-16s PVR %08x\n",
10347 for (i
= 0; ppc_cpu_aliases
[i
].alias
!= NULL
; i
++) {
10348 PowerPCCPUAlias
*alias
= &ppc_cpu_aliases
[i
];
10349 ObjectClass
*alias_oc
= ppc_cpu_class_by_alias(alias
);
10351 if (alias_oc
!= oc
) {
10355 * If running with KVM, we might update the family alias later, so
10356 * avoid printing the wrong alias here and use "preferred" instead
10358 if (strcmp(alias
->alias
, family
->desc
) == 0) {
10359 (*s
->cpu_fprintf
)(s
->file
,
10360 "PowerPC %-16s (alias for preferred %s CPU)\n",
10361 alias
->alias
, family
->desc
);
10363 (*s
->cpu_fprintf
)(s
->file
, "PowerPC %-16s (alias for %s)\n",
10364 alias
->alias
, name
);
10370 void ppc_cpu_list(FILE *f
, fprintf_function cpu_fprintf
)
10374 .cpu_fprintf
= cpu_fprintf
,
10378 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10379 list
= g_slist_sort(list
, ppc_cpu_list_compare
);
10380 g_slist_foreach(list
, ppc_cpu_list_entry
, &s
);
10381 g_slist_free(list
);
10384 cpu_fprintf(f
, "\n");
10385 cpu_fprintf(f
, "PowerPC %-16s\n", "host");
10389 static void ppc_cpu_defs_entry(gpointer data
, gpointer user_data
)
10391 ObjectClass
*oc
= data
;
10392 CpuDefinitionInfoList
**first
= user_data
;
10393 const char *typename
;
10394 CpuDefinitionInfoList
*entry
;
10395 CpuDefinitionInfo
*info
;
10396 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10398 if (!ppc_cpu_is_valid(pcc
)) {
10402 typename
= object_class_get_name(oc
);
10403 info
= g_malloc0(sizeof(*info
));
10404 info
->name
= g_strndup(typename
,
10405 strlen(typename
) - strlen("-" TYPE_POWERPC_CPU
));
10407 entry
= g_malloc0(sizeof(*entry
));
10408 entry
->value
= info
;
10409 entry
->next
= *first
;
10413 CpuDefinitionInfoList
*arch_query_cpu_definitions(Error
**errp
)
10415 CpuDefinitionInfoList
*cpu_list
= NULL
;
10419 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10420 g_slist_foreach(list
, ppc_cpu_defs_entry
, &cpu_list
);
10421 g_slist_free(list
);
10423 for (i
= 0; ppc_cpu_aliases
[i
].alias
!= NULL
; i
++) {
10424 PowerPCCPUAlias
*alias
= &ppc_cpu_aliases
[i
];
10426 CpuDefinitionInfoList
*entry
;
10427 CpuDefinitionInfo
*info
;
10429 oc
= ppc_cpu_class_by_alias(alias
);
10434 info
= g_malloc0(sizeof(*info
));
10435 info
->name
= g_strdup(alias
->alias
);
10436 info
->q_typename
= g_strdup(object_class_get_name(oc
));
10438 entry
= g_malloc0(sizeof(*entry
));
10439 entry
->value
= info
;
10440 entry
->next
= cpu_list
;
10447 static void ppc_cpu_set_pc(CPUState
*cs
, vaddr value
)
10449 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10451 cpu
->env
.nip
= value
;
10454 static bool ppc_cpu_has_work(CPUState
*cs
)
10456 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10457 CPUPPCState
*env
= &cpu
->env
;
10459 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
10462 /* CPUClass::reset() */
10463 static void ppc_cpu_reset(CPUState
*s
)
10465 PowerPCCPU
*cpu
= POWERPC_CPU(s
);
10466 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10467 CPUPPCState
*env
= &cpu
->env
;
10471 pcc
->parent_reset(s
);
10473 msr
= (target_ulong
)0;
10474 msr
|= (target_ulong
)MSR_HVB
;
10475 msr
|= (target_ulong
)0 << MSR_AP
; /* TO BE CHECKED */
10476 msr
|= (target_ulong
)0 << MSR_SA
; /* TO BE CHECKED */
10477 msr
|= (target_ulong
)1 << MSR_EP
;
10478 #if defined(DO_SINGLE_STEP) && 0
10479 /* Single step trace mode */
10480 msr
|= (target_ulong
)1 << MSR_SE
;
10481 msr
|= (target_ulong
)1 << MSR_BE
;
10483 #if defined(CONFIG_USER_ONLY)
10484 msr
|= (target_ulong
)1 << MSR_FP
; /* Allow floating point usage */
10485 msr
|= (target_ulong
)1 << MSR_VR
; /* Allow altivec usage */
10486 msr
|= (target_ulong
)1 << MSR_VSX
; /* Allow VSX usage */
10487 msr
|= (target_ulong
)1 << MSR_SPE
; /* Allow SPE usage */
10488 msr
|= (target_ulong
)1 << MSR_PR
;
10489 #if defined(TARGET_PPC64)
10490 msr
|= (target_ulong
)1 << MSR_TM
; /* Transactional memory */
10492 #if !defined(TARGET_WORDS_BIGENDIAN)
10493 msr
|= (target_ulong
)1 << MSR_LE
; /* Little-endian user mode */
10494 if (!((env
->msr_mask
>> MSR_LE
) & 1)) {
10495 fprintf(stderr
, "Selected CPU does not support little-endian.\n");
10501 #if defined(TARGET_PPC64)
10502 if (env
->mmu_model
& POWERPC_MMU_64
) {
10503 msr
|= (1ULL << MSR_SF
);
10507 hreg_store_msr(env
, msr
, 1);
10509 #if !defined(CONFIG_USER_ONLY)
10510 env
->nip
= env
->hreset_vector
| env
->excp_prefix
;
10511 if (env
->mmu_model
!= POWERPC_MMU_REAL
) {
10512 ppc_tlb_invalidate_all(env
);
10516 hreg_compute_hflags(env
);
10517 env
->reserve_addr
= (target_ulong
)-1ULL;
10518 /* Be sure no exception or interrupt is pending */
10519 env
->pending_interrupts
= 0;
10520 s
->exception_index
= POWERPC_EXCP_NONE
;
10521 env
->error_code
= 0;
10523 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
10525 env
->slb_shadow_addr
= 0;
10526 env
->slb_shadow_size
= 0;
10529 #endif /* TARGET_PPC64 */
10531 for (i
= 0; i
< ARRAY_SIZE(env
->spr_cb
); i
++) {
10532 ppc_spr_t
*spr
= &env
->spr_cb
[i
];
10537 env
->spr
[i
] = spr
->default_value
;
10541 #ifndef CONFIG_USER_ONLY
10542 static bool ppc_cpu_is_big_endian(CPUState
*cs
)
10544 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10545 CPUPPCState
*env
= &cpu
->env
;
10547 cpu_synchronize_state(cs
);
10553 static void ppc_cpu_initfn(Object
*obj
)
10555 CPUState
*cs
= CPU(obj
);
10556 PowerPCCPU
*cpu
= POWERPC_CPU(obj
);
10557 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10558 CPUPPCState
*env
= &cpu
->env
;
10562 env
->msr_mask
= pcc
->msr_mask
;
10563 env
->mmu_model
= pcc
->mmu_model
;
10564 env
->excp_model
= pcc
->excp_model
;
10565 env
->bus_model
= pcc
->bus_model
;
10566 env
->insns_flags
= pcc
->insns_flags
;
10567 env
->insns_flags2
= pcc
->insns_flags2
;
10568 env
->flags
= pcc
->flags
;
10569 env
->bfd_mach
= pcc
->bfd_mach
;
10570 env
->check_pow
= pcc
->check_pow
;
10572 /* Mark HV mode as supported if the CPU has an MSR_HV bit
10573 * in the msr_mask. The mask can later be cleared by PAPR
10574 * mode but the hv mode support will remain, thus enforcing
10575 * that we cannot use priv. instructions in guest in PAPR
10576 * mode. For 970 we currently simply don't set HV in msr_mask
10577 * thus simulating an "Apple mode" 970. If we ever want to
10578 * support 970 HV mode, we'll have to add a processor attribute
10581 #if !defined(CONFIG_USER_ONLY)
10582 env
->has_hv_mode
= !!(env
->msr_mask
& MSR_HVB
);
10585 #if defined(TARGET_PPC64)
10587 env
->sps
= *pcc
->sps
;
10588 } else if (env
->mmu_model
& POWERPC_MMU_64
) {
10589 /* Use default sets of page sizes. We don't support MPSS */
10590 static const struct ppc_segment_page_sizes defsps_4k
= {
10592 { .page_shift
= 12, /* 4K */
10594 .enc
= { { .page_shift
= 12, .pte_enc
= 0 } }
10596 { .page_shift
= 24, /* 16M */
10598 .enc
= { { .page_shift
= 24, .pte_enc
= 0 } }
10602 static const struct ppc_segment_page_sizes defsps_64k
= {
10604 { .page_shift
= 12, /* 4K */
10606 .enc
= { { .page_shift
= 12, .pte_enc
= 0 } }
10608 { .page_shift
= 16, /* 64K */
10610 .enc
= { { .page_shift
= 16, .pte_enc
= 1 } }
10612 { .page_shift
= 24, /* 16M */
10614 .enc
= { { .page_shift
= 24, .pte_enc
= 0 } }
10618 env
->sps
= (env
->mmu_model
& POWERPC_MMU_64K
) ? defsps_64k
: defsps_4k
;
10620 #endif /* defined(TARGET_PPC64) */
10622 if (tcg_enabled()) {
10623 ppc_translate_init();
10627 static bool ppc_pvr_match_default(PowerPCCPUClass
*pcc
, uint32_t pvr
)
10629 return pcc
->pvr
== pvr
;
10632 static gchar
*ppc_gdb_arch_name(CPUState
*cs
)
10634 #if defined(TARGET_PPC64)
10635 return g_strdup("powerpc:common64");
10637 return g_strdup("powerpc:common");
10641 static Property ppc_cpu_properties
[] = {
10642 DEFINE_PROP_BOOL("pre-2.8-migration", PowerPCCPU
, pre_2_8_migration
, false),
10643 DEFINE_PROP_END_OF_LIST(),
10646 static void ppc_cpu_class_init(ObjectClass
*oc
, void *data
)
10648 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10649 CPUClass
*cc
= CPU_CLASS(oc
);
10650 DeviceClass
*dc
= DEVICE_CLASS(oc
);
10652 pcc
->parent_realize
= dc
->realize
;
10653 pcc
->parent_unrealize
= dc
->unrealize
;
10654 pcc
->pvr_match
= ppc_pvr_match_default
;
10655 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_always
;
10656 dc
->realize
= ppc_cpu_realizefn
;
10657 dc
->unrealize
= ppc_cpu_unrealizefn
;
10658 dc
->props
= ppc_cpu_properties
;
10660 pcc
->parent_reset
= cc
->reset
;
10661 cc
->reset
= ppc_cpu_reset
;
10663 cc
->class_by_name
= ppc_cpu_class_by_name
;
10664 cc
->has_work
= ppc_cpu_has_work
;
10665 cc
->do_interrupt
= ppc_cpu_do_interrupt
;
10666 cc
->cpu_exec_interrupt
= ppc_cpu_exec_interrupt
;
10667 cc
->dump_state
= ppc_cpu_dump_state
;
10668 cc
->dump_statistics
= ppc_cpu_dump_statistics
;
10669 cc
->set_pc
= ppc_cpu_set_pc
;
10670 cc
->gdb_read_register
= ppc_cpu_gdb_read_register
;
10671 cc
->gdb_write_register
= ppc_cpu_gdb_write_register
;
10672 #ifdef CONFIG_USER_ONLY
10673 cc
->handle_mmu_fault
= ppc_cpu_handle_mmu_fault
;
10675 cc
->get_phys_page_debug
= ppc_cpu_get_phys_page_debug
;
10676 cc
->vmsd
= &vmstate_ppc_cpu
;
10678 #if defined(CONFIG_SOFTMMU)
10679 cc
->write_elf64_note
= ppc64_cpu_write_elf64_note
;
10680 cc
->write_elf32_note
= ppc32_cpu_write_elf32_note
;
10683 cc
->gdb_num_core_regs
= 71;
10685 #ifdef USE_APPLE_GDB
10686 cc
->gdb_read_register
= ppc_cpu_gdb_read_register_apple
;
10687 cc
->gdb_write_register
= ppc_cpu_gdb_write_register_apple
;
10688 cc
->gdb_num_core_regs
= 71 + 32;
10691 cc
->gdb_arch_name
= ppc_gdb_arch_name
;
10692 #if defined(TARGET_PPC64)
10693 cc
->gdb_core_xml_file
= "power64-core.xml";
10695 cc
->gdb_core_xml_file
= "power-core.xml";
10697 #ifndef CONFIG_USER_ONLY
10698 cc
->virtio_is_big_endian
= ppc_cpu_is_big_endian
;
10701 dc
->fw_name
= "PowerPC,UNKNOWN";
10704 static const TypeInfo ppc_cpu_type_info
= {
10705 .name
= TYPE_POWERPC_CPU
,
10706 .parent
= TYPE_CPU
,
10707 .instance_size
= sizeof(PowerPCCPU
),
10708 .instance_init
= ppc_cpu_initfn
,
10710 .class_size
= sizeof(PowerPCCPUClass
),
10711 .class_init
= ppc_cpu_class_init
,
10714 static const TypeInfo ppc_vhyp_type_info
= {
10715 .name
= TYPE_PPC_VIRTUAL_HYPERVISOR
,
10716 .parent
= TYPE_INTERFACE
,
10717 .class_size
= sizeof(PPCVirtualHypervisorClass
),
10720 static void ppc_cpu_register_types(void)
10722 type_register_static(&ppc_cpu_type_info
);
10723 type_register_static(&ppc_vhyp_type_info
);
10726 type_init(ppc_cpu_register_types
)