2 * PowerPC CPU initialization for qemu.
4 * Copyright (c) 2003-2007 Jocelyn Mayer
5 * Copyright 2011 Freescale Semiconductor, Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "qemu/osdep.h"
22 #include "disas/bfd.h"
23 #include "exec/gdbstub.h"
25 #include "sysemu/arch_init.h"
26 #include "sysemu/cpus.h"
27 #include "sysemu/hw_accel.h"
28 #include "cpu-models.h"
29 #include "mmu-hash32.h"
30 #include "mmu-hash64.h"
31 #include "qemu/error-report.h"
32 #include "qapi/visitor.h"
33 #include "hw/qdev-properties.h"
34 #include "hw/ppc/ppc.h"
35 #include "mmu-book3s-v3.h"
36 #include "sysemu/qtest.h"
38 //#define PPC_DUMP_CPU
39 //#define PPC_DEBUG_SPR
40 //#define PPC_DUMP_SPR_ACCESSES
41 /* #define USE_APPLE_GDB */
44 * do nothing but store/retrieve spr value
46 static void spr_load_dump_spr(int sprn
)
48 #ifdef PPC_DUMP_SPR_ACCESSES
49 TCGv_i32 t0
= tcg_const_i32(sprn
);
50 gen_helper_load_dump_spr(cpu_env
, t0
);
51 tcg_temp_free_i32(t0
);
55 static void spr_read_generic (DisasContext
*ctx
, int gprn
, int sprn
)
57 gen_load_spr(cpu_gpr
[gprn
], sprn
);
58 spr_load_dump_spr(sprn
);
61 static void spr_store_dump_spr(int sprn
)
63 #ifdef PPC_DUMP_SPR_ACCESSES
64 TCGv_i32 t0
= tcg_const_i32(sprn
);
65 gen_helper_store_dump_spr(cpu_env
, t0
);
66 tcg_temp_free_i32(t0
);
70 static void spr_write_generic(DisasContext
*ctx
, int sprn
, int gprn
)
72 gen_store_spr(sprn
, cpu_gpr
[gprn
]);
73 spr_store_dump_spr(sprn
);
76 #if !defined(CONFIG_USER_ONLY)
77 static void spr_write_generic32(DisasContext
*ctx
, int sprn
, int gprn
)
80 TCGv t0
= tcg_temp_new();
81 tcg_gen_ext32u_tl(t0
, cpu_gpr
[gprn
]);
82 gen_store_spr(sprn
, t0
);
84 spr_store_dump_spr(sprn
);
86 spr_write_generic(ctx
, sprn
, gprn
);
90 static void spr_write_clear(DisasContext
*ctx
, int sprn
, int gprn
)
92 TCGv t0
= tcg_temp_new();
93 TCGv t1
= tcg_temp_new();
94 gen_load_spr(t0
, sprn
);
95 tcg_gen_neg_tl(t1
, cpu_gpr
[gprn
]);
96 tcg_gen_and_tl(t0
, t0
, t1
);
97 gen_store_spr(sprn
, t0
);
102 static void spr_access_nop(DisasContext
*ctx
, int sprn
, int gprn
)
108 /* SPR common to all PowerPC */
110 static void spr_read_xer(DisasContext
*ctx
, int gprn
, int sprn
)
112 gen_read_xer(ctx
, cpu_gpr
[gprn
]);
115 static void spr_write_xer(DisasContext
*ctx
, int sprn
, int gprn
)
117 gen_write_xer(cpu_gpr
[gprn
]);
121 static void spr_read_lr(DisasContext
*ctx
, int gprn
, int sprn
)
123 tcg_gen_mov_tl(cpu_gpr
[gprn
], cpu_lr
);
126 static void spr_write_lr(DisasContext
*ctx
, int sprn
, int gprn
)
128 tcg_gen_mov_tl(cpu_lr
, cpu_gpr
[gprn
]);
132 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
133 static void spr_read_cfar(DisasContext
*ctx
, int gprn
, int sprn
)
135 tcg_gen_mov_tl(cpu_gpr
[gprn
], cpu_cfar
);
138 static void spr_write_cfar(DisasContext
*ctx
, int sprn
, int gprn
)
140 tcg_gen_mov_tl(cpu_cfar
, cpu_gpr
[gprn
]);
142 #endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
145 static void spr_read_ctr(DisasContext
*ctx
, int gprn
, int sprn
)
147 tcg_gen_mov_tl(cpu_gpr
[gprn
], cpu_ctr
);
150 static void spr_write_ctr(DisasContext
*ctx
, int sprn
, int gprn
)
152 tcg_gen_mov_tl(cpu_ctr
, cpu_gpr
[gprn
]);
155 /* User read access to SPR */
161 static void spr_read_ureg(DisasContext
*ctx
, int gprn
, int sprn
)
163 gen_load_spr(cpu_gpr
[gprn
], sprn
+ 0x10);
166 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
167 static void spr_write_ureg(DisasContext
*ctx
, int sprn
, int gprn
)
169 gen_store_spr(sprn
+ 0x10, cpu_gpr
[gprn
]);
173 /* SPR common to all non-embedded PowerPC */
175 #if !defined(CONFIG_USER_ONLY)
176 static void spr_read_decr(DisasContext
*ctx
, int gprn
, int sprn
)
178 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
181 gen_helper_load_decr(cpu_gpr
[gprn
], cpu_env
);
182 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
184 gen_stop_exception(ctx
);
188 static void spr_write_decr(DisasContext
*ctx
, int sprn
, int gprn
)
190 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
193 gen_helper_store_decr(cpu_env
, cpu_gpr
[gprn
]);
194 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
196 gen_stop_exception(ctx
);
201 /* SPR common to all non-embedded PowerPC, except 601 */
203 static void spr_read_tbl(DisasContext
*ctx
, int gprn
, int sprn
)
205 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
208 gen_helper_load_tbl(cpu_gpr
[gprn
], cpu_env
);
209 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
211 gen_stop_exception(ctx
);
215 static void spr_read_tbu(DisasContext
*ctx
, int gprn
, int sprn
)
217 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
220 gen_helper_load_tbu(cpu_gpr
[gprn
], cpu_env
);
221 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
223 gen_stop_exception(ctx
);
227 __attribute__ (( unused
))
228 static void spr_read_atbl(DisasContext
*ctx
, int gprn
, int sprn
)
230 gen_helper_load_atbl(cpu_gpr
[gprn
], cpu_env
);
233 __attribute__ (( unused
))
234 static void spr_read_atbu(DisasContext
*ctx
, int gprn
, int sprn
)
236 gen_helper_load_atbu(cpu_gpr
[gprn
], cpu_env
);
239 #if !defined(CONFIG_USER_ONLY)
240 static void spr_write_tbl(DisasContext
*ctx
, int sprn
, int gprn
)
242 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
245 gen_helper_store_tbl(cpu_env
, cpu_gpr
[gprn
]);
246 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
248 gen_stop_exception(ctx
);
252 static void spr_write_tbu(DisasContext
*ctx
, int sprn
, int gprn
)
254 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
257 gen_helper_store_tbu(cpu_env
, cpu_gpr
[gprn
]);
258 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
260 gen_stop_exception(ctx
);
264 __attribute__ (( unused
))
265 static void spr_write_atbl(DisasContext
*ctx
, int sprn
, int gprn
)
267 gen_helper_store_atbl(cpu_env
, cpu_gpr
[gprn
]);
270 __attribute__ (( unused
))
271 static void spr_write_atbu(DisasContext
*ctx
, int sprn
, int gprn
)
273 gen_helper_store_atbu(cpu_env
, cpu_gpr
[gprn
]);
276 #if defined(TARGET_PPC64)
277 __attribute__ (( unused
))
278 static void spr_read_purr(DisasContext
*ctx
, int gprn
, int sprn
)
280 gen_helper_load_purr(cpu_gpr
[gprn
], cpu_env
);
284 static void spr_read_hdecr(DisasContext
*ctx
, int gprn
, int sprn
)
286 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
289 gen_helper_load_hdecr(cpu_gpr
[gprn
], cpu_env
);
290 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
292 gen_stop_exception(ctx
);
296 static void spr_write_hdecr(DisasContext
*ctx
, int sprn
, int gprn
)
298 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
301 gen_helper_store_hdecr(cpu_env
, cpu_gpr
[gprn
]);
302 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
304 gen_stop_exception(ctx
);
311 #if !defined(CONFIG_USER_ONLY)
312 /* IBAT0U...IBAT0U */
313 /* IBAT0L...IBAT7L */
314 static void spr_read_ibat(DisasContext
*ctx
, int gprn
, int sprn
)
316 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, IBAT
[sprn
& 1][(sprn
- SPR_IBAT0U
) / 2]));
319 static void spr_read_ibat_h(DisasContext
*ctx
, int gprn
, int sprn
)
321 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, IBAT
[sprn
& 1][((sprn
- SPR_IBAT4U
) / 2) + 4]));
324 static void spr_write_ibatu(DisasContext
*ctx
, int sprn
, int gprn
)
326 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0U
) / 2);
327 gen_helper_store_ibatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
328 tcg_temp_free_i32(t0
);
331 static void spr_write_ibatu_h(DisasContext
*ctx
, int sprn
, int gprn
)
333 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_IBAT4U
) / 2) + 4);
334 gen_helper_store_ibatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
335 tcg_temp_free_i32(t0
);
338 static void spr_write_ibatl(DisasContext
*ctx
, int sprn
, int gprn
)
340 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0L
) / 2);
341 gen_helper_store_ibatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
342 tcg_temp_free_i32(t0
);
345 static void spr_write_ibatl_h(DisasContext
*ctx
, int sprn
, int gprn
)
347 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_IBAT4L
) / 2) + 4);
348 gen_helper_store_ibatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
349 tcg_temp_free_i32(t0
);
352 /* DBAT0U...DBAT7U */
353 /* DBAT0L...DBAT7L */
354 static void spr_read_dbat(DisasContext
*ctx
, int gprn
, int sprn
)
356 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, DBAT
[sprn
& 1][(sprn
- SPR_DBAT0U
) / 2]));
359 static void spr_read_dbat_h(DisasContext
*ctx
, int gprn
, int sprn
)
361 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, DBAT
[sprn
& 1][((sprn
- SPR_DBAT4U
) / 2) + 4]));
364 static void spr_write_dbatu(DisasContext
*ctx
, int sprn
, int gprn
)
366 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_DBAT0U
) / 2);
367 gen_helper_store_dbatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
368 tcg_temp_free_i32(t0
);
371 static void spr_write_dbatu_h(DisasContext
*ctx
, int sprn
, int gprn
)
373 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_DBAT4U
) / 2) + 4);
374 gen_helper_store_dbatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
375 tcg_temp_free_i32(t0
);
378 static void spr_write_dbatl(DisasContext
*ctx
, int sprn
, int gprn
)
380 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_DBAT0L
) / 2);
381 gen_helper_store_dbatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
382 tcg_temp_free_i32(t0
);
385 static void spr_write_dbatl_h(DisasContext
*ctx
, int sprn
, int gprn
)
387 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_DBAT4L
) / 2) + 4);
388 gen_helper_store_dbatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
389 tcg_temp_free_i32(t0
);
393 static void spr_write_sdr1(DisasContext
*ctx
, int sprn
, int gprn
)
395 gen_helper_store_sdr1(cpu_env
, cpu_gpr
[gprn
]);
398 #if defined(TARGET_PPC64)
399 /* 64 bits PowerPC specific SPRs */
401 static void spr_write_pidr(DisasContext
*ctx
, int sprn
, int gprn
)
403 gen_helper_store_pidr(cpu_env
, cpu_gpr
[gprn
]);
406 static void spr_read_hior(DisasContext
*ctx
, int gprn
, int sprn
)
408 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, excp_prefix
));
411 static void spr_write_hior(DisasContext
*ctx
, int sprn
, int gprn
)
413 TCGv t0
= tcg_temp_new();
414 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], 0x3FFFFF00000ULL
);
415 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_prefix
));
421 /* PowerPC 601 specific registers */
423 static void spr_read_601_rtcl(DisasContext
*ctx
, int gprn
, int sprn
)
425 gen_helper_load_601_rtcl(cpu_gpr
[gprn
], cpu_env
);
428 static void spr_read_601_rtcu(DisasContext
*ctx
, int gprn
, int sprn
)
430 gen_helper_load_601_rtcu(cpu_gpr
[gprn
], cpu_env
);
433 #if !defined(CONFIG_USER_ONLY)
434 static void spr_write_601_rtcu(DisasContext
*ctx
, int sprn
, int gprn
)
436 gen_helper_store_601_rtcu(cpu_env
, cpu_gpr
[gprn
]);
439 static void spr_write_601_rtcl(DisasContext
*ctx
, int sprn
, int gprn
)
441 gen_helper_store_601_rtcl(cpu_env
, cpu_gpr
[gprn
]);
444 static void spr_write_hid0_601(DisasContext
*ctx
, int sprn
, int gprn
)
446 gen_helper_store_hid0_601(cpu_env
, cpu_gpr
[gprn
]);
447 /* Must stop the translation as endianness may have changed */
448 gen_stop_exception(ctx
);
453 #if !defined(CONFIG_USER_ONLY)
454 static void spr_read_601_ubat(DisasContext
*ctx
, int gprn
, int sprn
)
456 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, IBAT
[sprn
& 1][(sprn
- SPR_IBAT0U
) / 2]));
459 static void spr_write_601_ubatu(DisasContext
*ctx
, int sprn
, int gprn
)
461 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0U
) / 2);
462 gen_helper_store_601_batl(cpu_env
, t0
, cpu_gpr
[gprn
]);
463 tcg_temp_free_i32(t0
);
466 static void spr_write_601_ubatl(DisasContext
*ctx
, int sprn
, int gprn
)
468 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0U
) / 2);
469 gen_helper_store_601_batu(cpu_env
, t0
, cpu_gpr
[gprn
]);
470 tcg_temp_free_i32(t0
);
474 /* PowerPC 40x specific registers */
475 #if !defined(CONFIG_USER_ONLY)
476 static void spr_read_40x_pit(DisasContext
*ctx
, int gprn
, int sprn
)
478 gen_helper_load_40x_pit(cpu_gpr
[gprn
], cpu_env
);
481 static void spr_write_40x_pit(DisasContext
*ctx
, int sprn
, int gprn
)
483 gen_helper_store_40x_pit(cpu_env
, cpu_gpr
[gprn
]);
486 static void spr_write_40x_dbcr0(DisasContext
*ctx
, int sprn
, int gprn
)
488 gen_helper_store_40x_dbcr0(cpu_env
, cpu_gpr
[gprn
]);
489 /* We must stop translation as we may have rebooted */
490 gen_stop_exception(ctx
);
493 static void spr_write_40x_sler(DisasContext
*ctx
, int sprn
, int gprn
)
495 gen_helper_store_40x_sler(cpu_env
, cpu_gpr
[gprn
]);
498 static void spr_write_booke_tcr(DisasContext
*ctx
, int sprn
, int gprn
)
500 gen_helper_store_booke_tcr(cpu_env
, cpu_gpr
[gprn
]);
503 static void spr_write_booke_tsr(DisasContext
*ctx
, int sprn
, int gprn
)
505 gen_helper_store_booke_tsr(cpu_env
, cpu_gpr
[gprn
]);
509 /* PowerPC 403 specific registers */
510 /* PBL1 / PBU1 / PBL2 / PBU2 */
511 #if !defined(CONFIG_USER_ONLY)
512 static void spr_read_403_pbr(DisasContext
*ctx
, int gprn
, int sprn
)
514 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, pb
[sprn
- SPR_403_PBL1
]));
517 static void spr_write_403_pbr(DisasContext
*ctx
, int sprn
, int gprn
)
519 TCGv_i32 t0
= tcg_const_i32(sprn
- SPR_403_PBL1
);
520 gen_helper_store_403_pbr(cpu_env
, t0
, cpu_gpr
[gprn
]);
521 tcg_temp_free_i32(t0
);
524 static void spr_write_pir(DisasContext
*ctx
, int sprn
, int gprn
)
526 TCGv t0
= tcg_temp_new();
527 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], 0xF);
528 gen_store_spr(SPR_PIR
, t0
);
533 /* SPE specific registers */
534 static void spr_read_spefscr(DisasContext
*ctx
, int gprn
, int sprn
)
536 TCGv_i32 t0
= tcg_temp_new_i32();
537 tcg_gen_ld_i32(t0
, cpu_env
, offsetof(CPUPPCState
, spe_fscr
));
538 tcg_gen_extu_i32_tl(cpu_gpr
[gprn
], t0
);
539 tcg_temp_free_i32(t0
);
542 static void spr_write_spefscr(DisasContext
*ctx
, int sprn
, int gprn
)
544 TCGv_i32 t0
= tcg_temp_new_i32();
545 tcg_gen_trunc_tl_i32(t0
, cpu_gpr
[gprn
]);
546 tcg_gen_st_i32(t0
, cpu_env
, offsetof(CPUPPCState
, spe_fscr
));
547 tcg_temp_free_i32(t0
);
550 #if !defined(CONFIG_USER_ONLY)
551 /* Callback used to write the exception vector base */
552 static void spr_write_excp_prefix(DisasContext
*ctx
, int sprn
, int gprn
)
554 TCGv t0
= tcg_temp_new();
555 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUPPCState
, ivpr_mask
));
556 tcg_gen_and_tl(t0
, t0
, cpu_gpr
[gprn
]);
557 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_prefix
));
558 gen_store_spr(sprn
, t0
);
562 static void spr_write_excp_vector(DisasContext
*ctx
, int sprn
, int gprn
)
566 if (sprn
>= SPR_BOOKE_IVOR0
&& sprn
<= SPR_BOOKE_IVOR15
) {
567 sprn_offs
= sprn
- SPR_BOOKE_IVOR0
;
568 } else if (sprn
>= SPR_BOOKE_IVOR32
&& sprn
<= SPR_BOOKE_IVOR37
) {
569 sprn_offs
= sprn
- SPR_BOOKE_IVOR32
+ 32;
570 } else if (sprn
>= SPR_BOOKE_IVOR38
&& sprn
<= SPR_BOOKE_IVOR42
) {
571 sprn_offs
= sprn
- SPR_BOOKE_IVOR38
+ 38;
573 printf("Trying to write an unknown exception vector %d %03x\n",
575 gen_inval_exception(ctx
, POWERPC_EXCP_PRIV_REG
);
579 TCGv t0
= tcg_temp_new();
580 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUPPCState
, ivor_mask
));
581 tcg_gen_and_tl(t0
, t0
, cpu_gpr
[gprn
]);
582 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_vectors
[sprn_offs
]));
583 gen_store_spr(sprn
, t0
);
588 static inline void vscr_init(CPUPPCState
*env
, uint32_t val
)
591 /* Altivec always uses round-to-nearest */
592 set_float_rounding_mode(float_round_nearest_even
, &env
->vec_status
);
593 set_flush_to_zero(vscr_nj
, &env
->vec_status
);
596 #ifdef CONFIG_USER_ONLY
597 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
598 oea_read, oea_write, one_reg_id, initial_value) \
599 _spr_register(env, num, name, uea_read, uea_write, initial_value)
600 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
601 oea_read, oea_write, hea_read, hea_write, \
602 one_reg_id, initial_value) \
603 _spr_register(env, num, name, uea_read, uea_write, initial_value)
605 #if !defined(CONFIG_KVM)
606 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
607 oea_read, oea_write, one_reg_id, initial_value) \
608 _spr_register(env, num, name, uea_read, uea_write, \
609 oea_read, oea_write, oea_read, oea_write, initial_value)
610 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
611 oea_read, oea_write, hea_read, hea_write, \
612 one_reg_id, initial_value) \
613 _spr_register(env, num, name, uea_read, uea_write, \
614 oea_read, oea_write, hea_read, hea_write, initial_value)
616 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
617 oea_read, oea_write, one_reg_id, initial_value) \
618 _spr_register(env, num, name, uea_read, uea_write, \
619 oea_read, oea_write, oea_read, oea_write, \
620 one_reg_id, initial_value)
621 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
622 oea_read, oea_write, hea_read, hea_write, \
623 one_reg_id, initial_value) \
624 _spr_register(env, num, name, uea_read, uea_write, \
625 oea_read, oea_write, hea_read, hea_write, \
626 one_reg_id, initial_value)
630 #define spr_register(env, num, name, uea_read, uea_write, \
631 oea_read, oea_write, initial_value) \
632 spr_register_kvm(env, num, name, uea_read, uea_write, \
633 oea_read, oea_write, 0, initial_value)
635 #define spr_register_hv(env, num, name, uea_read, uea_write, \
636 oea_read, oea_write, hea_read, hea_write, \
638 spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
639 oea_read, oea_write, hea_read, hea_write, \
642 static inline void _spr_register(CPUPPCState
*env
, int num
,
644 void (*uea_read
)(DisasContext
*ctx
, int gprn
, int sprn
),
645 void (*uea_write
)(DisasContext
*ctx
, int sprn
, int gprn
),
646 #if !defined(CONFIG_USER_ONLY)
648 void (*oea_read
)(DisasContext
*ctx
, int gprn
, int sprn
),
649 void (*oea_write
)(DisasContext
*ctx
, int sprn
, int gprn
),
650 void (*hea_read
)(DisasContext
*opaque
, int gprn
, int sprn
),
651 void (*hea_write
)(DisasContext
*opaque
, int sprn
, int gprn
),
653 #if defined(CONFIG_KVM)
656 target_ulong initial_value
)
660 spr
= &env
->spr_cb
[num
];
661 if (spr
->name
!= NULL
||env
-> spr
[num
] != 0x00000000 ||
662 #if !defined(CONFIG_USER_ONLY)
663 spr
->oea_read
!= NULL
|| spr
->oea_write
!= NULL
||
665 spr
->uea_read
!= NULL
|| spr
->uea_write
!= NULL
) {
666 printf("Error: Trying to register SPR %d (%03x) twice !\n", num
, num
);
669 #if defined(PPC_DEBUG_SPR)
670 printf("*** register spr %d (%03x) %s val " TARGET_FMT_lx
"\n", num
, num
,
671 name
, initial_value
);
674 spr
->uea_read
= uea_read
;
675 spr
->uea_write
= uea_write
;
676 #if !defined(CONFIG_USER_ONLY)
677 spr
->oea_read
= oea_read
;
678 spr
->oea_write
= oea_write
;
679 spr
->hea_read
= hea_read
;
680 spr
->hea_write
= hea_write
;
682 #if defined(CONFIG_KVM)
683 spr
->one_reg_id
= one_reg_id
,
685 env
->spr
[num
] = spr
->default_value
= initial_value
;
688 /* Generic PowerPC SPRs */
689 static void gen_spr_generic(CPUPPCState
*env
)
691 /* Integer processing */
692 spr_register(env
, SPR_XER
, "XER",
693 &spr_read_xer
, &spr_write_xer
,
694 &spr_read_xer
, &spr_write_xer
,
697 spr_register(env
, SPR_LR
, "LR",
698 &spr_read_lr
, &spr_write_lr
,
699 &spr_read_lr
, &spr_write_lr
,
701 spr_register(env
, SPR_CTR
, "CTR",
702 &spr_read_ctr
, &spr_write_ctr
,
703 &spr_read_ctr
, &spr_write_ctr
,
705 /* Interrupt processing */
706 spr_register(env
, SPR_SRR0
, "SRR0",
707 SPR_NOACCESS
, SPR_NOACCESS
,
708 &spr_read_generic
, &spr_write_generic
,
710 spr_register(env
, SPR_SRR1
, "SRR1",
711 SPR_NOACCESS
, SPR_NOACCESS
,
712 &spr_read_generic
, &spr_write_generic
,
714 /* Processor control */
715 spr_register(env
, SPR_SPRG0
, "SPRG0",
716 SPR_NOACCESS
, SPR_NOACCESS
,
717 &spr_read_generic
, &spr_write_generic
,
719 spr_register(env
, SPR_SPRG1
, "SPRG1",
720 SPR_NOACCESS
, SPR_NOACCESS
,
721 &spr_read_generic
, &spr_write_generic
,
723 spr_register(env
, SPR_SPRG2
, "SPRG2",
724 SPR_NOACCESS
, SPR_NOACCESS
,
725 &spr_read_generic
, &spr_write_generic
,
727 spr_register(env
, SPR_SPRG3
, "SPRG3",
728 SPR_NOACCESS
, SPR_NOACCESS
,
729 &spr_read_generic
, &spr_write_generic
,
733 /* SPR common to all non-embedded PowerPC, including 601 */
734 static void gen_spr_ne_601(CPUPPCState
*env
)
736 /* Exception processing */
737 spr_register_kvm(env
, SPR_DSISR
, "DSISR",
738 SPR_NOACCESS
, SPR_NOACCESS
,
739 &spr_read_generic
, &spr_write_generic
,
740 KVM_REG_PPC_DSISR
, 0x00000000);
741 spr_register_kvm(env
, SPR_DAR
, "DAR",
742 SPR_NOACCESS
, SPR_NOACCESS
,
743 &spr_read_generic
, &spr_write_generic
,
744 KVM_REG_PPC_DAR
, 0x00000000);
746 spr_register(env
, SPR_DECR
, "DECR",
747 SPR_NOACCESS
, SPR_NOACCESS
,
748 &spr_read_decr
, &spr_write_decr
,
752 /* Storage Description Register 1 */
753 static void gen_spr_sdr1(CPUPPCState
*env
)
755 #ifndef CONFIG_USER_ONLY
756 if (env
->has_hv_mode
) {
757 /* SDR1 is a hypervisor resource on CPUs which have a
759 spr_register_hv(env
, SPR_SDR1
, "SDR1",
760 SPR_NOACCESS
, SPR_NOACCESS
,
761 SPR_NOACCESS
, SPR_NOACCESS
,
762 &spr_read_generic
, &spr_write_sdr1
,
765 spr_register(env
, SPR_SDR1
, "SDR1",
766 SPR_NOACCESS
, SPR_NOACCESS
,
767 &spr_read_generic
, &spr_write_sdr1
,
774 static void gen_low_BATs(CPUPPCState
*env
)
776 #if !defined(CONFIG_USER_ONLY)
777 spr_register(env
, SPR_IBAT0U
, "IBAT0U",
778 SPR_NOACCESS
, SPR_NOACCESS
,
779 &spr_read_ibat
, &spr_write_ibatu
,
781 spr_register(env
, SPR_IBAT0L
, "IBAT0L",
782 SPR_NOACCESS
, SPR_NOACCESS
,
783 &spr_read_ibat
, &spr_write_ibatl
,
785 spr_register(env
, SPR_IBAT1U
, "IBAT1U",
786 SPR_NOACCESS
, SPR_NOACCESS
,
787 &spr_read_ibat
, &spr_write_ibatu
,
789 spr_register(env
, SPR_IBAT1L
, "IBAT1L",
790 SPR_NOACCESS
, SPR_NOACCESS
,
791 &spr_read_ibat
, &spr_write_ibatl
,
793 spr_register(env
, SPR_IBAT2U
, "IBAT2U",
794 SPR_NOACCESS
, SPR_NOACCESS
,
795 &spr_read_ibat
, &spr_write_ibatu
,
797 spr_register(env
, SPR_IBAT2L
, "IBAT2L",
798 SPR_NOACCESS
, SPR_NOACCESS
,
799 &spr_read_ibat
, &spr_write_ibatl
,
801 spr_register(env
, SPR_IBAT3U
, "IBAT3U",
802 SPR_NOACCESS
, SPR_NOACCESS
,
803 &spr_read_ibat
, &spr_write_ibatu
,
805 spr_register(env
, SPR_IBAT3L
, "IBAT3L",
806 SPR_NOACCESS
, SPR_NOACCESS
,
807 &spr_read_ibat
, &spr_write_ibatl
,
809 spr_register(env
, SPR_DBAT0U
, "DBAT0U",
810 SPR_NOACCESS
, SPR_NOACCESS
,
811 &spr_read_dbat
, &spr_write_dbatu
,
813 spr_register(env
, SPR_DBAT0L
, "DBAT0L",
814 SPR_NOACCESS
, SPR_NOACCESS
,
815 &spr_read_dbat
, &spr_write_dbatl
,
817 spr_register(env
, SPR_DBAT1U
, "DBAT1U",
818 SPR_NOACCESS
, SPR_NOACCESS
,
819 &spr_read_dbat
, &spr_write_dbatu
,
821 spr_register(env
, SPR_DBAT1L
, "DBAT1L",
822 SPR_NOACCESS
, SPR_NOACCESS
,
823 &spr_read_dbat
, &spr_write_dbatl
,
825 spr_register(env
, SPR_DBAT2U
, "DBAT2U",
826 SPR_NOACCESS
, SPR_NOACCESS
,
827 &spr_read_dbat
, &spr_write_dbatu
,
829 spr_register(env
, SPR_DBAT2L
, "DBAT2L",
830 SPR_NOACCESS
, SPR_NOACCESS
,
831 &spr_read_dbat
, &spr_write_dbatl
,
833 spr_register(env
, SPR_DBAT3U
, "DBAT3U",
834 SPR_NOACCESS
, SPR_NOACCESS
,
835 &spr_read_dbat
, &spr_write_dbatu
,
837 spr_register(env
, SPR_DBAT3L
, "DBAT3L",
838 SPR_NOACCESS
, SPR_NOACCESS
,
839 &spr_read_dbat
, &spr_write_dbatl
,
846 static void gen_high_BATs(CPUPPCState
*env
)
848 #if !defined(CONFIG_USER_ONLY)
849 spr_register(env
, SPR_IBAT4U
, "IBAT4U",
850 SPR_NOACCESS
, SPR_NOACCESS
,
851 &spr_read_ibat_h
, &spr_write_ibatu_h
,
853 spr_register(env
, SPR_IBAT4L
, "IBAT4L",
854 SPR_NOACCESS
, SPR_NOACCESS
,
855 &spr_read_ibat_h
, &spr_write_ibatl_h
,
857 spr_register(env
, SPR_IBAT5U
, "IBAT5U",
858 SPR_NOACCESS
, SPR_NOACCESS
,
859 &spr_read_ibat_h
, &spr_write_ibatu_h
,
861 spr_register(env
, SPR_IBAT5L
, "IBAT5L",
862 SPR_NOACCESS
, SPR_NOACCESS
,
863 &spr_read_ibat_h
, &spr_write_ibatl_h
,
865 spr_register(env
, SPR_IBAT6U
, "IBAT6U",
866 SPR_NOACCESS
, SPR_NOACCESS
,
867 &spr_read_ibat_h
, &spr_write_ibatu_h
,
869 spr_register(env
, SPR_IBAT6L
, "IBAT6L",
870 SPR_NOACCESS
, SPR_NOACCESS
,
871 &spr_read_ibat_h
, &spr_write_ibatl_h
,
873 spr_register(env
, SPR_IBAT7U
, "IBAT7U",
874 SPR_NOACCESS
, SPR_NOACCESS
,
875 &spr_read_ibat_h
, &spr_write_ibatu_h
,
877 spr_register(env
, SPR_IBAT7L
, "IBAT7L",
878 SPR_NOACCESS
, SPR_NOACCESS
,
879 &spr_read_ibat_h
, &spr_write_ibatl_h
,
881 spr_register(env
, SPR_DBAT4U
, "DBAT4U",
882 SPR_NOACCESS
, SPR_NOACCESS
,
883 &spr_read_dbat_h
, &spr_write_dbatu_h
,
885 spr_register(env
, SPR_DBAT4L
, "DBAT4L",
886 SPR_NOACCESS
, SPR_NOACCESS
,
887 &spr_read_dbat_h
, &spr_write_dbatl_h
,
889 spr_register(env
, SPR_DBAT5U
, "DBAT5U",
890 SPR_NOACCESS
, SPR_NOACCESS
,
891 &spr_read_dbat_h
, &spr_write_dbatu_h
,
893 spr_register(env
, SPR_DBAT5L
, "DBAT5L",
894 SPR_NOACCESS
, SPR_NOACCESS
,
895 &spr_read_dbat_h
, &spr_write_dbatl_h
,
897 spr_register(env
, SPR_DBAT6U
, "DBAT6U",
898 SPR_NOACCESS
, SPR_NOACCESS
,
899 &spr_read_dbat_h
, &spr_write_dbatu_h
,
901 spr_register(env
, SPR_DBAT6L
, "DBAT6L",
902 SPR_NOACCESS
, SPR_NOACCESS
,
903 &spr_read_dbat_h
, &spr_write_dbatl_h
,
905 spr_register(env
, SPR_DBAT7U
, "DBAT7U",
906 SPR_NOACCESS
, SPR_NOACCESS
,
907 &spr_read_dbat_h
, &spr_write_dbatu_h
,
909 spr_register(env
, SPR_DBAT7L
, "DBAT7L",
910 SPR_NOACCESS
, SPR_NOACCESS
,
911 &spr_read_dbat_h
, &spr_write_dbatl_h
,
917 /* Generic PowerPC time base */
918 static void gen_tbl(CPUPPCState
*env
)
920 spr_register(env
, SPR_VTBL
, "TBL",
921 &spr_read_tbl
, SPR_NOACCESS
,
922 &spr_read_tbl
, SPR_NOACCESS
,
924 spr_register(env
, SPR_TBL
, "TBL",
925 &spr_read_tbl
, SPR_NOACCESS
,
926 &spr_read_tbl
, &spr_write_tbl
,
928 spr_register(env
, SPR_VTBU
, "TBU",
929 &spr_read_tbu
, SPR_NOACCESS
,
930 &spr_read_tbu
, SPR_NOACCESS
,
932 spr_register(env
, SPR_TBU
, "TBU",
933 &spr_read_tbu
, SPR_NOACCESS
,
934 &spr_read_tbu
, &spr_write_tbu
,
938 /* Softare table search registers */
939 static void gen_6xx_7xx_soft_tlb(CPUPPCState
*env
, int nb_tlbs
, int nb_ways
)
941 #if !defined(CONFIG_USER_ONLY)
942 env
->nb_tlb
= nb_tlbs
;
943 env
->nb_ways
= nb_ways
;
945 env
->tlb_type
= TLB_6XX
;
946 spr_register(env
, SPR_DMISS
, "DMISS",
947 SPR_NOACCESS
, SPR_NOACCESS
,
948 &spr_read_generic
, SPR_NOACCESS
,
950 spr_register(env
, SPR_DCMP
, "DCMP",
951 SPR_NOACCESS
, SPR_NOACCESS
,
952 &spr_read_generic
, SPR_NOACCESS
,
954 spr_register(env
, SPR_HASH1
, "HASH1",
955 SPR_NOACCESS
, SPR_NOACCESS
,
956 &spr_read_generic
, SPR_NOACCESS
,
958 spr_register(env
, SPR_HASH2
, "HASH2",
959 SPR_NOACCESS
, SPR_NOACCESS
,
960 &spr_read_generic
, SPR_NOACCESS
,
962 spr_register(env
, SPR_IMISS
, "IMISS",
963 SPR_NOACCESS
, SPR_NOACCESS
,
964 &spr_read_generic
, SPR_NOACCESS
,
966 spr_register(env
, SPR_ICMP
, "ICMP",
967 SPR_NOACCESS
, SPR_NOACCESS
,
968 &spr_read_generic
, SPR_NOACCESS
,
970 spr_register(env
, SPR_RPA
, "RPA",
971 SPR_NOACCESS
, SPR_NOACCESS
,
972 &spr_read_generic
, &spr_write_generic
,
977 /* SPR common to MPC755 and G2 */
978 static void gen_spr_G2_755(CPUPPCState
*env
)
981 spr_register(env
, SPR_SPRG4
, "SPRG4",
982 SPR_NOACCESS
, SPR_NOACCESS
,
983 &spr_read_generic
, &spr_write_generic
,
985 spr_register(env
, SPR_SPRG5
, "SPRG5",
986 SPR_NOACCESS
, SPR_NOACCESS
,
987 &spr_read_generic
, &spr_write_generic
,
989 spr_register(env
, SPR_SPRG6
, "SPRG6",
990 SPR_NOACCESS
, SPR_NOACCESS
,
991 &spr_read_generic
, &spr_write_generic
,
993 spr_register(env
, SPR_SPRG7
, "SPRG7",
994 SPR_NOACCESS
, SPR_NOACCESS
,
995 &spr_read_generic
, &spr_write_generic
,
999 /* SPR common to all 7xx PowerPC implementations */
1000 static void gen_spr_7xx(CPUPPCState
*env
)
1003 /* XXX : not implemented */
1004 spr_register_kvm(env
, SPR_DABR
, "DABR",
1005 SPR_NOACCESS
, SPR_NOACCESS
,
1006 &spr_read_generic
, &spr_write_generic
,
1007 KVM_REG_PPC_DABR
, 0x00000000);
1008 /* XXX : not implemented */
1009 spr_register(env
, SPR_IABR
, "IABR",
1010 SPR_NOACCESS
, SPR_NOACCESS
,
1011 &spr_read_generic
, &spr_write_generic
,
1013 /* Cache management */
1014 /* XXX : not implemented */
1015 spr_register(env
, SPR_ICTC
, "ICTC",
1016 SPR_NOACCESS
, SPR_NOACCESS
,
1017 &spr_read_generic
, &spr_write_generic
,
1019 /* Performance monitors */
1020 /* XXX : not implemented */
1021 spr_register(env
, SPR_7XX_MMCR0
, "MMCR0",
1022 SPR_NOACCESS
, SPR_NOACCESS
,
1023 &spr_read_generic
, &spr_write_generic
,
1025 /* XXX : not implemented */
1026 spr_register(env
, SPR_7XX_MMCR1
, "MMCR1",
1027 SPR_NOACCESS
, SPR_NOACCESS
,
1028 &spr_read_generic
, &spr_write_generic
,
1030 /* XXX : not implemented */
1031 spr_register(env
, SPR_7XX_PMC1
, "PMC1",
1032 SPR_NOACCESS
, SPR_NOACCESS
,
1033 &spr_read_generic
, &spr_write_generic
,
1035 /* XXX : not implemented */
1036 spr_register(env
, SPR_7XX_PMC2
, "PMC2",
1037 SPR_NOACCESS
, SPR_NOACCESS
,
1038 &spr_read_generic
, &spr_write_generic
,
1040 /* XXX : not implemented */
1041 spr_register(env
, SPR_7XX_PMC3
, "PMC3",
1042 SPR_NOACCESS
, SPR_NOACCESS
,
1043 &spr_read_generic
, &spr_write_generic
,
1045 /* XXX : not implemented */
1046 spr_register(env
, SPR_7XX_PMC4
, "PMC4",
1047 SPR_NOACCESS
, SPR_NOACCESS
,
1048 &spr_read_generic
, &spr_write_generic
,
1050 /* XXX : not implemented */
1051 spr_register(env
, SPR_7XX_SIAR
, "SIAR",
1052 SPR_NOACCESS
, SPR_NOACCESS
,
1053 &spr_read_generic
, SPR_NOACCESS
,
1055 /* XXX : not implemented */
1056 spr_register(env
, SPR_7XX_UMMCR0
, "UMMCR0",
1057 &spr_read_ureg
, SPR_NOACCESS
,
1058 &spr_read_ureg
, SPR_NOACCESS
,
1060 /* XXX : not implemented */
1061 spr_register(env
, SPR_7XX_UMMCR1
, "UMMCR1",
1062 &spr_read_ureg
, SPR_NOACCESS
,
1063 &spr_read_ureg
, SPR_NOACCESS
,
1065 /* XXX : not implemented */
1066 spr_register(env
, SPR_7XX_UPMC1
, "UPMC1",
1067 &spr_read_ureg
, SPR_NOACCESS
,
1068 &spr_read_ureg
, SPR_NOACCESS
,
1070 /* XXX : not implemented */
1071 spr_register(env
, SPR_7XX_UPMC2
, "UPMC2",
1072 &spr_read_ureg
, SPR_NOACCESS
,
1073 &spr_read_ureg
, SPR_NOACCESS
,
1075 /* XXX : not implemented */
1076 spr_register(env
, SPR_7XX_UPMC3
, "UPMC3",
1077 &spr_read_ureg
, SPR_NOACCESS
,
1078 &spr_read_ureg
, SPR_NOACCESS
,
1080 /* XXX : not implemented */
1081 spr_register(env
, SPR_7XX_UPMC4
, "UPMC4",
1082 &spr_read_ureg
, SPR_NOACCESS
,
1083 &spr_read_ureg
, SPR_NOACCESS
,
1085 /* XXX : not implemented */
1086 spr_register(env
, SPR_7XX_USIAR
, "USIAR",
1087 &spr_read_ureg
, SPR_NOACCESS
,
1088 &spr_read_ureg
, SPR_NOACCESS
,
1090 /* External access control */
1091 /* XXX : not implemented */
1092 spr_register(env
, SPR_EAR
, "EAR",
1093 SPR_NOACCESS
, SPR_NOACCESS
,
1094 &spr_read_generic
, &spr_write_generic
,
1099 #ifndef CONFIG_USER_ONLY
1100 static void spr_write_amr(DisasContext
*ctx
, int sprn
, int gprn
)
1102 TCGv t0
= tcg_temp_new();
1103 TCGv t1
= tcg_temp_new();
1104 TCGv t2
= tcg_temp_new();
1106 /* Note, the HV=1 PR=0 case is handled earlier by simply using
1107 * spr_write_generic for HV mode in the SPR table
1110 /* Build insertion mask into t1 based on context */
1112 gen_load_spr(t1
, SPR_UAMOR
);
1114 gen_load_spr(t1
, SPR_AMOR
);
1117 /* Mask new bits into t2 */
1118 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1120 /* Load AMR and clear new bits in t0 */
1121 gen_load_spr(t0
, SPR_AMR
);
1122 tcg_gen_andc_tl(t0
, t0
, t1
);
1124 /* Or'in new bits and write it out */
1125 tcg_gen_or_tl(t0
, t0
, t2
);
1126 gen_store_spr(SPR_AMR
, t0
);
1127 spr_store_dump_spr(SPR_AMR
);
1134 static void spr_write_uamor(DisasContext
*ctx
, int sprn
, int gprn
)
1136 TCGv t0
= tcg_temp_new();
1137 TCGv t1
= tcg_temp_new();
1138 TCGv t2
= tcg_temp_new();
1140 /* Note, the HV=1 case is handled earlier by simply using
1141 * spr_write_generic for HV mode in the SPR table
1144 /* Build insertion mask into t1 based on context */
1145 gen_load_spr(t1
, SPR_AMOR
);
1147 /* Mask new bits into t2 */
1148 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1150 /* Load AMR and clear new bits in t0 */
1151 gen_load_spr(t0
, SPR_UAMOR
);
1152 tcg_gen_andc_tl(t0
, t0
, t1
);
1154 /* Or'in new bits and write it out */
1155 tcg_gen_or_tl(t0
, t0
, t2
);
1156 gen_store_spr(SPR_UAMOR
, t0
);
1157 spr_store_dump_spr(SPR_UAMOR
);
1164 static void spr_write_iamr(DisasContext
*ctx
, int sprn
, int gprn
)
1166 TCGv t0
= tcg_temp_new();
1167 TCGv t1
= tcg_temp_new();
1168 TCGv t2
= tcg_temp_new();
1170 /* Note, the HV=1 case is handled earlier by simply using
1171 * spr_write_generic for HV mode in the SPR table
1174 /* Build insertion mask into t1 based on context */
1175 gen_load_spr(t1
, SPR_AMOR
);
1177 /* Mask new bits into t2 */
1178 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1180 /* Load AMR and clear new bits in t0 */
1181 gen_load_spr(t0
, SPR_IAMR
);
1182 tcg_gen_andc_tl(t0
, t0
, t1
);
1184 /* Or'in new bits and write it out */
1185 tcg_gen_or_tl(t0
, t0
, t2
);
1186 gen_store_spr(SPR_IAMR
, t0
);
1187 spr_store_dump_spr(SPR_IAMR
);
1193 #endif /* CONFIG_USER_ONLY */
1195 static void gen_spr_amr(CPUPPCState
*env
)
1197 #ifndef CONFIG_USER_ONLY
1198 /* Virtual Page Class Key protection */
1199 /* The AMR is accessible either via SPR 13 or SPR 29. 13 is
1200 * userspace accessible, 29 is privileged. So we only need to set
1201 * the kvm ONE_REG id on one of them, we use 29 */
1202 spr_register(env
, SPR_UAMR
, "UAMR",
1203 &spr_read_generic
, &spr_write_amr
,
1204 &spr_read_generic
, &spr_write_amr
,
1206 spr_register_kvm_hv(env
, SPR_AMR
, "AMR",
1207 SPR_NOACCESS
, SPR_NOACCESS
,
1208 &spr_read_generic
, &spr_write_amr
,
1209 &spr_read_generic
, &spr_write_generic
,
1210 KVM_REG_PPC_AMR
, 0);
1211 spr_register_kvm_hv(env
, SPR_UAMOR
, "UAMOR",
1212 SPR_NOACCESS
, SPR_NOACCESS
,
1213 &spr_read_generic
, &spr_write_uamor
,
1214 &spr_read_generic
, &spr_write_generic
,
1215 KVM_REG_PPC_UAMOR
, 0);
1216 spr_register_hv(env
, SPR_AMOR
, "AMOR",
1217 SPR_NOACCESS
, SPR_NOACCESS
,
1218 SPR_NOACCESS
, SPR_NOACCESS
,
1219 &spr_read_generic
, &spr_write_generic
,
1221 #endif /* !CONFIG_USER_ONLY */
1224 static void gen_spr_iamr(CPUPPCState
*env
)
1226 #ifndef CONFIG_USER_ONLY
1227 spr_register_kvm_hv(env
, SPR_IAMR
, "IAMR",
1228 SPR_NOACCESS
, SPR_NOACCESS
,
1229 &spr_read_generic
, &spr_write_iamr
,
1230 &spr_read_generic
, &spr_write_generic
,
1231 KVM_REG_PPC_IAMR
, 0);
1232 #endif /* !CONFIG_USER_ONLY */
1234 #endif /* TARGET_PPC64 */
1236 #ifndef CONFIG_USER_ONLY
1237 static void spr_read_thrm(DisasContext
*ctx
, int gprn
, int sprn
)
1239 gen_helper_fixup_thrm(cpu_env
);
1240 gen_load_spr(cpu_gpr
[gprn
], sprn
);
1241 spr_load_dump_spr(sprn
);
1243 #endif /* !CONFIG_USER_ONLY */
1245 static void gen_spr_thrm(CPUPPCState
*env
)
1247 /* Thermal management */
1248 /* XXX : not implemented */
1249 spr_register(env
, SPR_THRM1
, "THRM1",
1250 SPR_NOACCESS
, SPR_NOACCESS
,
1251 &spr_read_thrm
, &spr_write_generic
,
1253 /* XXX : not implemented */
1254 spr_register(env
, SPR_THRM2
, "THRM2",
1255 SPR_NOACCESS
, SPR_NOACCESS
,
1256 &spr_read_thrm
, &spr_write_generic
,
1258 /* XXX : not implemented */
1259 spr_register(env
, SPR_THRM3
, "THRM3",
1260 SPR_NOACCESS
, SPR_NOACCESS
,
1261 &spr_read_thrm
, &spr_write_generic
,
1265 /* SPR specific to PowerPC 604 implementation */
1266 static void gen_spr_604(CPUPPCState
*env
)
1268 /* Processor identification */
1269 spr_register(env
, SPR_PIR
, "PIR",
1270 SPR_NOACCESS
, SPR_NOACCESS
,
1271 &spr_read_generic
, &spr_write_pir
,
1274 /* XXX : not implemented */
1275 spr_register(env
, SPR_IABR
, "IABR",
1276 SPR_NOACCESS
, SPR_NOACCESS
,
1277 &spr_read_generic
, &spr_write_generic
,
1279 /* XXX : not implemented */
1280 spr_register_kvm(env
, SPR_DABR
, "DABR",
1281 SPR_NOACCESS
, SPR_NOACCESS
,
1282 &spr_read_generic
, &spr_write_generic
,
1283 KVM_REG_PPC_DABR
, 0x00000000);
1284 /* Performance counters */
1285 /* XXX : not implemented */
1286 spr_register(env
, SPR_7XX_MMCR0
, "MMCR0",
1287 SPR_NOACCESS
, SPR_NOACCESS
,
1288 &spr_read_generic
, &spr_write_generic
,
1290 /* XXX : not implemented */
1291 spr_register(env
, SPR_7XX_PMC1
, "PMC1",
1292 SPR_NOACCESS
, SPR_NOACCESS
,
1293 &spr_read_generic
, &spr_write_generic
,
1295 /* XXX : not implemented */
1296 spr_register(env
, SPR_7XX_PMC2
, "PMC2",
1297 SPR_NOACCESS
, SPR_NOACCESS
,
1298 &spr_read_generic
, &spr_write_generic
,
1300 /* XXX : not implemented */
1301 spr_register(env
, SPR_7XX_SIAR
, "SIAR",
1302 SPR_NOACCESS
, SPR_NOACCESS
,
1303 &spr_read_generic
, SPR_NOACCESS
,
1305 /* XXX : not implemented */
1306 spr_register(env
, SPR_SDA
, "SDA",
1307 SPR_NOACCESS
, SPR_NOACCESS
,
1308 &spr_read_generic
, SPR_NOACCESS
,
1310 /* External access control */
1311 /* XXX : not implemented */
1312 spr_register(env
, SPR_EAR
, "EAR",
1313 SPR_NOACCESS
, SPR_NOACCESS
,
1314 &spr_read_generic
, &spr_write_generic
,
1318 /* SPR specific to PowerPC 603 implementation */
1319 static void gen_spr_603(CPUPPCState
*env
)
1321 /* External access control */
1322 /* XXX : not implemented */
1323 spr_register(env
, SPR_EAR
, "EAR",
1324 SPR_NOACCESS
, SPR_NOACCESS
,
1325 &spr_read_generic
, &spr_write_generic
,
1328 /* XXX : not implemented */
1329 spr_register(env
, SPR_IABR
, "IABR",
1330 SPR_NOACCESS
, SPR_NOACCESS
,
1331 &spr_read_generic
, &spr_write_generic
,
1336 /* SPR specific to PowerPC G2 implementation */
1337 static void gen_spr_G2(CPUPPCState
*env
)
1339 /* Memory base address */
1341 /* XXX : not implemented */
1342 spr_register(env
, SPR_MBAR
, "MBAR",
1343 SPR_NOACCESS
, SPR_NOACCESS
,
1344 &spr_read_generic
, &spr_write_generic
,
1346 /* Exception processing */
1347 spr_register(env
, SPR_BOOKE_CSRR0
, "CSRR0",
1348 SPR_NOACCESS
, SPR_NOACCESS
,
1349 &spr_read_generic
, &spr_write_generic
,
1351 spr_register(env
, SPR_BOOKE_CSRR1
, "CSRR1",
1352 SPR_NOACCESS
, SPR_NOACCESS
,
1353 &spr_read_generic
, &spr_write_generic
,
1356 /* XXX : not implemented */
1357 spr_register(env
, SPR_DABR
, "DABR",
1358 SPR_NOACCESS
, SPR_NOACCESS
,
1359 &spr_read_generic
, &spr_write_generic
,
1361 /* XXX : not implemented */
1362 spr_register(env
, SPR_DABR2
, "DABR2",
1363 SPR_NOACCESS
, SPR_NOACCESS
,
1364 &spr_read_generic
, &spr_write_generic
,
1366 /* XXX : not implemented */
1367 spr_register(env
, SPR_IABR
, "IABR",
1368 SPR_NOACCESS
, SPR_NOACCESS
,
1369 &spr_read_generic
, &spr_write_generic
,
1371 /* XXX : not implemented */
1372 spr_register(env
, SPR_IABR2
, "IABR2",
1373 SPR_NOACCESS
, SPR_NOACCESS
,
1374 &spr_read_generic
, &spr_write_generic
,
1376 /* XXX : not implemented */
1377 spr_register(env
, SPR_IBCR
, "IBCR",
1378 SPR_NOACCESS
, SPR_NOACCESS
,
1379 &spr_read_generic
, &spr_write_generic
,
1381 /* XXX : not implemented */
1382 spr_register(env
, SPR_DBCR
, "DBCR",
1383 SPR_NOACCESS
, SPR_NOACCESS
,
1384 &spr_read_generic
, &spr_write_generic
,
1388 /* SPR specific to PowerPC 602 implementation */
1389 static void gen_spr_602(CPUPPCState
*env
)
1392 /* XXX : not implemented */
1393 spr_register(env
, SPR_SER
, "SER",
1394 SPR_NOACCESS
, SPR_NOACCESS
,
1395 &spr_read_generic
, &spr_write_generic
,
1397 /* XXX : not implemented */
1398 spr_register(env
, SPR_SEBR
, "SEBR",
1399 SPR_NOACCESS
, SPR_NOACCESS
,
1400 &spr_read_generic
, &spr_write_generic
,
1402 /* XXX : not implemented */
1403 spr_register(env
, SPR_ESASRR
, "ESASRR",
1404 SPR_NOACCESS
, SPR_NOACCESS
,
1405 &spr_read_generic
, &spr_write_generic
,
1407 /* Floating point status */
1408 /* XXX : not implemented */
1409 spr_register(env
, SPR_SP
, "SP",
1410 SPR_NOACCESS
, SPR_NOACCESS
,
1411 &spr_read_generic
, &spr_write_generic
,
1413 /* XXX : not implemented */
1414 spr_register(env
, SPR_LT
, "LT",
1415 SPR_NOACCESS
, SPR_NOACCESS
,
1416 &spr_read_generic
, &spr_write_generic
,
1418 /* Watchdog timer */
1419 /* XXX : not implemented */
1420 spr_register(env
, SPR_TCR
, "TCR",
1421 SPR_NOACCESS
, SPR_NOACCESS
,
1422 &spr_read_generic
, &spr_write_generic
,
1424 /* Interrupt base */
1425 spr_register(env
, SPR_IBR
, "IBR",
1426 SPR_NOACCESS
, SPR_NOACCESS
,
1427 &spr_read_generic
, &spr_write_generic
,
1429 /* XXX : not implemented */
1430 spr_register(env
, SPR_IABR
, "IABR",
1431 SPR_NOACCESS
, SPR_NOACCESS
,
1432 &spr_read_generic
, &spr_write_generic
,
1436 /* SPR specific to PowerPC 601 implementation */
1437 static void gen_spr_601(CPUPPCState
*env
)
1439 /* Multiplication/division register */
1441 spr_register(env
, SPR_MQ
, "MQ",
1442 &spr_read_generic
, &spr_write_generic
,
1443 &spr_read_generic
, &spr_write_generic
,
1446 spr_register(env
, SPR_601_RTCU
, "RTCU",
1447 SPR_NOACCESS
, SPR_NOACCESS
,
1448 SPR_NOACCESS
, &spr_write_601_rtcu
,
1450 spr_register(env
, SPR_601_VRTCU
, "RTCU",
1451 &spr_read_601_rtcu
, SPR_NOACCESS
,
1452 &spr_read_601_rtcu
, SPR_NOACCESS
,
1454 spr_register(env
, SPR_601_RTCL
, "RTCL",
1455 SPR_NOACCESS
, SPR_NOACCESS
,
1456 SPR_NOACCESS
, &spr_write_601_rtcl
,
1458 spr_register(env
, SPR_601_VRTCL
, "RTCL",
1459 &spr_read_601_rtcl
, SPR_NOACCESS
,
1460 &spr_read_601_rtcl
, SPR_NOACCESS
,
1464 spr_register(env
, SPR_601_UDECR
, "UDECR",
1465 &spr_read_decr
, SPR_NOACCESS
,
1466 &spr_read_decr
, SPR_NOACCESS
,
1469 /* External access control */
1470 /* XXX : not implemented */
1471 spr_register(env
, SPR_EAR
, "EAR",
1472 SPR_NOACCESS
, SPR_NOACCESS
,
1473 &spr_read_generic
, &spr_write_generic
,
1475 /* Memory management */
1476 #if !defined(CONFIG_USER_ONLY)
1477 spr_register(env
, SPR_IBAT0U
, "IBAT0U",
1478 SPR_NOACCESS
, SPR_NOACCESS
,
1479 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1481 spr_register(env
, SPR_IBAT0L
, "IBAT0L",
1482 SPR_NOACCESS
, SPR_NOACCESS
,
1483 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1485 spr_register(env
, SPR_IBAT1U
, "IBAT1U",
1486 SPR_NOACCESS
, SPR_NOACCESS
,
1487 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1489 spr_register(env
, SPR_IBAT1L
, "IBAT1L",
1490 SPR_NOACCESS
, SPR_NOACCESS
,
1491 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1493 spr_register(env
, SPR_IBAT2U
, "IBAT2U",
1494 SPR_NOACCESS
, SPR_NOACCESS
,
1495 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1497 spr_register(env
, SPR_IBAT2L
, "IBAT2L",
1498 SPR_NOACCESS
, SPR_NOACCESS
,
1499 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1501 spr_register(env
, SPR_IBAT3U
, "IBAT3U",
1502 SPR_NOACCESS
, SPR_NOACCESS
,
1503 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1505 spr_register(env
, SPR_IBAT3L
, "IBAT3L",
1506 SPR_NOACCESS
, SPR_NOACCESS
,
1507 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1513 static void gen_spr_74xx(CPUPPCState
*env
)
1515 /* Processor identification */
1516 spr_register(env
, SPR_PIR
, "PIR",
1517 SPR_NOACCESS
, SPR_NOACCESS
,
1518 &spr_read_generic
, &spr_write_pir
,
1520 /* XXX : not implemented */
1521 spr_register(env
, SPR_74XX_MMCR2
, "MMCR2",
1522 SPR_NOACCESS
, SPR_NOACCESS
,
1523 &spr_read_generic
, &spr_write_generic
,
1525 /* XXX : not implemented */
1526 spr_register(env
, SPR_74XX_UMMCR2
, "UMMCR2",
1527 &spr_read_ureg
, SPR_NOACCESS
,
1528 &spr_read_ureg
, SPR_NOACCESS
,
1530 /* XXX: not implemented */
1531 spr_register(env
, SPR_BAMR
, "BAMR",
1532 SPR_NOACCESS
, SPR_NOACCESS
,
1533 &spr_read_generic
, &spr_write_generic
,
1535 /* XXX : not implemented */
1536 spr_register(env
, SPR_MSSCR0
, "MSSCR0",
1537 SPR_NOACCESS
, SPR_NOACCESS
,
1538 &spr_read_generic
, &spr_write_generic
,
1540 /* Hardware implementation registers */
1541 /* XXX : not implemented */
1542 spr_register(env
, SPR_HID0
, "HID0",
1543 SPR_NOACCESS
, SPR_NOACCESS
,
1544 &spr_read_generic
, &spr_write_generic
,
1546 /* XXX : not implemented */
1547 spr_register(env
, SPR_HID1
, "HID1",
1548 SPR_NOACCESS
, SPR_NOACCESS
,
1549 &spr_read_generic
, &spr_write_generic
,
1552 spr_register(env
, SPR_VRSAVE
, "VRSAVE",
1553 &spr_read_generic
, &spr_write_generic
,
1554 &spr_read_generic
, &spr_write_generic
,
1556 /* XXX : not implemented */
1557 spr_register(env
, SPR_L2CR
, "L2CR",
1558 SPR_NOACCESS
, SPR_NOACCESS
,
1559 &spr_read_generic
, spr_access_nop
,
1561 /* Not strictly an SPR */
1562 vscr_init(env
, 0x00010000);
1565 static void gen_l3_ctrl(CPUPPCState
*env
)
1568 /* XXX : not implemented */
1569 spr_register(env
, SPR_L3CR
, "L3CR",
1570 SPR_NOACCESS
, SPR_NOACCESS
,
1571 &spr_read_generic
, &spr_write_generic
,
1574 /* XXX : not implemented */
1575 spr_register(env
, SPR_L3ITCR0
, "L3ITCR0",
1576 SPR_NOACCESS
, SPR_NOACCESS
,
1577 &spr_read_generic
, &spr_write_generic
,
1580 /* XXX : not implemented */
1581 spr_register(env
, SPR_L3PM
, "L3PM",
1582 SPR_NOACCESS
, SPR_NOACCESS
,
1583 &spr_read_generic
, &spr_write_generic
,
1587 static void gen_74xx_soft_tlb(CPUPPCState
*env
, int nb_tlbs
, int nb_ways
)
1589 #if !defined(CONFIG_USER_ONLY)
1590 env
->nb_tlb
= nb_tlbs
;
1591 env
->nb_ways
= nb_ways
;
1593 env
->tlb_type
= TLB_6XX
;
1594 /* XXX : not implemented */
1595 spr_register(env
, SPR_PTEHI
, "PTEHI",
1596 SPR_NOACCESS
, SPR_NOACCESS
,
1597 &spr_read_generic
, &spr_write_generic
,
1599 /* XXX : not implemented */
1600 spr_register(env
, SPR_PTELO
, "PTELO",
1601 SPR_NOACCESS
, SPR_NOACCESS
,
1602 &spr_read_generic
, &spr_write_generic
,
1604 /* XXX : not implemented */
1605 spr_register(env
, SPR_TLBMISS
, "TLBMISS",
1606 SPR_NOACCESS
, SPR_NOACCESS
,
1607 &spr_read_generic
, &spr_write_generic
,
1612 #if !defined(CONFIG_USER_ONLY)
1613 static void spr_write_e500_l1csr0(DisasContext
*ctx
, int sprn
, int gprn
)
1615 TCGv t0
= tcg_temp_new();
1617 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], L1CSR0_DCE
| L1CSR0_CPE
);
1618 gen_store_spr(sprn
, t0
);
1622 static void spr_write_e500_l1csr1(DisasContext
*ctx
, int sprn
, int gprn
)
1624 TCGv t0
= tcg_temp_new();
1626 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], L1CSR1_ICE
| L1CSR1_CPE
);
1627 gen_store_spr(sprn
, t0
);
1631 static void spr_write_booke206_mmucsr0(DisasContext
*ctx
, int sprn
, int gprn
)
1633 gen_helper_booke206_tlbflush(cpu_env
, cpu_gpr
[gprn
]);
1636 static void spr_write_booke_pid(DisasContext
*ctx
, int sprn
, int gprn
)
1638 TCGv_i32 t0
= tcg_const_i32(sprn
);
1639 gen_helper_booke_setpid(cpu_env
, t0
, cpu_gpr
[gprn
]);
1640 tcg_temp_free_i32(t0
);
1644 static void gen_spr_usprg3(CPUPPCState
*env
)
1646 spr_register(env
, SPR_USPRG3
, "USPRG3",
1647 &spr_read_ureg
, SPR_NOACCESS
,
1648 &spr_read_ureg
, SPR_NOACCESS
,
1652 static void gen_spr_usprgh(CPUPPCState
*env
)
1654 spr_register(env
, SPR_USPRG4
, "USPRG4",
1655 &spr_read_ureg
, SPR_NOACCESS
,
1656 &spr_read_ureg
, SPR_NOACCESS
,
1658 spr_register(env
, SPR_USPRG5
, "USPRG5",
1659 &spr_read_ureg
, SPR_NOACCESS
,
1660 &spr_read_ureg
, SPR_NOACCESS
,
1662 spr_register(env
, SPR_USPRG6
, "USPRG6",
1663 &spr_read_ureg
, SPR_NOACCESS
,
1664 &spr_read_ureg
, SPR_NOACCESS
,
1666 spr_register(env
, SPR_USPRG7
, "USPRG7",
1667 &spr_read_ureg
, SPR_NOACCESS
,
1668 &spr_read_ureg
, SPR_NOACCESS
,
1672 /* PowerPC BookE SPR */
1673 static void gen_spr_BookE(CPUPPCState
*env
, uint64_t ivor_mask
)
1675 const char *ivor_names
[64] = {
1676 "IVOR0", "IVOR1", "IVOR2", "IVOR3",
1677 "IVOR4", "IVOR5", "IVOR6", "IVOR7",
1678 "IVOR8", "IVOR9", "IVOR10", "IVOR11",
1679 "IVOR12", "IVOR13", "IVOR14", "IVOR15",
1680 "IVOR16", "IVOR17", "IVOR18", "IVOR19",
1681 "IVOR20", "IVOR21", "IVOR22", "IVOR23",
1682 "IVOR24", "IVOR25", "IVOR26", "IVOR27",
1683 "IVOR28", "IVOR29", "IVOR30", "IVOR31",
1684 "IVOR32", "IVOR33", "IVOR34", "IVOR35",
1685 "IVOR36", "IVOR37", "IVOR38", "IVOR39",
1686 "IVOR40", "IVOR41", "IVOR42", "IVOR43",
1687 "IVOR44", "IVOR45", "IVOR46", "IVOR47",
1688 "IVOR48", "IVOR49", "IVOR50", "IVOR51",
1689 "IVOR52", "IVOR53", "IVOR54", "IVOR55",
1690 "IVOR56", "IVOR57", "IVOR58", "IVOR59",
1691 "IVOR60", "IVOR61", "IVOR62", "IVOR63",
1693 #define SPR_BOOKE_IVORxx (-1)
1694 int ivor_sprn
[64] = {
1695 SPR_BOOKE_IVOR0
, SPR_BOOKE_IVOR1
, SPR_BOOKE_IVOR2
, SPR_BOOKE_IVOR3
,
1696 SPR_BOOKE_IVOR4
, SPR_BOOKE_IVOR5
, SPR_BOOKE_IVOR6
, SPR_BOOKE_IVOR7
,
1697 SPR_BOOKE_IVOR8
, SPR_BOOKE_IVOR9
, SPR_BOOKE_IVOR10
, SPR_BOOKE_IVOR11
,
1698 SPR_BOOKE_IVOR12
, SPR_BOOKE_IVOR13
, SPR_BOOKE_IVOR14
, SPR_BOOKE_IVOR15
,
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_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1703 SPR_BOOKE_IVOR32
, SPR_BOOKE_IVOR33
, SPR_BOOKE_IVOR34
, SPR_BOOKE_IVOR35
,
1704 SPR_BOOKE_IVOR36
, SPR_BOOKE_IVOR37
, SPR_BOOKE_IVOR38
, SPR_BOOKE_IVOR39
,
1705 SPR_BOOKE_IVOR40
, SPR_BOOKE_IVOR41
, SPR_BOOKE_IVOR42
, 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
,
1710 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1714 /* Interrupt processing */
1715 spr_register(env
, SPR_BOOKE_CSRR0
, "CSRR0",
1716 SPR_NOACCESS
, SPR_NOACCESS
,
1717 &spr_read_generic
, &spr_write_generic
,
1719 spr_register(env
, SPR_BOOKE_CSRR1
, "CSRR1",
1720 SPR_NOACCESS
, SPR_NOACCESS
,
1721 &spr_read_generic
, &spr_write_generic
,
1724 /* XXX : not implemented */
1725 spr_register(env
, SPR_BOOKE_IAC1
, "IAC1",
1726 SPR_NOACCESS
, SPR_NOACCESS
,
1727 &spr_read_generic
, &spr_write_generic
,
1729 /* XXX : not implemented */
1730 spr_register(env
, SPR_BOOKE_IAC2
, "IAC2",
1731 SPR_NOACCESS
, SPR_NOACCESS
,
1732 &spr_read_generic
, &spr_write_generic
,
1734 /* XXX : not implemented */
1735 spr_register(env
, SPR_BOOKE_DAC1
, "DAC1",
1736 SPR_NOACCESS
, SPR_NOACCESS
,
1737 &spr_read_generic
, &spr_write_generic
,
1739 /* XXX : not implemented */
1740 spr_register(env
, SPR_BOOKE_DAC2
, "DAC2",
1741 SPR_NOACCESS
, SPR_NOACCESS
,
1742 &spr_read_generic
, &spr_write_generic
,
1744 /* XXX : not implemented */
1745 spr_register(env
, SPR_BOOKE_DBCR0
, "DBCR0",
1746 SPR_NOACCESS
, SPR_NOACCESS
,
1747 &spr_read_generic
, &spr_write_40x_dbcr0
,
1749 /* XXX : not implemented */
1750 spr_register(env
, SPR_BOOKE_DBCR1
, "DBCR1",
1751 SPR_NOACCESS
, SPR_NOACCESS
,
1752 &spr_read_generic
, &spr_write_generic
,
1754 /* XXX : not implemented */
1755 spr_register(env
, SPR_BOOKE_DBCR2
, "DBCR2",
1756 SPR_NOACCESS
, SPR_NOACCESS
,
1757 &spr_read_generic
, &spr_write_generic
,
1759 /* XXX : not implemented */
1760 spr_register(env
, SPR_BOOKE_DBSR
, "DBSR",
1761 SPR_NOACCESS
, SPR_NOACCESS
,
1762 &spr_read_generic
, &spr_write_clear
,
1764 spr_register(env
, SPR_BOOKE_DEAR
, "DEAR",
1765 SPR_NOACCESS
, SPR_NOACCESS
,
1766 &spr_read_generic
, &spr_write_generic
,
1768 spr_register(env
, SPR_BOOKE_ESR
, "ESR",
1769 SPR_NOACCESS
, SPR_NOACCESS
,
1770 &spr_read_generic
, &spr_write_generic
,
1772 spr_register(env
, SPR_BOOKE_IVPR
, "IVPR",
1773 SPR_NOACCESS
, SPR_NOACCESS
,
1774 &spr_read_generic
, &spr_write_excp_prefix
,
1776 /* Exception vectors */
1777 for (i
= 0; i
< 64; i
++) {
1778 if (ivor_mask
& (1ULL << i
)) {
1779 if (ivor_sprn
[i
] == SPR_BOOKE_IVORxx
) {
1780 fprintf(stderr
, "ERROR: IVOR %d SPR is not defined\n", i
);
1783 spr_register(env
, ivor_sprn
[i
], ivor_names
[i
],
1784 SPR_NOACCESS
, SPR_NOACCESS
,
1785 &spr_read_generic
, &spr_write_excp_vector
,
1789 spr_register(env
, SPR_BOOKE_PID
, "PID",
1790 SPR_NOACCESS
, SPR_NOACCESS
,
1791 &spr_read_generic
, &spr_write_booke_pid
,
1793 spr_register(env
, SPR_BOOKE_TCR
, "TCR",
1794 SPR_NOACCESS
, SPR_NOACCESS
,
1795 &spr_read_generic
, &spr_write_booke_tcr
,
1797 spr_register(env
, SPR_BOOKE_TSR
, "TSR",
1798 SPR_NOACCESS
, SPR_NOACCESS
,
1799 &spr_read_generic
, &spr_write_booke_tsr
,
1802 spr_register(env
, SPR_DECR
, "DECR",
1803 SPR_NOACCESS
, SPR_NOACCESS
,
1804 &spr_read_decr
, &spr_write_decr
,
1806 spr_register(env
, SPR_BOOKE_DECAR
, "DECAR",
1807 SPR_NOACCESS
, SPR_NOACCESS
,
1808 SPR_NOACCESS
, &spr_write_generic
,
1811 spr_register(env
, SPR_USPRG0
, "USPRG0",
1812 &spr_read_generic
, &spr_write_generic
,
1813 &spr_read_generic
, &spr_write_generic
,
1815 spr_register(env
, SPR_SPRG4
, "SPRG4",
1816 SPR_NOACCESS
, SPR_NOACCESS
,
1817 &spr_read_generic
, &spr_write_generic
,
1819 spr_register(env
, SPR_SPRG5
, "SPRG5",
1820 SPR_NOACCESS
, SPR_NOACCESS
,
1821 &spr_read_generic
, &spr_write_generic
,
1823 spr_register(env
, SPR_SPRG6
, "SPRG6",
1824 SPR_NOACCESS
, SPR_NOACCESS
,
1825 &spr_read_generic
, &spr_write_generic
,
1827 spr_register(env
, SPR_SPRG7
, "SPRG7",
1828 SPR_NOACCESS
, SPR_NOACCESS
,
1829 &spr_read_generic
, &spr_write_generic
,
1833 static inline uint32_t gen_tlbncfg(uint32_t assoc
, uint32_t minsize
,
1834 uint32_t maxsize
, uint32_t flags
,
1837 return (assoc
<< TLBnCFG_ASSOC_SHIFT
) |
1838 (minsize
<< TLBnCFG_MINSIZE_SHIFT
) |
1839 (maxsize
<< TLBnCFG_MAXSIZE_SHIFT
) |
1843 /* BookE 2.06 storage control registers */
1844 static void gen_spr_BookE206(CPUPPCState
*env
, uint32_t mas_mask
,
1845 uint32_t *tlbncfg
, uint32_t mmucfg
)
1847 #if !defined(CONFIG_USER_ONLY)
1848 const char *mas_names
[8] = {
1849 "MAS0", "MAS1", "MAS2", "MAS3", "MAS4", "MAS5", "MAS6", "MAS7",
1852 SPR_BOOKE_MAS0
, SPR_BOOKE_MAS1
, SPR_BOOKE_MAS2
, SPR_BOOKE_MAS3
,
1853 SPR_BOOKE_MAS4
, SPR_BOOKE_MAS5
, SPR_BOOKE_MAS6
, SPR_BOOKE_MAS7
,
1857 /* TLB assist registers */
1858 /* XXX : not implemented */
1859 for (i
= 0; i
< 8; i
++) {
1860 void (*uea_write
)(DisasContext
*ctx
, int sprn
, int gprn
) = &spr_write_generic32
;
1861 if (i
== 2 && (mas_mask
& (1 << i
)) && (env
->insns_flags
& PPC_64B
)) {
1862 uea_write
= &spr_write_generic
;
1864 if (mas_mask
& (1 << i
)) {
1865 spr_register(env
, mas_sprn
[i
], mas_names
[i
],
1866 SPR_NOACCESS
, SPR_NOACCESS
,
1867 &spr_read_generic
, uea_write
,
1871 if (env
->nb_pids
> 1) {
1872 /* XXX : not implemented */
1873 spr_register(env
, SPR_BOOKE_PID1
, "PID1",
1874 SPR_NOACCESS
, SPR_NOACCESS
,
1875 &spr_read_generic
, &spr_write_booke_pid
,
1878 if (env
->nb_pids
> 2) {
1879 /* XXX : not implemented */
1880 spr_register(env
, SPR_BOOKE_PID2
, "PID2",
1881 SPR_NOACCESS
, SPR_NOACCESS
,
1882 &spr_read_generic
, &spr_write_booke_pid
,
1885 /* XXX : not implemented */
1886 spr_register(env
, SPR_MMUCFG
, "MMUCFG",
1887 SPR_NOACCESS
, SPR_NOACCESS
,
1888 &spr_read_generic
, SPR_NOACCESS
,
1890 switch (env
->nb_ways
) {
1892 spr_register(env
, SPR_BOOKE_TLB3CFG
, "TLB3CFG",
1893 SPR_NOACCESS
, SPR_NOACCESS
,
1894 &spr_read_generic
, SPR_NOACCESS
,
1898 spr_register(env
, SPR_BOOKE_TLB2CFG
, "TLB2CFG",
1899 SPR_NOACCESS
, SPR_NOACCESS
,
1900 &spr_read_generic
, SPR_NOACCESS
,
1904 spr_register(env
, SPR_BOOKE_TLB1CFG
, "TLB1CFG",
1905 SPR_NOACCESS
, SPR_NOACCESS
,
1906 &spr_read_generic
, SPR_NOACCESS
,
1910 spr_register(env
, SPR_BOOKE_TLB0CFG
, "TLB0CFG",
1911 SPR_NOACCESS
, SPR_NOACCESS
,
1912 &spr_read_generic
, SPR_NOACCESS
,
1921 gen_spr_usprgh(env
);
1924 /* SPR specific to PowerPC 440 implementation */
1925 static void gen_spr_440(CPUPPCState
*env
)
1928 /* XXX : not implemented */
1929 spr_register(env
, SPR_440_DNV0
, "DNV0",
1930 SPR_NOACCESS
, SPR_NOACCESS
,
1931 &spr_read_generic
, &spr_write_generic
,
1933 /* XXX : not implemented */
1934 spr_register(env
, SPR_440_DNV1
, "DNV1",
1935 SPR_NOACCESS
, SPR_NOACCESS
,
1936 &spr_read_generic
, &spr_write_generic
,
1938 /* XXX : not implemented */
1939 spr_register(env
, SPR_440_DNV2
, "DNV2",
1940 SPR_NOACCESS
, SPR_NOACCESS
,
1941 &spr_read_generic
, &spr_write_generic
,
1943 /* XXX : not implemented */
1944 spr_register(env
, SPR_440_DNV3
, "DNV3",
1945 SPR_NOACCESS
, SPR_NOACCESS
,
1946 &spr_read_generic
, &spr_write_generic
,
1948 /* XXX : not implemented */
1949 spr_register(env
, SPR_440_DTV0
, "DTV0",
1950 SPR_NOACCESS
, SPR_NOACCESS
,
1951 &spr_read_generic
, &spr_write_generic
,
1953 /* XXX : not implemented */
1954 spr_register(env
, SPR_440_DTV1
, "DTV1",
1955 SPR_NOACCESS
, SPR_NOACCESS
,
1956 &spr_read_generic
, &spr_write_generic
,
1958 /* XXX : not implemented */
1959 spr_register(env
, SPR_440_DTV2
, "DTV2",
1960 SPR_NOACCESS
, SPR_NOACCESS
,
1961 &spr_read_generic
, &spr_write_generic
,
1963 /* XXX : not implemented */
1964 spr_register(env
, SPR_440_DTV3
, "DTV3",
1965 SPR_NOACCESS
, SPR_NOACCESS
,
1966 &spr_read_generic
, &spr_write_generic
,
1968 /* XXX : not implemented */
1969 spr_register(env
, SPR_440_DVLIM
, "DVLIM",
1970 SPR_NOACCESS
, SPR_NOACCESS
,
1971 &spr_read_generic
, &spr_write_generic
,
1973 /* XXX : not implemented */
1974 spr_register(env
, SPR_440_INV0
, "INV0",
1975 SPR_NOACCESS
, SPR_NOACCESS
,
1976 &spr_read_generic
, &spr_write_generic
,
1978 /* XXX : not implemented */
1979 spr_register(env
, SPR_440_INV1
, "INV1",
1980 SPR_NOACCESS
, SPR_NOACCESS
,
1981 &spr_read_generic
, &spr_write_generic
,
1983 /* XXX : not implemented */
1984 spr_register(env
, SPR_440_INV2
, "INV2",
1985 SPR_NOACCESS
, SPR_NOACCESS
,
1986 &spr_read_generic
, &spr_write_generic
,
1988 /* XXX : not implemented */
1989 spr_register(env
, SPR_440_INV3
, "INV3",
1990 SPR_NOACCESS
, SPR_NOACCESS
,
1991 &spr_read_generic
, &spr_write_generic
,
1993 /* XXX : not implemented */
1994 spr_register(env
, SPR_440_ITV0
, "ITV0",
1995 SPR_NOACCESS
, SPR_NOACCESS
,
1996 &spr_read_generic
, &spr_write_generic
,
1998 /* XXX : not implemented */
1999 spr_register(env
, SPR_440_ITV1
, "ITV1",
2000 SPR_NOACCESS
, SPR_NOACCESS
,
2001 &spr_read_generic
, &spr_write_generic
,
2003 /* XXX : not implemented */
2004 spr_register(env
, SPR_440_ITV2
, "ITV2",
2005 SPR_NOACCESS
, SPR_NOACCESS
,
2006 &spr_read_generic
, &spr_write_generic
,
2008 /* XXX : not implemented */
2009 spr_register(env
, SPR_440_ITV3
, "ITV3",
2010 SPR_NOACCESS
, SPR_NOACCESS
,
2011 &spr_read_generic
, &spr_write_generic
,
2013 /* XXX : not implemented */
2014 spr_register(env
, SPR_440_IVLIM
, "IVLIM",
2015 SPR_NOACCESS
, SPR_NOACCESS
,
2016 &spr_read_generic
, &spr_write_generic
,
2019 /* XXX : not implemented */
2020 spr_register(env
, SPR_BOOKE_DCDBTRH
, "DCDBTRH",
2021 SPR_NOACCESS
, SPR_NOACCESS
,
2022 &spr_read_generic
, SPR_NOACCESS
,
2024 /* XXX : not implemented */
2025 spr_register(env
, SPR_BOOKE_DCDBTRL
, "DCDBTRL",
2026 SPR_NOACCESS
, SPR_NOACCESS
,
2027 &spr_read_generic
, SPR_NOACCESS
,
2029 /* XXX : not implemented */
2030 spr_register(env
, SPR_BOOKE_ICDBDR
, "ICDBDR",
2031 SPR_NOACCESS
, SPR_NOACCESS
,
2032 &spr_read_generic
, SPR_NOACCESS
,
2034 /* XXX : not implemented */
2035 spr_register(env
, SPR_BOOKE_ICDBTRH
, "ICDBTRH",
2036 SPR_NOACCESS
, SPR_NOACCESS
,
2037 &spr_read_generic
, SPR_NOACCESS
,
2039 /* XXX : not implemented */
2040 spr_register(env
, SPR_BOOKE_ICDBTRL
, "ICDBTRL",
2041 SPR_NOACCESS
, SPR_NOACCESS
,
2042 &spr_read_generic
, SPR_NOACCESS
,
2044 /* XXX : not implemented */
2045 spr_register(env
, SPR_440_DBDR
, "DBDR",
2046 SPR_NOACCESS
, SPR_NOACCESS
,
2047 &spr_read_generic
, &spr_write_generic
,
2049 /* Processor control */
2050 spr_register(env
, SPR_4xx_CCR0
, "CCR0",
2051 SPR_NOACCESS
, SPR_NOACCESS
,
2052 &spr_read_generic
, &spr_write_generic
,
2054 spr_register(env
, SPR_440_RSTCFG
, "RSTCFG",
2055 SPR_NOACCESS
, SPR_NOACCESS
,
2056 &spr_read_generic
, SPR_NOACCESS
,
2058 /* Storage control */
2059 spr_register(env
, SPR_440_MMUCR
, "MMUCR",
2060 SPR_NOACCESS
, SPR_NOACCESS
,
2061 &spr_read_generic
, &spr_write_generic
,
2065 /* SPR shared between PowerPC 40x implementations */
2066 static void gen_spr_40x(CPUPPCState
*env
)
2069 /* not emulated, as QEMU do not emulate caches */
2070 spr_register(env
, SPR_40x_DCCR
, "DCCR",
2071 SPR_NOACCESS
, SPR_NOACCESS
,
2072 &spr_read_generic
, &spr_write_generic
,
2074 /* not emulated, as QEMU do not emulate caches */
2075 spr_register(env
, SPR_40x_ICCR
, "ICCR",
2076 SPR_NOACCESS
, SPR_NOACCESS
,
2077 &spr_read_generic
, &spr_write_generic
,
2079 /* not emulated, as QEMU do not emulate caches */
2080 spr_register(env
, SPR_BOOKE_ICDBDR
, "ICDBDR",
2081 SPR_NOACCESS
, SPR_NOACCESS
,
2082 &spr_read_generic
, SPR_NOACCESS
,
2085 spr_register(env
, SPR_40x_DEAR
, "DEAR",
2086 SPR_NOACCESS
, SPR_NOACCESS
,
2087 &spr_read_generic
, &spr_write_generic
,
2089 spr_register(env
, SPR_40x_ESR
, "ESR",
2090 SPR_NOACCESS
, SPR_NOACCESS
,
2091 &spr_read_generic
, &spr_write_generic
,
2093 spr_register(env
, SPR_40x_EVPR
, "EVPR",
2094 SPR_NOACCESS
, SPR_NOACCESS
,
2095 &spr_read_generic
, &spr_write_excp_prefix
,
2097 spr_register(env
, SPR_40x_SRR2
, "SRR2",
2098 &spr_read_generic
, &spr_write_generic
,
2099 &spr_read_generic
, &spr_write_generic
,
2101 spr_register(env
, SPR_40x_SRR3
, "SRR3",
2102 &spr_read_generic
, &spr_write_generic
,
2103 &spr_read_generic
, &spr_write_generic
,
2106 spr_register(env
, SPR_40x_PIT
, "PIT",
2107 SPR_NOACCESS
, SPR_NOACCESS
,
2108 &spr_read_40x_pit
, &spr_write_40x_pit
,
2110 spr_register(env
, SPR_40x_TCR
, "TCR",
2111 SPR_NOACCESS
, SPR_NOACCESS
,
2112 &spr_read_generic
, &spr_write_booke_tcr
,
2114 spr_register(env
, SPR_40x_TSR
, "TSR",
2115 SPR_NOACCESS
, SPR_NOACCESS
,
2116 &spr_read_generic
, &spr_write_booke_tsr
,
2120 /* SPR specific to PowerPC 405 implementation */
2121 static void gen_spr_405(CPUPPCState
*env
)
2124 spr_register(env
, SPR_40x_PID
, "PID",
2125 SPR_NOACCESS
, SPR_NOACCESS
,
2126 &spr_read_generic
, &spr_write_generic
,
2128 spr_register(env
, SPR_4xx_CCR0
, "CCR0",
2129 SPR_NOACCESS
, SPR_NOACCESS
,
2130 &spr_read_generic
, &spr_write_generic
,
2132 /* Debug interface */
2133 /* XXX : not implemented */
2134 spr_register(env
, SPR_40x_DBCR0
, "DBCR0",
2135 SPR_NOACCESS
, SPR_NOACCESS
,
2136 &spr_read_generic
, &spr_write_40x_dbcr0
,
2138 /* XXX : not implemented */
2139 spr_register(env
, SPR_405_DBCR1
, "DBCR1",
2140 SPR_NOACCESS
, SPR_NOACCESS
,
2141 &spr_read_generic
, &spr_write_generic
,
2143 /* XXX : not implemented */
2144 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2145 SPR_NOACCESS
, SPR_NOACCESS
,
2146 &spr_read_generic
, &spr_write_clear
,
2147 /* Last reset was system reset */
2149 /* XXX : not implemented */
2150 spr_register(env
, SPR_40x_DAC1
, "DAC1",
2151 SPR_NOACCESS
, SPR_NOACCESS
,
2152 &spr_read_generic
, &spr_write_generic
,
2154 spr_register(env
, SPR_40x_DAC2
, "DAC2",
2155 SPR_NOACCESS
, SPR_NOACCESS
,
2156 &spr_read_generic
, &spr_write_generic
,
2158 /* XXX : not implemented */
2159 spr_register(env
, SPR_405_DVC1
, "DVC1",
2160 SPR_NOACCESS
, SPR_NOACCESS
,
2161 &spr_read_generic
, &spr_write_generic
,
2163 /* XXX : not implemented */
2164 spr_register(env
, SPR_405_DVC2
, "DVC2",
2165 SPR_NOACCESS
, SPR_NOACCESS
,
2166 &spr_read_generic
, &spr_write_generic
,
2168 /* XXX : not implemented */
2169 spr_register(env
, SPR_40x_IAC1
, "IAC1",
2170 SPR_NOACCESS
, SPR_NOACCESS
,
2171 &spr_read_generic
, &spr_write_generic
,
2173 spr_register(env
, SPR_40x_IAC2
, "IAC2",
2174 SPR_NOACCESS
, SPR_NOACCESS
,
2175 &spr_read_generic
, &spr_write_generic
,
2177 /* XXX : not implemented */
2178 spr_register(env
, SPR_405_IAC3
, "IAC3",
2179 SPR_NOACCESS
, SPR_NOACCESS
,
2180 &spr_read_generic
, &spr_write_generic
,
2182 /* XXX : not implemented */
2183 spr_register(env
, SPR_405_IAC4
, "IAC4",
2184 SPR_NOACCESS
, SPR_NOACCESS
,
2185 &spr_read_generic
, &spr_write_generic
,
2187 /* Storage control */
2188 /* XXX: TODO: not implemented */
2189 spr_register(env
, SPR_405_SLER
, "SLER",
2190 SPR_NOACCESS
, SPR_NOACCESS
,
2191 &spr_read_generic
, &spr_write_40x_sler
,
2193 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2194 SPR_NOACCESS
, SPR_NOACCESS
,
2195 &spr_read_generic
, &spr_write_generic
,
2197 /* XXX : not implemented */
2198 spr_register(env
, SPR_405_SU0R
, "SU0R",
2199 SPR_NOACCESS
, SPR_NOACCESS
,
2200 &spr_read_generic
, &spr_write_generic
,
2203 spr_register(env
, SPR_USPRG0
, "USPRG0",
2204 &spr_read_ureg
, SPR_NOACCESS
,
2205 &spr_read_ureg
, SPR_NOACCESS
,
2207 spr_register(env
, SPR_SPRG4
, "SPRG4",
2208 SPR_NOACCESS
, SPR_NOACCESS
,
2209 &spr_read_generic
, &spr_write_generic
,
2211 spr_register(env
, SPR_SPRG5
, "SPRG5",
2212 SPR_NOACCESS
, SPR_NOACCESS
,
2213 spr_read_generic
, &spr_write_generic
,
2215 spr_register(env
, SPR_SPRG6
, "SPRG6",
2216 SPR_NOACCESS
, SPR_NOACCESS
,
2217 spr_read_generic
, &spr_write_generic
,
2219 spr_register(env
, SPR_SPRG7
, "SPRG7",
2220 SPR_NOACCESS
, SPR_NOACCESS
,
2221 spr_read_generic
, &spr_write_generic
,
2223 gen_spr_usprgh(env
);
2226 /* SPR shared between PowerPC 401 & 403 implementations */
2227 static void gen_spr_401_403(CPUPPCState
*env
)
2230 spr_register(env
, SPR_403_VTBL
, "TBL",
2231 &spr_read_tbl
, SPR_NOACCESS
,
2232 &spr_read_tbl
, SPR_NOACCESS
,
2234 spr_register(env
, SPR_403_TBL
, "TBL",
2235 SPR_NOACCESS
, SPR_NOACCESS
,
2236 SPR_NOACCESS
, &spr_write_tbl
,
2238 spr_register(env
, SPR_403_VTBU
, "TBU",
2239 &spr_read_tbu
, SPR_NOACCESS
,
2240 &spr_read_tbu
, SPR_NOACCESS
,
2242 spr_register(env
, SPR_403_TBU
, "TBU",
2243 SPR_NOACCESS
, SPR_NOACCESS
,
2244 SPR_NOACCESS
, &spr_write_tbu
,
2247 /* not emulated, as QEMU do not emulate caches */
2248 spr_register(env
, SPR_403_CDBCR
, "CDBCR",
2249 SPR_NOACCESS
, SPR_NOACCESS
,
2250 &spr_read_generic
, &spr_write_generic
,
2254 /* SPR specific to PowerPC 401 implementation */
2255 static void gen_spr_401(CPUPPCState
*env
)
2257 /* Debug interface */
2258 /* XXX : not implemented */
2259 spr_register(env
, SPR_40x_DBCR0
, "DBCR",
2260 SPR_NOACCESS
, SPR_NOACCESS
,
2261 &spr_read_generic
, &spr_write_40x_dbcr0
,
2263 /* XXX : not implemented */
2264 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2265 SPR_NOACCESS
, SPR_NOACCESS
,
2266 &spr_read_generic
, &spr_write_clear
,
2267 /* Last reset was system reset */
2269 /* XXX : not implemented */
2270 spr_register(env
, SPR_40x_DAC1
, "DAC",
2271 SPR_NOACCESS
, SPR_NOACCESS
,
2272 &spr_read_generic
, &spr_write_generic
,
2274 /* XXX : not implemented */
2275 spr_register(env
, SPR_40x_IAC1
, "IAC",
2276 SPR_NOACCESS
, SPR_NOACCESS
,
2277 &spr_read_generic
, &spr_write_generic
,
2279 /* Storage control */
2280 /* XXX: TODO: not implemented */
2281 spr_register(env
, SPR_405_SLER
, "SLER",
2282 SPR_NOACCESS
, SPR_NOACCESS
,
2283 &spr_read_generic
, &spr_write_40x_sler
,
2285 /* not emulated, as QEMU never does speculative access */
2286 spr_register(env
, SPR_40x_SGR
, "SGR",
2287 SPR_NOACCESS
, SPR_NOACCESS
,
2288 &spr_read_generic
, &spr_write_generic
,
2290 /* not emulated, as QEMU do not emulate caches */
2291 spr_register(env
, SPR_40x_DCWR
, "DCWR",
2292 SPR_NOACCESS
, SPR_NOACCESS
,
2293 &spr_read_generic
, &spr_write_generic
,
2297 static void gen_spr_401x2(CPUPPCState
*env
)
2300 spr_register(env
, SPR_40x_PID
, "PID",
2301 SPR_NOACCESS
, SPR_NOACCESS
,
2302 &spr_read_generic
, &spr_write_generic
,
2304 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2305 SPR_NOACCESS
, SPR_NOACCESS
,
2306 &spr_read_generic
, &spr_write_generic
,
2310 /* SPR specific to PowerPC 403 implementation */
2311 static void gen_spr_403(CPUPPCState
*env
)
2313 /* Debug interface */
2314 /* XXX : not implemented */
2315 spr_register(env
, SPR_40x_DBCR0
, "DBCR0",
2316 SPR_NOACCESS
, SPR_NOACCESS
,
2317 &spr_read_generic
, &spr_write_40x_dbcr0
,
2319 /* XXX : not implemented */
2320 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2321 SPR_NOACCESS
, SPR_NOACCESS
,
2322 &spr_read_generic
, &spr_write_clear
,
2323 /* Last reset was system reset */
2325 /* XXX : not implemented */
2326 spr_register(env
, SPR_40x_DAC1
, "DAC1",
2327 SPR_NOACCESS
, SPR_NOACCESS
,
2328 &spr_read_generic
, &spr_write_generic
,
2330 /* XXX : not implemented */
2331 spr_register(env
, SPR_40x_DAC2
, "DAC2",
2332 SPR_NOACCESS
, SPR_NOACCESS
,
2333 &spr_read_generic
, &spr_write_generic
,
2335 /* XXX : not implemented */
2336 spr_register(env
, SPR_40x_IAC1
, "IAC1",
2337 SPR_NOACCESS
, SPR_NOACCESS
,
2338 &spr_read_generic
, &spr_write_generic
,
2340 /* XXX : not implemented */
2341 spr_register(env
, SPR_40x_IAC2
, "IAC2",
2342 SPR_NOACCESS
, SPR_NOACCESS
,
2343 &spr_read_generic
, &spr_write_generic
,
2347 static void gen_spr_403_real(CPUPPCState
*env
)
2349 spr_register(env
, SPR_403_PBL1
, "PBL1",
2350 SPR_NOACCESS
, SPR_NOACCESS
,
2351 &spr_read_403_pbr
, &spr_write_403_pbr
,
2353 spr_register(env
, SPR_403_PBU1
, "PBU1",
2354 SPR_NOACCESS
, SPR_NOACCESS
,
2355 &spr_read_403_pbr
, &spr_write_403_pbr
,
2357 spr_register(env
, SPR_403_PBL2
, "PBL2",
2358 SPR_NOACCESS
, SPR_NOACCESS
,
2359 &spr_read_403_pbr
, &spr_write_403_pbr
,
2361 spr_register(env
, SPR_403_PBU2
, "PBU2",
2362 SPR_NOACCESS
, SPR_NOACCESS
,
2363 &spr_read_403_pbr
, &spr_write_403_pbr
,
2367 static void gen_spr_403_mmu(CPUPPCState
*env
)
2370 spr_register(env
, SPR_40x_PID
, "PID",
2371 SPR_NOACCESS
, SPR_NOACCESS
,
2372 &spr_read_generic
, &spr_write_generic
,
2374 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2375 SPR_NOACCESS
, SPR_NOACCESS
,
2376 &spr_read_generic
, &spr_write_generic
,
2380 /* SPR specific to PowerPC compression coprocessor extension */
2381 static void gen_spr_compress(CPUPPCState
*env
)
2383 /* XXX : not implemented */
2384 spr_register(env
, SPR_401_SKR
, "SKR",
2385 SPR_NOACCESS
, SPR_NOACCESS
,
2386 &spr_read_generic
, &spr_write_generic
,
2390 static void gen_spr_5xx_8xx(CPUPPCState
*env
)
2392 /* Exception processing */
2393 spr_register_kvm(env
, SPR_DSISR
, "DSISR",
2394 SPR_NOACCESS
, SPR_NOACCESS
,
2395 &spr_read_generic
, &spr_write_generic
,
2396 KVM_REG_PPC_DSISR
, 0x00000000);
2397 spr_register_kvm(env
, SPR_DAR
, "DAR",
2398 SPR_NOACCESS
, SPR_NOACCESS
,
2399 &spr_read_generic
, &spr_write_generic
,
2400 KVM_REG_PPC_DAR
, 0x00000000);
2402 spr_register(env
, SPR_DECR
, "DECR",
2403 SPR_NOACCESS
, SPR_NOACCESS
,
2404 &spr_read_decr
, &spr_write_decr
,
2406 /* XXX : not implemented */
2407 spr_register(env
, SPR_MPC_EIE
, "EIE",
2408 SPR_NOACCESS
, SPR_NOACCESS
,
2409 &spr_read_generic
, &spr_write_generic
,
2411 /* XXX : not implemented */
2412 spr_register(env
, SPR_MPC_EID
, "EID",
2413 SPR_NOACCESS
, SPR_NOACCESS
,
2414 &spr_read_generic
, &spr_write_generic
,
2416 /* XXX : not implemented */
2417 spr_register(env
, SPR_MPC_NRI
, "NRI",
2418 SPR_NOACCESS
, SPR_NOACCESS
,
2419 &spr_read_generic
, &spr_write_generic
,
2421 /* XXX : not implemented */
2422 spr_register(env
, SPR_MPC_CMPA
, "CMPA",
2423 SPR_NOACCESS
, SPR_NOACCESS
,
2424 &spr_read_generic
, &spr_write_generic
,
2426 /* XXX : not implemented */
2427 spr_register(env
, SPR_MPC_CMPB
, "CMPB",
2428 SPR_NOACCESS
, SPR_NOACCESS
,
2429 &spr_read_generic
, &spr_write_generic
,
2431 /* XXX : not implemented */
2432 spr_register(env
, SPR_MPC_CMPC
, "CMPC",
2433 SPR_NOACCESS
, SPR_NOACCESS
,
2434 &spr_read_generic
, &spr_write_generic
,
2436 /* XXX : not implemented */
2437 spr_register(env
, SPR_MPC_CMPD
, "CMPD",
2438 SPR_NOACCESS
, SPR_NOACCESS
,
2439 &spr_read_generic
, &spr_write_generic
,
2441 /* XXX : not implemented */
2442 spr_register(env
, SPR_MPC_ECR
, "ECR",
2443 SPR_NOACCESS
, SPR_NOACCESS
,
2444 &spr_read_generic
, &spr_write_generic
,
2446 /* XXX : not implemented */
2447 spr_register(env
, SPR_MPC_DER
, "DER",
2448 SPR_NOACCESS
, SPR_NOACCESS
,
2449 &spr_read_generic
, &spr_write_generic
,
2451 /* XXX : not implemented */
2452 spr_register(env
, SPR_MPC_COUNTA
, "COUNTA",
2453 SPR_NOACCESS
, SPR_NOACCESS
,
2454 &spr_read_generic
, &spr_write_generic
,
2456 /* XXX : not implemented */
2457 spr_register(env
, SPR_MPC_COUNTB
, "COUNTB",
2458 SPR_NOACCESS
, SPR_NOACCESS
,
2459 &spr_read_generic
, &spr_write_generic
,
2461 /* XXX : not implemented */
2462 spr_register(env
, SPR_MPC_CMPE
, "CMPE",
2463 SPR_NOACCESS
, SPR_NOACCESS
,
2464 &spr_read_generic
, &spr_write_generic
,
2466 /* XXX : not implemented */
2467 spr_register(env
, SPR_MPC_CMPF
, "CMPF",
2468 SPR_NOACCESS
, SPR_NOACCESS
,
2469 &spr_read_generic
, &spr_write_generic
,
2471 /* XXX : not implemented */
2472 spr_register(env
, SPR_MPC_CMPG
, "CMPG",
2473 SPR_NOACCESS
, SPR_NOACCESS
,
2474 &spr_read_generic
, &spr_write_generic
,
2476 /* XXX : not implemented */
2477 spr_register(env
, SPR_MPC_CMPH
, "CMPH",
2478 SPR_NOACCESS
, SPR_NOACCESS
,
2479 &spr_read_generic
, &spr_write_generic
,
2481 /* XXX : not implemented */
2482 spr_register(env
, SPR_MPC_LCTRL1
, "LCTRL1",
2483 SPR_NOACCESS
, SPR_NOACCESS
,
2484 &spr_read_generic
, &spr_write_generic
,
2486 /* XXX : not implemented */
2487 spr_register(env
, SPR_MPC_LCTRL2
, "LCTRL2",
2488 SPR_NOACCESS
, SPR_NOACCESS
,
2489 &spr_read_generic
, &spr_write_generic
,
2491 /* XXX : not implemented */
2492 spr_register(env
, SPR_MPC_BAR
, "BAR",
2493 SPR_NOACCESS
, SPR_NOACCESS
,
2494 &spr_read_generic
, &spr_write_generic
,
2496 /* XXX : not implemented */
2497 spr_register(env
, SPR_MPC_DPDR
, "DPDR",
2498 SPR_NOACCESS
, SPR_NOACCESS
,
2499 &spr_read_generic
, &spr_write_generic
,
2501 /* XXX : not implemented */
2502 spr_register(env
, SPR_MPC_IMMR
, "IMMR",
2503 SPR_NOACCESS
, SPR_NOACCESS
,
2504 &spr_read_generic
, &spr_write_generic
,
2508 static void gen_spr_5xx(CPUPPCState
*env
)
2510 /* XXX : not implemented */
2511 spr_register(env
, SPR_RCPU_MI_GRA
, "MI_GRA",
2512 SPR_NOACCESS
, SPR_NOACCESS
,
2513 &spr_read_generic
, &spr_write_generic
,
2515 /* XXX : not implemented */
2516 spr_register(env
, SPR_RCPU_L2U_GRA
, "L2U_GRA",
2517 SPR_NOACCESS
, SPR_NOACCESS
,
2518 &spr_read_generic
, &spr_write_generic
,
2520 /* XXX : not implemented */
2521 spr_register(env
, SPR_RPCU_BBCMCR
, "L2U_BBCMCR",
2522 SPR_NOACCESS
, SPR_NOACCESS
,
2523 &spr_read_generic
, &spr_write_generic
,
2525 /* XXX : not implemented */
2526 spr_register(env
, SPR_RCPU_L2U_MCR
, "L2U_MCR",
2527 SPR_NOACCESS
, SPR_NOACCESS
,
2528 &spr_read_generic
, &spr_write_generic
,
2530 /* XXX : not implemented */
2531 spr_register(env
, SPR_RCPU_MI_RBA0
, "MI_RBA0",
2532 SPR_NOACCESS
, SPR_NOACCESS
,
2533 &spr_read_generic
, &spr_write_generic
,
2535 /* XXX : not implemented */
2536 spr_register(env
, SPR_RCPU_MI_RBA1
, "MI_RBA1",
2537 SPR_NOACCESS
, SPR_NOACCESS
,
2538 &spr_read_generic
, &spr_write_generic
,
2540 /* XXX : not implemented */
2541 spr_register(env
, SPR_RCPU_MI_RBA2
, "MI_RBA2",
2542 SPR_NOACCESS
, SPR_NOACCESS
,
2543 &spr_read_generic
, &spr_write_generic
,
2545 /* XXX : not implemented */
2546 spr_register(env
, SPR_RCPU_MI_RBA3
, "MI_RBA3",
2547 SPR_NOACCESS
, SPR_NOACCESS
,
2548 &spr_read_generic
, &spr_write_generic
,
2550 /* XXX : not implemented */
2551 spr_register(env
, SPR_RCPU_L2U_RBA0
, "L2U_RBA0",
2552 SPR_NOACCESS
, SPR_NOACCESS
,
2553 &spr_read_generic
, &spr_write_generic
,
2555 /* XXX : not implemented */
2556 spr_register(env
, SPR_RCPU_L2U_RBA1
, "L2U_RBA1",
2557 SPR_NOACCESS
, SPR_NOACCESS
,
2558 &spr_read_generic
, &spr_write_generic
,
2560 /* XXX : not implemented */
2561 spr_register(env
, SPR_RCPU_L2U_RBA2
, "L2U_RBA2",
2562 SPR_NOACCESS
, SPR_NOACCESS
,
2563 &spr_read_generic
, &spr_write_generic
,
2565 /* XXX : not implemented */
2566 spr_register(env
, SPR_RCPU_L2U_RBA3
, "L2U_RBA3",
2567 SPR_NOACCESS
, SPR_NOACCESS
,
2568 &spr_read_generic
, &spr_write_generic
,
2570 /* XXX : not implemented */
2571 spr_register(env
, SPR_RCPU_MI_RA0
, "MI_RA0",
2572 SPR_NOACCESS
, SPR_NOACCESS
,
2573 &spr_read_generic
, &spr_write_generic
,
2575 /* XXX : not implemented */
2576 spr_register(env
, SPR_RCPU_MI_RA1
, "MI_RA1",
2577 SPR_NOACCESS
, SPR_NOACCESS
,
2578 &spr_read_generic
, &spr_write_generic
,
2580 /* XXX : not implemented */
2581 spr_register(env
, SPR_RCPU_MI_RA2
, "MI_RA2",
2582 SPR_NOACCESS
, SPR_NOACCESS
,
2583 &spr_read_generic
, &spr_write_generic
,
2585 /* XXX : not implemented */
2586 spr_register(env
, SPR_RCPU_MI_RA3
, "MI_RA3",
2587 SPR_NOACCESS
, SPR_NOACCESS
,
2588 &spr_read_generic
, &spr_write_generic
,
2590 /* XXX : not implemented */
2591 spr_register(env
, SPR_RCPU_L2U_RA0
, "L2U_RA0",
2592 SPR_NOACCESS
, SPR_NOACCESS
,
2593 &spr_read_generic
, &spr_write_generic
,
2595 /* XXX : not implemented */
2596 spr_register(env
, SPR_RCPU_L2U_RA1
, "L2U_RA1",
2597 SPR_NOACCESS
, SPR_NOACCESS
,
2598 &spr_read_generic
, &spr_write_generic
,
2600 /* XXX : not implemented */
2601 spr_register(env
, SPR_RCPU_L2U_RA2
, "L2U_RA2",
2602 SPR_NOACCESS
, SPR_NOACCESS
,
2603 &spr_read_generic
, &spr_write_generic
,
2605 /* XXX : not implemented */
2606 spr_register(env
, SPR_RCPU_L2U_RA3
, "L2U_RA3",
2607 SPR_NOACCESS
, SPR_NOACCESS
,
2608 &spr_read_generic
, &spr_write_generic
,
2610 /* XXX : not implemented */
2611 spr_register(env
, SPR_RCPU_FPECR
, "FPECR",
2612 SPR_NOACCESS
, SPR_NOACCESS
,
2613 &spr_read_generic
, &spr_write_generic
,
2617 static void gen_spr_8xx(CPUPPCState
*env
)
2619 /* XXX : not implemented */
2620 spr_register(env
, SPR_MPC_IC_CST
, "IC_CST",
2621 SPR_NOACCESS
, SPR_NOACCESS
,
2622 &spr_read_generic
, &spr_write_generic
,
2624 /* XXX : not implemented */
2625 spr_register(env
, SPR_MPC_IC_ADR
, "IC_ADR",
2626 SPR_NOACCESS
, SPR_NOACCESS
,
2627 &spr_read_generic
, &spr_write_generic
,
2629 /* XXX : not implemented */
2630 spr_register(env
, SPR_MPC_IC_DAT
, "IC_DAT",
2631 SPR_NOACCESS
, SPR_NOACCESS
,
2632 &spr_read_generic
, &spr_write_generic
,
2634 /* XXX : not implemented */
2635 spr_register(env
, SPR_MPC_DC_CST
, "DC_CST",
2636 SPR_NOACCESS
, SPR_NOACCESS
,
2637 &spr_read_generic
, &spr_write_generic
,
2639 /* XXX : not implemented */
2640 spr_register(env
, SPR_MPC_DC_ADR
, "DC_ADR",
2641 SPR_NOACCESS
, SPR_NOACCESS
,
2642 &spr_read_generic
, &spr_write_generic
,
2644 /* XXX : not implemented */
2645 spr_register(env
, SPR_MPC_DC_DAT
, "DC_DAT",
2646 SPR_NOACCESS
, SPR_NOACCESS
,
2647 &spr_read_generic
, &spr_write_generic
,
2649 /* XXX : not implemented */
2650 spr_register(env
, SPR_MPC_MI_CTR
, "MI_CTR",
2651 SPR_NOACCESS
, SPR_NOACCESS
,
2652 &spr_read_generic
, &spr_write_generic
,
2654 /* XXX : not implemented */
2655 spr_register(env
, SPR_MPC_MI_AP
, "MI_AP",
2656 SPR_NOACCESS
, SPR_NOACCESS
,
2657 &spr_read_generic
, &spr_write_generic
,
2659 /* XXX : not implemented */
2660 spr_register(env
, SPR_MPC_MI_EPN
, "MI_EPN",
2661 SPR_NOACCESS
, SPR_NOACCESS
,
2662 &spr_read_generic
, &spr_write_generic
,
2664 /* XXX : not implemented */
2665 spr_register(env
, SPR_MPC_MI_TWC
, "MI_TWC",
2666 SPR_NOACCESS
, SPR_NOACCESS
,
2667 &spr_read_generic
, &spr_write_generic
,
2669 /* XXX : not implemented */
2670 spr_register(env
, SPR_MPC_MI_RPN
, "MI_RPN",
2671 SPR_NOACCESS
, SPR_NOACCESS
,
2672 &spr_read_generic
, &spr_write_generic
,
2674 /* XXX : not implemented */
2675 spr_register(env
, SPR_MPC_MI_DBCAM
, "MI_DBCAM",
2676 SPR_NOACCESS
, SPR_NOACCESS
,
2677 &spr_read_generic
, &spr_write_generic
,
2679 /* XXX : not implemented */
2680 spr_register(env
, SPR_MPC_MI_DBRAM0
, "MI_DBRAM0",
2681 SPR_NOACCESS
, SPR_NOACCESS
,
2682 &spr_read_generic
, &spr_write_generic
,
2684 /* XXX : not implemented */
2685 spr_register(env
, SPR_MPC_MI_DBRAM1
, "MI_DBRAM1",
2686 SPR_NOACCESS
, SPR_NOACCESS
,
2687 &spr_read_generic
, &spr_write_generic
,
2689 /* XXX : not implemented */
2690 spr_register(env
, SPR_MPC_MD_CTR
, "MD_CTR",
2691 SPR_NOACCESS
, SPR_NOACCESS
,
2692 &spr_read_generic
, &spr_write_generic
,
2694 /* XXX : not implemented */
2695 spr_register(env
, SPR_MPC_MD_CASID
, "MD_CASID",
2696 SPR_NOACCESS
, SPR_NOACCESS
,
2697 &spr_read_generic
, &spr_write_generic
,
2699 /* XXX : not implemented */
2700 spr_register(env
, SPR_MPC_MD_AP
, "MD_AP",
2701 SPR_NOACCESS
, SPR_NOACCESS
,
2702 &spr_read_generic
, &spr_write_generic
,
2704 /* XXX : not implemented */
2705 spr_register(env
, SPR_MPC_MD_EPN
, "MD_EPN",
2706 SPR_NOACCESS
, SPR_NOACCESS
,
2707 &spr_read_generic
, &spr_write_generic
,
2709 /* XXX : not implemented */
2710 spr_register(env
, SPR_MPC_MD_TWB
, "MD_TWB",
2711 SPR_NOACCESS
, SPR_NOACCESS
,
2712 &spr_read_generic
, &spr_write_generic
,
2714 /* XXX : not implemented */
2715 spr_register(env
, SPR_MPC_MD_TWC
, "MD_TWC",
2716 SPR_NOACCESS
, SPR_NOACCESS
,
2717 &spr_read_generic
, &spr_write_generic
,
2719 /* XXX : not implemented */
2720 spr_register(env
, SPR_MPC_MD_RPN
, "MD_RPN",
2721 SPR_NOACCESS
, SPR_NOACCESS
,
2722 &spr_read_generic
, &spr_write_generic
,
2724 /* XXX : not implemented */
2725 spr_register(env
, SPR_MPC_MD_TW
, "MD_TW",
2726 SPR_NOACCESS
, SPR_NOACCESS
,
2727 &spr_read_generic
, &spr_write_generic
,
2729 /* XXX : not implemented */
2730 spr_register(env
, SPR_MPC_MD_DBCAM
, "MD_DBCAM",
2731 SPR_NOACCESS
, SPR_NOACCESS
,
2732 &spr_read_generic
, &spr_write_generic
,
2734 /* XXX : not implemented */
2735 spr_register(env
, SPR_MPC_MD_DBRAM0
, "MD_DBRAM0",
2736 SPR_NOACCESS
, SPR_NOACCESS
,
2737 &spr_read_generic
, &spr_write_generic
,
2739 /* XXX : not implemented */
2740 spr_register(env
, SPR_MPC_MD_DBRAM1
, "MD_DBRAM1",
2741 SPR_NOACCESS
, SPR_NOACCESS
,
2742 &spr_read_generic
, &spr_write_generic
,
2748 * AMR => SPR 29 (Power 2.04)
2749 * CTRL => SPR 136 (Power 2.04)
2750 * CTRL => SPR 152 (Power 2.04)
2751 * SCOMC => SPR 276 (64 bits ?)
2752 * SCOMD => SPR 277 (64 bits ?)
2753 * TBU40 => SPR 286 (Power 2.04 hypv)
2754 * HSPRG0 => SPR 304 (Power 2.04 hypv)
2755 * HSPRG1 => SPR 305 (Power 2.04 hypv)
2756 * HDSISR => SPR 306 (Power 2.04 hypv)
2757 * HDAR => SPR 307 (Power 2.04 hypv)
2758 * PURR => SPR 309 (Power 2.04 hypv)
2759 * HDEC => SPR 310 (Power 2.04 hypv)
2760 * HIOR => SPR 311 (hypv)
2761 * RMOR => SPR 312 (970)
2762 * HRMOR => SPR 313 (Power 2.04 hypv)
2763 * HSRR0 => SPR 314 (Power 2.04 hypv)
2764 * HSRR1 => SPR 315 (Power 2.04 hypv)
2765 * LPIDR => SPR 317 (970)
2766 * EPR => SPR 702 (Power 2.04 emb)
2767 * perf => 768-783 (Power 2.04)
2768 * perf => 784-799 (Power 2.04)
2769 * PPR => SPR 896 (Power 2.04)
2770 * EPLC => SPR 947 (Power 2.04 emb)
2771 * EPSC => SPR 948 (Power 2.04 emb)
2772 * DABRX => 1015 (Power 2.04 hypv)
2773 * FPECR => SPR 1022 (?)
2774 * ... and more (thermal management, performance counters, ...)
2777 /*****************************************************************************/
2778 /* Exception vectors models */
2779 static void init_excp_4xx_real(CPUPPCState
*env
)
2781 #if !defined(CONFIG_USER_ONLY)
2782 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000100;
2783 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2784 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2785 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2786 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2787 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2788 env
->excp_vectors
[POWERPC_EXCP_PIT
] = 0x00001000;
2789 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00001010;
2790 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001020;
2791 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00002000;
2792 env
->ivor_mask
= 0x0000FFF0UL
;
2793 env
->ivpr_mask
= 0xFFFF0000UL
;
2794 /* Hardware reset vector */
2795 env
->hreset_vector
= 0xFFFFFFFCUL
;
2799 static void init_excp_4xx_softmmu(CPUPPCState
*env
)
2801 #if !defined(CONFIG_USER_ONLY)
2802 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000100;
2803 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2804 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2805 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2806 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2807 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2808 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2809 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2810 env
->excp_vectors
[POWERPC_EXCP_PIT
] = 0x00001000;
2811 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00001010;
2812 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001020;
2813 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00001100;
2814 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00001200;
2815 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00002000;
2816 env
->ivor_mask
= 0x0000FFF0UL
;
2817 env
->ivpr_mask
= 0xFFFF0000UL
;
2818 /* Hardware reset vector */
2819 env
->hreset_vector
= 0xFFFFFFFCUL
;
2823 static void init_excp_MPC5xx(CPUPPCState
*env
)
2825 #if !defined(CONFIG_USER_ONLY)
2826 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2827 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2828 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2829 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2830 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2831 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000900;
2832 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2833 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2834 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2835 env
->excp_vectors
[POWERPC_EXCP_FPA
] = 0x00000E00;
2836 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001000;
2837 env
->excp_vectors
[POWERPC_EXCP_DABR
] = 0x00001C00;
2838 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001C00;
2839 env
->excp_vectors
[POWERPC_EXCP_MEXTBR
] = 0x00001E00;
2840 env
->excp_vectors
[POWERPC_EXCP_NMEXTBR
] = 0x00001F00;
2841 env
->ivor_mask
= 0x0000FFF0UL
;
2842 env
->ivpr_mask
= 0xFFFF0000UL
;
2843 /* Hardware reset vector */
2844 env
->hreset_vector
= 0x00000100UL
;
2848 static void init_excp_MPC8xx(CPUPPCState
*env
)
2850 #if !defined(CONFIG_USER_ONLY)
2851 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2852 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2853 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2854 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2855 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2856 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2857 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2858 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000900;
2859 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2860 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2861 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2862 env
->excp_vectors
[POWERPC_EXCP_FPA
] = 0x00000E00;
2863 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001000;
2864 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00001100;
2865 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00001200;
2866 env
->excp_vectors
[POWERPC_EXCP_ITLBE
] = 0x00001300;
2867 env
->excp_vectors
[POWERPC_EXCP_DTLBE
] = 0x00001400;
2868 env
->excp_vectors
[POWERPC_EXCP_DABR
] = 0x00001C00;
2869 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001C00;
2870 env
->excp_vectors
[POWERPC_EXCP_MEXTBR
] = 0x00001E00;
2871 env
->excp_vectors
[POWERPC_EXCP_NMEXTBR
] = 0x00001F00;
2872 env
->ivor_mask
= 0x0000FFF0UL
;
2873 env
->ivpr_mask
= 0xFFFF0000UL
;
2874 /* Hardware reset vector */
2875 env
->hreset_vector
= 0x00000100UL
;
2879 static void init_excp_G2(CPUPPCState
*env
)
2881 #if !defined(CONFIG_USER_ONLY)
2882 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2883 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2884 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2885 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2886 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2887 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2888 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2889 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
2890 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2891 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000A00;
2892 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2893 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2894 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
2895 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
2896 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
2897 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
2898 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
2899 /* Hardware reset vector */
2900 env
->hreset_vector
= 0x00000100UL
;
2904 static void init_excp_e200(CPUPPCState
*env
, target_ulong ivpr_mask
)
2906 #if !defined(CONFIG_USER_ONLY)
2907 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000FFC;
2908 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000000;
2909 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000000;
2910 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000000;
2911 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000000;
2912 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000000;
2913 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000000;
2914 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000000;
2915 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000000;
2916 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000000;
2917 env
->excp_vectors
[POWERPC_EXCP_APU
] = 0x00000000;
2918 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000000;
2919 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00000000;
2920 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00000000;
2921 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00000000;
2922 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00000000;
2923 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00000000;
2924 env
->excp_vectors
[POWERPC_EXCP_SPEU
] = 0x00000000;
2925 env
->excp_vectors
[POWERPC_EXCP_EFPDI
] = 0x00000000;
2926 env
->excp_vectors
[POWERPC_EXCP_EFPRI
] = 0x00000000;
2927 env
->ivor_mask
= 0x0000FFF7UL
;
2928 env
->ivpr_mask
= ivpr_mask
;
2929 /* Hardware reset vector */
2930 env
->hreset_vector
= 0xFFFFFFFCUL
;
2934 static void init_excp_BookE(CPUPPCState
*env
)
2936 #if !defined(CONFIG_USER_ONLY)
2937 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000000;
2938 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000000;
2939 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000000;
2940 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000000;
2941 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000000;
2942 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000000;
2943 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000000;
2944 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000000;
2945 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000000;
2946 env
->excp_vectors
[POWERPC_EXCP_APU
] = 0x00000000;
2947 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000000;
2948 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00000000;
2949 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00000000;
2950 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00000000;
2951 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00000000;
2952 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00000000;
2953 env
->ivor_mask
= 0x0000FFF0UL
;
2954 env
->ivpr_mask
= 0xFFFF0000UL
;
2955 /* Hardware reset vector */
2956 env
->hreset_vector
= 0xFFFFFFFCUL
;
2960 static void init_excp_601(CPUPPCState
*env
)
2962 #if !defined(CONFIG_USER_ONLY)
2963 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2964 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2965 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2966 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2967 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2968 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2969 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2970 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
2971 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2972 env
->excp_vectors
[POWERPC_EXCP_IO
] = 0x00000A00;
2973 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2974 env
->excp_vectors
[POWERPC_EXCP_RUNM
] = 0x00002000;
2975 /* Hardware reset vector */
2976 env
->hreset_vector
= 0x00000100UL
;
2980 static void init_excp_602(CPUPPCState
*env
)
2982 #if !defined(CONFIG_USER_ONLY)
2983 /* XXX: exception prefix has a special behavior on 602 */
2984 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2985 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2986 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2987 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2988 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2989 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2990 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2991 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
2992 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2993 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2994 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2995 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
2996 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
2997 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
2998 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
2999 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3000 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001500;
3001 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001600;
3002 /* Hardware reset vector */
3003 env
->hreset_vector
= 0x00000100UL
;
3007 static void init_excp_603(CPUPPCState
*env
)
3009 #if !defined(CONFIG_USER_ONLY)
3010 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3011 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3012 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3013 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3014 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3015 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3016 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3017 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3018 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3019 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3020 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3021 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3022 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3023 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3024 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3025 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3026 /* Hardware reset vector */
3027 env
->hreset_vector
= 0x00000100UL
;
3031 static void init_excp_604(CPUPPCState
*env
)
3033 #if !defined(CONFIG_USER_ONLY)
3034 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3035 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3036 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3037 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3038 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3039 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3040 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3041 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3042 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3043 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3044 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3045 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3046 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3047 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3048 /* Hardware reset vector */
3049 env
->hreset_vector
= 0x00000100UL
;
3053 static void init_excp_7x0(CPUPPCState
*env
)
3055 #if !defined(CONFIG_USER_ONLY)
3056 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3057 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3058 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3059 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3060 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3061 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3062 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3063 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3064 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3065 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3066 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3067 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3068 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3069 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3070 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3071 /* Hardware reset vector */
3072 env
->hreset_vector
= 0x00000100UL
;
3076 static void init_excp_750cl(CPUPPCState
*env
)
3078 #if !defined(CONFIG_USER_ONLY)
3079 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3080 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3081 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3082 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3083 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3084 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3085 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3086 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3087 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3088 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3089 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3090 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3091 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3092 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3093 /* Hardware reset vector */
3094 env
->hreset_vector
= 0x00000100UL
;
3098 static void init_excp_750cx(CPUPPCState
*env
)
3100 #if !defined(CONFIG_USER_ONLY)
3101 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3102 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3103 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3104 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3105 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3106 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3107 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3108 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3109 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3110 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3111 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3112 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3113 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3114 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3115 /* Hardware reset vector */
3116 env
->hreset_vector
= 0x00000100UL
;
3120 /* XXX: Check if this is correct */
3121 static void init_excp_7x5(CPUPPCState
*env
)
3123 #if !defined(CONFIG_USER_ONLY)
3124 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3125 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3126 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3127 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3128 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3129 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3130 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3131 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3132 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3133 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3134 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3135 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3136 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3137 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3138 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3139 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3140 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3141 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3142 /* Hardware reset vector */
3143 env
->hreset_vector
= 0x00000100UL
;
3147 static void init_excp_7400(CPUPPCState
*env
)
3149 #if !defined(CONFIG_USER_ONLY)
3150 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3151 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3152 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3153 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3154 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3155 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3156 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3157 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3158 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3159 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3160 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3161 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3162 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3163 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3164 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3165 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001600;
3166 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3167 /* Hardware reset vector */
3168 env
->hreset_vector
= 0x00000100UL
;
3172 static void init_excp_7450(CPUPPCState
*env
)
3174 #if !defined(CONFIG_USER_ONLY)
3175 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3176 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3177 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3178 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3179 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3180 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3181 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3182 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3183 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3184 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3185 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3186 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3187 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3188 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3189 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3190 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3191 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3192 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3193 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001600;
3194 /* Hardware reset vector */
3195 env
->hreset_vector
= 0x00000100UL
;
3199 #if defined(TARGET_PPC64)
3200 static void init_excp_970(CPUPPCState
*env
)
3202 #if !defined(CONFIG_USER_ONLY)
3203 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3204 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3205 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3206 env
->excp_vectors
[POWERPC_EXCP_DSEG
] = 0x00000380;
3207 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3208 env
->excp_vectors
[POWERPC_EXCP_ISEG
] = 0x00000480;
3209 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3210 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3211 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3212 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3213 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3214 env
->excp_vectors
[POWERPC_EXCP_HDECR
] = 0x00000980;
3215 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3216 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3217 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3218 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3219 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3220 env
->excp_vectors
[POWERPC_EXCP_MAINT
] = 0x00001600;
3221 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001700;
3222 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001800;
3223 /* Hardware reset vector */
3224 env
->hreset_vector
= 0x0000000000000100ULL
;
3228 static void init_excp_POWER7(CPUPPCState
*env
)
3230 #if !defined(CONFIG_USER_ONLY)
3231 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3232 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3233 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3234 env
->excp_vectors
[POWERPC_EXCP_DSEG
] = 0x00000380;
3235 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3236 env
->excp_vectors
[POWERPC_EXCP_ISEG
] = 0x00000480;
3237 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3238 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3239 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3240 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3241 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3242 env
->excp_vectors
[POWERPC_EXCP_HDECR
] = 0x00000980;
3243 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3244 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3245 env
->excp_vectors
[POWERPC_EXCP_HDSI
] = 0x00000E00;
3246 env
->excp_vectors
[POWERPC_EXCP_HISI
] = 0x00000E20;
3247 env
->excp_vectors
[POWERPC_EXCP_HV_EMU
] = 0x00000E40;
3248 env
->excp_vectors
[POWERPC_EXCP_HV_MAINT
] = 0x00000E60;
3249 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3250 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3251 env
->excp_vectors
[POWERPC_EXCP_VSXU
] = 0x00000F40;
3252 /* Hardware reset vector */
3253 env
->hreset_vector
= 0x0000000000000100ULL
;
3257 static void init_excp_POWER8(CPUPPCState
*env
)
3259 init_excp_POWER7(env
);
3261 #if !defined(CONFIG_USER_ONLY)
3262 env
->excp_vectors
[POWERPC_EXCP_SDOOR
] = 0x00000A00;
3263 env
->excp_vectors
[POWERPC_EXCP_FU
] = 0x00000F60;
3264 env
->excp_vectors
[POWERPC_EXCP_HV_FU
] = 0x00000F80;
3265 env
->excp_vectors
[POWERPC_EXCP_SDOOR_HV
] = 0x00000E80;
3271 /*****************************************************************************/
3272 /* Power management enable checks */
3273 static int check_pow_none(CPUPPCState
*env
)
3278 static int check_pow_nocheck(CPUPPCState
*env
)
3283 static int check_pow_hid0(CPUPPCState
*env
)
3285 if (env
->spr
[SPR_HID0
] & 0x00E00000)
3291 static int check_pow_hid0_74xx(CPUPPCState
*env
)
3293 if (env
->spr
[SPR_HID0
] & 0x00600000)
3299 static bool ppc_cpu_interrupts_big_endian_always(PowerPCCPU
*cpu
)
3305 static bool ppc_cpu_interrupts_big_endian_lpcr(PowerPCCPU
*cpu
)
3307 return !(cpu
->env
.spr
[SPR_LPCR
] & LPCR_ILE
);
3311 /*****************************************************************************/
3312 /* PowerPC implementations definitions */
3314 #define POWERPC_FAMILY(_name) \
3316 glue(glue(ppc_, _name), _cpu_family_class_init)(ObjectClass *, void *); \
3318 static const TypeInfo \
3319 glue(glue(ppc_, _name), _cpu_family_type_info) = { \
3320 .name = stringify(_name) "-family-" TYPE_POWERPC_CPU, \
3321 .parent = TYPE_POWERPC_CPU, \
3323 .class_init = glue(glue(ppc_, _name), _cpu_family_class_init), \
3326 static void glue(glue(ppc_, _name), _cpu_family_register_types)(void) \
3328 type_register_static( \
3329 &glue(glue(ppc_, _name), _cpu_family_type_info)); \
3332 type_init(glue(glue(ppc_, _name), _cpu_family_register_types)) \
3334 static void glue(glue(ppc_, _name), _cpu_family_class_init)
3336 static void init_proc_401(CPUPPCState
*env
)
3339 gen_spr_401_403(env
);
3341 init_excp_4xx_real(env
);
3342 env
->dcache_line_size
= 32;
3343 env
->icache_line_size
= 32;
3344 /* Allocate hardware IRQ controller */
3345 ppc40x_irq_init(ppc_env_get_cpu(env
));
3347 SET_FIT_PERIOD(12, 16, 20, 24);
3348 SET_WDT_PERIOD(16, 20, 24, 28);
3351 POWERPC_FAMILY(401)(ObjectClass
*oc
, void *data
)
3353 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3354 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3356 dc
->desc
= "PowerPC 401";
3357 pcc
->init_proc
= init_proc_401
;
3358 pcc
->check_pow
= check_pow_nocheck
;
3359 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3360 PPC_WRTEE
| PPC_DCR
|
3361 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3363 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3364 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3365 pcc
->msr_mask
= (1ull << MSR_KEY
) |
3374 pcc
->mmu_model
= POWERPC_MMU_REAL
;
3375 pcc
->excp_model
= POWERPC_EXCP_40x
;
3376 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3377 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3378 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3379 POWERPC_FLAG_BUS_CLK
;
3382 static void init_proc_401x2(CPUPPCState
*env
)
3385 gen_spr_401_403(env
);
3387 gen_spr_compress(env
);
3388 /* Memory management */
3389 #if !defined(CONFIG_USER_ONLY)
3393 env
->tlb_type
= TLB_EMB
;
3395 init_excp_4xx_softmmu(env
);
3396 env
->dcache_line_size
= 32;
3397 env
->icache_line_size
= 32;
3398 /* Allocate hardware IRQ controller */
3399 ppc40x_irq_init(ppc_env_get_cpu(env
));
3401 SET_FIT_PERIOD(12, 16, 20, 24);
3402 SET_WDT_PERIOD(16, 20, 24, 28);
3405 POWERPC_FAMILY(401x2
)(ObjectClass
*oc
, void *data
)
3407 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3408 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3410 dc
->desc
= "PowerPC 401x2";
3411 pcc
->init_proc
= init_proc_401x2
;
3412 pcc
->check_pow
= check_pow_nocheck
;
3413 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3414 PPC_DCR
| PPC_WRTEE
|
3415 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3416 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3417 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3418 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3419 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3420 pcc
->msr_mask
= (1ull << 20) |
3432 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3433 pcc
->excp_model
= POWERPC_EXCP_40x
;
3434 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3435 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3436 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3437 POWERPC_FLAG_BUS_CLK
;
3440 static void init_proc_401x3(CPUPPCState
*env
)
3443 gen_spr_401_403(env
);
3446 gen_spr_compress(env
);
3447 init_excp_4xx_softmmu(env
);
3448 env
->dcache_line_size
= 32;
3449 env
->icache_line_size
= 32;
3450 /* Allocate hardware IRQ controller */
3451 ppc40x_irq_init(ppc_env_get_cpu(env
));
3453 SET_FIT_PERIOD(12, 16, 20, 24);
3454 SET_WDT_PERIOD(16, 20, 24, 28);
3457 POWERPC_FAMILY(401x3
)(ObjectClass
*oc
, void *data
)
3459 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3460 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3462 dc
->desc
= "PowerPC 401x3";
3463 pcc
->init_proc
= init_proc_401x3
;
3464 pcc
->check_pow
= check_pow_nocheck
;
3465 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3466 PPC_DCR
| PPC_WRTEE
|
3467 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3468 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3469 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3470 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3471 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3472 pcc
->msr_mask
= (1ull << 20) |
3485 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3486 pcc
->excp_model
= POWERPC_EXCP_40x
;
3487 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3488 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3489 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3490 POWERPC_FLAG_BUS_CLK
;
3493 static void init_proc_IOP480(CPUPPCState
*env
)
3496 gen_spr_401_403(env
);
3498 gen_spr_compress(env
);
3499 /* Memory management */
3500 #if !defined(CONFIG_USER_ONLY)
3504 env
->tlb_type
= TLB_EMB
;
3506 init_excp_4xx_softmmu(env
);
3507 env
->dcache_line_size
= 32;
3508 env
->icache_line_size
= 32;
3509 /* Allocate hardware IRQ controller */
3510 ppc40x_irq_init(ppc_env_get_cpu(env
));
3512 SET_FIT_PERIOD(8, 12, 16, 20);
3513 SET_WDT_PERIOD(16, 20, 24, 28);
3516 POWERPC_FAMILY(IOP480
)(ObjectClass
*oc
, void *data
)
3518 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3519 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3521 dc
->desc
= "IOP480";
3522 pcc
->init_proc
= init_proc_IOP480
;
3523 pcc
->check_pow
= check_pow_nocheck
;
3524 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3525 PPC_DCR
| PPC_WRTEE
|
3526 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3527 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3528 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3529 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3530 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3531 pcc
->msr_mask
= (1ull << 20) |
3543 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3544 pcc
->excp_model
= POWERPC_EXCP_40x
;
3545 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3546 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3547 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3548 POWERPC_FLAG_BUS_CLK
;
3551 static void init_proc_403(CPUPPCState
*env
)
3554 gen_spr_401_403(env
);
3556 gen_spr_403_real(env
);
3557 init_excp_4xx_real(env
);
3558 env
->dcache_line_size
= 32;
3559 env
->icache_line_size
= 32;
3560 /* Allocate hardware IRQ controller */
3561 ppc40x_irq_init(ppc_env_get_cpu(env
));
3563 SET_FIT_PERIOD(8, 12, 16, 20);
3564 SET_WDT_PERIOD(16, 20, 24, 28);
3567 POWERPC_FAMILY(403)(ObjectClass
*oc
, void *data
)
3569 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3570 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3572 dc
->desc
= "PowerPC 403";
3573 pcc
->init_proc
= init_proc_403
;
3574 pcc
->check_pow
= check_pow_nocheck
;
3575 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3576 PPC_DCR
| PPC_WRTEE
|
3577 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3579 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3580 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3581 pcc
->msr_mask
= (1ull << MSR_POW
) |
3590 pcc
->mmu_model
= POWERPC_MMU_REAL
;
3591 pcc
->excp_model
= POWERPC_EXCP_40x
;
3592 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3593 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3594 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_PX
|
3595 POWERPC_FLAG_BUS_CLK
;
3598 static void init_proc_403GCX(CPUPPCState
*env
)
3601 gen_spr_401_403(env
);
3603 gen_spr_403_real(env
);
3604 gen_spr_403_mmu(env
);
3605 /* Bus access control */
3606 /* not emulated, as QEMU never does speculative access */
3607 spr_register(env
, SPR_40x_SGR
, "SGR",
3608 SPR_NOACCESS
, SPR_NOACCESS
,
3609 &spr_read_generic
, &spr_write_generic
,
3611 /* not emulated, as QEMU do not emulate caches */
3612 spr_register(env
, SPR_40x_DCWR
, "DCWR",
3613 SPR_NOACCESS
, SPR_NOACCESS
,
3614 &spr_read_generic
, &spr_write_generic
,
3616 /* Memory management */
3617 #if !defined(CONFIG_USER_ONLY)
3621 env
->tlb_type
= TLB_EMB
;
3623 init_excp_4xx_softmmu(env
);
3624 env
->dcache_line_size
= 32;
3625 env
->icache_line_size
= 32;
3626 /* Allocate hardware IRQ controller */
3627 ppc40x_irq_init(ppc_env_get_cpu(env
));
3629 SET_FIT_PERIOD(8, 12, 16, 20);
3630 SET_WDT_PERIOD(16, 20, 24, 28);
3633 POWERPC_FAMILY(403GCX
)(ObjectClass
*oc
, void *data
)
3635 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3636 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3638 dc
->desc
= "PowerPC 403 GCX";
3639 pcc
->init_proc
= init_proc_403GCX
;
3640 pcc
->check_pow
= check_pow_nocheck
;
3641 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3642 PPC_DCR
| PPC_WRTEE
|
3643 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3645 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3646 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3647 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3648 pcc
->msr_mask
= (1ull << MSR_POW
) |
3657 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3658 pcc
->excp_model
= POWERPC_EXCP_40x
;
3659 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3660 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3661 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_PX
|
3662 POWERPC_FLAG_BUS_CLK
;
3665 static void init_proc_405(CPUPPCState
*env
)
3671 /* Bus access control */
3672 /* not emulated, as QEMU never does speculative access */
3673 spr_register(env
, SPR_40x_SGR
, "SGR",
3674 SPR_NOACCESS
, SPR_NOACCESS
,
3675 &spr_read_generic
, &spr_write_generic
,
3677 /* not emulated, as QEMU do not emulate caches */
3678 spr_register(env
, SPR_40x_DCWR
, "DCWR",
3679 SPR_NOACCESS
, SPR_NOACCESS
,
3680 &spr_read_generic
, &spr_write_generic
,
3682 /* Memory management */
3683 #if !defined(CONFIG_USER_ONLY)
3687 env
->tlb_type
= TLB_EMB
;
3689 init_excp_4xx_softmmu(env
);
3690 env
->dcache_line_size
= 32;
3691 env
->icache_line_size
= 32;
3692 /* Allocate hardware IRQ controller */
3693 ppc40x_irq_init(ppc_env_get_cpu(env
));
3695 SET_FIT_PERIOD(8, 12, 16, 20);
3696 SET_WDT_PERIOD(16, 20, 24, 28);
3699 POWERPC_FAMILY(405)(ObjectClass
*oc
, void *data
)
3701 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3702 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3704 dc
->desc
= "PowerPC 405";
3705 pcc
->init_proc
= init_proc_405
;
3706 pcc
->check_pow
= check_pow_nocheck
;
3707 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3708 PPC_DCR
| PPC_WRTEE
|
3709 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3710 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3711 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3712 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3713 PPC_4xx_COMMON
| PPC_405_MAC
| PPC_40x_EXCP
;
3714 pcc
->msr_mask
= (1ull << MSR_POW
) |
3723 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx
;
3724 pcc
->excp_model
= POWERPC_EXCP_40x
;
3725 pcc
->bus_model
= PPC_FLAGS_INPUT_405
;
3726 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3727 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3728 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3731 static void init_proc_440EP(CPUPPCState
*env
)
3735 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3737 gen_spr_usprgh(env
);
3738 /* Processor identification */
3739 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3740 SPR_NOACCESS
, SPR_NOACCESS
,
3741 &spr_read_generic
, &spr_write_pir
,
3743 /* XXX : not implemented */
3744 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
3745 SPR_NOACCESS
, SPR_NOACCESS
,
3746 &spr_read_generic
, &spr_write_generic
,
3748 /* XXX : not implemented */
3749 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
3750 SPR_NOACCESS
, SPR_NOACCESS
,
3751 &spr_read_generic
, &spr_write_generic
,
3753 /* XXX : not implemented */
3754 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
3755 SPR_NOACCESS
, SPR_NOACCESS
,
3756 &spr_read_generic
, &spr_write_generic
,
3758 /* XXX : not implemented */
3759 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
3760 SPR_NOACCESS
, SPR_NOACCESS
,
3761 &spr_read_generic
, &spr_write_generic
,
3763 /* XXX : not implemented */
3764 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
3765 SPR_NOACCESS
, SPR_NOACCESS
,
3766 &spr_read_generic
, &spr_write_generic
,
3768 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
3769 SPR_NOACCESS
, SPR_NOACCESS
,
3770 &spr_read_generic
, &spr_write_generic
,
3772 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
3773 SPR_NOACCESS
, SPR_NOACCESS
,
3774 &spr_read_generic
, &spr_write_generic
,
3776 /* XXX : not implemented */
3777 spr_register(env
, SPR_440_CCR1
, "CCR1",
3778 SPR_NOACCESS
, SPR_NOACCESS
,
3779 &spr_read_generic
, &spr_write_generic
,
3781 /* Memory management */
3782 #if !defined(CONFIG_USER_ONLY)
3786 env
->tlb_type
= TLB_EMB
;
3788 init_excp_BookE(env
);
3789 env
->dcache_line_size
= 32;
3790 env
->icache_line_size
= 32;
3791 ppc40x_irq_init(ppc_env_get_cpu(env
));
3793 SET_FIT_PERIOD(12, 16, 20, 24);
3794 SET_WDT_PERIOD(20, 24, 28, 32);
3797 POWERPC_FAMILY(440EP
)(ObjectClass
*oc
, void *data
)
3799 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3800 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3802 dc
->desc
= "PowerPC 440 EP";
3803 pcc
->init_proc
= init_proc_440EP
;
3804 pcc
->check_pow
= check_pow_nocheck
;
3805 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3806 PPC_FLOAT
| PPC_FLOAT_FRES
| PPC_FLOAT_FSEL
|
3807 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
3809 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
3810 PPC_CACHE
| PPC_CACHE_ICBI
|
3811 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3812 PPC_MEM_TLBSYNC
| PPC_MFTB
|
3813 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3815 pcc
->msr_mask
= (1ull << MSR_POW
) |
3827 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3828 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3829 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3830 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3831 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3832 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3835 static void init_proc_440GP(CPUPPCState
*env
)
3839 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3841 gen_spr_usprgh(env
);
3842 /* Processor identification */
3843 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3844 SPR_NOACCESS
, SPR_NOACCESS
,
3845 &spr_read_generic
, &spr_write_pir
,
3847 /* XXX : not implemented */
3848 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
3849 SPR_NOACCESS
, SPR_NOACCESS
,
3850 &spr_read_generic
, &spr_write_generic
,
3852 /* XXX : not implemented */
3853 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
3854 SPR_NOACCESS
, SPR_NOACCESS
,
3855 &spr_read_generic
, &spr_write_generic
,
3857 /* XXX : not implemented */
3858 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
3859 SPR_NOACCESS
, SPR_NOACCESS
,
3860 &spr_read_generic
, &spr_write_generic
,
3862 /* XXX : not implemented */
3863 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
3864 SPR_NOACCESS
, SPR_NOACCESS
,
3865 &spr_read_generic
, &spr_write_generic
,
3867 /* Memory management */
3868 #if !defined(CONFIG_USER_ONLY)
3872 env
->tlb_type
= TLB_EMB
;
3874 init_excp_BookE(env
);
3875 env
->dcache_line_size
= 32;
3876 env
->icache_line_size
= 32;
3877 /* XXX: TODO: allocate internal IRQ controller */
3879 SET_FIT_PERIOD(12, 16, 20, 24);
3880 SET_WDT_PERIOD(20, 24, 28, 32);
3883 POWERPC_FAMILY(440GP
)(ObjectClass
*oc
, void *data
)
3885 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3886 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3888 dc
->desc
= "PowerPC 440 GP";
3889 pcc
->init_proc
= init_proc_440GP
;
3890 pcc
->check_pow
= check_pow_nocheck
;
3891 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3892 PPC_DCR
| PPC_DCRX
| PPC_WRTEE
| PPC_MFAPIDI
|
3893 PPC_CACHE
| PPC_CACHE_ICBI
|
3894 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3895 PPC_MEM_TLBSYNC
| PPC_TLBIVA
| PPC_MFTB
|
3896 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3898 pcc
->msr_mask
= (1ull << MSR_POW
) |
3910 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3911 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3912 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3913 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3914 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3915 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3918 static void init_proc_440x4(CPUPPCState
*env
)
3922 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3924 gen_spr_usprgh(env
);
3925 /* Processor identification */
3926 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3927 SPR_NOACCESS
, SPR_NOACCESS
,
3928 &spr_read_generic
, &spr_write_pir
,
3930 /* XXX : not implemented */
3931 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
3932 SPR_NOACCESS
, SPR_NOACCESS
,
3933 &spr_read_generic
, &spr_write_generic
,
3935 /* XXX : not implemented */
3936 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
3937 SPR_NOACCESS
, SPR_NOACCESS
,
3938 &spr_read_generic
, &spr_write_generic
,
3940 /* XXX : not implemented */
3941 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
3942 SPR_NOACCESS
, SPR_NOACCESS
,
3943 &spr_read_generic
, &spr_write_generic
,
3945 /* XXX : not implemented */
3946 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
3947 SPR_NOACCESS
, SPR_NOACCESS
,
3948 &spr_read_generic
, &spr_write_generic
,
3950 /* Memory management */
3951 #if !defined(CONFIG_USER_ONLY)
3955 env
->tlb_type
= TLB_EMB
;
3957 init_excp_BookE(env
);
3958 env
->dcache_line_size
= 32;
3959 env
->icache_line_size
= 32;
3960 /* XXX: TODO: allocate internal IRQ controller */
3962 SET_FIT_PERIOD(12, 16, 20, 24);
3963 SET_WDT_PERIOD(20, 24, 28, 32);
3966 POWERPC_FAMILY(440x4
)(ObjectClass
*oc
, void *data
)
3968 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3969 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3971 dc
->desc
= "PowerPC 440x4";
3972 pcc
->init_proc
= init_proc_440x4
;
3973 pcc
->check_pow
= check_pow_nocheck
;
3974 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3975 PPC_DCR
| PPC_WRTEE
|
3976 PPC_CACHE
| PPC_CACHE_ICBI
|
3977 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3978 PPC_MEM_TLBSYNC
| PPC_MFTB
|
3979 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3981 pcc
->msr_mask
= (1ull << MSR_POW
) |
3993 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3994 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3995 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3996 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3997 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3998 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4001 static void init_proc_440x5(CPUPPCState
*env
)
4005 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
4007 gen_spr_usprgh(env
);
4008 /* Processor identification */
4009 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4010 SPR_NOACCESS
, SPR_NOACCESS
,
4011 &spr_read_generic
, &spr_write_pir
,
4013 /* XXX : not implemented */
4014 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4015 SPR_NOACCESS
, SPR_NOACCESS
,
4016 &spr_read_generic
, &spr_write_generic
,
4018 /* XXX : not implemented */
4019 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4020 SPR_NOACCESS
, SPR_NOACCESS
,
4021 &spr_read_generic
, &spr_write_generic
,
4023 /* XXX : not implemented */
4024 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
4025 SPR_NOACCESS
, SPR_NOACCESS
,
4026 &spr_read_generic
, &spr_write_generic
,
4028 /* XXX : not implemented */
4029 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
4030 SPR_NOACCESS
, SPR_NOACCESS
,
4031 &spr_read_generic
, &spr_write_generic
,
4033 /* XXX : not implemented */
4034 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
4035 SPR_NOACCESS
, SPR_NOACCESS
,
4036 &spr_read_generic
, &spr_write_generic
,
4038 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
4039 SPR_NOACCESS
, SPR_NOACCESS
,
4040 &spr_read_generic
, &spr_write_generic
,
4042 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
4043 SPR_NOACCESS
, SPR_NOACCESS
,
4044 &spr_read_generic
, &spr_write_generic
,
4046 /* XXX : not implemented */
4047 spr_register(env
, SPR_440_CCR1
, "CCR1",
4048 SPR_NOACCESS
, SPR_NOACCESS
,
4049 &spr_read_generic
, &spr_write_generic
,
4051 /* Memory management */
4052 #if !defined(CONFIG_USER_ONLY)
4056 env
->tlb_type
= TLB_EMB
;
4058 init_excp_BookE(env
);
4059 env
->dcache_line_size
= 32;
4060 env
->icache_line_size
= 32;
4061 ppc40x_irq_init(ppc_env_get_cpu(env
));
4063 SET_FIT_PERIOD(12, 16, 20, 24);
4064 SET_WDT_PERIOD(20, 24, 28, 32);
4067 POWERPC_FAMILY(440x5
)(ObjectClass
*oc
, void *data
)
4069 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4070 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4072 dc
->desc
= "PowerPC 440x5";
4073 pcc
->init_proc
= init_proc_440x5
;
4074 pcc
->check_pow
= check_pow_nocheck
;
4075 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4076 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
4077 PPC_CACHE
| PPC_CACHE_ICBI
|
4078 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4079 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4080 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4082 pcc
->msr_mask
= (1ull << MSR_POW
) |
4094 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4095 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4096 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4097 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4098 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4099 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4102 POWERPC_FAMILY(440x5wDFPU
)(ObjectClass
*oc
, void *data
)
4104 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4105 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4107 dc
->desc
= "PowerPC 440x5 with double precision FPU";
4108 pcc
->init_proc
= init_proc_440x5
;
4109 pcc
->check_pow
= check_pow_nocheck
;
4110 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4111 PPC_FLOAT
| PPC_FLOAT_FSQRT
|
4113 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
4114 PPC_CACHE
| PPC_CACHE_ICBI
|
4115 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4116 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4117 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4119 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
4120 pcc
->msr_mask
= (1ull << MSR_POW
) |
4132 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4133 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4134 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4135 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4136 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4137 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4140 static void init_proc_460 (CPUPPCState
*env
)
4144 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
4146 gen_spr_usprgh(env
);
4147 /* Processor identification */
4148 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4149 SPR_NOACCESS
, SPR_NOACCESS
,
4150 &spr_read_generic
, &spr_write_pir
,
4152 /* XXX : not implemented */
4153 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4154 SPR_NOACCESS
, SPR_NOACCESS
,
4155 &spr_read_generic
, &spr_write_generic
,
4157 /* XXX : not implemented */
4158 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4159 SPR_NOACCESS
, SPR_NOACCESS
,
4160 &spr_read_generic
, &spr_write_generic
,
4162 /* XXX : not implemented */
4163 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
4164 SPR_NOACCESS
, SPR_NOACCESS
,
4165 &spr_read_generic
, &spr_write_generic
,
4167 /* XXX : not implemented */
4168 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
4169 SPR_NOACCESS
, SPR_NOACCESS
,
4170 &spr_read_generic
, &spr_write_generic
,
4172 /* XXX : not implemented */
4173 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
4174 SPR_NOACCESS
, SPR_NOACCESS
,
4175 &spr_read_generic
, &spr_write_generic
,
4177 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
4178 SPR_NOACCESS
, SPR_NOACCESS
,
4179 &spr_read_generic
, &spr_write_generic
,
4181 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
4182 SPR_NOACCESS
, SPR_NOACCESS
,
4183 &spr_read_generic
, &spr_write_generic
,
4185 /* XXX : not implemented */
4186 spr_register(env
, SPR_440_CCR1
, "CCR1",
4187 SPR_NOACCESS
, SPR_NOACCESS
,
4188 &spr_read_generic
, &spr_write_generic
,
4190 /* XXX : not implemented */
4191 spr_register(env
, SPR_DCRIPR
, "SPR_DCRIPR",
4192 &spr_read_generic
, &spr_write_generic
,
4193 &spr_read_generic
, &spr_write_generic
,
4195 /* Memory management */
4196 #if !defined(CONFIG_USER_ONLY)
4200 env
->tlb_type
= TLB_EMB
;
4202 init_excp_BookE(env
);
4203 env
->dcache_line_size
= 32;
4204 env
->icache_line_size
= 32;
4205 /* XXX: TODO: allocate internal IRQ controller */
4207 SET_FIT_PERIOD(12, 16, 20, 24);
4208 SET_WDT_PERIOD(20, 24, 28, 32);
4211 POWERPC_FAMILY(460)(ObjectClass
*oc
, void *data
)
4213 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4214 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4216 dc
->desc
= "PowerPC 460 (guessed)";
4217 pcc
->init_proc
= init_proc_460
;
4218 pcc
->check_pow
= check_pow_nocheck
;
4219 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4220 PPC_DCR
| PPC_DCRX
| PPC_DCRUX
|
4221 PPC_WRTEE
| PPC_MFAPIDI
| PPC_MFTB
|
4222 PPC_CACHE
| PPC_CACHE_ICBI
|
4223 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4224 PPC_MEM_TLBSYNC
| PPC_TLBIVA
|
4225 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4227 pcc
->msr_mask
= (1ull << MSR_POW
) |
4239 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4240 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4241 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4242 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4243 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4244 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4247 static void init_proc_460F(CPUPPCState
*env
)
4251 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
4253 gen_spr_usprgh(env
);
4254 /* Processor identification */
4255 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4256 SPR_NOACCESS
, SPR_NOACCESS
,
4257 &spr_read_generic
, &spr_write_pir
,
4259 /* XXX : not implemented */
4260 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4261 SPR_NOACCESS
, SPR_NOACCESS
,
4262 &spr_read_generic
, &spr_write_generic
,
4264 /* XXX : not implemented */
4265 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4266 SPR_NOACCESS
, SPR_NOACCESS
,
4267 &spr_read_generic
, &spr_write_generic
,
4269 /* XXX : not implemented */
4270 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
4271 SPR_NOACCESS
, SPR_NOACCESS
,
4272 &spr_read_generic
, &spr_write_generic
,
4274 /* XXX : not implemented */
4275 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
4276 SPR_NOACCESS
, SPR_NOACCESS
,
4277 &spr_read_generic
, &spr_write_generic
,
4279 /* XXX : not implemented */
4280 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
4281 SPR_NOACCESS
, SPR_NOACCESS
,
4282 &spr_read_generic
, &spr_write_generic
,
4284 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
4285 SPR_NOACCESS
, SPR_NOACCESS
,
4286 &spr_read_generic
, &spr_write_generic
,
4288 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
4289 SPR_NOACCESS
, SPR_NOACCESS
,
4290 &spr_read_generic
, &spr_write_generic
,
4292 /* XXX : not implemented */
4293 spr_register(env
, SPR_440_CCR1
, "CCR1",
4294 SPR_NOACCESS
, SPR_NOACCESS
,
4295 &spr_read_generic
, &spr_write_generic
,
4297 /* XXX : not implemented */
4298 spr_register(env
, SPR_DCRIPR
, "SPR_DCRIPR",
4299 &spr_read_generic
, &spr_write_generic
,
4300 &spr_read_generic
, &spr_write_generic
,
4302 /* Memory management */
4303 #if !defined(CONFIG_USER_ONLY)
4307 env
->tlb_type
= TLB_EMB
;
4309 init_excp_BookE(env
);
4310 env
->dcache_line_size
= 32;
4311 env
->icache_line_size
= 32;
4312 /* XXX: TODO: allocate internal IRQ controller */
4314 SET_FIT_PERIOD(12, 16, 20, 24);
4315 SET_WDT_PERIOD(20, 24, 28, 32);
4318 POWERPC_FAMILY(460F
)(ObjectClass
*oc
, void *data
)
4320 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4321 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4323 dc
->desc
= "PowerPC 460F (guessed)";
4324 pcc
->init_proc
= init_proc_460F
;
4325 pcc
->check_pow
= check_pow_nocheck
;
4326 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4327 PPC_FLOAT
| PPC_FLOAT_FRES
| PPC_FLOAT_FSEL
|
4328 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
4329 PPC_FLOAT_STFIWX
| PPC_MFTB
|
4330 PPC_DCR
| PPC_DCRX
| PPC_DCRUX
|
4331 PPC_WRTEE
| PPC_MFAPIDI
|
4332 PPC_CACHE
| PPC_CACHE_ICBI
|
4333 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4334 PPC_MEM_TLBSYNC
| PPC_TLBIVA
|
4335 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4337 pcc
->msr_mask
= (1ull << MSR_POW
) |
4349 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4350 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4351 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4352 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4353 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4354 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4357 static void init_proc_MPC5xx(CPUPPCState
*env
)
4361 gen_spr_5xx_8xx(env
);
4363 init_excp_MPC5xx(env
);
4364 env
->dcache_line_size
= 32;
4365 env
->icache_line_size
= 32;
4366 /* XXX: TODO: allocate internal IRQ controller */
4369 POWERPC_FAMILY(MPC5xx
)(ObjectClass
*oc
, void *data
)
4371 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4372 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4374 dc
->desc
= "Freescale 5xx cores (aka RCPU)";
4375 pcc
->init_proc
= init_proc_MPC5xx
;
4376 pcc
->check_pow
= check_pow_none
;
4377 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4378 PPC_MEM_EIEIO
| PPC_MEM_SYNC
|
4379 PPC_CACHE_ICBI
| PPC_FLOAT
| PPC_FLOAT_STFIWX
|
4381 pcc
->msr_mask
= (1ull << MSR_ILE
) |
4393 pcc
->mmu_model
= POWERPC_MMU_REAL
;
4394 pcc
->excp_model
= POWERPC_EXCP_603
;
4395 pcc
->bus_model
= PPC_FLAGS_INPUT_RCPU
;
4396 pcc
->bfd_mach
= bfd_mach_ppc_505
;
4397 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
4398 POWERPC_FLAG_BUS_CLK
;
4401 static void init_proc_MPC8xx(CPUPPCState
*env
)
4405 gen_spr_5xx_8xx(env
);
4407 init_excp_MPC8xx(env
);
4408 env
->dcache_line_size
= 32;
4409 env
->icache_line_size
= 32;
4410 /* XXX: TODO: allocate internal IRQ controller */
4413 POWERPC_FAMILY(MPC8xx
)(ObjectClass
*oc
, void *data
)
4415 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4416 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4418 dc
->desc
= "Freescale 8xx cores (aka PowerQUICC)";
4419 pcc
->init_proc
= init_proc_MPC8xx
;
4420 pcc
->check_pow
= check_pow_none
;
4421 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4422 PPC_MEM_EIEIO
| PPC_MEM_SYNC
|
4423 PPC_CACHE_ICBI
| PPC_MFTB
;
4424 pcc
->msr_mask
= (1ull << MSR_ILE
) |
4436 pcc
->mmu_model
= POWERPC_MMU_MPC8xx
;
4437 pcc
->excp_model
= POWERPC_EXCP_603
;
4438 pcc
->bus_model
= PPC_FLAGS_INPUT_RCPU
;
4439 pcc
->bfd_mach
= bfd_mach_ppc_860
;
4440 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
4441 POWERPC_FLAG_BUS_CLK
;
4444 /* Freescale 82xx cores (aka PowerQUICC-II) */
4446 static void init_proc_G2(CPUPPCState
*env
)
4448 gen_spr_ne_601(env
);
4450 gen_spr_G2_755(env
);
4454 /* External access control */
4455 /* XXX : not implemented */
4456 spr_register(env
, SPR_EAR
, "EAR",
4457 SPR_NOACCESS
, SPR_NOACCESS
,
4458 &spr_read_generic
, &spr_write_generic
,
4460 /* Hardware implementation register */
4461 /* XXX : not implemented */
4462 spr_register(env
, SPR_HID0
, "HID0",
4463 SPR_NOACCESS
, SPR_NOACCESS
,
4464 &spr_read_generic
, &spr_write_generic
,
4466 /* XXX : not implemented */
4467 spr_register(env
, SPR_HID1
, "HID1",
4468 SPR_NOACCESS
, SPR_NOACCESS
,
4469 &spr_read_generic
, &spr_write_generic
,
4471 /* XXX : not implemented */
4472 spr_register(env
, SPR_HID2
, "HID2",
4473 SPR_NOACCESS
, SPR_NOACCESS
,
4474 &spr_read_generic
, &spr_write_generic
,
4476 /* Memory management */
4479 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4481 env
->dcache_line_size
= 32;
4482 env
->icache_line_size
= 32;
4483 /* Allocate hardware IRQ controller */
4484 ppc6xx_irq_init(ppc_env_get_cpu(env
));
4487 POWERPC_FAMILY(G2
)(ObjectClass
*oc
, void *data
)
4489 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4490 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4492 dc
->desc
= "PowerPC G2";
4493 pcc
->init_proc
= init_proc_G2
;
4494 pcc
->check_pow
= check_pow_hid0
;
4495 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4496 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4498 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4499 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4500 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4501 PPC_SEGMENT
| PPC_EXTERN
;
4502 pcc
->msr_mask
= (1ull << MSR_POW
) |
4503 (1ull << MSR_TGPR
) |
4517 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4518 pcc
->excp_model
= POWERPC_EXCP_G2
;
4519 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4520 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
4521 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4522 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4525 static void init_proc_G2LE(CPUPPCState
*env
)
4527 gen_spr_ne_601(env
);
4529 gen_spr_G2_755(env
);
4533 /* External access control */
4534 /* XXX : not implemented */
4535 spr_register(env
, SPR_EAR
, "EAR",
4536 SPR_NOACCESS
, SPR_NOACCESS
,
4537 &spr_read_generic
, &spr_write_generic
,
4539 /* Hardware implementation register */
4540 /* XXX : not implemented */
4541 spr_register(env
, SPR_HID0
, "HID0",
4542 SPR_NOACCESS
, SPR_NOACCESS
,
4543 &spr_read_generic
, &spr_write_generic
,
4545 /* XXX : not implemented */
4546 spr_register(env
, SPR_HID1
, "HID1",
4547 SPR_NOACCESS
, SPR_NOACCESS
,
4548 &spr_read_generic
, &spr_write_generic
,
4550 /* XXX : not implemented */
4551 spr_register(env
, SPR_HID2
, "HID2",
4552 SPR_NOACCESS
, SPR_NOACCESS
,
4553 &spr_read_generic
, &spr_write_generic
,
4556 /* Memory management */
4559 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4561 env
->dcache_line_size
= 32;
4562 env
->icache_line_size
= 32;
4563 /* Allocate hardware IRQ controller */
4564 ppc6xx_irq_init(ppc_env_get_cpu(env
));
4567 POWERPC_FAMILY(G2LE
)(ObjectClass
*oc
, void *data
)
4569 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4570 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4572 dc
->desc
= "PowerPC G2LE";
4573 pcc
->init_proc
= init_proc_G2LE
;
4574 pcc
->check_pow
= check_pow_hid0
;
4575 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4576 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4578 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4579 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4580 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4581 PPC_SEGMENT
| PPC_EXTERN
;
4582 pcc
->msr_mask
= (1ull << MSR_POW
) |
4583 (1ull << MSR_TGPR
) |
4599 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4600 pcc
->excp_model
= POWERPC_EXCP_G2
;
4601 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4602 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
4603 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4604 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4607 static void init_proc_e200(CPUPPCState
*env
)
4611 gen_spr_BookE(env
, 0x000000070000FFFFULL
);
4612 /* XXX : not implemented */
4613 spr_register(env
, SPR_BOOKE_SPEFSCR
, "SPEFSCR",
4614 &spr_read_spefscr
, &spr_write_spefscr
,
4615 &spr_read_spefscr
, &spr_write_spefscr
,
4617 /* Memory management */
4618 gen_spr_BookE206(env
, 0x0000005D, NULL
, 0);
4619 /* XXX : not implemented */
4620 spr_register(env
, SPR_HID0
, "HID0",
4621 SPR_NOACCESS
, SPR_NOACCESS
,
4622 &spr_read_generic
, &spr_write_generic
,
4624 /* XXX : not implemented */
4625 spr_register(env
, SPR_HID1
, "HID1",
4626 SPR_NOACCESS
, SPR_NOACCESS
,
4627 &spr_read_generic
, &spr_write_generic
,
4629 /* XXX : not implemented */
4630 spr_register(env
, SPR_Exxx_ALTCTXCR
, "ALTCTXCR",
4631 SPR_NOACCESS
, SPR_NOACCESS
,
4632 &spr_read_generic
, &spr_write_generic
,
4634 /* XXX : not implemented */
4635 spr_register(env
, SPR_Exxx_BUCSR
, "BUCSR",
4636 SPR_NOACCESS
, SPR_NOACCESS
,
4637 &spr_read_generic
, &spr_write_generic
,
4639 /* XXX : not implemented */
4640 spr_register(env
, SPR_Exxx_CTXCR
, "CTXCR",
4641 SPR_NOACCESS
, SPR_NOACCESS
,
4642 &spr_read_generic
, &spr_write_generic
,
4644 /* XXX : not implemented */
4645 spr_register(env
, SPR_Exxx_DBCNT
, "DBCNT",
4646 SPR_NOACCESS
, SPR_NOACCESS
,
4647 &spr_read_generic
, &spr_write_generic
,
4649 /* XXX : not implemented */
4650 spr_register(env
, SPR_Exxx_DBCR3
, "DBCR3",
4651 SPR_NOACCESS
, SPR_NOACCESS
,
4652 &spr_read_generic
, &spr_write_generic
,
4654 /* XXX : not implemented */
4655 spr_register(env
, SPR_Exxx_L1CFG0
, "L1CFG0",
4656 &spr_read_generic
, SPR_NOACCESS
,
4657 &spr_read_generic
, SPR_NOACCESS
,
4659 /* XXX : not implemented */
4660 spr_register(env
, SPR_Exxx_L1CSR0
, "L1CSR0",
4661 SPR_NOACCESS
, SPR_NOACCESS
,
4662 &spr_read_generic
, &spr_write_generic
,
4664 /* XXX : not implemented */
4665 spr_register(env
, SPR_Exxx_L1FINV0
, "L1FINV0",
4666 SPR_NOACCESS
, SPR_NOACCESS
,
4667 &spr_read_generic
, &spr_write_generic
,
4669 /* XXX : not implemented */
4670 spr_register(env
, SPR_BOOKE_TLB0CFG
, "TLB0CFG",
4671 SPR_NOACCESS
, SPR_NOACCESS
,
4672 &spr_read_generic
, &spr_write_generic
,
4674 /* XXX : not implemented */
4675 spr_register(env
, SPR_BOOKE_TLB1CFG
, "TLB1CFG",
4676 SPR_NOACCESS
, SPR_NOACCESS
,
4677 &spr_read_generic
, &spr_write_generic
,
4679 /* XXX : not implemented */
4680 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4681 SPR_NOACCESS
, SPR_NOACCESS
,
4682 &spr_read_generic
, &spr_write_generic
,
4684 /* XXX : not implemented */
4685 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4686 SPR_NOACCESS
, SPR_NOACCESS
,
4687 &spr_read_generic
, &spr_write_generic
,
4689 /* XXX : not implemented */
4690 spr_register(env
, SPR_MMUCSR0
, "MMUCSR0",
4691 SPR_NOACCESS
, SPR_NOACCESS
,
4692 &spr_read_generic
, &spr_write_generic
,
4693 0x00000000); /* TOFIX */
4694 spr_register(env
, SPR_BOOKE_DSRR0
, "DSRR0",
4695 SPR_NOACCESS
, SPR_NOACCESS
,
4696 &spr_read_generic
, &spr_write_generic
,
4698 spr_register(env
, SPR_BOOKE_DSRR1
, "DSRR1",
4699 SPR_NOACCESS
, SPR_NOACCESS
,
4700 &spr_read_generic
, &spr_write_generic
,
4702 #if !defined(CONFIG_USER_ONLY)
4706 env
->tlb_type
= TLB_EMB
;
4708 init_excp_e200(env
, 0xFFFF0000UL
);
4709 env
->dcache_line_size
= 32;
4710 env
->icache_line_size
= 32;
4711 /* XXX: TODO: allocate internal IRQ controller */
4714 POWERPC_FAMILY(e200
)(ObjectClass
*oc
, void *data
)
4716 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4717 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4719 dc
->desc
= "e200 core";
4720 pcc
->init_proc
= init_proc_e200
;
4721 pcc
->check_pow
= check_pow_hid0
;
4722 /* XXX: unimplemented instructions:
4729 * all SPE multiply-accumulate instructions
4731 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
4732 PPC_SPE
| PPC_SPE_SINGLE
|
4733 PPC_WRTEE
| PPC_RFDI
|
4734 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
4735 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4736 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
|
4738 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
4752 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
4753 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4754 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4755 pcc
->bfd_mach
= bfd_mach_ppc_860
;
4756 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
4757 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
4758 POWERPC_FLAG_BUS_CLK
;
4761 static void init_proc_e300(CPUPPCState
*env
)
4763 gen_spr_ne_601(env
);
4768 /* hardware implementation registers */
4769 /* XXX : not implemented */
4770 spr_register(env
, SPR_HID0
, "HID0",
4771 SPR_NOACCESS
, SPR_NOACCESS
,
4772 &spr_read_generic
, &spr_write_generic
,
4774 /* XXX : not implemented */
4775 spr_register(env
, SPR_HID1
, "HID1",
4776 SPR_NOACCESS
, SPR_NOACCESS
,
4777 &spr_read_generic
, &spr_write_generic
,
4779 /* XXX : not implemented */
4780 spr_register(env
, SPR_HID2
, "HID2",
4781 SPR_NOACCESS
, SPR_NOACCESS
,
4782 &spr_read_generic
, &spr_write_generic
,
4785 /* XXX : not implemented */
4786 spr_register(env
, SPR_DABR
, "DABR",
4787 SPR_NOACCESS
, SPR_NOACCESS
,
4788 &spr_read_generic
, &spr_write_generic
,
4790 /* XXX : not implemented */
4791 spr_register(env
, SPR_DABR2
, "DABR2",
4792 SPR_NOACCESS
, SPR_NOACCESS
,
4793 &spr_read_generic
, &spr_write_generic
,
4795 /* XXX : not implemented */
4796 spr_register(env
, SPR_IABR2
, "IABR2",
4797 SPR_NOACCESS
, SPR_NOACCESS
,
4798 &spr_read_generic
, &spr_write_generic
,
4800 /* XXX : not implemented */
4801 spr_register(env
, SPR_IBCR
, "IBCR",
4802 SPR_NOACCESS
, SPR_NOACCESS
,
4803 &spr_read_generic
, &spr_write_generic
,
4805 /* XXX : not implemented */
4806 spr_register(env
, SPR_DBCR
, "DBCR",
4807 SPR_NOACCESS
, SPR_NOACCESS
,
4808 &spr_read_generic
, &spr_write_generic
,
4810 /* Memory management */
4813 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4815 env
->dcache_line_size
= 32;
4816 env
->icache_line_size
= 32;
4817 /* Allocate hardware IRQ controller */
4818 ppc6xx_irq_init(ppc_env_get_cpu(env
));
4821 POWERPC_FAMILY(e300
)(ObjectClass
*oc
, void *data
)
4823 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4824 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4826 dc
->desc
= "e300 core";
4827 pcc
->init_proc
= init_proc_e300
;
4828 pcc
->check_pow
= check_pow_hid0
;
4829 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4830 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4832 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4833 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4834 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4835 PPC_SEGMENT
| PPC_EXTERN
;
4836 pcc
->msr_mask
= (1ull << MSR_POW
) |
4837 (1ull << MSR_TGPR
) |
4853 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4854 pcc
->excp_model
= POWERPC_EXCP_603
;
4855 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4856 pcc
->bfd_mach
= bfd_mach_ppc_603
;
4857 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4858 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4861 #if !defined(CONFIG_USER_ONLY)
4862 static void spr_write_mas73(DisasContext
*ctx
, int sprn
, int gprn
)
4864 TCGv val
= tcg_temp_new();
4865 tcg_gen_ext32u_tl(val
, cpu_gpr
[gprn
]);
4866 gen_store_spr(SPR_BOOKE_MAS3
, val
);
4867 tcg_gen_shri_tl(val
, cpu_gpr
[gprn
], 32);
4868 gen_store_spr(SPR_BOOKE_MAS7
, val
);
4872 static void spr_read_mas73(DisasContext
*ctx
, int gprn
, int sprn
)
4874 TCGv mas7
= tcg_temp_new();
4875 TCGv mas3
= tcg_temp_new();
4876 gen_load_spr(mas7
, SPR_BOOKE_MAS7
);
4877 tcg_gen_shli_tl(mas7
, mas7
, 32);
4878 gen_load_spr(mas3
, SPR_BOOKE_MAS3
);
4879 tcg_gen_or_tl(cpu_gpr
[gprn
], mas3
, mas7
);
4880 tcg_temp_free(mas3
);
4881 tcg_temp_free(mas7
);
4886 enum fsl_e500_version
{
4894 static void init_proc_e500(CPUPPCState
*env
, int version
)
4896 PowerPCCPU
*cpu
= ppc_env_get_cpu(env
);
4897 uint32_t tlbncfg
[2];
4899 uint64_t ivpr_mask
= 0xFFFF0000ULL
;
4900 uint32_t l1cfg0
= 0x3800 /* 8 ways */
4901 | 0x0020; /* 32 kb */
4902 uint32_t l1cfg1
= 0x3800 /* 8 ways */
4903 | 0x0020; /* 32 kb */
4904 uint32_t mmucfg
= 0;
4905 #if !defined(CONFIG_USER_ONLY)
4912 * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't
4913 * complain when accessing them.
4914 * gen_spr_BookE(env, 0x0000000F0000FD7FULL);
4920 ivor_mask
= 0x0000000F0000FFFFULL
;
4924 ivor_mask
= 0x000003FE0000FFFFULL
;
4927 ivor_mask
= 0x000003FF0000FFFFULL
;
4930 gen_spr_BookE(env
, ivor_mask
);
4931 gen_spr_usprg3(env
);
4932 /* Processor identification */
4933 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4934 SPR_NOACCESS
, SPR_NOACCESS
,
4935 &spr_read_generic
, &spr_write_pir
,
4937 /* XXX : not implemented */
4938 spr_register(env
, SPR_BOOKE_SPEFSCR
, "SPEFSCR",
4939 &spr_read_spefscr
, &spr_write_spefscr
,
4940 &spr_read_spefscr
, &spr_write_spefscr
,
4942 #if !defined(CONFIG_USER_ONLY)
4943 /* Memory management */
4949 tlbncfg
[0] = gen_tlbncfg(2, 1, 1, 0, 256);
4950 tlbncfg
[1] = gen_tlbncfg(16, 1, 9, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 16);
4953 tlbncfg
[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4954 tlbncfg
[1] = gen_tlbncfg(16, 1, 12, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 16);
4958 tlbncfg
[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4959 tlbncfg
[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 64);
4964 tlbncfg
[0] = 0x08052400;
4965 tlbncfg
[1] = 0x40028040;
4968 cpu_abort(CPU(cpu
), "Unknown CPU: " TARGET_FMT_lx
"\n", env
->spr
[SPR_PVR
]);
4975 env
->dcache_line_size
= 32;
4976 env
->icache_line_size
= 32;
4980 env
->dcache_line_size
= 64;
4981 env
->icache_line_size
= 64;
4982 l1cfg0
|= 0x1000000; /* 64 byte cache block size */
4983 l1cfg1
|= 0x1000000; /* 64 byte cache block size */
4986 env
->dcache_line_size
= 32;
4987 env
->icache_line_size
= 32;
4988 l1cfg0
|= 0x0F83820;
4989 l1cfg1
|= 0x0B83820;
4992 cpu_abort(CPU(cpu
), "Unknown CPU: " TARGET_FMT_lx
"\n", env
->spr
[SPR_PVR
]);
4994 gen_spr_BookE206(env
, 0x000000DF, tlbncfg
, mmucfg
);
4995 /* XXX : not implemented */
4996 spr_register(env
, SPR_HID0
, "HID0",
4997 SPR_NOACCESS
, SPR_NOACCESS
,
4998 &spr_read_generic
, &spr_write_generic
,
5000 /* XXX : not implemented */
5001 spr_register(env
, SPR_HID1
, "HID1",
5002 SPR_NOACCESS
, SPR_NOACCESS
,
5003 &spr_read_generic
, &spr_write_generic
,
5005 /* XXX : not implemented */
5006 spr_register(env
, SPR_Exxx_BBEAR
, "BBEAR",
5007 SPR_NOACCESS
, SPR_NOACCESS
,
5008 &spr_read_generic
, &spr_write_generic
,
5010 /* XXX : not implemented */
5011 spr_register(env
, SPR_Exxx_BBTAR
, "BBTAR",
5012 SPR_NOACCESS
, SPR_NOACCESS
,
5013 &spr_read_generic
, &spr_write_generic
,
5015 /* XXX : not implemented */
5016 spr_register(env
, SPR_Exxx_MCAR
, "MCAR",
5017 SPR_NOACCESS
, SPR_NOACCESS
,
5018 &spr_read_generic
, &spr_write_generic
,
5020 /* XXX : not implemented */
5021 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
5022 SPR_NOACCESS
, SPR_NOACCESS
,
5023 &spr_read_generic
, &spr_write_generic
,
5025 /* XXX : not implemented */
5026 spr_register(env
, SPR_Exxx_NPIDR
, "NPIDR",
5027 SPR_NOACCESS
, SPR_NOACCESS
,
5028 &spr_read_generic
, &spr_write_generic
,
5030 /* XXX : not implemented */
5031 spr_register(env
, SPR_Exxx_BUCSR
, "BUCSR",
5032 SPR_NOACCESS
, SPR_NOACCESS
,
5033 &spr_read_generic
, &spr_write_generic
,
5035 /* XXX : not implemented */
5036 spr_register(env
, SPR_Exxx_L1CFG0
, "L1CFG0",
5037 &spr_read_generic
, SPR_NOACCESS
,
5038 &spr_read_generic
, SPR_NOACCESS
,
5040 spr_register(env
, SPR_Exxx_L1CFG1
, "L1CFG1",
5041 &spr_read_generic
, SPR_NOACCESS
,
5042 &spr_read_generic
, SPR_NOACCESS
,
5044 spr_register(env
, SPR_Exxx_L1CSR0
, "L1CSR0",
5045 SPR_NOACCESS
, SPR_NOACCESS
,
5046 &spr_read_generic
, &spr_write_e500_l1csr0
,
5048 spr_register(env
, SPR_Exxx_L1CSR1
, "L1CSR1",
5049 SPR_NOACCESS
, SPR_NOACCESS
,
5050 &spr_read_generic
, &spr_write_e500_l1csr1
,
5052 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
5053 SPR_NOACCESS
, SPR_NOACCESS
,
5054 &spr_read_generic
, &spr_write_generic
,
5056 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
5057 SPR_NOACCESS
, SPR_NOACCESS
,
5058 &spr_read_generic
, &spr_write_generic
,
5060 spr_register(env
, SPR_MMUCSR0
, "MMUCSR0",
5061 SPR_NOACCESS
, SPR_NOACCESS
,
5062 &spr_read_generic
, &spr_write_booke206_mmucsr0
,
5064 spr_register(env
, SPR_BOOKE_EPR
, "EPR",
5065 SPR_NOACCESS
, SPR_NOACCESS
,
5066 &spr_read_generic
, SPR_NOACCESS
,
5068 /* XXX better abstract into Emb.xxx features */
5069 if ((version
== fsl_e5500
) || (version
== fsl_e6500
)) {
5070 spr_register(env
, SPR_BOOKE_EPCR
, "EPCR",
5071 SPR_NOACCESS
, SPR_NOACCESS
,
5072 &spr_read_generic
, &spr_write_generic
,
5074 spr_register(env
, SPR_BOOKE_MAS7_MAS3
, "MAS7_MAS3",
5075 SPR_NOACCESS
, SPR_NOACCESS
,
5076 &spr_read_mas73
, &spr_write_mas73
,
5078 ivpr_mask
= (target_ulong
)~0xFFFFULL
;
5081 if (version
== fsl_e6500
) {
5082 spr_register(env
, SPR_BOOKE_SPRG8
, "SPRG8",
5083 SPR_NOACCESS
, SPR_NOACCESS
,
5084 &spr_read_generic
, &spr_write_generic
,
5086 spr_register(env
, SPR_BOOKE_SPRG9
, "SPRG9",
5087 SPR_NOACCESS
, SPR_NOACCESS
,
5088 &spr_read_generic
, &spr_write_generic
,
5090 /* Thread identification */
5091 spr_register(env
, SPR_TIR
, "TIR",
5092 SPR_NOACCESS
, SPR_NOACCESS
,
5093 &spr_read_generic
, SPR_NOACCESS
,
5095 spr_register(env
, SPR_BOOKE_TLB0PS
, "TLB0PS",
5096 SPR_NOACCESS
, SPR_NOACCESS
,
5097 &spr_read_generic
, SPR_NOACCESS
,
5099 spr_register(env
, SPR_BOOKE_TLB1PS
, "TLB1PS",
5100 SPR_NOACCESS
, SPR_NOACCESS
,
5101 &spr_read_generic
, SPR_NOACCESS
,
5105 #if !defined(CONFIG_USER_ONLY)
5107 env
->tlb_type
= TLB_MAS
;
5108 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
5109 env
->nb_tlb
+= booke206_tlb_size(env
, i
);
5113 init_excp_e200(env
, ivpr_mask
);
5114 /* Allocate hardware IRQ controller */
5115 ppce500_irq_init(ppc_env_get_cpu(env
));
5118 static void init_proc_e500v1(CPUPPCState
*env
)
5120 init_proc_e500(env
, fsl_e500v1
);
5123 POWERPC_FAMILY(e500v1
)(ObjectClass
*oc
, void *data
)
5125 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5126 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5128 dc
->desc
= "e500v1 core";
5129 pcc
->init_proc
= init_proc_e500v1
;
5130 pcc
->check_pow
= check_pow_hid0
;
5131 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
5132 PPC_SPE
| PPC_SPE_SINGLE
|
5133 PPC_WRTEE
| PPC_RFDI
|
5134 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5135 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5136 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5137 pcc
->insns_flags2
= PPC2_BOOKE206
;
5138 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
5152 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5153 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5154 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5155 pcc
->bfd_mach
= bfd_mach_ppc_860
;
5156 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
5157 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
5158 POWERPC_FLAG_BUS_CLK
;
5161 static void init_proc_e500v2(CPUPPCState
*env
)
5163 init_proc_e500(env
, fsl_e500v2
);
5166 POWERPC_FAMILY(e500v2
)(ObjectClass
*oc
, void *data
)
5168 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5169 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5171 dc
->desc
= "e500v2 core";
5172 pcc
->init_proc
= init_proc_e500v2
;
5173 pcc
->check_pow
= check_pow_hid0
;
5174 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
5175 PPC_SPE
| PPC_SPE_SINGLE
| PPC_SPE_DOUBLE
|
5176 PPC_WRTEE
| PPC_RFDI
|
5177 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5178 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5179 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5180 pcc
->insns_flags2
= PPC2_BOOKE206
;
5181 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
5195 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5196 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5197 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5198 pcc
->bfd_mach
= bfd_mach_ppc_860
;
5199 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
5200 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
5201 POWERPC_FLAG_BUS_CLK
;
5204 static void init_proc_e500mc(CPUPPCState
*env
)
5206 init_proc_e500(env
, fsl_e500mc
);
5209 POWERPC_FAMILY(e500mc
)(ObjectClass
*oc
, void *data
)
5211 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5212 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5214 dc
->desc
= "e500mc core";
5215 pcc
->init_proc
= init_proc_e500mc
;
5216 pcc
->check_pow
= check_pow_none
;
5217 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5218 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5219 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5220 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5221 PPC_FLOAT
| PPC_FLOAT_FRES
|
5222 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5223 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5224 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5225 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
;
5226 pcc
->msr_mask
= (1ull << MSR_GS
) |
5227 (1ull << MSR_UCLE
) |
5240 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5241 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5242 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5243 /* FIXME: figure out the correct flag for e500mc */
5244 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5245 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5246 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5250 static void init_proc_e5500(CPUPPCState
*env
)
5252 init_proc_e500(env
, fsl_e5500
);
5255 POWERPC_FAMILY(e5500
)(ObjectClass
*oc
, void *data
)
5257 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5258 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5260 dc
->desc
= "e5500 core";
5261 pcc
->init_proc
= init_proc_e5500
;
5262 pcc
->check_pow
= check_pow_none
;
5263 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5264 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5265 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5266 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5267 PPC_FLOAT
| PPC_FLOAT_FRES
|
5268 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5269 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5270 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
|
5271 PPC_64B
| PPC_POPCNTB
| PPC_POPCNTWD
;
5272 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
| PPC2_PERM_ISA206
| \
5274 pcc
->msr_mask
= (1ull << MSR_CM
) |
5276 (1ull << MSR_UCLE
) |
5289 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5290 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5291 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5292 /* FIXME: figure out the correct flag for e5500 */
5293 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5294 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5295 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5298 static void init_proc_e6500(CPUPPCState
*env
)
5300 init_proc_e500(env
, fsl_e6500
);
5303 POWERPC_FAMILY(e6500
)(ObjectClass
*oc
, void *data
)
5305 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5306 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5308 dc
->desc
= "e6500 core";
5309 pcc
->init_proc
= init_proc_e6500
;
5310 pcc
->check_pow
= check_pow_none
;
5311 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5312 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5313 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5314 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5315 PPC_FLOAT
| PPC_FLOAT_FRES
|
5316 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5317 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5318 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
|
5319 PPC_64B
| PPC_POPCNTB
| PPC_POPCNTWD
| PPC_ALTIVEC
;
5320 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
| PPC2_PERM_ISA206
| \
5321 PPC2_FP_CVT_S64
| PPC2_ATOMIC_ISA206
;
5322 pcc
->msr_mask
= (1ull << MSR_CM
) |
5324 (1ull << MSR_UCLE
) |
5338 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5339 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5340 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5341 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5342 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5343 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_VRE
;
5348 /* Non-embedded PowerPC */
5350 #define POWERPC_MSRR_601 (0x0000000000001040ULL)
5352 static void init_proc_601(CPUPPCState
*env
)
5354 gen_spr_ne_601(env
);
5357 /* Hardware implementation registers */
5358 /* XXX : not implemented */
5359 spr_register(env
, SPR_HID0
, "HID0",
5360 SPR_NOACCESS
, SPR_NOACCESS
,
5361 &spr_read_generic
, &spr_write_hid0_601
,
5363 /* XXX : not implemented */
5364 spr_register(env
, SPR_HID1
, "HID1",
5365 SPR_NOACCESS
, SPR_NOACCESS
,
5366 &spr_read_generic
, &spr_write_generic
,
5368 /* XXX : not implemented */
5369 spr_register(env
, SPR_601_HID2
, "HID2",
5370 SPR_NOACCESS
, SPR_NOACCESS
,
5371 &spr_read_generic
, &spr_write_generic
,
5373 /* XXX : not implemented */
5374 spr_register(env
, SPR_601_HID5
, "HID5",
5375 SPR_NOACCESS
, SPR_NOACCESS
,
5376 &spr_read_generic
, &spr_write_generic
,
5378 /* Memory management */
5380 /* XXX: beware that dcache line size is 64
5381 * but dcbz uses 32 bytes "sectors"
5382 * XXX: this breaks clcs instruction !
5384 env
->dcache_line_size
= 32;
5385 env
->icache_line_size
= 64;
5386 /* Allocate hardware IRQ controller */
5387 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5390 POWERPC_FAMILY(601)(ObjectClass
*oc
, void *data
)
5392 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5393 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5395 dc
->desc
= "PowerPC 601";
5396 pcc
->init_proc
= init_proc_601
;
5397 pcc
->check_pow
= check_pow_none
;
5398 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_POWER_BR
|
5400 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5401 PPC_MEM_SYNC
| PPC_MEM_EIEIO
| PPC_MEM_TLBIE
|
5402 PPC_SEGMENT
| PPC_EXTERN
;
5403 pcc
->msr_mask
= (1ull << MSR_EE
) |
5413 pcc
->mmu_model
= POWERPC_MMU_601
;
5414 #if defined(CONFIG_SOFTMMU)
5415 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5417 pcc
->excp_model
= POWERPC_EXCP_601
;
5418 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5419 pcc
->bfd_mach
= bfd_mach_ppc_601
;
5420 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_RTC_CLK
;
5423 #define POWERPC_MSRR_601v (0x0000000000001040ULL)
5425 static void init_proc_601v(CPUPPCState
*env
)
5428 /* XXX : not implemented */
5429 spr_register(env
, SPR_601_HID15
, "HID15",
5430 SPR_NOACCESS
, SPR_NOACCESS
,
5431 &spr_read_generic
, &spr_write_generic
,
5435 POWERPC_FAMILY(601v
)(ObjectClass
*oc
, void *data
)
5437 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5438 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5440 dc
->desc
= "PowerPC 601v";
5441 pcc
->init_proc
= init_proc_601v
;
5442 pcc
->check_pow
= check_pow_none
;
5443 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_POWER_BR
|
5445 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5446 PPC_MEM_SYNC
| PPC_MEM_EIEIO
| PPC_MEM_TLBIE
|
5447 PPC_SEGMENT
| PPC_EXTERN
;
5448 pcc
->msr_mask
= (1ull << MSR_EE
) |
5458 pcc
->mmu_model
= POWERPC_MMU_601
;
5459 #if defined(CONFIG_SOFTMMU)
5460 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5462 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5463 pcc
->bfd_mach
= bfd_mach_ppc_601
;
5464 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_RTC_CLK
;
5467 static void init_proc_602(CPUPPCState
*env
)
5469 gen_spr_ne_601(env
);
5474 /* hardware implementation registers */
5475 /* XXX : not implemented */
5476 spr_register(env
, SPR_HID0
, "HID0",
5477 SPR_NOACCESS
, SPR_NOACCESS
,
5478 &spr_read_generic
, &spr_write_generic
,
5480 /* XXX : not implemented */
5481 spr_register(env
, SPR_HID1
, "HID1",
5482 SPR_NOACCESS
, SPR_NOACCESS
,
5483 &spr_read_generic
, &spr_write_generic
,
5485 /* Memory management */
5487 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5489 env
->dcache_line_size
= 32;
5490 env
->icache_line_size
= 32;
5491 /* Allocate hardware IRQ controller */
5492 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5495 POWERPC_FAMILY(602)(ObjectClass
*oc
, void *data
)
5497 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5498 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5500 dc
->desc
= "PowerPC 602";
5501 pcc
->init_proc
= init_proc_602
;
5502 pcc
->check_pow
= check_pow_hid0
;
5503 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5504 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5505 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5506 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5507 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5508 PPC_MEM_TLBIE
| PPC_6xx_TLB
| PPC_MEM_TLBSYNC
|
5509 PPC_SEGMENT
| PPC_602_SPEC
;
5510 pcc
->msr_mask
= (1ull << MSR_VSX
) |
5513 (1ull << MSR_TGPR
) |
5528 /* XXX: 602 MMU is quite specific. Should add a special case */
5529 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5530 pcc
->excp_model
= POWERPC_EXCP_602
;
5531 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5532 pcc
->bfd_mach
= bfd_mach_ppc_602
;
5533 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5534 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5537 static void init_proc_603(CPUPPCState
*env
)
5539 gen_spr_ne_601(env
);
5544 /* hardware implementation registers */
5545 /* XXX : not implemented */
5546 spr_register(env
, SPR_HID0
, "HID0",
5547 SPR_NOACCESS
, SPR_NOACCESS
,
5548 &spr_read_generic
, &spr_write_generic
,
5550 /* XXX : not implemented */
5551 spr_register(env
, SPR_HID1
, "HID1",
5552 SPR_NOACCESS
, SPR_NOACCESS
,
5553 &spr_read_generic
, &spr_write_generic
,
5555 /* Memory management */
5557 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5559 env
->dcache_line_size
= 32;
5560 env
->icache_line_size
= 32;
5561 /* Allocate hardware IRQ controller */
5562 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5565 POWERPC_FAMILY(603)(ObjectClass
*oc
, void *data
)
5567 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5568 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5570 dc
->desc
= "PowerPC 603";
5571 pcc
->init_proc
= init_proc_603
;
5572 pcc
->check_pow
= check_pow_hid0
;
5573 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5574 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5575 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5576 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5577 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5578 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
5579 PPC_SEGMENT
| PPC_EXTERN
;
5580 pcc
->msr_mask
= (1ull << MSR_POW
) |
5581 (1ull << MSR_TGPR
) |
5596 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5597 pcc
->excp_model
= POWERPC_EXCP_603
;
5598 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5599 pcc
->bfd_mach
= bfd_mach_ppc_603
;
5600 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5601 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5604 static void init_proc_603E(CPUPPCState
*env
)
5606 gen_spr_ne_601(env
);
5611 /* hardware implementation registers */
5612 /* XXX : not implemented */
5613 spr_register(env
, SPR_HID0
, "HID0",
5614 SPR_NOACCESS
, SPR_NOACCESS
,
5615 &spr_read_generic
, &spr_write_generic
,
5617 /* XXX : not implemented */
5618 spr_register(env
, SPR_HID1
, "HID1",
5619 SPR_NOACCESS
, SPR_NOACCESS
,
5620 &spr_read_generic
, &spr_write_generic
,
5622 /* Memory management */
5624 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5626 env
->dcache_line_size
= 32;
5627 env
->icache_line_size
= 32;
5628 /* Allocate hardware IRQ controller */
5629 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5632 POWERPC_FAMILY(603E
)(ObjectClass
*oc
, void *data
)
5634 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5635 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5637 dc
->desc
= "PowerPC 603e";
5638 pcc
->init_proc
= init_proc_603E
;
5639 pcc
->check_pow
= check_pow_hid0
;
5640 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5641 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5642 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5643 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5644 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5645 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
5646 PPC_SEGMENT
| PPC_EXTERN
;
5647 pcc
->msr_mask
= (1ull << MSR_POW
) |
5648 (1ull << MSR_TGPR
) |
5663 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5664 pcc
->excp_model
= POWERPC_EXCP_603E
;
5665 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5666 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
5667 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5668 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5671 static void init_proc_604(CPUPPCState
*env
)
5673 gen_spr_ne_601(env
);
5678 /* Hardware implementation registers */
5679 /* XXX : not implemented */
5680 spr_register(env
, SPR_HID0
, "HID0",
5681 SPR_NOACCESS
, SPR_NOACCESS
,
5682 &spr_read_generic
, &spr_write_generic
,
5684 /* Memory management */
5687 env
->dcache_line_size
= 32;
5688 env
->icache_line_size
= 32;
5689 /* Allocate hardware IRQ controller */
5690 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5693 POWERPC_FAMILY(604)(ObjectClass
*oc
, void *data
)
5695 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5696 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5698 dc
->desc
= "PowerPC 604";
5699 pcc
->init_proc
= init_proc_604
;
5700 pcc
->check_pow
= check_pow_nocheck
;
5701 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5702 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5703 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5704 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5705 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5706 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5707 PPC_SEGMENT
| PPC_EXTERN
;
5708 pcc
->msr_mask
= (1ull << MSR_POW
) |
5724 pcc
->mmu_model
= POWERPC_MMU_32B
;
5725 #if defined(CONFIG_SOFTMMU)
5726 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5728 pcc
->excp_model
= POWERPC_EXCP_604
;
5729 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5730 pcc
->bfd_mach
= bfd_mach_ppc_604
;
5731 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5732 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5735 static void init_proc_604E(CPUPPCState
*env
)
5737 gen_spr_ne_601(env
);
5740 /* XXX : not implemented */
5741 spr_register(env
, SPR_7XX_MMCR1
, "MMCR1",
5742 SPR_NOACCESS
, SPR_NOACCESS
,
5743 &spr_read_generic
, &spr_write_generic
,
5745 /* XXX : not implemented */
5746 spr_register(env
, SPR_7XX_PMC3
, "PMC3",
5747 SPR_NOACCESS
, SPR_NOACCESS
,
5748 &spr_read_generic
, &spr_write_generic
,
5750 /* XXX : not implemented */
5751 spr_register(env
, SPR_7XX_PMC4
, "PMC4",
5752 SPR_NOACCESS
, SPR_NOACCESS
,
5753 &spr_read_generic
, &spr_write_generic
,
5757 /* Hardware implementation registers */
5758 /* XXX : not implemented */
5759 spr_register(env
, SPR_HID0
, "HID0",
5760 SPR_NOACCESS
, SPR_NOACCESS
,
5761 &spr_read_generic
, &spr_write_generic
,
5763 /* XXX : not implemented */
5764 spr_register(env
, SPR_HID1
, "HID1",
5765 SPR_NOACCESS
, SPR_NOACCESS
,
5766 &spr_read_generic
, &spr_write_generic
,
5768 /* Memory management */
5771 env
->dcache_line_size
= 32;
5772 env
->icache_line_size
= 32;
5773 /* Allocate hardware IRQ controller */
5774 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5777 POWERPC_FAMILY(604E
)(ObjectClass
*oc
, void *data
)
5779 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5780 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5782 dc
->desc
= "PowerPC 604E";
5783 pcc
->init_proc
= init_proc_604E
;
5784 pcc
->check_pow
= check_pow_nocheck
;
5785 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5786 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5787 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5788 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5789 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5790 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5791 PPC_SEGMENT
| PPC_EXTERN
;
5792 pcc
->msr_mask
= (1ull << MSR_POW
) |
5808 pcc
->mmu_model
= POWERPC_MMU_32B
;
5809 #if defined(CONFIG_SOFTMMU)
5810 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5812 pcc
->excp_model
= POWERPC_EXCP_604
;
5813 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5814 pcc
->bfd_mach
= bfd_mach_ppc_604
;
5815 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5816 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5819 static void init_proc_740(CPUPPCState
*env
)
5821 gen_spr_ne_601(env
);
5826 /* Thermal management */
5828 /* Hardware implementation registers */
5829 /* XXX : not implemented */
5830 spr_register(env
, SPR_HID0
, "HID0",
5831 SPR_NOACCESS
, SPR_NOACCESS
,
5832 &spr_read_generic
, &spr_write_generic
,
5834 /* XXX : not implemented */
5835 spr_register(env
, SPR_HID1
, "HID1",
5836 SPR_NOACCESS
, SPR_NOACCESS
,
5837 &spr_read_generic
, &spr_write_generic
,
5839 /* Memory management */
5842 env
->dcache_line_size
= 32;
5843 env
->icache_line_size
= 32;
5844 /* Allocate hardware IRQ controller */
5845 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5848 POWERPC_FAMILY(740)(ObjectClass
*oc
, void *data
)
5850 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5851 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5853 dc
->desc
= "PowerPC 740";
5854 pcc
->init_proc
= init_proc_740
;
5855 pcc
->check_pow
= check_pow_hid0
;
5856 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5857 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5858 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5859 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5860 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5861 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5862 PPC_SEGMENT
| PPC_EXTERN
;
5863 pcc
->msr_mask
= (1ull << MSR_POW
) |
5879 pcc
->mmu_model
= POWERPC_MMU_32B
;
5880 #if defined(CONFIG_SOFTMMU)
5881 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5883 pcc
->excp_model
= POWERPC_EXCP_7x0
;
5884 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5885 pcc
->bfd_mach
= bfd_mach_ppc_750
;
5886 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5887 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5890 static void init_proc_750(CPUPPCState
*env
)
5892 gen_spr_ne_601(env
);
5895 /* XXX : not implemented */
5896 spr_register(env
, SPR_L2CR
, "L2CR",
5897 SPR_NOACCESS
, SPR_NOACCESS
,
5898 &spr_read_generic
, spr_access_nop
,
5902 /* Thermal management */
5904 /* Hardware implementation registers */
5905 /* XXX : not implemented */
5906 spr_register(env
, SPR_HID0
, "HID0",
5907 SPR_NOACCESS
, SPR_NOACCESS
,
5908 &spr_read_generic
, &spr_write_generic
,
5910 /* XXX : not implemented */
5911 spr_register(env
, SPR_HID1
, "HID1",
5912 SPR_NOACCESS
, SPR_NOACCESS
,
5913 &spr_read_generic
, &spr_write_generic
,
5915 /* Memory management */
5917 /* XXX: high BATs are also present but are known to be bugged on
5921 env
->dcache_line_size
= 32;
5922 env
->icache_line_size
= 32;
5923 /* Allocate hardware IRQ controller */
5924 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5927 POWERPC_FAMILY(750)(ObjectClass
*oc
, void *data
)
5929 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5930 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5932 dc
->desc
= "PowerPC 750";
5933 pcc
->init_proc
= init_proc_750
;
5934 pcc
->check_pow
= check_pow_hid0
;
5935 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5936 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5937 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5938 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5939 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5940 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5941 PPC_SEGMENT
| PPC_EXTERN
;
5942 pcc
->msr_mask
= (1ull << MSR_POW
) |
5958 pcc
->mmu_model
= POWERPC_MMU_32B
;
5959 #if defined(CONFIG_SOFTMMU)
5960 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5962 pcc
->excp_model
= POWERPC_EXCP_7x0
;
5963 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5964 pcc
->bfd_mach
= bfd_mach_ppc_750
;
5965 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5966 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5969 static void init_proc_750cl(CPUPPCState
*env
)
5971 gen_spr_ne_601(env
);
5974 /* XXX : not implemented */
5975 spr_register(env
, SPR_L2CR
, "L2CR",
5976 SPR_NOACCESS
, SPR_NOACCESS
,
5977 &spr_read_generic
, spr_access_nop
,
5981 /* Thermal management */
5982 /* Those registers are fake on 750CL */
5983 spr_register(env
, SPR_THRM1
, "THRM1",
5984 SPR_NOACCESS
, SPR_NOACCESS
,
5985 &spr_read_generic
, &spr_write_generic
,
5987 spr_register(env
, SPR_THRM2
, "THRM2",
5988 SPR_NOACCESS
, SPR_NOACCESS
,
5989 &spr_read_generic
, &spr_write_generic
,
5991 spr_register(env
, SPR_THRM3
, "THRM3",
5992 SPR_NOACCESS
, SPR_NOACCESS
,
5993 &spr_read_generic
, &spr_write_generic
,
5995 /* XXX: not implemented */
5996 spr_register(env
, SPR_750_TDCL
, "TDCL",
5997 SPR_NOACCESS
, SPR_NOACCESS
,
5998 &spr_read_generic
, &spr_write_generic
,
6000 spr_register(env
, SPR_750_TDCH
, "TDCH",
6001 SPR_NOACCESS
, SPR_NOACCESS
,
6002 &spr_read_generic
, &spr_write_generic
,
6005 /* XXX : not implemented */
6006 spr_register(env
, SPR_750_WPAR
, "WPAR",
6007 SPR_NOACCESS
, SPR_NOACCESS
,
6008 &spr_read_generic
, &spr_write_generic
,
6010 spr_register(env
, SPR_750_DMAL
, "DMAL",
6011 SPR_NOACCESS
, SPR_NOACCESS
,
6012 &spr_read_generic
, &spr_write_generic
,
6014 spr_register(env
, SPR_750_DMAU
, "DMAU",
6015 SPR_NOACCESS
, SPR_NOACCESS
,
6016 &spr_read_generic
, &spr_write_generic
,
6018 /* Hardware implementation registers */
6019 /* XXX : not implemented */
6020 spr_register(env
, SPR_HID0
, "HID0",
6021 SPR_NOACCESS
, SPR_NOACCESS
,
6022 &spr_read_generic
, &spr_write_generic
,
6024 /* XXX : not implemented */
6025 spr_register(env
, SPR_HID1
, "HID1",
6026 SPR_NOACCESS
, SPR_NOACCESS
,
6027 &spr_read_generic
, &spr_write_generic
,
6029 /* XXX : not implemented */
6030 spr_register(env
, SPR_750CL_HID2
, "HID2",
6031 SPR_NOACCESS
, SPR_NOACCESS
,
6032 &spr_read_generic
, &spr_write_generic
,
6034 /* XXX : not implemented */
6035 spr_register(env
, SPR_750CL_HID4
, "HID4",
6036 SPR_NOACCESS
, SPR_NOACCESS
,
6037 &spr_read_generic
, &spr_write_generic
,
6039 /* Quantization registers */
6040 /* XXX : not implemented */
6041 spr_register(env
, SPR_750_GQR0
, "GQR0",
6042 SPR_NOACCESS
, SPR_NOACCESS
,
6043 &spr_read_generic
, &spr_write_generic
,
6045 /* XXX : not implemented */
6046 spr_register(env
, SPR_750_GQR1
, "GQR1",
6047 SPR_NOACCESS
, SPR_NOACCESS
,
6048 &spr_read_generic
, &spr_write_generic
,
6050 /* XXX : not implemented */
6051 spr_register(env
, SPR_750_GQR2
, "GQR2",
6052 SPR_NOACCESS
, SPR_NOACCESS
,
6053 &spr_read_generic
, &spr_write_generic
,
6055 /* XXX : not implemented */
6056 spr_register(env
, SPR_750_GQR3
, "GQR3",
6057 SPR_NOACCESS
, SPR_NOACCESS
,
6058 &spr_read_generic
, &spr_write_generic
,
6060 /* XXX : not implemented */
6061 spr_register(env
, SPR_750_GQR4
, "GQR4",
6062 SPR_NOACCESS
, SPR_NOACCESS
,
6063 &spr_read_generic
, &spr_write_generic
,
6065 /* XXX : not implemented */
6066 spr_register(env
, SPR_750_GQR5
, "GQR5",
6067 SPR_NOACCESS
, SPR_NOACCESS
,
6068 &spr_read_generic
, &spr_write_generic
,
6070 /* XXX : not implemented */
6071 spr_register(env
, SPR_750_GQR6
, "GQR6",
6072 SPR_NOACCESS
, SPR_NOACCESS
,
6073 &spr_read_generic
, &spr_write_generic
,
6075 /* XXX : not implemented */
6076 spr_register(env
, SPR_750_GQR7
, "GQR7",
6077 SPR_NOACCESS
, SPR_NOACCESS
,
6078 &spr_read_generic
, &spr_write_generic
,
6080 /* Memory management */
6082 /* PowerPC 750cl has 8 DBATs and 8 IBATs */
6084 init_excp_750cl(env
);
6085 env
->dcache_line_size
= 32;
6086 env
->icache_line_size
= 32;
6087 /* Allocate hardware IRQ controller */
6088 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6091 POWERPC_FAMILY(750cl
)(ObjectClass
*oc
, void *data
)
6093 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6094 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6096 dc
->desc
= "PowerPC 750 CL";
6097 pcc
->init_proc
= init_proc_750cl
;
6098 pcc
->check_pow
= check_pow_hid0
;
6099 /* XXX: not implemented:
6100 * cache lock instructions:
6102 * floating point paired instructions
6137 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6138 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6139 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6140 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6141 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6142 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6143 PPC_SEGMENT
| PPC_EXTERN
;
6144 pcc
->msr_mask
= (1ull << MSR_POW
) |
6160 pcc
->mmu_model
= POWERPC_MMU_32B
;
6161 #if defined(CONFIG_SOFTMMU)
6162 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6164 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6165 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6166 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6167 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6168 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6171 static void init_proc_750cx(CPUPPCState
*env
)
6173 gen_spr_ne_601(env
);
6176 /* XXX : not implemented */
6177 spr_register(env
, SPR_L2CR
, "L2CR",
6178 SPR_NOACCESS
, SPR_NOACCESS
,
6179 &spr_read_generic
, spr_access_nop
,
6183 /* Thermal management */
6185 /* This register is not implemented but is present for compatibility */
6186 spr_register(env
, SPR_SDA
, "SDA",
6187 SPR_NOACCESS
, SPR_NOACCESS
,
6188 &spr_read_generic
, &spr_write_generic
,
6190 /* Hardware implementation registers */
6191 /* XXX : not implemented */
6192 spr_register(env
, SPR_HID0
, "HID0",
6193 SPR_NOACCESS
, SPR_NOACCESS
,
6194 &spr_read_generic
, &spr_write_generic
,
6196 /* XXX : not implemented */
6197 spr_register(env
, SPR_HID1
, "HID1",
6198 SPR_NOACCESS
, SPR_NOACCESS
,
6199 &spr_read_generic
, &spr_write_generic
,
6201 /* Memory management */
6203 /* PowerPC 750cx has 8 DBATs and 8 IBATs */
6205 init_excp_750cx(env
);
6206 env
->dcache_line_size
= 32;
6207 env
->icache_line_size
= 32;
6208 /* Allocate hardware IRQ controller */
6209 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6212 POWERPC_FAMILY(750cx
)(ObjectClass
*oc
, void *data
)
6214 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6215 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6217 dc
->desc
= "PowerPC 750CX";
6218 pcc
->init_proc
= init_proc_750cx
;
6219 pcc
->check_pow
= check_pow_hid0
;
6220 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6221 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6222 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6223 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6224 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6225 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6226 PPC_SEGMENT
| PPC_EXTERN
;
6227 pcc
->msr_mask
= (1ull << MSR_POW
) |
6243 pcc
->mmu_model
= POWERPC_MMU_32B
;
6244 #if defined(CONFIG_SOFTMMU)
6245 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6247 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6248 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6249 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6250 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6251 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6254 static void init_proc_750fx(CPUPPCState
*env
)
6256 gen_spr_ne_601(env
);
6259 /* XXX : not implemented */
6260 spr_register(env
, SPR_L2CR
, "L2CR",
6261 SPR_NOACCESS
, SPR_NOACCESS
,
6262 &spr_read_generic
, spr_access_nop
,
6266 /* Thermal management */
6268 /* XXX : not implemented */
6269 spr_register(env
, SPR_750_THRM4
, "THRM4",
6270 SPR_NOACCESS
, SPR_NOACCESS
,
6271 &spr_read_generic
, &spr_write_generic
,
6273 /* Hardware implementation registers */
6274 /* XXX : not implemented */
6275 spr_register(env
, SPR_HID0
, "HID0",
6276 SPR_NOACCESS
, SPR_NOACCESS
,
6277 &spr_read_generic
, &spr_write_generic
,
6279 /* XXX : not implemented */
6280 spr_register(env
, SPR_HID1
, "HID1",
6281 SPR_NOACCESS
, SPR_NOACCESS
,
6282 &spr_read_generic
, &spr_write_generic
,
6284 /* XXX : not implemented */
6285 spr_register(env
, SPR_750FX_HID2
, "HID2",
6286 SPR_NOACCESS
, SPR_NOACCESS
,
6287 &spr_read_generic
, &spr_write_generic
,
6289 /* Memory management */
6291 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6294 env
->dcache_line_size
= 32;
6295 env
->icache_line_size
= 32;
6296 /* Allocate hardware IRQ controller */
6297 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6300 POWERPC_FAMILY(750fx
)(ObjectClass
*oc
, void *data
)
6302 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6303 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6305 dc
->desc
= "PowerPC 750FX";
6306 pcc
->init_proc
= init_proc_750fx
;
6307 pcc
->check_pow
= check_pow_hid0
;
6308 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6309 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6310 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6311 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6312 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6313 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6314 PPC_SEGMENT
| PPC_EXTERN
;
6315 pcc
->msr_mask
= (1ull << MSR_POW
) |
6331 pcc
->mmu_model
= POWERPC_MMU_32B
;
6332 #if defined(CONFIG_SOFTMMU)
6333 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6335 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6336 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6337 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6338 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6339 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6342 static void init_proc_750gx(CPUPPCState
*env
)
6344 gen_spr_ne_601(env
);
6347 /* XXX : not implemented (XXX: different from 750fx) */
6348 spr_register(env
, SPR_L2CR
, "L2CR",
6349 SPR_NOACCESS
, SPR_NOACCESS
,
6350 &spr_read_generic
, spr_access_nop
,
6354 /* Thermal management */
6356 /* XXX : not implemented */
6357 spr_register(env
, SPR_750_THRM4
, "THRM4",
6358 SPR_NOACCESS
, SPR_NOACCESS
,
6359 &spr_read_generic
, &spr_write_generic
,
6361 /* Hardware implementation registers */
6362 /* XXX : not implemented (XXX: different from 750fx) */
6363 spr_register(env
, SPR_HID0
, "HID0",
6364 SPR_NOACCESS
, SPR_NOACCESS
,
6365 &spr_read_generic
, &spr_write_generic
,
6367 /* XXX : not implemented */
6368 spr_register(env
, SPR_HID1
, "HID1",
6369 SPR_NOACCESS
, SPR_NOACCESS
,
6370 &spr_read_generic
, &spr_write_generic
,
6372 /* XXX : not implemented (XXX: different from 750fx) */
6373 spr_register(env
, SPR_750FX_HID2
, "HID2",
6374 SPR_NOACCESS
, SPR_NOACCESS
,
6375 &spr_read_generic
, &spr_write_generic
,
6377 /* Memory management */
6379 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6382 env
->dcache_line_size
= 32;
6383 env
->icache_line_size
= 32;
6384 /* Allocate hardware IRQ controller */
6385 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6388 POWERPC_FAMILY(750gx
)(ObjectClass
*oc
, void *data
)
6390 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6391 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6393 dc
->desc
= "PowerPC 750GX";
6394 pcc
->init_proc
= init_proc_750gx
;
6395 pcc
->check_pow
= check_pow_hid0
;
6396 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6397 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6398 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6399 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6400 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6401 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6402 PPC_SEGMENT
| PPC_EXTERN
;
6403 pcc
->msr_mask
= (1ull << MSR_POW
) |
6419 pcc
->mmu_model
= POWERPC_MMU_32B
;
6420 #if defined(CONFIG_SOFTMMU)
6421 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6423 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6424 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6425 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6426 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6427 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6430 static void init_proc_745(CPUPPCState
*env
)
6432 gen_spr_ne_601(env
);
6435 gen_spr_G2_755(env
);
6438 /* Thermal management */
6440 /* Hardware implementation registers */
6441 /* XXX : not implemented */
6442 spr_register(env
, SPR_HID0
, "HID0",
6443 SPR_NOACCESS
, SPR_NOACCESS
,
6444 &spr_read_generic
, &spr_write_generic
,
6446 /* XXX : not implemented */
6447 spr_register(env
, SPR_HID1
, "HID1",
6448 SPR_NOACCESS
, SPR_NOACCESS
,
6449 &spr_read_generic
, &spr_write_generic
,
6451 /* XXX : not implemented */
6452 spr_register(env
, SPR_HID2
, "HID2",
6453 SPR_NOACCESS
, SPR_NOACCESS
,
6454 &spr_read_generic
, &spr_write_generic
,
6456 /* Memory management */
6459 gen_6xx_7xx_soft_tlb(env
, 64, 2);
6461 env
->dcache_line_size
= 32;
6462 env
->icache_line_size
= 32;
6463 /* Allocate hardware IRQ controller */
6464 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6467 POWERPC_FAMILY(745)(ObjectClass
*oc
, void *data
)
6469 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6470 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6472 dc
->desc
= "PowerPC 745";
6473 pcc
->init_proc
= init_proc_745
;
6474 pcc
->check_pow
= check_pow_hid0
;
6475 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6476 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6477 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6478 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6479 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6480 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
6481 PPC_SEGMENT
| PPC_EXTERN
;
6482 pcc
->msr_mask
= (1ull << MSR_POW
) |
6498 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
6499 pcc
->excp_model
= POWERPC_EXCP_7x5
;
6500 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6501 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6502 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6503 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6506 static void init_proc_755(CPUPPCState
*env
)
6508 gen_spr_ne_601(env
);
6511 gen_spr_G2_755(env
);
6514 /* L2 cache control */
6515 /* XXX : not implemented */
6516 spr_register(env
, SPR_L2CR
, "L2CR",
6517 SPR_NOACCESS
, SPR_NOACCESS
,
6518 &spr_read_generic
, spr_access_nop
,
6520 /* XXX : not implemented */
6521 spr_register(env
, SPR_L2PMCR
, "L2PMCR",
6522 SPR_NOACCESS
, SPR_NOACCESS
,
6523 &spr_read_generic
, &spr_write_generic
,
6525 /* Thermal management */
6527 /* Hardware implementation registers */
6528 /* XXX : not implemented */
6529 spr_register(env
, SPR_HID0
, "HID0",
6530 SPR_NOACCESS
, SPR_NOACCESS
,
6531 &spr_read_generic
, &spr_write_generic
,
6533 /* XXX : not implemented */
6534 spr_register(env
, SPR_HID1
, "HID1",
6535 SPR_NOACCESS
, SPR_NOACCESS
,
6536 &spr_read_generic
, &spr_write_generic
,
6538 /* XXX : not implemented */
6539 spr_register(env
, SPR_HID2
, "HID2",
6540 SPR_NOACCESS
, SPR_NOACCESS
,
6541 &spr_read_generic
, &spr_write_generic
,
6543 /* Memory management */
6546 gen_6xx_7xx_soft_tlb(env
, 64, 2);
6548 env
->dcache_line_size
= 32;
6549 env
->icache_line_size
= 32;
6550 /* Allocate hardware IRQ controller */
6551 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6554 POWERPC_FAMILY(755)(ObjectClass
*oc
, void *data
)
6556 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6557 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6559 dc
->desc
= "PowerPC 755";
6560 pcc
->init_proc
= init_proc_755
;
6561 pcc
->check_pow
= check_pow_hid0
;
6562 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6563 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6564 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6565 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6566 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6567 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
6568 PPC_SEGMENT
| PPC_EXTERN
;
6569 pcc
->msr_mask
= (1ull << MSR_POW
) |
6585 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
6586 pcc
->excp_model
= POWERPC_EXCP_7x5
;
6587 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6588 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6589 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6590 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6593 static void init_proc_7400(CPUPPCState
*env
)
6595 gen_spr_ne_601(env
);
6600 /* 74xx specific SPR */
6602 /* XXX : not implemented */
6603 spr_register(env
, SPR_UBAMR
, "UBAMR",
6604 &spr_read_ureg
, SPR_NOACCESS
,
6605 &spr_read_ureg
, SPR_NOACCESS
,
6607 /* XXX: this seems not implemented on all revisions. */
6608 /* XXX : not implemented */
6609 spr_register(env
, SPR_MSSCR1
, "MSSCR1",
6610 SPR_NOACCESS
, SPR_NOACCESS
,
6611 &spr_read_generic
, &spr_write_generic
,
6613 /* Thermal management */
6615 /* Memory management */
6617 init_excp_7400(env
);
6618 env
->dcache_line_size
= 32;
6619 env
->icache_line_size
= 32;
6620 /* Allocate hardware IRQ controller */
6621 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6624 POWERPC_FAMILY(7400)(ObjectClass
*oc
, void *data
)
6626 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6627 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6629 dc
->desc
= "PowerPC 7400 (aka G4)";
6630 pcc
->init_proc
= init_proc_7400
;
6631 pcc
->check_pow
= check_pow_hid0
;
6632 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6633 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6634 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6636 PPC_CACHE
| PPC_CACHE_ICBI
|
6637 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6638 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6639 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6641 PPC_SEGMENT
| PPC_EXTERN
|
6643 pcc
->msr_mask
= (1ull << MSR_VR
) |
6660 pcc
->mmu_model
= POWERPC_MMU_32B
;
6661 #if defined(CONFIG_SOFTMMU)
6662 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6664 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6665 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6666 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6667 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6668 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6669 POWERPC_FLAG_BUS_CLK
;
6672 static void init_proc_7410(CPUPPCState
*env
)
6674 gen_spr_ne_601(env
);
6679 /* 74xx specific SPR */
6681 /* XXX : not implemented */
6682 spr_register(env
, SPR_UBAMR
, "UBAMR",
6683 &spr_read_ureg
, SPR_NOACCESS
,
6684 &spr_read_ureg
, SPR_NOACCESS
,
6686 /* Thermal management */
6689 /* XXX : not implemented */
6690 spr_register(env
, SPR_L2PMCR
, "L2PMCR",
6691 SPR_NOACCESS
, SPR_NOACCESS
,
6692 &spr_read_generic
, &spr_write_generic
,
6695 /* XXX : not implemented */
6696 spr_register(env
, SPR_LDSTDB
, "LDSTDB",
6697 SPR_NOACCESS
, SPR_NOACCESS
,
6698 &spr_read_generic
, &spr_write_generic
,
6700 /* Memory management */
6702 init_excp_7400(env
);
6703 env
->dcache_line_size
= 32;
6704 env
->icache_line_size
= 32;
6705 /* Allocate hardware IRQ controller */
6706 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6709 POWERPC_FAMILY(7410)(ObjectClass
*oc
, void *data
)
6711 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6712 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6714 dc
->desc
= "PowerPC 7410 (aka G4)";
6715 pcc
->init_proc
= init_proc_7410
;
6716 pcc
->check_pow
= check_pow_hid0
;
6717 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6718 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6719 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6721 PPC_CACHE
| PPC_CACHE_ICBI
|
6722 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6723 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6724 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6726 PPC_SEGMENT
| PPC_EXTERN
|
6728 pcc
->msr_mask
= (1ull << MSR_VR
) |
6745 pcc
->mmu_model
= POWERPC_MMU_32B
;
6746 #if defined(CONFIG_SOFTMMU)
6747 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6749 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6750 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6751 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6752 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6753 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6754 POWERPC_FLAG_BUS_CLK
;
6757 static void init_proc_7440(CPUPPCState
*env
)
6759 gen_spr_ne_601(env
);
6764 /* 74xx specific SPR */
6766 /* XXX : not implemented */
6767 spr_register(env
, SPR_UBAMR
, "UBAMR",
6768 &spr_read_ureg
, SPR_NOACCESS
,
6769 &spr_read_ureg
, SPR_NOACCESS
,
6772 /* XXX : not implemented */
6773 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6774 SPR_NOACCESS
, SPR_NOACCESS
,
6775 &spr_read_generic
, &spr_write_generic
,
6778 /* XXX : not implemented */
6779 spr_register(env
, SPR_ICTRL
, "ICTRL",
6780 SPR_NOACCESS
, SPR_NOACCESS
,
6781 &spr_read_generic
, &spr_write_generic
,
6784 /* XXX : not implemented */
6785 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6786 SPR_NOACCESS
, SPR_NOACCESS
,
6787 &spr_read_generic
, &spr_write_generic
,
6790 /* XXX : not implemented */
6791 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6792 SPR_NOACCESS
, SPR_NOACCESS
,
6793 &spr_read_generic
, &spr_write_generic
,
6795 /* XXX : not implemented */
6796 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6797 &spr_read_ureg
, SPR_NOACCESS
,
6798 &spr_read_ureg
, SPR_NOACCESS
,
6800 /* XXX : not implemented */
6801 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6802 SPR_NOACCESS
, SPR_NOACCESS
,
6803 &spr_read_generic
, &spr_write_generic
,
6805 /* XXX : not implemented */
6806 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6807 &spr_read_ureg
, SPR_NOACCESS
,
6808 &spr_read_ureg
, SPR_NOACCESS
,
6810 /* Memory management */
6812 gen_74xx_soft_tlb(env
, 128, 2);
6813 init_excp_7450(env
);
6814 env
->dcache_line_size
= 32;
6815 env
->icache_line_size
= 32;
6816 /* Allocate hardware IRQ controller */
6817 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6820 POWERPC_FAMILY(7440)(ObjectClass
*oc
, void *data
)
6822 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6823 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6825 dc
->desc
= "PowerPC 7440 (aka G4)";
6826 pcc
->init_proc
= init_proc_7440
;
6827 pcc
->check_pow
= check_pow_hid0_74xx
;
6828 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6829 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6830 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6832 PPC_CACHE
| PPC_CACHE_ICBI
|
6833 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6834 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6835 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6836 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6837 PPC_SEGMENT
| PPC_EXTERN
|
6839 pcc
->msr_mask
= (1ull << MSR_VR
) |
6856 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6857 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6858 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6859 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6860 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6861 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6862 POWERPC_FLAG_BUS_CLK
;
6865 static void init_proc_7450(CPUPPCState
*env
)
6867 gen_spr_ne_601(env
);
6872 /* 74xx specific SPR */
6874 /* Level 3 cache control */
6877 /* XXX : not implemented */
6878 spr_register(env
, SPR_L3ITCR1
, "L3ITCR1",
6879 SPR_NOACCESS
, SPR_NOACCESS
,
6880 &spr_read_generic
, &spr_write_generic
,
6883 /* XXX : not implemented */
6884 spr_register(env
, SPR_L3ITCR2
, "L3ITCR2",
6885 SPR_NOACCESS
, SPR_NOACCESS
,
6886 &spr_read_generic
, &spr_write_generic
,
6889 /* XXX : not implemented */
6890 spr_register(env
, SPR_L3ITCR3
, "L3ITCR3",
6891 SPR_NOACCESS
, SPR_NOACCESS
,
6892 &spr_read_generic
, &spr_write_generic
,
6895 /* XXX : not implemented */
6896 spr_register(env
, SPR_L3OHCR
, "L3OHCR",
6897 SPR_NOACCESS
, SPR_NOACCESS
,
6898 &spr_read_generic
, &spr_write_generic
,
6900 /* XXX : not implemented */
6901 spr_register(env
, SPR_UBAMR
, "UBAMR",
6902 &spr_read_ureg
, SPR_NOACCESS
,
6903 &spr_read_ureg
, SPR_NOACCESS
,
6906 /* XXX : not implemented */
6907 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6908 SPR_NOACCESS
, SPR_NOACCESS
,
6909 &spr_read_generic
, &spr_write_generic
,
6912 /* XXX : not implemented */
6913 spr_register(env
, SPR_ICTRL
, "ICTRL",
6914 SPR_NOACCESS
, SPR_NOACCESS
,
6915 &spr_read_generic
, &spr_write_generic
,
6918 /* XXX : not implemented */
6919 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6920 SPR_NOACCESS
, SPR_NOACCESS
,
6921 &spr_read_generic
, &spr_write_generic
,
6924 /* XXX : not implemented */
6925 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6926 SPR_NOACCESS
, SPR_NOACCESS
,
6927 &spr_read_generic
, &spr_write_generic
,
6929 /* XXX : not implemented */
6930 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6931 &spr_read_ureg
, SPR_NOACCESS
,
6932 &spr_read_ureg
, SPR_NOACCESS
,
6934 /* XXX : not implemented */
6935 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6936 SPR_NOACCESS
, SPR_NOACCESS
,
6937 &spr_read_generic
, &spr_write_generic
,
6939 /* XXX : not implemented */
6940 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6941 &spr_read_ureg
, SPR_NOACCESS
,
6942 &spr_read_ureg
, SPR_NOACCESS
,
6944 /* Memory management */
6946 gen_74xx_soft_tlb(env
, 128, 2);
6947 init_excp_7450(env
);
6948 env
->dcache_line_size
= 32;
6949 env
->icache_line_size
= 32;
6950 /* Allocate hardware IRQ controller */
6951 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6954 POWERPC_FAMILY(7450)(ObjectClass
*oc
, void *data
)
6956 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6957 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6959 dc
->desc
= "PowerPC 7450 (aka G4)";
6960 pcc
->init_proc
= init_proc_7450
;
6961 pcc
->check_pow
= check_pow_hid0_74xx
;
6962 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6963 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6964 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6966 PPC_CACHE
| PPC_CACHE_ICBI
|
6967 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6968 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6969 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6970 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6971 PPC_SEGMENT
| PPC_EXTERN
|
6973 pcc
->msr_mask
= (1ull << MSR_VR
) |
6990 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6991 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6992 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6993 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6994 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6995 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6996 POWERPC_FLAG_BUS_CLK
;
6999 static void init_proc_7445(CPUPPCState
*env
)
7001 gen_spr_ne_601(env
);
7006 /* 74xx specific SPR */
7009 /* XXX : not implemented */
7010 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7011 SPR_NOACCESS
, SPR_NOACCESS
,
7012 &spr_read_generic
, &spr_write_generic
,
7015 /* XXX : not implemented */
7016 spr_register(env
, SPR_ICTRL
, "ICTRL",
7017 SPR_NOACCESS
, SPR_NOACCESS
,
7018 &spr_read_generic
, &spr_write_generic
,
7021 /* XXX : not implemented */
7022 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7023 SPR_NOACCESS
, SPR_NOACCESS
,
7024 &spr_read_generic
, &spr_write_generic
,
7027 /* XXX : not implemented */
7028 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7029 SPR_NOACCESS
, SPR_NOACCESS
,
7030 &spr_read_generic
, &spr_write_generic
,
7032 /* XXX : not implemented */
7033 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7034 &spr_read_ureg
, SPR_NOACCESS
,
7035 &spr_read_ureg
, SPR_NOACCESS
,
7037 /* XXX : not implemented */
7038 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7039 SPR_NOACCESS
, SPR_NOACCESS
,
7040 &spr_read_generic
, &spr_write_generic
,
7042 /* XXX : not implemented */
7043 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7044 &spr_read_ureg
, SPR_NOACCESS
,
7045 &spr_read_ureg
, SPR_NOACCESS
,
7048 spr_register(env
, SPR_SPRG4
, "SPRG4",
7049 SPR_NOACCESS
, SPR_NOACCESS
,
7050 &spr_read_generic
, &spr_write_generic
,
7052 spr_register(env
, SPR_USPRG4
, "USPRG4",
7053 &spr_read_ureg
, SPR_NOACCESS
,
7054 &spr_read_ureg
, SPR_NOACCESS
,
7056 spr_register(env
, SPR_SPRG5
, "SPRG5",
7057 SPR_NOACCESS
, SPR_NOACCESS
,
7058 &spr_read_generic
, &spr_write_generic
,
7060 spr_register(env
, SPR_USPRG5
, "USPRG5",
7061 &spr_read_ureg
, SPR_NOACCESS
,
7062 &spr_read_ureg
, SPR_NOACCESS
,
7064 spr_register(env
, SPR_SPRG6
, "SPRG6",
7065 SPR_NOACCESS
, SPR_NOACCESS
,
7066 &spr_read_generic
, &spr_write_generic
,
7068 spr_register(env
, SPR_USPRG6
, "USPRG6",
7069 &spr_read_ureg
, SPR_NOACCESS
,
7070 &spr_read_ureg
, SPR_NOACCESS
,
7072 spr_register(env
, SPR_SPRG7
, "SPRG7",
7073 SPR_NOACCESS
, SPR_NOACCESS
,
7074 &spr_read_generic
, &spr_write_generic
,
7076 spr_register(env
, SPR_USPRG7
, "USPRG7",
7077 &spr_read_ureg
, SPR_NOACCESS
,
7078 &spr_read_ureg
, SPR_NOACCESS
,
7080 /* Memory management */
7083 gen_74xx_soft_tlb(env
, 128, 2);
7084 init_excp_7450(env
);
7085 env
->dcache_line_size
= 32;
7086 env
->icache_line_size
= 32;
7087 /* Allocate hardware IRQ controller */
7088 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7091 POWERPC_FAMILY(7445)(ObjectClass
*oc
, void *data
)
7093 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7094 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7096 dc
->desc
= "PowerPC 7445 (aka G4)";
7097 pcc
->init_proc
= init_proc_7445
;
7098 pcc
->check_pow
= check_pow_hid0_74xx
;
7099 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7100 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7101 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7103 PPC_CACHE
| PPC_CACHE_ICBI
|
7104 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7105 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7106 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7107 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7108 PPC_SEGMENT
| PPC_EXTERN
|
7110 pcc
->msr_mask
= (1ull << MSR_VR
) |
7127 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7128 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7129 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7130 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7131 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7132 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7133 POWERPC_FLAG_BUS_CLK
;
7136 static void init_proc_7455(CPUPPCState
*env
)
7138 gen_spr_ne_601(env
);
7143 /* 74xx specific SPR */
7145 /* Level 3 cache control */
7148 /* XXX : not implemented */
7149 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7150 SPR_NOACCESS
, SPR_NOACCESS
,
7151 &spr_read_generic
, &spr_write_generic
,
7154 /* XXX : not implemented */
7155 spr_register(env
, SPR_ICTRL
, "ICTRL",
7156 SPR_NOACCESS
, SPR_NOACCESS
,
7157 &spr_read_generic
, &spr_write_generic
,
7160 /* XXX : not implemented */
7161 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7162 SPR_NOACCESS
, SPR_NOACCESS
,
7163 &spr_read_generic
, &spr_write_generic
,
7166 /* XXX : not implemented */
7167 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7168 SPR_NOACCESS
, SPR_NOACCESS
,
7169 &spr_read_generic
, &spr_write_generic
,
7171 /* XXX : not implemented */
7172 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7173 &spr_read_ureg
, SPR_NOACCESS
,
7174 &spr_read_ureg
, SPR_NOACCESS
,
7176 /* XXX : not implemented */
7177 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7178 SPR_NOACCESS
, SPR_NOACCESS
,
7179 &spr_read_generic
, &spr_write_generic
,
7181 /* XXX : not implemented */
7182 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7183 &spr_read_ureg
, SPR_NOACCESS
,
7184 &spr_read_ureg
, SPR_NOACCESS
,
7187 spr_register(env
, SPR_SPRG4
, "SPRG4",
7188 SPR_NOACCESS
, SPR_NOACCESS
,
7189 &spr_read_generic
, &spr_write_generic
,
7191 spr_register(env
, SPR_USPRG4
, "USPRG4",
7192 &spr_read_ureg
, SPR_NOACCESS
,
7193 &spr_read_ureg
, SPR_NOACCESS
,
7195 spr_register(env
, SPR_SPRG5
, "SPRG5",
7196 SPR_NOACCESS
, SPR_NOACCESS
,
7197 &spr_read_generic
, &spr_write_generic
,
7199 spr_register(env
, SPR_USPRG5
, "USPRG5",
7200 &spr_read_ureg
, SPR_NOACCESS
,
7201 &spr_read_ureg
, SPR_NOACCESS
,
7203 spr_register(env
, SPR_SPRG6
, "SPRG6",
7204 SPR_NOACCESS
, SPR_NOACCESS
,
7205 &spr_read_generic
, &spr_write_generic
,
7207 spr_register(env
, SPR_USPRG6
, "USPRG6",
7208 &spr_read_ureg
, SPR_NOACCESS
,
7209 &spr_read_ureg
, SPR_NOACCESS
,
7211 spr_register(env
, SPR_SPRG7
, "SPRG7",
7212 SPR_NOACCESS
, SPR_NOACCESS
,
7213 &spr_read_generic
, &spr_write_generic
,
7215 spr_register(env
, SPR_USPRG7
, "USPRG7",
7216 &spr_read_ureg
, SPR_NOACCESS
,
7217 &spr_read_ureg
, SPR_NOACCESS
,
7219 /* Memory management */
7222 gen_74xx_soft_tlb(env
, 128, 2);
7223 init_excp_7450(env
);
7224 env
->dcache_line_size
= 32;
7225 env
->icache_line_size
= 32;
7226 /* Allocate hardware IRQ controller */
7227 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7230 POWERPC_FAMILY(7455)(ObjectClass
*oc
, void *data
)
7232 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7233 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7235 dc
->desc
= "PowerPC 7455 (aka G4)";
7236 pcc
->init_proc
= init_proc_7455
;
7237 pcc
->check_pow
= check_pow_hid0_74xx
;
7238 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7239 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7240 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7242 PPC_CACHE
| PPC_CACHE_ICBI
|
7243 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7244 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7245 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7246 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7247 PPC_SEGMENT
| PPC_EXTERN
|
7249 pcc
->msr_mask
= (1ull << MSR_VR
) |
7266 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7267 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7268 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7269 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7270 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7271 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7272 POWERPC_FLAG_BUS_CLK
;
7275 static void init_proc_7457(CPUPPCState
*env
)
7277 gen_spr_ne_601(env
);
7282 /* 74xx specific SPR */
7284 /* Level 3 cache control */
7287 /* XXX : not implemented */
7288 spr_register(env
, SPR_L3ITCR1
, "L3ITCR1",
7289 SPR_NOACCESS
, SPR_NOACCESS
,
7290 &spr_read_generic
, &spr_write_generic
,
7293 /* XXX : not implemented */
7294 spr_register(env
, SPR_L3ITCR2
, "L3ITCR2",
7295 SPR_NOACCESS
, SPR_NOACCESS
,
7296 &spr_read_generic
, &spr_write_generic
,
7299 /* XXX : not implemented */
7300 spr_register(env
, SPR_L3ITCR3
, "L3ITCR3",
7301 SPR_NOACCESS
, SPR_NOACCESS
,
7302 &spr_read_generic
, &spr_write_generic
,
7305 /* XXX : not implemented */
7306 spr_register(env
, SPR_L3OHCR
, "L3OHCR",
7307 SPR_NOACCESS
, SPR_NOACCESS
,
7308 &spr_read_generic
, &spr_write_generic
,
7311 /* XXX : not implemented */
7312 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7313 SPR_NOACCESS
, SPR_NOACCESS
,
7314 &spr_read_generic
, &spr_write_generic
,
7317 /* XXX : not implemented */
7318 spr_register(env
, SPR_ICTRL
, "ICTRL",
7319 SPR_NOACCESS
, SPR_NOACCESS
,
7320 &spr_read_generic
, &spr_write_generic
,
7323 /* XXX : not implemented */
7324 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7325 SPR_NOACCESS
, SPR_NOACCESS
,
7326 &spr_read_generic
, &spr_write_generic
,
7329 /* XXX : not implemented */
7330 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7331 SPR_NOACCESS
, SPR_NOACCESS
,
7332 &spr_read_generic
, &spr_write_generic
,
7334 /* XXX : not implemented */
7335 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7336 &spr_read_ureg
, SPR_NOACCESS
,
7337 &spr_read_ureg
, SPR_NOACCESS
,
7339 /* XXX : not implemented */
7340 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7341 SPR_NOACCESS
, SPR_NOACCESS
,
7342 &spr_read_generic
, &spr_write_generic
,
7344 /* XXX : not implemented */
7345 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7346 &spr_read_ureg
, SPR_NOACCESS
,
7347 &spr_read_ureg
, SPR_NOACCESS
,
7350 spr_register(env
, SPR_SPRG4
, "SPRG4",
7351 SPR_NOACCESS
, SPR_NOACCESS
,
7352 &spr_read_generic
, &spr_write_generic
,
7354 spr_register(env
, SPR_USPRG4
, "USPRG4",
7355 &spr_read_ureg
, SPR_NOACCESS
,
7356 &spr_read_ureg
, SPR_NOACCESS
,
7358 spr_register(env
, SPR_SPRG5
, "SPRG5",
7359 SPR_NOACCESS
, SPR_NOACCESS
,
7360 &spr_read_generic
, &spr_write_generic
,
7362 spr_register(env
, SPR_USPRG5
, "USPRG5",
7363 &spr_read_ureg
, SPR_NOACCESS
,
7364 &spr_read_ureg
, SPR_NOACCESS
,
7366 spr_register(env
, SPR_SPRG6
, "SPRG6",
7367 SPR_NOACCESS
, SPR_NOACCESS
,
7368 &spr_read_generic
, &spr_write_generic
,
7370 spr_register(env
, SPR_USPRG6
, "USPRG6",
7371 &spr_read_ureg
, SPR_NOACCESS
,
7372 &spr_read_ureg
, SPR_NOACCESS
,
7374 spr_register(env
, SPR_SPRG7
, "SPRG7",
7375 SPR_NOACCESS
, SPR_NOACCESS
,
7376 &spr_read_generic
, &spr_write_generic
,
7378 spr_register(env
, SPR_USPRG7
, "USPRG7",
7379 &spr_read_ureg
, SPR_NOACCESS
,
7380 &spr_read_ureg
, SPR_NOACCESS
,
7382 /* Memory management */
7385 gen_74xx_soft_tlb(env
, 128, 2);
7386 init_excp_7450(env
);
7387 env
->dcache_line_size
= 32;
7388 env
->icache_line_size
= 32;
7389 /* Allocate hardware IRQ controller */
7390 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7393 POWERPC_FAMILY(7457)(ObjectClass
*oc
, void *data
)
7395 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7396 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7398 dc
->desc
= "PowerPC 7457 (aka G4)";
7399 pcc
->init_proc
= init_proc_7457
;
7400 pcc
->check_pow
= check_pow_hid0_74xx
;
7401 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7402 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7403 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7405 PPC_CACHE
| PPC_CACHE_ICBI
|
7406 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7407 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7408 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7409 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7410 PPC_SEGMENT
| PPC_EXTERN
|
7412 pcc
->msr_mask
= (1ull << MSR_VR
) |
7429 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7430 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7431 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7432 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7433 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7434 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7435 POWERPC_FLAG_BUS_CLK
;
7438 static void init_proc_e600(CPUPPCState
*env
)
7440 gen_spr_ne_601(env
);
7445 /* 74xx specific SPR */
7447 /* XXX : not implemented */
7448 spr_register(env
, SPR_UBAMR
, "UBAMR",
7449 &spr_read_ureg
, SPR_NOACCESS
,
7450 &spr_read_ureg
, SPR_NOACCESS
,
7452 /* XXX : not implemented */
7453 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7454 SPR_NOACCESS
, SPR_NOACCESS
,
7455 &spr_read_generic
, &spr_write_generic
,
7457 /* XXX : not implemented */
7458 spr_register(env
, SPR_ICTRL
, "ICTRL",
7459 SPR_NOACCESS
, SPR_NOACCESS
,
7460 &spr_read_generic
, &spr_write_generic
,
7462 /* XXX : not implemented */
7463 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7464 SPR_NOACCESS
, SPR_NOACCESS
,
7465 &spr_read_generic
, &spr_write_generic
,
7467 /* XXX : not implemented */
7468 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7469 SPR_NOACCESS
, SPR_NOACCESS
,
7470 &spr_read_generic
, &spr_write_generic
,
7472 /* XXX : not implemented */
7473 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7474 &spr_read_ureg
, SPR_NOACCESS
,
7475 &spr_read_ureg
, SPR_NOACCESS
,
7477 /* XXX : not implemented */
7478 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7479 SPR_NOACCESS
, SPR_NOACCESS
,
7480 &spr_read_generic
, &spr_write_generic
,
7482 /* XXX : not implemented */
7483 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7484 &spr_read_ureg
, SPR_NOACCESS
,
7485 &spr_read_ureg
, SPR_NOACCESS
,
7488 spr_register(env
, SPR_SPRG4
, "SPRG4",
7489 SPR_NOACCESS
, SPR_NOACCESS
,
7490 &spr_read_generic
, &spr_write_generic
,
7492 spr_register(env
, SPR_USPRG4
, "USPRG4",
7493 &spr_read_ureg
, SPR_NOACCESS
,
7494 &spr_read_ureg
, SPR_NOACCESS
,
7496 spr_register(env
, SPR_SPRG5
, "SPRG5",
7497 SPR_NOACCESS
, SPR_NOACCESS
,
7498 &spr_read_generic
, &spr_write_generic
,
7500 spr_register(env
, SPR_USPRG5
, "USPRG5",
7501 &spr_read_ureg
, SPR_NOACCESS
,
7502 &spr_read_ureg
, SPR_NOACCESS
,
7504 spr_register(env
, SPR_SPRG6
, "SPRG6",
7505 SPR_NOACCESS
, SPR_NOACCESS
,
7506 &spr_read_generic
, &spr_write_generic
,
7508 spr_register(env
, SPR_USPRG6
, "USPRG6",
7509 &spr_read_ureg
, SPR_NOACCESS
,
7510 &spr_read_ureg
, SPR_NOACCESS
,
7512 spr_register(env
, SPR_SPRG7
, "SPRG7",
7513 SPR_NOACCESS
, SPR_NOACCESS
,
7514 &spr_read_generic
, &spr_write_generic
,
7516 spr_register(env
, SPR_USPRG7
, "USPRG7",
7517 &spr_read_ureg
, SPR_NOACCESS
,
7518 &spr_read_ureg
, SPR_NOACCESS
,
7520 /* Memory management */
7523 gen_74xx_soft_tlb(env
, 128, 2);
7524 init_excp_7450(env
);
7525 env
->dcache_line_size
= 32;
7526 env
->icache_line_size
= 32;
7527 /* Allocate hardware IRQ controller */
7528 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7531 POWERPC_FAMILY(e600
)(ObjectClass
*oc
, void *data
)
7533 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7534 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7536 dc
->desc
= "PowerPC e600";
7537 pcc
->init_proc
= init_proc_e600
;
7538 pcc
->check_pow
= check_pow_hid0_74xx
;
7539 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7540 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7541 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7543 PPC_CACHE
| PPC_CACHE_ICBI
|
7544 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7545 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7546 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7547 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7548 PPC_SEGMENT
| PPC_EXTERN
|
7550 pcc
->insns_flags2
= PPC_NONE
;
7551 pcc
->msr_mask
= (1ull << MSR_VR
) |
7568 pcc
->mmu_model
= POWERPC_MMU_32B
;
7569 #if defined(CONFIG_SOFTMMU)
7570 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
7572 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7573 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7574 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7575 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7576 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7577 POWERPC_FLAG_BUS_CLK
;
7580 #if defined(TARGET_PPC64)
7581 #if defined(CONFIG_USER_ONLY)
7582 #define POWERPC970_HID5_INIT 0x00000080
7584 #define POWERPC970_HID5_INIT 0x00000000
7587 static void gen_fscr_facility_check(DisasContext
*ctx
, int facility_sprn
,
7588 int bit
, int sprn
, int cause
)
7590 TCGv_i32 t1
= tcg_const_i32(bit
);
7591 TCGv_i32 t2
= tcg_const_i32(sprn
);
7592 TCGv_i32 t3
= tcg_const_i32(cause
);
7594 gen_helper_fscr_facility_check(cpu_env
, t1
, t2
, t3
);
7596 tcg_temp_free_i32(t3
);
7597 tcg_temp_free_i32(t2
);
7598 tcg_temp_free_i32(t1
);
7601 static void gen_msr_facility_check(DisasContext
*ctx
, int facility_sprn
,
7602 int bit
, int sprn
, int cause
)
7604 TCGv_i32 t1
= tcg_const_i32(bit
);
7605 TCGv_i32 t2
= tcg_const_i32(sprn
);
7606 TCGv_i32 t3
= tcg_const_i32(cause
);
7608 gen_helper_msr_facility_check(cpu_env
, t1
, t2
, t3
);
7610 tcg_temp_free_i32(t3
);
7611 tcg_temp_free_i32(t2
);
7612 tcg_temp_free_i32(t1
);
7615 static void spr_read_prev_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
7617 TCGv spr_up
= tcg_temp_new();
7618 TCGv spr
= tcg_temp_new();
7620 gen_load_spr(spr
, sprn
- 1);
7621 tcg_gen_shri_tl(spr_up
, spr
, 32);
7622 tcg_gen_ext32u_tl(cpu_gpr
[gprn
], spr_up
);
7625 tcg_temp_free(spr_up
);
7628 static void spr_write_prev_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
7630 TCGv spr
= tcg_temp_new();
7632 gen_load_spr(spr
, sprn
- 1);
7633 tcg_gen_deposit_tl(spr
, spr
, cpu_gpr
[gprn
], 32, 32);
7634 gen_store_spr(sprn
- 1, spr
);
7639 static int check_pow_970(CPUPPCState
*env
)
7641 if (env
->spr
[SPR_HID0
] & (HID0_DEEPNAP
| HID0_DOZE
| HID0_NAP
)) {
7648 static void gen_spr_970_hid(CPUPPCState
*env
)
7650 /* Hardware implementation registers */
7651 /* XXX : not implemented */
7652 spr_register(env
, SPR_HID0
, "HID0",
7653 SPR_NOACCESS
, SPR_NOACCESS
,
7654 &spr_read_generic
, &spr_write_clear
,
7656 spr_register(env
, SPR_HID1
, "HID1",
7657 SPR_NOACCESS
, SPR_NOACCESS
,
7658 &spr_read_generic
, &spr_write_generic
,
7660 spr_register(env
, SPR_970_HID5
, "HID5",
7661 SPR_NOACCESS
, SPR_NOACCESS
,
7662 &spr_read_generic
, &spr_write_generic
,
7663 POWERPC970_HID5_INIT
);
7666 static void gen_spr_970_hior(CPUPPCState
*env
)
7668 spr_register(env
, SPR_HIOR
, "SPR_HIOR",
7669 SPR_NOACCESS
, SPR_NOACCESS
,
7670 &spr_read_hior
, &spr_write_hior
,
7674 static void gen_spr_book3s_ctrl(CPUPPCState
*env
)
7676 spr_register(env
, SPR_CTRL
, "SPR_CTRL",
7677 SPR_NOACCESS
, SPR_NOACCESS
,
7678 SPR_NOACCESS
, &spr_write_generic
,
7680 spr_register(env
, SPR_UCTRL
, "SPR_UCTRL",
7681 &spr_read_ureg
, SPR_NOACCESS
,
7682 &spr_read_ureg
, SPR_NOACCESS
,
7686 static void gen_spr_book3s_altivec(CPUPPCState
*env
)
7688 if (!(env
->insns_flags
& PPC_ALTIVEC
)) {
7692 spr_register_kvm(env
, SPR_VRSAVE
, "VRSAVE",
7693 &spr_read_generic
, &spr_write_generic
,
7694 &spr_read_generic
, &spr_write_generic
,
7695 KVM_REG_PPC_VRSAVE
, 0x00000000);
7697 /* Can't find information on what this should be on reset. This
7698 * value is the one used by 74xx processors. */
7699 vscr_init(env
, 0x00010000);
7702 static void gen_spr_book3s_dbg(CPUPPCState
*env
)
7705 * TODO: different specs define different scopes for these,
7706 * will have to address this:
7707 * 970: super/write and super/read
7708 * powerisa 2.03..2.04: hypv/write and super/read.
7709 * powerisa 2.05 and newer: hypv/write and hypv/read.
7711 spr_register_kvm(env
, SPR_DABR
, "DABR",
7712 SPR_NOACCESS
, SPR_NOACCESS
,
7713 &spr_read_generic
, &spr_write_generic
,
7714 KVM_REG_PPC_DABR
, 0x00000000);
7715 spr_register_kvm(env
, SPR_DABRX
, "DABRX",
7716 SPR_NOACCESS
, SPR_NOACCESS
,
7717 &spr_read_generic
, &spr_write_generic
,
7718 KVM_REG_PPC_DABRX
, 0x00000000);
7721 static void gen_spr_book3s_207_dbg(CPUPPCState
*env
)
7723 spr_register_kvm_hv(env
, SPR_DAWR
, "DAWR",
7724 SPR_NOACCESS
, SPR_NOACCESS
,
7725 SPR_NOACCESS
, SPR_NOACCESS
,
7726 &spr_read_generic
, &spr_write_generic
,
7727 KVM_REG_PPC_DAWR
, 0x00000000);
7728 spr_register_kvm_hv(env
, SPR_DAWRX
, "DAWRX",
7729 SPR_NOACCESS
, SPR_NOACCESS
,
7730 SPR_NOACCESS
, SPR_NOACCESS
,
7731 &spr_read_generic
, &spr_write_generic
,
7732 KVM_REG_PPC_DAWRX
, 0x00000000);
7733 spr_register_kvm_hv(env
, SPR_CIABR
, "CIABR",
7734 SPR_NOACCESS
, SPR_NOACCESS
,
7735 SPR_NOACCESS
, SPR_NOACCESS
,
7736 &spr_read_generic
, &spr_write_generic
,
7737 KVM_REG_PPC_CIABR
, 0x00000000);
7740 static void gen_spr_970_dbg(CPUPPCState
*env
)
7743 spr_register(env
, SPR_IABR
, "IABR",
7744 SPR_NOACCESS
, SPR_NOACCESS
,
7745 &spr_read_generic
, &spr_write_generic
,
7749 static void gen_spr_book3s_pmu_sup(CPUPPCState
*env
)
7751 spr_register_kvm(env
, SPR_POWER_MMCR0
, "MMCR0",
7752 SPR_NOACCESS
, SPR_NOACCESS
,
7753 &spr_read_generic
, &spr_write_generic
,
7754 KVM_REG_PPC_MMCR0
, 0x00000000);
7755 spr_register_kvm(env
, SPR_POWER_MMCR1
, "MMCR1",
7756 SPR_NOACCESS
, SPR_NOACCESS
,
7757 &spr_read_generic
, &spr_write_generic
,
7758 KVM_REG_PPC_MMCR1
, 0x00000000);
7759 spr_register_kvm(env
, SPR_POWER_MMCRA
, "MMCRA",
7760 SPR_NOACCESS
, SPR_NOACCESS
,
7761 &spr_read_generic
, &spr_write_generic
,
7762 KVM_REG_PPC_MMCRA
, 0x00000000);
7763 spr_register_kvm(env
, SPR_POWER_PMC1
, "PMC1",
7764 SPR_NOACCESS
, SPR_NOACCESS
,
7765 &spr_read_generic
, &spr_write_generic
,
7766 KVM_REG_PPC_PMC1
, 0x00000000);
7767 spr_register_kvm(env
, SPR_POWER_PMC2
, "PMC2",
7768 SPR_NOACCESS
, SPR_NOACCESS
,
7769 &spr_read_generic
, &spr_write_generic
,
7770 KVM_REG_PPC_PMC2
, 0x00000000);
7771 spr_register_kvm(env
, SPR_POWER_PMC3
, "PMC3",
7772 SPR_NOACCESS
, SPR_NOACCESS
,
7773 &spr_read_generic
, &spr_write_generic
,
7774 KVM_REG_PPC_PMC3
, 0x00000000);
7775 spr_register_kvm(env
, SPR_POWER_PMC4
, "PMC4",
7776 SPR_NOACCESS
, SPR_NOACCESS
,
7777 &spr_read_generic
, &spr_write_generic
,
7778 KVM_REG_PPC_PMC4
, 0x00000000);
7779 spr_register_kvm(env
, SPR_POWER_PMC5
, "PMC5",
7780 SPR_NOACCESS
, SPR_NOACCESS
,
7781 &spr_read_generic
, &spr_write_generic
,
7782 KVM_REG_PPC_PMC5
, 0x00000000);
7783 spr_register_kvm(env
, SPR_POWER_PMC6
, "PMC6",
7784 SPR_NOACCESS
, SPR_NOACCESS
,
7785 &spr_read_generic
, &spr_write_generic
,
7786 KVM_REG_PPC_PMC6
, 0x00000000);
7787 spr_register_kvm(env
, SPR_POWER_SIAR
, "SIAR",
7788 SPR_NOACCESS
, SPR_NOACCESS
,
7789 &spr_read_generic
, &spr_write_generic
,
7790 KVM_REG_PPC_SIAR
, 0x00000000);
7791 spr_register_kvm(env
, SPR_POWER_SDAR
, "SDAR",
7792 SPR_NOACCESS
, SPR_NOACCESS
,
7793 &spr_read_generic
, &spr_write_generic
,
7794 KVM_REG_PPC_SDAR
, 0x00000000);
7797 static void gen_spr_book3s_pmu_user(CPUPPCState
*env
)
7799 spr_register(env
, SPR_POWER_UMMCR0
, "UMMCR0",
7800 &spr_read_ureg
, SPR_NOACCESS
,
7801 &spr_read_ureg
, &spr_write_ureg
,
7803 spr_register(env
, SPR_POWER_UMMCR1
, "UMMCR1",
7804 &spr_read_ureg
, SPR_NOACCESS
,
7805 &spr_read_ureg
, &spr_write_ureg
,
7807 spr_register(env
, SPR_POWER_UMMCRA
, "UMMCRA",
7808 &spr_read_ureg
, SPR_NOACCESS
,
7809 &spr_read_ureg
, &spr_write_ureg
,
7811 spr_register(env
, SPR_POWER_UPMC1
, "UPMC1",
7812 &spr_read_ureg
, SPR_NOACCESS
,
7813 &spr_read_ureg
, &spr_write_ureg
,
7815 spr_register(env
, SPR_POWER_UPMC2
, "UPMC2",
7816 &spr_read_ureg
, SPR_NOACCESS
,
7817 &spr_read_ureg
, &spr_write_ureg
,
7819 spr_register(env
, SPR_POWER_UPMC3
, "UPMC3",
7820 &spr_read_ureg
, SPR_NOACCESS
,
7821 &spr_read_ureg
, &spr_write_ureg
,
7823 spr_register(env
, SPR_POWER_UPMC4
, "UPMC4",
7824 &spr_read_ureg
, SPR_NOACCESS
,
7825 &spr_read_ureg
, &spr_write_ureg
,
7827 spr_register(env
, SPR_POWER_UPMC5
, "UPMC5",
7828 &spr_read_ureg
, SPR_NOACCESS
,
7829 &spr_read_ureg
, &spr_write_ureg
,
7831 spr_register(env
, SPR_POWER_UPMC6
, "UPMC6",
7832 &spr_read_ureg
, SPR_NOACCESS
,
7833 &spr_read_ureg
, &spr_write_ureg
,
7835 spr_register(env
, SPR_POWER_USIAR
, "USIAR",
7836 &spr_read_ureg
, SPR_NOACCESS
,
7837 &spr_read_ureg
, &spr_write_ureg
,
7839 spr_register(env
, SPR_POWER_USDAR
, "USDAR",
7840 &spr_read_ureg
, SPR_NOACCESS
,
7841 &spr_read_ureg
, &spr_write_ureg
,
7845 static void gen_spr_970_pmu_sup(CPUPPCState
*env
)
7847 spr_register_kvm(env
, SPR_970_PMC7
, "PMC7",
7848 SPR_NOACCESS
, SPR_NOACCESS
,
7849 &spr_read_generic
, &spr_write_generic
,
7850 KVM_REG_PPC_PMC7
, 0x00000000);
7851 spr_register_kvm(env
, SPR_970_PMC8
, "PMC8",
7852 SPR_NOACCESS
, SPR_NOACCESS
,
7853 &spr_read_generic
, &spr_write_generic
,
7854 KVM_REG_PPC_PMC8
, 0x00000000);
7857 static void gen_spr_970_pmu_user(CPUPPCState
*env
)
7859 spr_register(env
, SPR_970_UPMC7
, "UPMC7",
7860 &spr_read_ureg
, SPR_NOACCESS
,
7861 &spr_read_ureg
, &spr_write_ureg
,
7863 spr_register(env
, SPR_970_UPMC8
, "UPMC8",
7864 &spr_read_ureg
, SPR_NOACCESS
,
7865 &spr_read_ureg
, &spr_write_ureg
,
7869 static void gen_spr_power8_pmu_sup(CPUPPCState
*env
)
7871 spr_register_kvm(env
, SPR_POWER_MMCR2
, "MMCR2",
7872 SPR_NOACCESS
, SPR_NOACCESS
,
7873 &spr_read_generic
, &spr_write_generic
,
7874 KVM_REG_PPC_MMCR2
, 0x00000000);
7875 spr_register_kvm(env
, SPR_POWER_MMCRS
, "MMCRS",
7876 SPR_NOACCESS
, SPR_NOACCESS
,
7877 &spr_read_generic
, &spr_write_generic
,
7878 KVM_REG_PPC_MMCRS
, 0x00000000);
7879 spr_register_kvm(env
, SPR_POWER_SIER
, "SIER",
7880 SPR_NOACCESS
, SPR_NOACCESS
,
7881 &spr_read_generic
, &spr_write_generic
,
7882 KVM_REG_PPC_SIER
, 0x00000000);
7883 spr_register_kvm(env
, SPR_POWER_SPMC1
, "SPMC1",
7884 SPR_NOACCESS
, SPR_NOACCESS
,
7885 &spr_read_generic
, &spr_write_generic
,
7886 KVM_REG_PPC_SPMC1
, 0x00000000);
7887 spr_register_kvm(env
, SPR_POWER_SPMC2
, "SPMC2",
7888 SPR_NOACCESS
, SPR_NOACCESS
,
7889 &spr_read_generic
, &spr_write_generic
,
7890 KVM_REG_PPC_SPMC2
, 0x00000000);
7891 spr_register_kvm(env
, SPR_TACR
, "TACR",
7892 SPR_NOACCESS
, SPR_NOACCESS
,
7893 &spr_read_generic
, &spr_write_generic
,
7894 KVM_REG_PPC_TACR
, 0x00000000);
7895 spr_register_kvm(env
, SPR_TCSCR
, "TCSCR",
7896 SPR_NOACCESS
, SPR_NOACCESS
,
7897 &spr_read_generic
, &spr_write_generic
,
7898 KVM_REG_PPC_TCSCR
, 0x00000000);
7899 spr_register_kvm(env
, SPR_CSIGR
, "CSIGR",
7900 SPR_NOACCESS
, SPR_NOACCESS
,
7901 &spr_read_generic
, &spr_write_generic
,
7902 KVM_REG_PPC_CSIGR
, 0x00000000);
7905 static void gen_spr_power8_pmu_user(CPUPPCState
*env
)
7907 spr_register(env
, SPR_POWER_UMMCR2
, "UMMCR2",
7908 &spr_read_ureg
, SPR_NOACCESS
,
7909 &spr_read_ureg
, &spr_write_ureg
,
7911 spr_register(env
, SPR_POWER_USIER
, "USIER",
7912 &spr_read_generic
, SPR_NOACCESS
,
7913 &spr_read_generic
, &spr_write_generic
,
7917 static void gen_spr_power5p_ear(CPUPPCState
*env
)
7919 /* External access control */
7920 spr_register(env
, SPR_EAR
, "EAR",
7921 SPR_NOACCESS
, SPR_NOACCESS
,
7922 &spr_read_generic
, &spr_write_generic
,
7926 #if !defined(CONFIG_USER_ONLY)
7927 static void spr_write_hmer(DisasContext
*ctx
, int sprn
, int gprn
)
7929 TCGv hmer
= tcg_temp_new();
7931 gen_load_spr(hmer
, sprn
);
7932 tcg_gen_and_tl(hmer
, cpu_gpr
[gprn
], hmer
);
7933 gen_store_spr(sprn
, hmer
);
7934 spr_store_dump_spr(sprn
);
7935 tcg_temp_free(hmer
);
7938 static void spr_write_lpcr(DisasContext
*ctx
, int sprn
, int gprn
)
7940 gen_helper_store_lpcr(cpu_env
, cpu_gpr
[gprn
]);
7943 static void spr_write_970_hid4(DisasContext
*ctx
, int sprn
, int gprn
)
7945 #if defined(TARGET_PPC64)
7946 spr_write_generic(ctx
, sprn
, gprn
);
7947 gen_helper_store_lpcr(cpu_env
, cpu_gpr
[gprn
]);
7951 #endif /* !defined(CONFIG_USER_ONLY) */
7953 static void gen_spr_970_lpar(CPUPPCState
*env
)
7955 #if !defined(CONFIG_USER_ONLY)
7956 /* Logical partitionning */
7957 /* PPC970: HID4 is effectively the LPCR */
7958 spr_register(env
, SPR_970_HID4
, "HID4",
7959 SPR_NOACCESS
, SPR_NOACCESS
,
7960 &spr_read_generic
, &spr_write_970_hid4
,
7965 static void gen_spr_power5p_lpar(CPUPPCState
*env
)
7967 #if !defined(CONFIG_USER_ONLY)
7968 /* Logical partitionning */
7969 spr_register_kvm_hv(env
, SPR_LPCR
, "LPCR",
7970 SPR_NOACCESS
, SPR_NOACCESS
,
7971 SPR_NOACCESS
, SPR_NOACCESS
,
7972 &spr_read_generic
, &spr_write_lpcr
,
7973 KVM_REG_PPC_LPCR
, LPCR_LPES0
| LPCR_LPES1
);
7974 spr_register_hv(env
, SPR_HDEC
, "HDEC",
7975 SPR_NOACCESS
, SPR_NOACCESS
,
7976 SPR_NOACCESS
, SPR_NOACCESS
,
7977 &spr_read_hdecr
, &spr_write_hdecr
, 0);
7981 static void gen_spr_book3s_ids(CPUPPCState
*env
)
7983 /* FIXME: Will need to deal with thread vs core only SPRs */
7985 /* Processor identification */
7986 spr_register_hv(env
, SPR_PIR
, "PIR",
7987 SPR_NOACCESS
, SPR_NOACCESS
,
7988 SPR_NOACCESS
, SPR_NOACCESS
,
7989 &spr_read_generic
, NULL
,
7991 spr_register_hv(env
, SPR_HID0
, "HID0",
7992 SPR_NOACCESS
, SPR_NOACCESS
,
7993 SPR_NOACCESS
, SPR_NOACCESS
,
7994 &spr_read_generic
, &spr_write_generic
,
7996 spr_register_hv(env
, SPR_TSCR
, "TSCR",
7997 SPR_NOACCESS
, SPR_NOACCESS
,
7998 SPR_NOACCESS
, SPR_NOACCESS
,
7999 &spr_read_generic
, &spr_write_generic
,
8001 spr_register_hv(env
, SPR_HMER
, "HMER",
8002 SPR_NOACCESS
, SPR_NOACCESS
,
8003 SPR_NOACCESS
, SPR_NOACCESS
,
8004 &spr_read_generic
, &spr_write_hmer
,
8006 spr_register_hv(env
, SPR_HMEER
, "HMEER",
8007 SPR_NOACCESS
, SPR_NOACCESS
,
8008 SPR_NOACCESS
, SPR_NOACCESS
,
8009 &spr_read_generic
, &spr_write_generic
,
8011 spr_register_hv(env
, SPR_TFMR
, "TFMR",
8012 SPR_NOACCESS
, SPR_NOACCESS
,
8013 SPR_NOACCESS
, SPR_NOACCESS
,
8014 &spr_read_generic
, &spr_write_generic
,
8016 spr_register_hv(env
, SPR_LPIDR
, "LPIDR",
8017 SPR_NOACCESS
, SPR_NOACCESS
,
8018 SPR_NOACCESS
, SPR_NOACCESS
,
8019 &spr_read_generic
, &spr_write_generic
,
8021 spr_register_hv(env
, SPR_HFSCR
, "HFSCR",
8022 SPR_NOACCESS
, SPR_NOACCESS
,
8023 SPR_NOACCESS
, SPR_NOACCESS
,
8024 &spr_read_generic
, &spr_write_generic
,
8026 spr_register_hv(env
, SPR_MMCRC
, "MMCRC",
8027 SPR_NOACCESS
, SPR_NOACCESS
,
8028 SPR_NOACCESS
, SPR_NOACCESS
,
8029 &spr_read_generic
, &spr_write_generic
,
8031 spr_register_hv(env
, SPR_MMCRH
, "MMCRH",
8032 SPR_NOACCESS
, SPR_NOACCESS
,
8033 SPR_NOACCESS
, SPR_NOACCESS
,
8034 &spr_read_generic
, &spr_write_generic
,
8036 spr_register_hv(env
, SPR_HSPRG0
, "HSPRG0",
8037 SPR_NOACCESS
, SPR_NOACCESS
,
8038 SPR_NOACCESS
, SPR_NOACCESS
,
8039 &spr_read_generic
, &spr_write_generic
,
8041 spr_register_hv(env
, SPR_HSPRG1
, "HSPRG1",
8042 SPR_NOACCESS
, SPR_NOACCESS
,
8043 SPR_NOACCESS
, SPR_NOACCESS
,
8044 &spr_read_generic
, &spr_write_generic
,
8046 spr_register_hv(env
, SPR_HSRR0
, "HSRR0",
8047 SPR_NOACCESS
, SPR_NOACCESS
,
8048 SPR_NOACCESS
, SPR_NOACCESS
,
8049 &spr_read_generic
, &spr_write_generic
,
8051 spr_register_hv(env
, SPR_HSRR1
, "HSRR1",
8052 SPR_NOACCESS
, SPR_NOACCESS
,
8053 SPR_NOACCESS
, SPR_NOACCESS
,
8054 &spr_read_generic
, &spr_write_generic
,
8056 spr_register_hv(env
, SPR_HDAR
, "HDAR",
8057 SPR_NOACCESS
, SPR_NOACCESS
,
8058 SPR_NOACCESS
, SPR_NOACCESS
,
8059 &spr_read_generic
, &spr_write_generic
,
8061 spr_register_hv(env
, SPR_HDSISR
, "HDSISR",
8062 SPR_NOACCESS
, SPR_NOACCESS
,
8063 SPR_NOACCESS
, SPR_NOACCESS
,
8064 &spr_read_generic
, &spr_write_generic
,
8066 spr_register_hv(env
, SPR_RMOR
, "RMOR",
8067 SPR_NOACCESS
, SPR_NOACCESS
,
8068 SPR_NOACCESS
, SPR_NOACCESS
,
8069 &spr_read_generic
, &spr_write_generic
,
8071 spr_register_hv(env
, SPR_HRMOR
, "HRMOR",
8072 SPR_NOACCESS
, SPR_NOACCESS
,
8073 SPR_NOACCESS
, SPR_NOACCESS
,
8074 &spr_read_generic
, &spr_write_generic
,
8078 static void gen_spr_power8_ids(CPUPPCState
*env
)
8080 /* Thread identification */
8081 spr_register(env
, SPR_TIR
, "TIR",
8082 SPR_NOACCESS
, SPR_NOACCESS
,
8083 &spr_read_generic
, SPR_NOACCESS
,
8087 static void gen_spr_book3s_purr(CPUPPCState
*env
)
8089 #if !defined(CONFIG_USER_ONLY)
8090 /* PURR & SPURR: Hack - treat these as aliases for the TB for now */
8091 spr_register_kvm(env
, SPR_PURR
, "PURR",
8092 &spr_read_purr
, SPR_NOACCESS
,
8093 &spr_read_purr
, SPR_NOACCESS
,
8094 KVM_REG_PPC_PURR
, 0x00000000);
8095 spr_register_kvm(env
, SPR_SPURR
, "SPURR",
8096 &spr_read_purr
, SPR_NOACCESS
,
8097 &spr_read_purr
, SPR_NOACCESS
,
8098 KVM_REG_PPC_SPURR
, 0x00000000);
8102 static void gen_spr_power6_dbg(CPUPPCState
*env
)
8104 #if !defined(CONFIG_USER_ONLY)
8105 spr_register(env
, SPR_CFAR
, "SPR_CFAR",
8106 SPR_NOACCESS
, SPR_NOACCESS
,
8107 &spr_read_cfar
, &spr_write_cfar
,
8112 static void gen_spr_power5p_common(CPUPPCState
*env
)
8114 spr_register_kvm(env
, SPR_PPR
, "PPR",
8115 &spr_read_generic
, &spr_write_generic
,
8116 &spr_read_generic
, &spr_write_generic
,
8117 KVM_REG_PPC_PPR
, 0x00000000);
8120 static void gen_spr_power6_common(CPUPPCState
*env
)
8122 #if !defined(CONFIG_USER_ONLY)
8123 spr_register_kvm(env
, SPR_DSCR
, "SPR_DSCR",
8124 SPR_NOACCESS
, SPR_NOACCESS
,
8125 &spr_read_generic
, &spr_write_generic
,
8126 KVM_REG_PPC_DSCR
, 0x00000000);
8129 * Register PCR to report POWERPC_EXCP_PRIV_REG instead of
8130 * POWERPC_EXCP_INVAL_SPR.
8132 spr_register(env
, SPR_PCR
, "PCR",
8133 SPR_NOACCESS
, SPR_NOACCESS
,
8134 SPR_NOACCESS
, SPR_NOACCESS
,
8138 static void spr_read_tar(DisasContext
*ctx
, int gprn
, int sprn
)
8140 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_TAR
, sprn
, FSCR_IC_TAR
);
8141 spr_read_generic(ctx
, gprn
, sprn
);
8144 static void spr_write_tar(DisasContext
*ctx
, int sprn
, int gprn
)
8146 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_TAR
, sprn
, FSCR_IC_TAR
);
8147 spr_write_generic(ctx
, sprn
, gprn
);
8150 static void gen_spr_power8_tce_address_control(CPUPPCState
*env
)
8152 spr_register_kvm(env
, SPR_TAR
, "TAR",
8153 &spr_read_tar
, &spr_write_tar
,
8154 &spr_read_generic
, &spr_write_generic
,
8155 KVM_REG_PPC_TAR
, 0x00000000);
8158 static void spr_read_tm(DisasContext
*ctx
, int gprn
, int sprn
)
8160 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8161 spr_read_generic(ctx
, gprn
, sprn
);
8164 static void spr_write_tm(DisasContext
*ctx
, int sprn
, int gprn
)
8166 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8167 spr_write_generic(ctx
, sprn
, gprn
);
8170 static void spr_read_tm_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
8172 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8173 spr_read_prev_upper32(ctx
, gprn
, sprn
);
8176 static void spr_write_tm_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
8178 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8179 spr_write_prev_upper32(ctx
, sprn
, gprn
);
8182 static void gen_spr_power8_tm(CPUPPCState
*env
)
8184 spr_register_kvm(env
, SPR_TFHAR
, "TFHAR",
8185 &spr_read_tm
, &spr_write_tm
,
8186 &spr_read_tm
, &spr_write_tm
,
8187 KVM_REG_PPC_TFHAR
, 0x00000000);
8188 spr_register_kvm(env
, SPR_TFIAR
, "TFIAR",
8189 &spr_read_tm
, &spr_write_tm
,
8190 &spr_read_tm
, &spr_write_tm
,
8191 KVM_REG_PPC_TFIAR
, 0x00000000);
8192 spr_register_kvm(env
, SPR_TEXASR
, "TEXASR",
8193 &spr_read_tm
, &spr_write_tm
,
8194 &spr_read_tm
, &spr_write_tm
,
8195 KVM_REG_PPC_TEXASR
, 0x00000000);
8196 spr_register(env
, SPR_TEXASRU
, "TEXASRU",
8197 &spr_read_tm_upper32
, &spr_write_tm_upper32
,
8198 &spr_read_tm_upper32
, &spr_write_tm_upper32
,
8202 static void spr_read_ebb(DisasContext
*ctx
, int gprn
, int sprn
)
8204 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8205 spr_read_generic(ctx
, gprn
, sprn
);
8208 static void spr_write_ebb(DisasContext
*ctx
, int sprn
, int gprn
)
8210 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8211 spr_write_generic(ctx
, sprn
, gprn
);
8214 static void spr_read_ebb_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
8216 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8217 spr_read_prev_upper32(ctx
, gprn
, sprn
);
8220 static void spr_write_ebb_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
8222 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8223 spr_write_prev_upper32(ctx
, sprn
, gprn
);
8226 static void gen_spr_power8_ebb(CPUPPCState
*env
)
8228 spr_register(env
, SPR_BESCRS
, "BESCRS",
8229 &spr_read_ebb
, &spr_write_ebb
,
8230 &spr_read_generic
, &spr_write_generic
,
8232 spr_register(env
, SPR_BESCRSU
, "BESCRSU",
8233 &spr_read_ebb_upper32
, &spr_write_ebb_upper32
,
8234 &spr_read_prev_upper32
, &spr_write_prev_upper32
,
8236 spr_register(env
, SPR_BESCRR
, "BESCRR",
8237 &spr_read_ebb
, &spr_write_ebb
,
8238 &spr_read_generic
, &spr_write_generic
,
8240 spr_register(env
, SPR_BESCRRU
, "BESCRRU",
8241 &spr_read_ebb_upper32
, &spr_write_ebb_upper32
,
8242 &spr_read_prev_upper32
, &spr_write_prev_upper32
,
8244 spr_register_kvm(env
, SPR_EBBHR
, "EBBHR",
8245 &spr_read_ebb
, &spr_write_ebb
,
8246 &spr_read_generic
, &spr_write_generic
,
8247 KVM_REG_PPC_EBBHR
, 0x00000000);
8248 spr_register_kvm(env
, SPR_EBBRR
, "EBBRR",
8249 &spr_read_ebb
, &spr_write_ebb
,
8250 &spr_read_generic
, &spr_write_generic
,
8251 KVM_REG_PPC_EBBRR
, 0x00000000);
8252 spr_register_kvm(env
, SPR_BESCR
, "BESCR",
8253 &spr_read_ebb
, &spr_write_ebb
,
8254 &spr_read_generic
, &spr_write_generic
,
8255 KVM_REG_PPC_BESCR
, 0x00000000);
8258 /* Virtual Time Base */
8259 static void gen_spr_vtb(CPUPPCState
*env
)
8261 spr_register(env
, SPR_VTB
, "VTB",
8262 SPR_NOACCESS
, SPR_NOACCESS
,
8263 &spr_read_tbl
, SPR_NOACCESS
,
8267 static void gen_spr_power8_fscr(CPUPPCState
*env
)
8269 #if defined(CONFIG_USER_ONLY)
8270 target_ulong initval
= 1ULL << FSCR_TAR
;
8272 target_ulong initval
= 0;
8274 spr_register_kvm(env
, SPR_FSCR
, "FSCR",
8275 SPR_NOACCESS
, SPR_NOACCESS
,
8276 &spr_read_generic
, &spr_write_generic
,
8277 KVM_REG_PPC_FSCR
, initval
);
8280 static void gen_spr_power8_pspb(CPUPPCState
*env
)
8282 spr_register_kvm(env
, SPR_PSPB
, "PSPB",
8283 SPR_NOACCESS
, SPR_NOACCESS
,
8284 &spr_read_generic
, &spr_write_generic32
,
8285 KVM_REG_PPC_PSPB
, 0);
8288 static void gen_spr_power8_ic(CPUPPCState
*env
)
8290 #if !defined(CONFIG_USER_ONLY)
8291 spr_register_hv(env
, SPR_IC
, "IC",
8292 SPR_NOACCESS
, SPR_NOACCESS
,
8293 &spr_read_generic
, SPR_NOACCESS
,
8294 &spr_read_generic
, &spr_write_generic
,
8299 static void gen_spr_power8_book4(CPUPPCState
*env
)
8301 /* Add a number of P8 book4 registers */
8302 #if !defined(CONFIG_USER_ONLY)
8303 spr_register_kvm(env
, SPR_ACOP
, "ACOP",
8304 SPR_NOACCESS
, SPR_NOACCESS
,
8305 &spr_read_generic
, &spr_write_generic
,
8306 KVM_REG_PPC_ACOP
, 0);
8307 spr_register_kvm(env
, SPR_BOOKS_PID
, "PID",
8308 SPR_NOACCESS
, SPR_NOACCESS
,
8309 &spr_read_generic
, &spr_write_pidr
,
8310 KVM_REG_PPC_PID
, 0);
8311 spr_register_kvm(env
, SPR_WORT
, "WORT",
8312 SPR_NOACCESS
, SPR_NOACCESS
,
8313 &spr_read_generic
, &spr_write_generic
,
8314 KVM_REG_PPC_WORT
, 0);
8318 static void gen_spr_power7_book4(CPUPPCState
*env
)
8320 /* Add a number of P7 book4 registers */
8321 #if !defined(CONFIG_USER_ONLY)
8322 spr_register_kvm(env
, SPR_ACOP
, "ACOP",
8323 SPR_NOACCESS
, SPR_NOACCESS
,
8324 &spr_read_generic
, &spr_write_generic
,
8325 KVM_REG_PPC_ACOP
, 0);
8326 spr_register_kvm(env
, SPR_BOOKS_PID
, "PID",
8327 SPR_NOACCESS
, SPR_NOACCESS
,
8328 &spr_read_generic
, &spr_write_generic
,
8329 KVM_REG_PPC_PID
, 0);
8333 static void gen_spr_power8_rpr(CPUPPCState
*env
)
8335 #if !defined(CONFIG_USER_ONLY)
8336 spr_register_hv(env
, SPR_RPR
, "RPR",
8337 SPR_NOACCESS
, SPR_NOACCESS
,
8338 SPR_NOACCESS
, SPR_NOACCESS
,
8339 &spr_read_generic
, &spr_write_generic
,
8340 0x00000103070F1F3F);
8344 static void init_proc_book3s_common(CPUPPCState
*env
)
8346 gen_spr_ne_601(env
);
8348 gen_spr_usprg3(env
);
8349 gen_spr_book3s_altivec(env
);
8350 gen_spr_book3s_pmu_sup(env
);
8351 gen_spr_book3s_pmu_user(env
);
8352 gen_spr_book3s_ctrl(env
);
8355 static void init_proc_970(CPUPPCState
*env
)
8357 /* Common Registers */
8358 init_proc_book3s_common(env
);
8360 gen_spr_book3s_dbg(env
);
8362 /* 970 Specific Registers */
8363 gen_spr_970_hid(env
);
8364 gen_spr_970_hior(env
);
8366 gen_spr_970_pmu_sup(env
);
8367 gen_spr_970_pmu_user(env
);
8368 gen_spr_970_lpar(env
);
8369 gen_spr_970_dbg(env
);
8372 #if !defined(CONFIG_USER_ONLY)
8375 env
->dcache_line_size
= 128;
8376 env
->icache_line_size
= 128;
8378 /* Allocate hardware IRQ controller */
8380 ppc970_irq_init(ppc_env_get_cpu(env
));
8383 POWERPC_FAMILY(970)(ObjectClass
*oc
, void *data
)
8385 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8386 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8388 dc
->desc
= "PowerPC 970";
8389 pcc
->init_proc
= init_proc_970
;
8390 pcc
->check_pow
= check_pow_970
;
8391 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
8392 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8393 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8395 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8396 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8397 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8398 PPC_64B
| PPC_ALTIVEC
|
8399 PPC_SEGMENT_64B
| PPC_SLBI
;
8400 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
8401 pcc
->msr_mask
= (1ull << MSR_SF
) |
8416 pcc
->mmu_model
= POWERPC_MMU_64B
;
8417 #if defined(CONFIG_SOFTMMU)
8418 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8420 pcc
->excp_model
= POWERPC_EXCP_970
;
8421 pcc
->bus_model
= PPC_FLAGS_INPUT_970
;
8422 pcc
->bfd_mach
= bfd_mach_ppc64
;
8423 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8424 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8425 POWERPC_FLAG_BUS_CLK
;
8426 pcc
->l1_dcache_size
= 0x8000;
8427 pcc
->l1_icache_size
= 0x10000;
8430 static void init_proc_power5plus(CPUPPCState
*env
)
8432 /* Common Registers */
8433 init_proc_book3s_common(env
);
8435 gen_spr_book3s_dbg(env
);
8437 /* POWER5+ Specific Registers */
8438 gen_spr_970_hid(env
);
8439 gen_spr_970_hior(env
);
8441 gen_spr_970_pmu_sup(env
);
8442 gen_spr_970_pmu_user(env
);
8443 gen_spr_power5p_common(env
);
8444 gen_spr_power5p_lpar(env
);
8445 gen_spr_power5p_ear(env
);
8448 #if !defined(CONFIG_USER_ONLY)
8451 env
->dcache_line_size
= 128;
8452 env
->icache_line_size
= 128;
8454 /* Allocate hardware IRQ controller */
8456 ppc970_irq_init(ppc_env_get_cpu(env
));
8459 POWERPC_FAMILY(POWER5P
)(ObjectClass
*oc
, void *data
)
8461 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8462 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8464 dc
->fw_name
= "PowerPC,POWER5";
8465 dc
->desc
= "POWER5+";
8466 pcc
->init_proc
= init_proc_power5plus
;
8467 pcc
->check_pow
= check_pow_970
;
8468 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
8469 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8470 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8472 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8473 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8474 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8476 PPC_SEGMENT_64B
| PPC_SLBI
;
8477 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
8478 pcc
->msr_mask
= (1ull << MSR_SF
) |
8493 pcc
->mmu_model
= POWERPC_MMU_2_03
;
8494 #if defined(CONFIG_SOFTMMU)
8495 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8497 pcc
->excp_model
= POWERPC_EXCP_970
;
8498 pcc
->bus_model
= PPC_FLAGS_INPUT_970
;
8499 pcc
->bfd_mach
= bfd_mach_ppc64
;
8500 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8501 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8502 POWERPC_FLAG_BUS_CLK
;
8503 pcc
->l1_dcache_size
= 0x8000;
8504 pcc
->l1_icache_size
= 0x10000;
8508 * The CPU used to have a "compat" property which set the
8509 * compatibility mode PVR. However, this was conceptually broken - it
8510 * only makes sense on the pseries machine type (otherwise the guest
8511 * owns the PCR and can control the compatibility mode itself). It's
8512 * been replaced with the 'max-cpu-compat' property on the pseries
8513 * machine type. For backwards compatibility, pseries specially
8514 * parses the -cpu parameter and converts old compat= parameters into
8515 * the appropriate machine parameters. This stub implementation of
8516 * the parameter catches any uses on explicitly created CPUs.
8518 static void getset_compat_deprecated(Object
*obj
, Visitor
*v
, const char *name
,
8519 void *opaque
, Error
**errp
)
8523 if (!qtest_enabled()) {
8524 error_report("CPU 'compat' property is deprecated and has no effect; "
8525 "use max-cpu-compat machine property instead");
8527 visit_type_null(v
, name
, &null
, NULL
);
8531 static const PropertyInfo ppc_compat_deprecated_propinfo
= {
8533 .description
= "compatibility mode (deprecated)",
8534 .get
= getset_compat_deprecated
,
8535 .set
= getset_compat_deprecated
,
8537 static Property powerpc_servercpu_properties
[] = {
8540 .info
= &ppc_compat_deprecated_propinfo
,
8542 DEFINE_PROP_END_OF_LIST(),
8545 #ifdef CONFIG_SOFTMMU
8546 static const struct ppc_segment_page_sizes POWER7_POWER8_sps
= {
8549 .page_shift
= 12, /* 4K */
8551 .enc
= { { .page_shift
= 12, .pte_enc
= 0 },
8552 { .page_shift
= 16, .pte_enc
= 0x7 },
8553 { .page_shift
= 24, .pte_enc
= 0x38 }, },
8556 .page_shift
= 16, /* 64K */
8557 .slb_enc
= SLB_VSID_64K
,
8558 .enc
= { { .page_shift
= 16, .pte_enc
= 0x1 },
8559 { .page_shift
= 24, .pte_enc
= 0x8 }, },
8562 .page_shift
= 24, /* 16M */
8563 .slb_enc
= SLB_VSID_16M
,
8564 .enc
= { { .page_shift
= 24, .pte_enc
= 0 }, },
8567 .page_shift
= 34, /* 16G */
8568 .slb_enc
= SLB_VSID_16G
,
8569 .enc
= { { .page_shift
= 34, .pte_enc
= 0x3 }, },
8573 #endif /* CONFIG_SOFTMMU */
8575 static void init_proc_POWER7(CPUPPCState
*env
)
8577 /* Common Registers */
8578 init_proc_book3s_common(env
);
8580 gen_spr_book3s_dbg(env
);
8582 /* POWER7 Specific Registers */
8583 gen_spr_book3s_ids(env
);
8585 gen_spr_book3s_purr(env
);
8586 gen_spr_power5p_common(env
);
8587 gen_spr_power5p_lpar(env
);
8588 gen_spr_power5p_ear(env
);
8589 gen_spr_power6_common(env
);
8590 gen_spr_power6_dbg(env
);
8591 gen_spr_power7_book4(env
);
8594 #if !defined(CONFIG_USER_ONLY)
8597 env
->ci_large_pages
= true;
8598 env
->dcache_line_size
= 128;
8599 env
->icache_line_size
= 128;
8601 /* Allocate hardware IRQ controller */
8602 init_excp_POWER7(env
);
8603 ppcPOWER7_irq_init(ppc_env_get_cpu(env
));
8606 static bool ppc_pvr_match_power7(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8608 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER7P_BASE
) {
8611 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER7_BASE
) {
8617 static bool cpu_has_work_POWER7(CPUState
*cs
)
8619 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8620 CPUPPCState
*env
= &cpu
->env
;
8623 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8626 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8627 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE0
)) {
8630 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8631 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE1
)) {
8634 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
)) &&
8635 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE2
)) {
8638 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HMI
)) &&
8639 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE2
)) {
8642 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8647 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8651 POWERPC_FAMILY(POWER7
)(ObjectClass
*oc
, void *data
)
8653 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8654 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8655 CPUClass
*cc
= CPU_CLASS(oc
);
8657 dc
->fw_name
= "PowerPC,POWER7";
8658 dc
->desc
= "POWER7";
8659 dc
->props
= powerpc_servercpu_properties
;
8660 pcc
->pvr_match
= ppc_pvr_match_power7
;
8661 pcc
->pcr_mask
= PCR_VEC_DIS
| PCR_VSX_DIS
| PCR_COMPAT_2_05
;
8662 pcc
->pcr_supported
= PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8663 pcc
->init_proc
= init_proc_POWER7
;
8664 pcc
->check_pow
= check_pow_nocheck
;
8665 cc
->has_work
= cpu_has_work_POWER7
;
8666 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8667 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8668 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8669 PPC_FLOAT_FRSQRTES
|
8672 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8673 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8674 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8675 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
8676 PPC_SEGMENT_64B
| PPC_SLBI
|
8677 PPC_POPCNTB
| PPC_POPCNTWD
|
8679 pcc
->insns_flags2
= PPC2_VSX
| PPC2_DFP
| PPC2_DBRX
| PPC2_ISA205
|
8680 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8681 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8682 PPC2_FP_TST_ISA206
| PPC2_FP_CVT_S64
|
8684 pcc
->msr_mask
= (1ull << MSR_SF
) |
8700 pcc
->mmu_model
= POWERPC_MMU_2_06
;
8701 #if defined(CONFIG_SOFTMMU)
8702 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8703 pcc
->sps
= &POWER7_POWER8_sps
;
8705 pcc
->excp_model
= POWERPC_EXCP_POWER7
;
8706 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8707 pcc
->bfd_mach
= bfd_mach_ppc64
;
8708 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8709 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8710 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8712 pcc
->l1_dcache_size
= 0x8000;
8713 pcc
->l1_icache_size
= 0x8000;
8714 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8717 static void init_proc_POWER8(CPUPPCState
*env
)
8719 /* Common Registers */
8720 init_proc_book3s_common(env
);
8722 gen_spr_book3s_207_dbg(env
);
8724 /* POWER8 Specific Registers */
8725 gen_spr_book3s_ids(env
);
8728 gen_spr_book3s_purr(env
);
8729 gen_spr_power5p_common(env
);
8730 gen_spr_power5p_lpar(env
);
8731 gen_spr_power5p_ear(env
);
8732 gen_spr_power6_common(env
);
8733 gen_spr_power6_dbg(env
);
8734 gen_spr_power8_tce_address_control(env
);
8735 gen_spr_power8_ids(env
);
8736 gen_spr_power8_ebb(env
);
8737 gen_spr_power8_fscr(env
);
8738 gen_spr_power8_pmu_sup(env
);
8739 gen_spr_power8_pmu_user(env
);
8740 gen_spr_power8_tm(env
);
8741 gen_spr_power8_pspb(env
);
8743 gen_spr_power8_ic(env
);
8744 gen_spr_power8_book4(env
);
8745 gen_spr_power8_rpr(env
);
8748 #if !defined(CONFIG_USER_ONLY)
8751 env
->ci_large_pages
= true;
8752 env
->dcache_line_size
= 128;
8753 env
->icache_line_size
= 128;
8755 /* Allocate hardware IRQ controller */
8756 init_excp_POWER8(env
);
8757 ppcPOWER7_irq_init(ppc_env_get_cpu(env
));
8760 static bool ppc_pvr_match_power8(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8762 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8NVL_BASE
) {
8765 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8E_BASE
) {
8768 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8_BASE
) {
8774 static bool cpu_has_work_POWER8(CPUState
*cs
)
8776 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8777 CPUPPCState
*env
= &cpu
->env
;
8780 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8783 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8784 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE2
)) {
8787 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8788 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE3
)) {
8791 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
)) &&
8792 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE4
)) {
8795 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HMI
)) &&
8796 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE4
)) {
8799 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DOORBELL
)) &&
8800 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE0
)) {
8803 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HDOORBELL
)) &&
8804 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE1
)) {
8807 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8812 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8816 POWERPC_FAMILY(POWER8
)(ObjectClass
*oc
, void *data
)
8818 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8819 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8820 CPUClass
*cc
= CPU_CLASS(oc
);
8822 dc
->fw_name
= "PowerPC,POWER8";
8823 dc
->desc
= "POWER8";
8824 dc
->props
= powerpc_servercpu_properties
;
8825 pcc
->pvr_match
= ppc_pvr_match_power8
;
8826 pcc
->pcr_mask
= PCR_TM_DIS
| PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8827 pcc
->pcr_supported
= PCR_COMPAT_2_07
| PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8828 pcc
->init_proc
= init_proc_POWER8
;
8829 pcc
->check_pow
= check_pow_nocheck
;
8830 cc
->has_work
= cpu_has_work_POWER8
;
8831 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8832 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8833 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8834 PPC_FLOAT_FRSQRTES
|
8837 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8838 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8839 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8840 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
8841 PPC_SEGMENT_64B
| PPC_SLBI
|
8842 PPC_POPCNTB
| PPC_POPCNTWD
|
8844 pcc
->insns_flags2
= PPC2_VSX
| PPC2_VSX207
| PPC2_DFP
| PPC2_DBRX
|
8845 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8846 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8847 PPC2_FP_TST_ISA206
| PPC2_BCTAR_ISA207
|
8848 PPC2_LSQ_ISA207
| PPC2_ALTIVEC_207
|
8849 PPC2_ISA205
| PPC2_ISA207S
| PPC2_FP_CVT_S64
|
8850 PPC2_TM
| PPC2_PM_ISA206
;
8851 pcc
->msr_mask
= (1ull << MSR_SF
) |
8869 pcc
->mmu_model
= POWERPC_MMU_2_07
;
8870 #if defined(CONFIG_SOFTMMU)
8871 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8872 pcc
->sps
= &POWER7_POWER8_sps
;
8874 pcc
->excp_model
= POWERPC_EXCP_POWER8
;
8875 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8876 pcc
->bfd_mach
= bfd_mach_ppc64
;
8877 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8878 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8879 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8880 POWERPC_FLAG_VSX
| POWERPC_FLAG_TM
;
8881 pcc
->l1_dcache_size
= 0x8000;
8882 pcc
->l1_icache_size
= 0x8000;
8883 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8886 #ifdef CONFIG_SOFTMMU
8888 * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
8889 * Encoded as array of int_32s in the form:
8890 * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
8892 * y -> radix mode supported page size (encoded as a shift)
8894 static struct ppc_radix_page_info POWER9_radix_page_info
= {
8897 0x0000000c, /* 4K - enc: 0x0 */
8898 0xa0000010, /* 64K - enc: 0x5 */
8899 0x20000015, /* 2M - enc: 0x1 */
8900 0x4000001e /* 1G - enc: 0x2 */
8903 #endif /* CONFIG_SOFTMMU */
8905 static void init_proc_POWER9(CPUPPCState
*env
)
8907 /* Common Registers */
8908 init_proc_book3s_common(env
);
8909 gen_spr_book3s_207_dbg(env
);
8911 /* POWER8 Specific Registers */
8912 gen_spr_book3s_ids(env
);
8915 gen_spr_book3s_purr(env
);
8916 gen_spr_power5p_common(env
);
8917 gen_spr_power5p_lpar(env
);
8918 gen_spr_power5p_ear(env
);
8919 gen_spr_power6_common(env
);
8920 gen_spr_power6_dbg(env
);
8921 gen_spr_power8_tce_address_control(env
);
8922 gen_spr_power8_ids(env
);
8923 gen_spr_power8_ebb(env
);
8924 gen_spr_power8_fscr(env
);
8925 gen_spr_power8_pmu_sup(env
);
8926 gen_spr_power8_pmu_user(env
);
8927 gen_spr_power8_tm(env
);
8928 gen_spr_power8_pspb(env
);
8930 gen_spr_power8_ic(env
);
8931 gen_spr_power8_book4(env
);
8932 gen_spr_power8_rpr(env
);
8934 /* POWER9 Specific registers */
8935 spr_register_kvm(env
, SPR_TIDR
, "TIDR", NULL
, NULL
,
8936 spr_read_generic
, spr_write_generic
,
8937 KVM_REG_PPC_TIDR
, 0);
8939 /* FIXME: Filter fields properly based on privilege level */
8940 spr_register_kvm_hv(env
, SPR_PSSCR
, "PSSCR", NULL
, NULL
, NULL
, NULL
,
8941 spr_read_generic
, spr_write_generic
,
8942 KVM_REG_PPC_PSSCR
, 0);
8945 #if !defined(CONFIG_USER_ONLY)
8948 env
->ci_large_pages
= true;
8949 env
->dcache_line_size
= 128;
8950 env
->icache_line_size
= 128;
8952 /* Allocate hardware IRQ controller */
8953 init_excp_POWER8(env
);
8954 ppcPOWER7_irq_init(ppc_env_get_cpu(env
));
8957 static bool ppc_pvr_match_power9(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8959 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER9_BASE
) {
8965 static bool cpu_has_work_POWER9(CPUState
*cs
)
8967 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8968 CPUPPCState
*env
= &cpu
->env
;
8971 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8974 /* External Exception */
8975 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8976 (env
->spr
[SPR_LPCR
] & LPCR_EEE
)) {
8979 /* Decrementer Exception */
8980 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8981 (env
->spr
[SPR_LPCR
] & LPCR_DEE
)) {
8984 /* Machine Check or Hypervisor Maintenance Exception */
8985 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
|
8986 1u << PPC_INTERRUPT_HMI
)) && (env
->spr
[SPR_LPCR
] & LPCR_OEE
)) {
8989 /* Privileged Doorbell Exception */
8990 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DOORBELL
)) &&
8991 (env
->spr
[SPR_LPCR
] & LPCR_PDEE
)) {
8994 /* Hypervisor Doorbell Exception */
8995 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HDOORBELL
)) &&
8996 (env
->spr
[SPR_LPCR
] & LPCR_HDEE
)) {
8999 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
9004 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
9008 POWERPC_FAMILY(POWER9
)(ObjectClass
*oc
, void *data
)
9010 DeviceClass
*dc
= DEVICE_CLASS(oc
);
9011 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
9012 CPUClass
*cc
= CPU_CLASS(oc
);
9014 dc
->fw_name
= "PowerPC,POWER9";
9015 dc
->desc
= "POWER9";
9016 dc
->props
= powerpc_servercpu_properties
;
9017 pcc
->pvr_match
= ppc_pvr_match_power9
;
9018 pcc
->pcr_mask
= PCR_COMPAT_2_05
| PCR_COMPAT_2_06
| PCR_COMPAT_2_07
;
9019 pcc
->pcr_supported
= PCR_COMPAT_3_00
| PCR_COMPAT_2_07
| PCR_COMPAT_2_06
|
9021 pcc
->init_proc
= init_proc_POWER9
;
9022 pcc
->check_pow
= check_pow_nocheck
;
9023 cc
->has_work
= cpu_has_work_POWER9
;
9024 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
9025 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
9026 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
9027 PPC_FLOAT_FRSQRTES
|
9030 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
9031 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
9033 PPC_64B
| PPC_64BX
| PPC_ALTIVEC
|
9034 PPC_SEGMENT_64B
| PPC_SLBI
|
9035 PPC_POPCNTB
| PPC_POPCNTWD
|
9037 pcc
->insns_flags2
= PPC2_VSX
| PPC2_VSX207
| PPC2_DFP
| PPC2_DBRX
|
9038 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
9039 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
9040 PPC2_FP_TST_ISA206
| PPC2_BCTAR_ISA207
|
9041 PPC2_LSQ_ISA207
| PPC2_ALTIVEC_207
|
9042 PPC2_ISA205
| PPC2_ISA207S
| PPC2_FP_CVT_S64
|
9043 PPC2_TM
| PPC2_PM_ISA206
| PPC2_ISA300
;
9044 pcc
->msr_mask
= (1ull << MSR_SF
) |
9061 pcc
->mmu_model
= POWERPC_MMU_3_00
;
9062 #if defined(CONFIG_SOFTMMU)
9063 pcc
->handle_mmu_fault
= ppc64_v3_handle_mmu_fault
;
9064 /* segment page size remain the same */
9065 pcc
->sps
= &POWER7_POWER8_sps
;
9066 pcc
->radix_page_info
= &POWER9_radix_page_info
;
9068 pcc
->excp_model
= POWERPC_EXCP_POWER8
;
9069 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
9070 pcc
->bfd_mach
= bfd_mach_ppc64
;
9071 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
9072 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
9073 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
9074 POWERPC_FLAG_VSX
| POWERPC_FLAG_TM
;
9075 pcc
->l1_dcache_size
= 0x8000;
9076 pcc
->l1_icache_size
= 0x8000;
9077 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
9080 #if !defined(CONFIG_USER_ONLY)
9081 void cpu_ppc_set_papr(PowerPCCPU
*cpu
, PPCVirtualHypervisor
*vhyp
)
9083 CPUPPCState
*env
= &cpu
->env
;
9084 ppc_spr_t
*lpcr
= &env
->spr_cb
[SPR_LPCR
];
9085 ppc_spr_t
*amor
= &env
->spr_cb
[SPR_AMOR
];
9089 /* PAPR always has exception vectors in RAM not ROM. To ensure this,
9090 * MSR[IP] should never be set.
9092 * We also disallow setting of MSR_HV
9094 env
->msr_mask
&= ~((1ull << MSR_EP
) | MSR_HVB
);
9096 /* Set emulated LPCR to not send interrupts to hypervisor. Note that
9097 * under KVM, the actual HW LPCR will be set differently by KVM itself,
9098 * the settings below ensure proper operations with TCG in absence of
9099 * a real hypervisor.
9101 * Clearing VPM0 will also cause us to use RMOR in mmu-hash64.c for
9102 * real mode accesses, which thankfully defaults to 0 and isn't
9103 * accessible in guest mode.
9105 lpcr
->default_value
&= ~(LPCR_VPM0
| LPCR_VPM1
| LPCR_ISL
| LPCR_KBV
);
9106 lpcr
->default_value
|= LPCR_LPES0
| LPCR_LPES1
;
9108 /* Set RMLS to the max (ie, 16G) */
9109 lpcr
->default_value
&= ~LPCR_RMLS
;
9110 lpcr
->default_value
|= 1ull << LPCR_RMLS_SHIFT
;
9112 switch (env
->mmu_model
) {
9113 case POWERPC_MMU_3_00
:
9114 /* By default we choose legacy mode and switch to new hash or radix
9115 * when a register process table hcall is made. So disable process
9116 * tables and guest translation shootdown by default
9118 * Hot-plugged CPUs inherit from the guest radix setting under
9119 * KVM but not under TCG. Update the default LPCR to keep new
9120 * CPUs in sync when radix is enabled.
9122 if (ppc64_radix_guest(cpu
)) {
9123 lpcr
->default_value
|= LPCR_UPRT
| LPCR_GTSE
;
9125 lpcr
->default_value
&= ~(LPCR_UPRT
| LPCR_GTSE
);
9127 lpcr
->default_value
|= LPCR_PDEE
| LPCR_HDEE
| LPCR_EEE
| LPCR_DEE
|
9131 /* P7 and P8 has slightly different PECE bits, mostly because P8 adds
9132 * bit 47 and 48 which are reserved on P7. Here we set them all, which
9133 * will work as expected for both implementations
9135 lpcr
->default_value
|= LPCR_P8_PECE0
| LPCR_P8_PECE1
| LPCR_P8_PECE2
|
9136 LPCR_P8_PECE3
| LPCR_P8_PECE4
;
9139 /* We should be followed by a CPU reset but update the active value
9142 env
->spr
[SPR_LPCR
] = lpcr
->default_value
;
9144 /* Set a full AMOR so guest can use the AMR as it sees fit */
9145 env
->spr
[SPR_AMOR
] = amor
->default_value
= 0xffffffffffffffffull
;
9147 /* Update some env bits based on new LPCR value */
9148 ppc_hash64_update_rmls(env
);
9149 ppc_hash64_update_vrma(env
);
9151 /* Tell KVM that we're in PAPR mode */
9152 if (kvm_enabled()) {
9153 kvmppc_set_papr(cpu
);
9157 #endif /* !defined(CONFIG_USER_ONLY) */
9159 #endif /* defined(TARGET_PPC64) */
9161 /*****************************************************************************/
9162 /* Generic CPU instantiation routine */
9163 static void init_ppc_proc(PowerPCCPU
*cpu
)
9165 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9166 CPUPPCState
*env
= &cpu
->env
;
9167 #if !defined(CONFIG_USER_ONLY)
9170 env
->irq_inputs
= NULL
;
9171 /* Set all exception vectors to an invalid address */
9172 for (i
= 0; i
< POWERPC_EXCP_NB
; i
++)
9173 env
->excp_vectors
[i
] = (target_ulong
)(-1ULL);
9174 env
->ivor_mask
= 0x00000000;
9175 env
->ivpr_mask
= 0x00000000;
9176 /* Default MMU definitions */
9180 env
->tlb_type
= TLB_NONE
;
9182 /* Register SPR common to all PowerPC implementations */
9183 gen_spr_generic(env
);
9184 spr_register(env
, SPR_PVR
, "PVR",
9185 /* Linux permits userspace to read PVR */
9186 #if defined(CONFIG_LINUX_USER)
9192 &spr_read_generic
, SPR_NOACCESS
,
9194 /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
9195 if (pcc
->svr
!= POWERPC_SVR_NONE
) {
9196 if (pcc
->svr
& POWERPC_SVR_E500
) {
9197 spr_register(env
, SPR_E500_SVR
, "SVR",
9198 SPR_NOACCESS
, SPR_NOACCESS
,
9199 &spr_read_generic
, SPR_NOACCESS
,
9200 pcc
->svr
& ~POWERPC_SVR_E500
);
9202 spr_register(env
, SPR_SVR
, "SVR",
9203 SPR_NOACCESS
, SPR_NOACCESS
,
9204 &spr_read_generic
, SPR_NOACCESS
,
9208 /* PowerPC implementation specific initialisations (SPRs, timers, ...) */
9209 (*pcc
->init_proc
)(env
);
9211 /* MSR bits & flags consistency checks */
9212 if (env
->msr_mask
& (1 << 25)) {
9213 switch (env
->flags
& (POWERPC_FLAG_SPE
| POWERPC_FLAG_VRE
)) {
9214 case POWERPC_FLAG_SPE
:
9215 case POWERPC_FLAG_VRE
:
9218 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9219 "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n");
9222 } else if (env
->flags
& (POWERPC_FLAG_SPE
| POWERPC_FLAG_VRE
)) {
9223 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9224 "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n");
9227 if (env
->msr_mask
& (1 << 17)) {
9228 switch (env
->flags
& (POWERPC_FLAG_TGPR
| POWERPC_FLAG_CE
)) {
9229 case POWERPC_FLAG_TGPR
:
9230 case POWERPC_FLAG_CE
:
9233 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9234 "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n");
9237 } else if (env
->flags
& (POWERPC_FLAG_TGPR
| POWERPC_FLAG_CE
)) {
9238 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9239 "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n");
9242 if (env
->msr_mask
& (1 << 10)) {
9243 switch (env
->flags
& (POWERPC_FLAG_SE
| POWERPC_FLAG_DWE
|
9244 POWERPC_FLAG_UBLE
)) {
9245 case POWERPC_FLAG_SE
:
9246 case POWERPC_FLAG_DWE
:
9247 case POWERPC_FLAG_UBLE
:
9250 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9251 "Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE or "
9252 "POWERPC_FLAG_UBLE\n");
9255 } else if (env
->flags
& (POWERPC_FLAG_SE
| POWERPC_FLAG_DWE
|
9256 POWERPC_FLAG_UBLE
)) {
9257 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9258 "Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE nor "
9259 "POWERPC_FLAG_UBLE\n");
9262 if (env
->msr_mask
& (1 << 9)) {
9263 switch (env
->flags
& (POWERPC_FLAG_BE
| POWERPC_FLAG_DE
)) {
9264 case POWERPC_FLAG_BE
:
9265 case POWERPC_FLAG_DE
:
9268 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9269 "Should define POWERPC_FLAG_BE or POWERPC_FLAG_DE\n");
9272 } else if (env
->flags
& (POWERPC_FLAG_BE
| POWERPC_FLAG_DE
)) {
9273 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9274 "Should not define POWERPC_FLAG_BE nor POWERPC_FLAG_DE\n");
9277 if (env
->msr_mask
& (1 << 2)) {
9278 switch (env
->flags
& (POWERPC_FLAG_PX
| POWERPC_FLAG_PMM
)) {
9279 case POWERPC_FLAG_PX
:
9280 case POWERPC_FLAG_PMM
:
9283 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9284 "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n");
9287 } else if (env
->flags
& (POWERPC_FLAG_PX
| POWERPC_FLAG_PMM
)) {
9288 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9289 "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
9292 if ((env
->flags
& (POWERPC_FLAG_RTC_CLK
| POWERPC_FLAG_BUS_CLK
)) == 0) {
9293 fprintf(stderr
, "PowerPC flags inconsistency\n"
9294 "Should define the time-base and decrementer clock source\n");
9297 /* Allocate TLBs buffer when needed */
9298 #if !defined(CONFIG_USER_ONLY)
9299 if (env
->nb_tlb
!= 0) {
9300 int nb_tlb
= env
->nb_tlb
;
9301 if (env
->id_tlbs
!= 0)
9303 switch (env
->tlb_type
) {
9305 env
->tlb
.tlb6
= g_malloc0(nb_tlb
* sizeof(ppc6xx_tlb_t
));
9308 env
->tlb
.tlbe
= g_malloc0(nb_tlb
* sizeof(ppcemb_tlb_t
));
9311 env
->tlb
.tlbm
= g_malloc0(nb_tlb
* sizeof(ppcmas_tlb_t
));
9314 /* Pre-compute some useful values */
9315 env
->tlb_per_way
= env
->nb_tlb
/ env
->nb_ways
;
9317 if (env
->irq_inputs
== NULL
) {
9318 fprintf(stderr
, "WARNING: no internal IRQ controller registered.\n"
9319 " Attempt QEMU to crash very soon !\n");
9322 if (env
->check_pow
== NULL
) {
9323 fprintf(stderr
, "WARNING: no power management check handler "
9325 " Attempt QEMU to crash very soon !\n");
9329 #if defined(PPC_DUMP_CPU)
9330 static void dump_ppc_sprs(CPUPPCState
*env
)
9333 #if !defined(CONFIG_USER_ONLY)
9339 printf("Special purpose registers:\n");
9340 for (i
= 0; i
< 32; i
++) {
9341 for (j
= 0; j
< 32; j
++) {
9343 spr
= &env
->spr_cb
[n
];
9344 uw
= spr
->uea_write
!= NULL
&& spr
->uea_write
!= SPR_NOACCESS
;
9345 ur
= spr
->uea_read
!= NULL
&& spr
->uea_read
!= SPR_NOACCESS
;
9346 #if !defined(CONFIG_USER_ONLY)
9347 sw
= spr
->oea_write
!= NULL
&& spr
->oea_write
!= SPR_NOACCESS
;
9348 sr
= spr
->oea_read
!= NULL
&& spr
->oea_read
!= SPR_NOACCESS
;
9349 if (sw
|| sr
|| uw
|| ur
) {
9350 printf("SPR: %4d (%03x) %-8s s%c%c u%c%c\n",
9351 (i
<< 5) | j
, (i
<< 5) | j
, spr
->name
,
9352 sw
? 'w' : '-', sr
? 'r' : '-',
9353 uw
? 'w' : '-', ur
? 'r' : '-');
9357 printf("SPR: %4d (%03x) %-8s u%c%c\n",
9358 (i
<< 5) | j
, (i
<< 5) | j
, spr
->name
,
9359 uw
? 'w' : '-', ur
? 'r' : '-');
9369 /*****************************************************************************/
9373 PPC_DIRECT
= 0, /* Opcode routine */
9374 PPC_INDIRECT
= 1, /* Indirect opcode table */
9377 #define PPC_OPCODE_MASK 0x3
9379 static inline int is_indirect_opcode(void *handler
)
9381 return ((uintptr_t)handler
& PPC_OPCODE_MASK
) == PPC_INDIRECT
;
9384 static inline opc_handler_t
**ind_table(void *handler
)
9386 return (opc_handler_t
**)((uintptr_t)handler
& ~PPC_OPCODE_MASK
);
9389 /* Instruction table creation */
9390 /* Opcodes tables creation */
9391 static void fill_new_table(opc_handler_t
**table
, int len
)
9395 for (i
= 0; i
< len
; i
++)
9396 table
[i
] = &invalid_handler
;
9399 static int create_new_table(opc_handler_t
**table
, unsigned char idx
)
9401 opc_handler_t
**tmp
;
9403 tmp
= g_new(opc_handler_t
*, PPC_CPU_INDIRECT_OPCODES_LEN
);
9404 fill_new_table(tmp
, PPC_CPU_INDIRECT_OPCODES_LEN
);
9405 table
[idx
] = (opc_handler_t
*)((uintptr_t)tmp
| PPC_INDIRECT
);
9410 static int insert_in_table(opc_handler_t
**table
, unsigned char idx
,
9411 opc_handler_t
*handler
)
9413 if (table
[idx
] != &invalid_handler
)
9415 table
[idx
] = handler
;
9420 static int register_direct_insn(opc_handler_t
**ppc_opcodes
,
9421 unsigned char idx
, opc_handler_t
*handler
)
9423 if (insert_in_table(ppc_opcodes
, idx
, handler
) < 0) {
9424 printf("*** ERROR: opcode %02x already assigned in main "
9425 "opcode table\n", idx
);
9426 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9427 printf(" Registered handler '%s' - new handler '%s'\n",
9428 ppc_opcodes
[idx
]->oname
, handler
->oname
);
9436 static int register_ind_in_table(opc_handler_t
**table
,
9437 unsigned char idx1
, unsigned char idx2
,
9438 opc_handler_t
*handler
)
9440 if (table
[idx1
] == &invalid_handler
) {
9441 if (create_new_table(table
, idx1
) < 0) {
9442 printf("*** ERROR: unable to create indirect table "
9443 "idx=%02x\n", idx1
);
9447 if (!is_indirect_opcode(table
[idx1
])) {
9448 printf("*** ERROR: idx %02x already assigned to a direct "
9450 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9451 printf(" Registered handler '%s' - new handler '%s'\n",
9452 ind_table(table
[idx1
])[idx2
]->oname
, handler
->oname
);
9457 if (handler
!= NULL
&&
9458 insert_in_table(ind_table(table
[idx1
]), idx2
, handler
) < 0) {
9459 printf("*** ERROR: opcode %02x already assigned in "
9460 "opcode table %02x\n", idx2
, idx1
);
9461 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9462 printf(" Registered handler '%s' - new handler '%s'\n",
9463 ind_table(table
[idx1
])[idx2
]->oname
, handler
->oname
);
9471 static int register_ind_insn(opc_handler_t
**ppc_opcodes
,
9472 unsigned char idx1
, unsigned char idx2
,
9473 opc_handler_t
*handler
)
9475 return register_ind_in_table(ppc_opcodes
, idx1
, idx2
, handler
);
9478 static int register_dblind_insn(opc_handler_t
**ppc_opcodes
,
9479 unsigned char idx1
, unsigned char idx2
,
9480 unsigned char idx3
, opc_handler_t
*handler
)
9482 if (register_ind_in_table(ppc_opcodes
, idx1
, idx2
, NULL
) < 0) {
9483 printf("*** ERROR: unable to join indirect table idx "
9484 "[%02x-%02x]\n", idx1
, idx2
);
9487 if (register_ind_in_table(ind_table(ppc_opcodes
[idx1
]), idx2
, idx3
,
9489 printf("*** ERROR: unable to insert opcode "
9490 "[%02x-%02x-%02x]\n", idx1
, idx2
, idx3
);
9497 static int register_trplind_insn(opc_handler_t
**ppc_opcodes
,
9498 unsigned char idx1
, unsigned char idx2
,
9499 unsigned char idx3
, unsigned char idx4
,
9500 opc_handler_t
*handler
)
9502 opc_handler_t
**table
;
9504 if (register_ind_in_table(ppc_opcodes
, idx1
, idx2
, NULL
) < 0) {
9505 printf("*** ERROR: unable to join indirect table idx "
9506 "[%02x-%02x]\n", idx1
, idx2
);
9509 table
= ind_table(ppc_opcodes
[idx1
]);
9510 if (register_ind_in_table(table
, idx2
, idx3
, NULL
) < 0) {
9511 printf("*** ERROR: unable to join 2nd-level indirect table idx "
9512 "[%02x-%02x-%02x]\n", idx1
, idx2
, idx3
);
9515 table
= ind_table(table
[idx2
]);
9516 if (register_ind_in_table(table
, idx3
, idx4
, handler
) < 0) {
9517 printf("*** ERROR: unable to insert opcode "
9518 "[%02x-%02x-%02x-%02x]\n", idx1
, idx2
, idx3
, idx4
);
9523 static int register_insn(opc_handler_t
**ppc_opcodes
, opcode_t
*insn
)
9525 if (insn
->opc2
!= 0xFF) {
9526 if (insn
->opc3
!= 0xFF) {
9527 if (insn
->opc4
!= 0xFF) {
9528 if (register_trplind_insn(ppc_opcodes
, insn
->opc1
, insn
->opc2
,
9529 insn
->opc3
, insn
->opc4
,
9530 &insn
->handler
) < 0) {
9534 if (register_dblind_insn(ppc_opcodes
, insn
->opc1
, insn
->opc2
,
9535 insn
->opc3
, &insn
->handler
) < 0)
9539 if (register_ind_insn(ppc_opcodes
, insn
->opc1
,
9540 insn
->opc2
, &insn
->handler
) < 0)
9544 if (register_direct_insn(ppc_opcodes
, insn
->opc1
, &insn
->handler
) < 0)
9551 static int test_opcode_table(opc_handler_t
**table
, int len
)
9555 for (i
= 0, count
= 0; i
< len
; i
++) {
9556 /* Consistency fixup */
9557 if (table
[i
] == NULL
)
9558 table
[i
] = &invalid_handler
;
9559 if (table
[i
] != &invalid_handler
) {
9560 if (is_indirect_opcode(table
[i
])) {
9561 tmp
= test_opcode_table(ind_table(table
[i
]),
9562 PPC_CPU_INDIRECT_OPCODES_LEN
);
9565 table
[i
] = &invalid_handler
;
9578 static void fix_opcode_tables(opc_handler_t
**ppc_opcodes
)
9580 if (test_opcode_table(ppc_opcodes
, PPC_CPU_OPCODES_LEN
) == 0)
9581 printf("*** WARNING: no opcode defined !\n");
9584 /*****************************************************************************/
9585 static void create_ppc_opcodes(PowerPCCPU
*cpu
, Error
**errp
)
9587 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9588 CPUPPCState
*env
= &cpu
->env
;
9591 fill_new_table(env
->opcodes
, PPC_CPU_OPCODES_LEN
);
9592 for (opc
= opcodes
; opc
< &opcodes
[ARRAY_SIZE(opcodes
)]; opc
++) {
9593 if (((opc
->handler
.type
& pcc
->insns_flags
) != 0) ||
9594 ((opc
->handler
.type2
& pcc
->insns_flags2
) != 0)) {
9595 if (register_insn(env
->opcodes
, opc
) < 0) {
9596 error_setg(errp
, "ERROR initializing PowerPC instruction "
9597 "0x%02x 0x%02x 0x%02x", opc
->opc1
, opc
->opc2
,
9603 fix_opcode_tables(env
->opcodes
);
9608 #if defined(PPC_DUMP_CPU)
9609 static void dump_ppc_insns(CPUPPCState
*env
)
9611 opc_handler_t
**table
, *handler
;
9613 uint8_t opc1
, opc2
, opc3
, opc4
;
9615 printf("Instructions set:\n");
9616 /* opc1 is 6 bits long */
9617 for (opc1
= 0x00; opc1
< PPC_CPU_OPCODES_LEN
; opc1
++) {
9618 table
= env
->opcodes
;
9619 handler
= table
[opc1
];
9620 if (is_indirect_opcode(handler
)) {
9621 /* opc2 is 5 bits long */
9622 for (opc2
= 0; opc2
< PPC_CPU_INDIRECT_OPCODES_LEN
; opc2
++) {
9623 table
= env
->opcodes
;
9624 handler
= env
->opcodes
[opc1
];
9625 table
= ind_table(handler
);
9626 handler
= table
[opc2
];
9627 if (is_indirect_opcode(handler
)) {
9628 table
= ind_table(handler
);
9629 /* opc3 is 5 bits long */
9630 for (opc3
= 0; opc3
< PPC_CPU_INDIRECT_OPCODES_LEN
;
9632 handler
= table
[opc3
];
9633 if (is_indirect_opcode(handler
)) {
9634 table
= ind_table(handler
);
9635 /* opc4 is 5 bits long */
9636 for (opc4
= 0; opc4
< PPC_CPU_INDIRECT_OPCODES_LEN
;
9638 handler
= table
[opc4
];
9639 if (handler
->handler
!= &gen_invalid
) {
9640 printf("INSN: %02x %02x %02x %02x -- "
9641 "(%02d %04d %02d) : %s\n",
9642 opc1
, opc2
, opc3
, opc4
,
9643 opc1
, (opc3
<< 5) | opc2
, opc4
,
9648 if (handler
->handler
!= &gen_invalid
) {
9649 /* Special hack to properly dump SPE insns */
9650 p
= strchr(handler
->oname
, '_');
9652 printf("INSN: %02x %02x %02x (%02d %04d) : "
9654 opc1
, opc2
, opc3
, opc1
,
9659 if ((p
- handler
->oname
) != strlen(q
)
9660 || (memcmp(handler
->oname
, q
, strlen(q
))
9662 /* First instruction */
9663 printf("INSN: %02x %02x %02x"
9664 "(%02d %04d) : %.*s\n",
9665 opc1
, opc2
<< 1, opc3
, opc1
,
9666 (opc3
<< 6) | (opc2
<< 1),
9667 (int)(p
- handler
->oname
),
9670 if (strcmp(p
+ 1, q
) != 0) {
9671 /* Second instruction */
9672 printf("INSN: %02x %02x %02x "
9673 "(%02d %04d) : %s\n", opc1
,
9674 (opc2
<< 1) | 1, opc3
, opc1
,
9675 (opc3
<< 6) | (opc2
<< 1) | 1,
9683 if (handler
->handler
!= &gen_invalid
) {
9684 printf("INSN: %02x %02x -- (%02d %04d) : %s\n",
9685 opc1
, opc2
, opc1
, opc2
, handler
->oname
);
9690 if (handler
->handler
!= &gen_invalid
) {
9691 printf("INSN: %02x -- -- (%02d ----) : %s\n",
9692 opc1
, opc1
, handler
->oname
);
9699 static bool avr_need_swap(CPUPPCState
*env
)
9701 #ifdef HOST_WORDS_BIGENDIAN
9708 static int gdb_get_float_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9711 stfq_p(mem_buf
, env
->fpr
[n
]);
9712 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9716 stl_p(mem_buf
, env
->fpscr
);
9717 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9723 static int gdb_set_float_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9726 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9727 env
->fpr
[n
] = ldfq_p(mem_buf
);
9731 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9732 helper_store_fpscr(env
, ldl_p(mem_buf
), 0xffffffff);
9738 static int gdb_get_avr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9741 if (!avr_need_swap(env
)) {
9742 stq_p(mem_buf
, env
->avr
[n
].u64
[0]);
9743 stq_p(mem_buf
+8, env
->avr
[n
].u64
[1]);
9745 stq_p(mem_buf
, env
->avr
[n
].u64
[1]);
9746 stq_p(mem_buf
+8, env
->avr
[n
].u64
[0]);
9748 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9749 ppc_maybe_bswap_register(env
, mem_buf
+ 8, 8);
9753 stl_p(mem_buf
, env
->vscr
);
9754 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9758 stl_p(mem_buf
, (uint32_t)env
->spr
[SPR_VRSAVE
]);
9759 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9765 static int gdb_set_avr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9768 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9769 ppc_maybe_bswap_register(env
, mem_buf
+ 8, 8);
9770 if (!avr_need_swap(env
)) {
9771 env
->avr
[n
].u64
[0] = ldq_p(mem_buf
);
9772 env
->avr
[n
].u64
[1] = ldq_p(mem_buf
+8);
9774 env
->avr
[n
].u64
[1] = ldq_p(mem_buf
);
9775 env
->avr
[n
].u64
[0] = ldq_p(mem_buf
+8);
9780 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9781 env
->vscr
= ldl_p(mem_buf
);
9785 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9786 env
->spr
[SPR_VRSAVE
] = (target_ulong
)ldl_p(mem_buf
);
9792 static int gdb_get_spe_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9795 #if defined(TARGET_PPC64)
9796 stl_p(mem_buf
, env
->gpr
[n
] >> 32);
9797 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9799 stl_p(mem_buf
, env
->gprh
[n
]);
9804 stq_p(mem_buf
, env
->spe_acc
);
9805 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9809 stl_p(mem_buf
, env
->spe_fscr
);
9810 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9816 static int gdb_set_spe_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9819 #if defined(TARGET_PPC64)
9820 target_ulong lo
= (uint32_t)env
->gpr
[n
];
9823 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9825 hi
= (target_ulong
)ldl_p(mem_buf
) << 32;
9826 env
->gpr
[n
] = lo
| hi
;
9828 env
->gprh
[n
] = ldl_p(mem_buf
);
9833 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9834 env
->spe_acc
= ldq_p(mem_buf
);
9838 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9839 env
->spe_fscr
= ldl_p(mem_buf
);
9845 static int gdb_get_vsx_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9848 stq_p(mem_buf
, env
->vsr
[n
]);
9849 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9855 static int gdb_set_vsx_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9858 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9859 env
->vsr
[n
] = ldq_p(mem_buf
);
9865 static int ppc_fixup_cpu(PowerPCCPU
*cpu
)
9867 CPUPPCState
*env
= &cpu
->env
;
9869 /* TCG doesn't (yet) emulate some groups of instructions that
9870 * are implemented on some otherwise supported CPUs (e.g. VSX
9871 * and decimal floating point instructions on POWER7). We
9872 * remove unsupported instruction groups from the cpu state's
9873 * instruction masks and hope the guest can cope. For at
9874 * least the pseries machine, the unavailability of these
9875 * instructions can be advertised to the guest via the device
9877 if ((env
->insns_flags
& ~PPC_TCG_INSNS
)
9878 || (env
->insns_flags2
& ~PPC_TCG_INSNS2
)) {
9879 fprintf(stderr
, "Warning: Disabling some instructions which are not "
9880 "emulated by TCG (0x%" PRIx64
", 0x%" PRIx64
")\n",
9881 env
->insns_flags
& ~PPC_TCG_INSNS
,
9882 env
->insns_flags2
& ~PPC_TCG_INSNS2
);
9884 env
->insns_flags
&= PPC_TCG_INSNS
;
9885 env
->insns_flags2
&= PPC_TCG_INSNS2
;
9889 static inline bool ppc_cpu_is_valid(PowerPCCPUClass
*pcc
)
9891 #ifdef TARGET_PPCEMB
9892 return pcc
->mmu_model
== POWERPC_MMU_BOOKE
||
9893 pcc
->mmu_model
== POWERPC_MMU_SOFT_4xx
||
9894 pcc
->mmu_model
== POWERPC_MMU_SOFT_4xx_Z
;
9900 static void ppc_cpu_realizefn(DeviceState
*dev
, Error
**errp
)
9902 CPUState
*cs
= CPU(dev
);
9903 PowerPCCPU
*cpu
= POWERPC_CPU(dev
);
9904 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9905 Error
*local_err
= NULL
;
9906 #if !defined(CONFIG_USER_ONLY)
9907 int max_smt
= kvmppc_smt_threads();
9910 cpu_exec_realizefn(cs
, &local_err
);
9911 if (local_err
!= NULL
) {
9912 error_propagate(errp
, local_err
);
9916 #if !defined(CONFIG_USER_ONLY)
9917 cpu
->vcpu_id
= (cs
->cpu_index
/ smp_threads
) * max_smt
9918 + (cs
->cpu_index
% smp_threads
);
9920 if (kvm_enabled() && !kvm_vcpu_id_is_valid(cpu
->vcpu_id
)) {
9921 error_setg(errp
, "Can't create CPU with id %d in KVM", cpu
->vcpu_id
);
9922 error_append_hint(errp
, "Adjust the number of cpus to %d "
9923 "or try to raise the number of threads per core\n",
9924 cpu
->vcpu_id
* smp_threads
/ max_smt
);
9929 if (tcg_enabled()) {
9930 if (ppc_fixup_cpu(cpu
) != 0) {
9931 error_setg(errp
, "Unable to emulate selected CPU with TCG");
9936 #if defined(TARGET_PPCEMB)
9937 if (!ppc_cpu_is_valid(pcc
)) {
9938 error_setg(errp
, "CPU does not possess a BookE or 4xx MMU. "
9939 "Please use qemu-system-ppc or qemu-system-ppc64 instead "
9940 "or choose another CPU model.");
9945 create_ppc_opcodes(cpu
, &local_err
);
9946 if (local_err
!= NULL
) {
9947 error_propagate(errp
, local_err
);
9952 if (pcc
->insns_flags
& PPC_FLOAT
) {
9953 gdb_register_coprocessor(cs
, gdb_get_float_reg
, gdb_set_float_reg
,
9954 33, "power-fpu.xml", 0);
9956 if (pcc
->insns_flags
& PPC_ALTIVEC
) {
9957 gdb_register_coprocessor(cs
, gdb_get_avr_reg
, gdb_set_avr_reg
,
9958 34, "power-altivec.xml", 0);
9960 if (pcc
->insns_flags
& PPC_SPE
) {
9961 gdb_register_coprocessor(cs
, gdb_get_spe_reg
, gdb_set_spe_reg
,
9962 34, "power-spe.xml", 0);
9964 if (pcc
->insns_flags2
& PPC2_VSX
) {
9965 gdb_register_coprocessor(cs
, gdb_get_vsx_reg
, gdb_set_vsx_reg
,
9966 32, "power-vsx.xml", 0);
9971 pcc
->parent_realize(dev
, errp
);
9973 #if defined(PPC_DUMP_CPU)
9975 CPUPPCState
*env
= &cpu
->env
;
9976 const char *mmu_model
, *excp_model
, *bus_model
;
9977 switch (env
->mmu_model
) {
9978 case POWERPC_MMU_32B
:
9979 mmu_model
= "PowerPC 32";
9981 case POWERPC_MMU_SOFT_6xx
:
9982 mmu_model
= "PowerPC 6xx/7xx with software driven TLBs";
9984 case POWERPC_MMU_SOFT_74xx
:
9985 mmu_model
= "PowerPC 74xx with software driven TLBs";
9987 case POWERPC_MMU_SOFT_4xx
:
9988 mmu_model
= "PowerPC 4xx with software driven TLBs";
9990 case POWERPC_MMU_SOFT_4xx_Z
:
9991 mmu_model
= "PowerPC 4xx with software driven TLBs "
9992 "and zones protections";
9994 case POWERPC_MMU_REAL
:
9995 mmu_model
= "PowerPC real mode only";
9997 case POWERPC_MMU_MPC8xx
:
9998 mmu_model
= "PowerPC MPC8xx";
10000 case POWERPC_MMU_BOOKE
:
10001 mmu_model
= "PowerPC BookE";
10003 case POWERPC_MMU_BOOKE206
:
10004 mmu_model
= "PowerPC BookE 2.06";
10006 case POWERPC_MMU_601
:
10007 mmu_model
= "PowerPC 601";
10009 #if defined(TARGET_PPC64)
10010 case POWERPC_MMU_64B
:
10011 mmu_model
= "PowerPC 64";
10015 mmu_model
= "Unknown or invalid";
10018 switch (env
->excp_model
) {
10019 case POWERPC_EXCP_STD
:
10020 excp_model
= "PowerPC";
10022 case POWERPC_EXCP_40x
:
10023 excp_model
= "PowerPC 40x";
10025 case POWERPC_EXCP_601
:
10026 excp_model
= "PowerPC 601";
10028 case POWERPC_EXCP_602
:
10029 excp_model
= "PowerPC 602";
10031 case POWERPC_EXCP_603
:
10032 excp_model
= "PowerPC 603";
10034 case POWERPC_EXCP_603E
:
10035 excp_model
= "PowerPC 603e";
10037 case POWERPC_EXCP_604
:
10038 excp_model
= "PowerPC 604";
10040 case POWERPC_EXCP_7x0
:
10041 excp_model
= "PowerPC 740/750";
10043 case POWERPC_EXCP_7x5
:
10044 excp_model
= "PowerPC 745/755";
10046 case POWERPC_EXCP_74xx
:
10047 excp_model
= "PowerPC 74xx";
10049 case POWERPC_EXCP_BOOKE
:
10050 excp_model
= "PowerPC BookE";
10052 #if defined(TARGET_PPC64)
10053 case POWERPC_EXCP_970
:
10054 excp_model
= "PowerPC 970";
10058 excp_model
= "Unknown or invalid";
10061 switch (env
->bus_model
) {
10062 case PPC_FLAGS_INPUT_6xx
:
10063 bus_model
= "PowerPC 6xx";
10065 case PPC_FLAGS_INPUT_BookE
:
10066 bus_model
= "PowerPC BookE";
10068 case PPC_FLAGS_INPUT_405
:
10069 bus_model
= "PowerPC 405";
10071 case PPC_FLAGS_INPUT_401
:
10072 bus_model
= "PowerPC 401/403";
10074 case PPC_FLAGS_INPUT_RCPU
:
10075 bus_model
= "RCPU / MPC8xx";
10077 #if defined(TARGET_PPC64)
10078 case PPC_FLAGS_INPUT_970
:
10079 bus_model
= "PowerPC 970";
10083 bus_model
= "Unknown or invalid";
10086 printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64
"\n"
10087 " MMU model : %s\n",
10088 object_class_get_name(OBJECT_CLASS(pcc
)),
10089 pcc
->pvr
, pcc
->msr_mask
, mmu_model
);
10090 #if !defined(CONFIG_USER_ONLY)
10091 if (env
->tlb
.tlb6
) {
10092 printf(" %d %s TLB in %d ways\n",
10093 env
->nb_tlb
, env
->id_tlbs
? "splitted" : "merged",
10097 printf(" Exceptions model : %s\n"
10098 " Bus model : %s\n",
10099 excp_model
, bus_model
);
10100 printf(" MSR features :\n");
10101 if (env
->flags
& POWERPC_FLAG_SPE
)
10102 printf(" signal processing engine enable"
10104 else if (env
->flags
& POWERPC_FLAG_VRE
)
10105 printf(" vector processor enable\n");
10106 if (env
->flags
& POWERPC_FLAG_TGPR
)
10107 printf(" temporary GPRs\n");
10108 else if (env
->flags
& POWERPC_FLAG_CE
)
10109 printf(" critical input enable\n");
10110 if (env
->flags
& POWERPC_FLAG_SE
)
10111 printf(" single-step trace mode\n");
10112 else if (env
->flags
& POWERPC_FLAG_DWE
)
10113 printf(" debug wait enable\n");
10114 else if (env
->flags
& POWERPC_FLAG_UBLE
)
10115 printf(" user BTB lock enable\n");
10116 if (env
->flags
& POWERPC_FLAG_BE
)
10117 printf(" branch-step trace mode\n");
10118 else if (env
->flags
& POWERPC_FLAG_DE
)
10119 printf(" debug interrupt enable\n");
10120 if (env
->flags
& POWERPC_FLAG_PX
)
10121 printf(" inclusive protection\n");
10122 else if (env
->flags
& POWERPC_FLAG_PMM
)
10123 printf(" performance monitor mark\n");
10124 if (env
->flags
== POWERPC_FLAG_NONE
)
10126 printf(" Time-base/decrementer clock source: %s\n",
10127 env
->flags
& POWERPC_FLAG_RTC_CLK
? "RTC clock" : "bus clock");
10128 dump_ppc_insns(env
);
10129 dump_ppc_sprs(env
);
10136 cpu_exec_unrealizefn(cs
);
10139 static void ppc_cpu_unrealizefn(DeviceState
*dev
, Error
**errp
)
10141 PowerPCCPU
*cpu
= POWERPC_CPU(dev
);
10142 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10143 CPUPPCState
*env
= &cpu
->env
;
10144 Error
*local_err
= NULL
;
10145 opc_handler_t
**table
, **table_2
;
10148 pcc
->parent_unrealize(dev
, &local_err
);
10149 if (local_err
!= NULL
) {
10150 error_propagate(errp
, local_err
);
10154 for (i
= 0; i
< PPC_CPU_OPCODES_LEN
; i
++) {
10155 if (env
->opcodes
[i
] == &invalid_handler
) {
10158 if (is_indirect_opcode(env
->opcodes
[i
])) {
10159 table
= ind_table(env
->opcodes
[i
]);
10160 for (j
= 0; j
< PPC_CPU_INDIRECT_OPCODES_LEN
; j
++) {
10161 if (table
[j
] == &invalid_handler
) {
10164 if (is_indirect_opcode(table
[j
])) {
10165 table_2
= ind_table(table
[j
]);
10166 for (k
= 0; k
< PPC_CPU_INDIRECT_OPCODES_LEN
; k
++) {
10167 if (table_2
[k
] != &invalid_handler
&&
10168 is_indirect_opcode(table_2
[k
])) {
10169 g_free((opc_handler_t
*)((uintptr_t)table_2
[k
] &
10173 g_free((opc_handler_t
*)((uintptr_t)table
[j
] &
10177 g_free((opc_handler_t
*)((uintptr_t)env
->opcodes
[i
] &
10183 static gint
ppc_cpu_compare_class_pvr(gconstpointer a
, gconstpointer b
)
10185 ObjectClass
*oc
= (ObjectClass
*)a
;
10186 uint32_t pvr
= *(uint32_t *)b
;
10187 PowerPCCPUClass
*pcc
= (PowerPCCPUClass
*)a
;
10189 /* -cpu host does a PVR lookup during construction */
10190 if (unlikely(strcmp(object_class_get_name(oc
),
10191 TYPE_HOST_POWERPC_CPU
) == 0)) {
10195 if (!ppc_cpu_is_valid(pcc
)) {
10199 return pcc
->pvr
== pvr
? 0 : -1;
10202 PowerPCCPUClass
*ppc_cpu_class_by_pvr(uint32_t pvr
)
10204 GSList
*list
, *item
;
10205 PowerPCCPUClass
*pcc
= NULL
;
10207 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10208 item
= g_slist_find_custom(list
, &pvr
, ppc_cpu_compare_class_pvr
);
10209 if (item
!= NULL
) {
10210 pcc
= POWERPC_CPU_CLASS(item
->data
);
10212 g_slist_free(list
);
10217 static gint
ppc_cpu_compare_class_pvr_mask(gconstpointer a
, gconstpointer b
)
10219 ObjectClass
*oc
= (ObjectClass
*)a
;
10220 uint32_t pvr
= *(uint32_t *)b
;
10221 PowerPCCPUClass
*pcc
= (PowerPCCPUClass
*)a
;
10223 /* -cpu host does a PVR lookup during construction */
10224 if (unlikely(strcmp(object_class_get_name(oc
),
10225 TYPE_HOST_POWERPC_CPU
) == 0)) {
10229 if (!ppc_cpu_is_valid(pcc
)) {
10233 if (pcc
->pvr_match(pcc
, pvr
)) {
10240 PowerPCCPUClass
*ppc_cpu_class_by_pvr_mask(uint32_t pvr
)
10242 GSList
*list
, *item
;
10243 PowerPCCPUClass
*pcc
= NULL
;
10245 list
= object_class_get_list(TYPE_POWERPC_CPU
, true);
10246 item
= g_slist_find_custom(list
, &pvr
, ppc_cpu_compare_class_pvr_mask
);
10247 if (item
!= NULL
) {
10248 pcc
= POWERPC_CPU_CLASS(item
->data
);
10250 g_slist_free(list
);
10255 static gint
ppc_cpu_compare_class_name(gconstpointer a
, gconstpointer b
)
10257 ObjectClass
*oc
= (ObjectClass
*)a
;
10258 const char *name
= b
;
10259 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10261 if (strncasecmp(name
, object_class_get_name(oc
), strlen(name
)) == 0 &&
10262 ppc_cpu_is_valid(pcc
) &&
10263 strcmp(object_class_get_name(oc
) + strlen(name
),
10264 POWERPC_CPU_TYPE_SUFFIX
) == 0) {
10271 static ObjectClass
*ppc_cpu_class_by_name(const char *name
);
10273 static ObjectClass
*ppc_cpu_class_by_alias(PowerPCCPUAlias
*alias
)
10275 ObjectClass
*invalid_class
= (void*)ppc_cpu_class_by_alias
;
10277 /* Cache target class lookups in the alias table */
10279 alias
->oc
= ppc_cpu_class_by_name(alias
->model
);
10281 /* Fast check for non-existing aliases */
10282 alias
->oc
= invalid_class
;
10286 if (alias
->oc
== invalid_class
) {
10293 static ObjectClass
*ppc_cpu_class_by_name(const char *name
)
10295 GSList
*list
, *item
;
10296 ObjectClass
*ret
= NULL
;
10300 /* Check if the given name is a PVR */
10301 len
= strlen(name
);
10302 if (len
== 10 && name
[0] == '0' && name
[1] == 'x') {
10305 } else if (len
== 8) {
10308 for (i
= 0; i
< 8; i
++) {
10309 if (!qemu_isxdigit(*p
++))
10313 return OBJECT_CLASS(ppc_cpu_class_by_pvr(strtoul(name
, NULL
, 16)));
10317 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10318 item
= g_slist_find_custom(list
, name
, ppc_cpu_compare_class_name
);
10319 if (item
!= NULL
) {
10320 ret
= OBJECT_CLASS(item
->data
);
10322 g_slist_free(list
);
10328 for (i
= 0; ppc_cpu_aliases
[i
].alias
!= NULL
; i
++) {
10329 if (strcmp(ppc_cpu_aliases
[i
].alias
, name
) == 0) {
10330 return ppc_cpu_class_by_alias(&ppc_cpu_aliases
[i
]);
10337 const char *ppc_cpu_lookup_alias(const char *alias
)
10341 for (ai
= 0; ppc_cpu_aliases
[ai
].alias
!= NULL
; ai
++) {
10342 if (strcmp(ppc_cpu_aliases
[ai
].alias
, alias
) == 0) {
10343 return ppc_cpu_aliases
[ai
].model
;
10350 PowerPCCPUClass
*ppc_cpu_get_family_class(PowerPCCPUClass
*pcc
)
10352 ObjectClass
*oc
= OBJECT_CLASS(pcc
);
10354 while (oc
&& !object_class_is_abstract(oc
)) {
10355 oc
= object_class_get_parent(oc
);
10359 return POWERPC_CPU_CLASS(oc
);
10362 /* Sort by PVR, ordering special case "host" last. */
10363 static gint
ppc_cpu_list_compare(gconstpointer a
, gconstpointer b
)
10365 ObjectClass
*oc_a
= (ObjectClass
*)a
;
10366 ObjectClass
*oc_b
= (ObjectClass
*)b
;
10367 PowerPCCPUClass
*pcc_a
= POWERPC_CPU_CLASS(oc_a
);
10368 PowerPCCPUClass
*pcc_b
= POWERPC_CPU_CLASS(oc_b
);
10369 const char *name_a
= object_class_get_name(oc_a
);
10370 const char *name_b
= object_class_get_name(oc_b
);
10372 if (strcmp(name_a
, TYPE_HOST_POWERPC_CPU
) == 0) {
10374 } else if (strcmp(name_b
, TYPE_HOST_POWERPC_CPU
) == 0) {
10377 /* Avoid an integer overflow during subtraction */
10378 if (pcc_a
->pvr
< pcc_b
->pvr
) {
10380 } else if (pcc_a
->pvr
> pcc_b
->pvr
) {
10388 static void ppc_cpu_list_entry(gpointer data
, gpointer user_data
)
10390 ObjectClass
*oc
= data
;
10391 CPUListState
*s
= user_data
;
10392 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10393 DeviceClass
*family
= DEVICE_CLASS(ppc_cpu_get_family_class(pcc
));
10394 const char *typename
= object_class_get_name(oc
);
10398 if (!ppc_cpu_is_valid(pcc
)) {
10401 if (unlikely(strcmp(typename
, TYPE_HOST_POWERPC_CPU
) == 0)) {
10405 name
= g_strndup(typename
,
10406 strlen(typename
) - strlen(POWERPC_CPU_TYPE_SUFFIX
));
10407 (*s
->cpu_fprintf
)(s
->file
, "PowerPC %-16s PVR %08x\n",
10409 for (i
= 0; ppc_cpu_aliases
[i
].alias
!= NULL
; i
++) {
10410 PowerPCCPUAlias
*alias
= &ppc_cpu_aliases
[i
];
10411 ObjectClass
*alias_oc
= ppc_cpu_class_by_alias(alias
);
10413 if (alias_oc
!= oc
) {
10417 * If running with KVM, we might update the family alias later, so
10418 * avoid printing the wrong alias here and use "preferred" instead
10420 if (strcmp(alias
->alias
, family
->desc
) == 0) {
10421 (*s
->cpu_fprintf
)(s
->file
,
10422 "PowerPC %-16s (alias for preferred %s CPU)\n",
10423 alias
->alias
, family
->desc
);
10425 (*s
->cpu_fprintf
)(s
->file
, "PowerPC %-16s (alias for %s)\n",
10426 alias
->alias
, name
);
10432 void ppc_cpu_list(FILE *f
, fprintf_function cpu_fprintf
)
10436 .cpu_fprintf
= cpu_fprintf
,
10440 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10441 list
= g_slist_sort(list
, ppc_cpu_list_compare
);
10442 g_slist_foreach(list
, ppc_cpu_list_entry
, &s
);
10443 g_slist_free(list
);
10446 cpu_fprintf(f
, "\n");
10447 cpu_fprintf(f
, "PowerPC %-16s\n", "host");
10451 static void ppc_cpu_defs_entry(gpointer data
, gpointer user_data
)
10453 ObjectClass
*oc
= data
;
10454 CpuDefinitionInfoList
**first
= user_data
;
10455 const char *typename
;
10456 CpuDefinitionInfoList
*entry
;
10457 CpuDefinitionInfo
*info
;
10458 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10460 if (!ppc_cpu_is_valid(pcc
)) {
10464 typename
= object_class_get_name(oc
);
10465 info
= g_malloc0(sizeof(*info
));
10466 info
->name
= g_strndup(typename
,
10467 strlen(typename
) - strlen(POWERPC_CPU_TYPE_SUFFIX
));
10469 entry
= g_malloc0(sizeof(*entry
));
10470 entry
->value
= info
;
10471 entry
->next
= *first
;
10475 CpuDefinitionInfoList
*arch_query_cpu_definitions(Error
**errp
)
10477 CpuDefinitionInfoList
*cpu_list
= NULL
;
10481 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10482 g_slist_foreach(list
, ppc_cpu_defs_entry
, &cpu_list
);
10483 g_slist_free(list
);
10485 for (i
= 0; ppc_cpu_aliases
[i
].alias
!= NULL
; i
++) {
10486 PowerPCCPUAlias
*alias
= &ppc_cpu_aliases
[i
];
10488 CpuDefinitionInfoList
*entry
;
10489 CpuDefinitionInfo
*info
;
10491 oc
= ppc_cpu_class_by_alias(alias
);
10496 info
= g_malloc0(sizeof(*info
));
10497 info
->name
= g_strdup(alias
->alias
);
10498 info
->q_typename
= g_strdup(object_class_get_name(oc
));
10500 entry
= g_malloc0(sizeof(*entry
));
10501 entry
->value
= info
;
10502 entry
->next
= cpu_list
;
10509 static void ppc_cpu_set_pc(CPUState
*cs
, vaddr value
)
10511 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10513 cpu
->env
.nip
= value
;
10516 static bool ppc_cpu_has_work(CPUState
*cs
)
10518 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10519 CPUPPCState
*env
= &cpu
->env
;
10521 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
10524 /* CPUClass::reset() */
10525 static void ppc_cpu_reset(CPUState
*s
)
10527 PowerPCCPU
*cpu
= POWERPC_CPU(s
);
10528 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10529 CPUPPCState
*env
= &cpu
->env
;
10533 pcc
->parent_reset(s
);
10535 msr
= (target_ulong
)0;
10536 msr
|= (target_ulong
)MSR_HVB
;
10537 msr
|= (target_ulong
)0 << MSR_AP
; /* TO BE CHECKED */
10538 msr
|= (target_ulong
)0 << MSR_SA
; /* TO BE CHECKED */
10539 msr
|= (target_ulong
)1 << MSR_EP
;
10540 #if defined(DO_SINGLE_STEP) && 0
10541 /* Single step trace mode */
10542 msr
|= (target_ulong
)1 << MSR_SE
;
10543 msr
|= (target_ulong
)1 << MSR_BE
;
10545 #if defined(CONFIG_USER_ONLY)
10546 msr
|= (target_ulong
)1 << MSR_FP
; /* Allow floating point usage */
10547 msr
|= (target_ulong
)1 << MSR_VR
; /* Allow altivec usage */
10548 msr
|= (target_ulong
)1 << MSR_VSX
; /* Allow VSX usage */
10549 msr
|= (target_ulong
)1 << MSR_SPE
; /* Allow SPE usage */
10550 msr
|= (target_ulong
)1 << MSR_PR
;
10551 #if defined(TARGET_PPC64)
10552 msr
|= (target_ulong
)1 << MSR_TM
; /* Transactional memory */
10554 #if !defined(TARGET_WORDS_BIGENDIAN)
10555 msr
|= (target_ulong
)1 << MSR_LE
; /* Little-endian user mode */
10556 if (!((env
->msr_mask
>> MSR_LE
) & 1)) {
10557 fprintf(stderr
, "Selected CPU does not support little-endian.\n");
10563 #if defined(TARGET_PPC64)
10564 if (env
->mmu_model
& POWERPC_MMU_64
) {
10565 msr
|= (1ULL << MSR_SF
);
10569 hreg_store_msr(env
, msr
, 1);
10571 #if !defined(CONFIG_USER_ONLY)
10572 env
->nip
= env
->hreset_vector
| env
->excp_prefix
;
10573 if (env
->mmu_model
!= POWERPC_MMU_REAL
) {
10574 ppc_tlb_invalidate_all(env
);
10578 hreg_compute_hflags(env
);
10579 env
->reserve_addr
= (target_ulong
)-1ULL;
10580 /* Be sure no exception or interrupt is pending */
10581 env
->pending_interrupts
= 0;
10582 s
->exception_index
= POWERPC_EXCP_NONE
;
10583 env
->error_code
= 0;
10585 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
10587 env
->slb_shadow_addr
= 0;
10588 env
->slb_shadow_size
= 0;
10591 #endif /* TARGET_PPC64 */
10593 for (i
= 0; i
< ARRAY_SIZE(env
->spr_cb
); i
++) {
10594 ppc_spr_t
*spr
= &env
->spr_cb
[i
];
10599 env
->spr
[i
] = spr
->default_value
;
10603 #ifndef CONFIG_USER_ONLY
10604 static bool ppc_cpu_is_big_endian(CPUState
*cs
)
10606 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10607 CPUPPCState
*env
= &cpu
->env
;
10609 cpu_synchronize_state(cs
);
10615 static void ppc_cpu_initfn(Object
*obj
)
10617 CPUState
*cs
= CPU(obj
);
10618 PowerPCCPU
*cpu
= POWERPC_CPU(obj
);
10619 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10620 CPUPPCState
*env
= &cpu
->env
;
10624 env
->msr_mask
= pcc
->msr_mask
;
10625 env
->mmu_model
= pcc
->mmu_model
;
10626 env
->excp_model
= pcc
->excp_model
;
10627 env
->bus_model
= pcc
->bus_model
;
10628 env
->insns_flags
= pcc
->insns_flags
;
10629 env
->insns_flags2
= pcc
->insns_flags2
;
10630 env
->flags
= pcc
->flags
;
10631 env
->bfd_mach
= pcc
->bfd_mach
;
10632 env
->check_pow
= pcc
->check_pow
;
10634 /* Mark HV mode as supported if the CPU has an MSR_HV bit
10635 * in the msr_mask. The mask can later be cleared by PAPR
10636 * mode but the hv mode support will remain, thus enforcing
10637 * that we cannot use priv. instructions in guest in PAPR
10638 * mode. For 970 we currently simply don't set HV in msr_mask
10639 * thus simulating an "Apple mode" 970. If we ever want to
10640 * support 970 HV mode, we'll have to add a processor attribute
10643 #if !defined(CONFIG_USER_ONLY)
10644 env
->has_hv_mode
= !!(env
->msr_mask
& MSR_HVB
);
10647 #if defined(TARGET_PPC64)
10649 env
->sps
= *pcc
->sps
;
10650 } else if (env
->mmu_model
& POWERPC_MMU_64
) {
10651 /* Use default sets of page sizes. We don't support MPSS */
10652 static const struct ppc_segment_page_sizes defsps_4k
= {
10654 { .page_shift
= 12, /* 4K */
10656 .enc
= { { .page_shift
= 12, .pte_enc
= 0 } }
10658 { .page_shift
= 24, /* 16M */
10660 .enc
= { { .page_shift
= 24, .pte_enc
= 0 } }
10664 static const struct ppc_segment_page_sizes defsps_64k
= {
10666 { .page_shift
= 12, /* 4K */
10668 .enc
= { { .page_shift
= 12, .pte_enc
= 0 } }
10670 { .page_shift
= 16, /* 64K */
10672 .enc
= { { .page_shift
= 16, .pte_enc
= 1 } }
10674 { .page_shift
= 24, /* 16M */
10676 .enc
= { { .page_shift
= 24, .pte_enc
= 0 } }
10680 env
->sps
= (env
->mmu_model
& POWERPC_MMU_64K
) ? defsps_64k
: defsps_4k
;
10682 #endif /* defined(TARGET_PPC64) */
10684 if (tcg_enabled()) {
10685 ppc_translate_init();
10689 static bool ppc_pvr_match_default(PowerPCCPUClass
*pcc
, uint32_t pvr
)
10691 return pcc
->pvr
== pvr
;
10694 static gchar
*ppc_gdb_arch_name(CPUState
*cs
)
10696 #if defined(TARGET_PPC64)
10697 return g_strdup("powerpc:common64");
10699 return g_strdup("powerpc:common");
10703 static Property ppc_cpu_properties
[] = {
10704 DEFINE_PROP_BOOL("pre-2.8-migration", PowerPCCPU
, pre_2_8_migration
, false),
10705 DEFINE_PROP_BOOL("pre-2.10-migration", PowerPCCPU
, pre_2_10_migration
,
10707 DEFINE_PROP_END_OF_LIST(),
10710 static void ppc_cpu_class_init(ObjectClass
*oc
, void *data
)
10712 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10713 CPUClass
*cc
= CPU_CLASS(oc
);
10714 DeviceClass
*dc
= DEVICE_CLASS(oc
);
10716 pcc
->parent_realize
= dc
->realize
;
10717 pcc
->parent_unrealize
= dc
->unrealize
;
10718 pcc
->pvr_match
= ppc_pvr_match_default
;
10719 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_always
;
10720 dc
->realize
= ppc_cpu_realizefn
;
10721 dc
->unrealize
= ppc_cpu_unrealizefn
;
10722 dc
->props
= ppc_cpu_properties
;
10724 pcc
->parent_reset
= cc
->reset
;
10725 cc
->reset
= ppc_cpu_reset
;
10727 cc
->class_by_name
= ppc_cpu_class_by_name
;
10728 cc
->has_work
= ppc_cpu_has_work
;
10729 cc
->do_interrupt
= ppc_cpu_do_interrupt
;
10730 cc
->cpu_exec_interrupt
= ppc_cpu_exec_interrupt
;
10731 cc
->dump_state
= ppc_cpu_dump_state
;
10732 cc
->dump_statistics
= ppc_cpu_dump_statistics
;
10733 cc
->set_pc
= ppc_cpu_set_pc
;
10734 cc
->gdb_read_register
= ppc_cpu_gdb_read_register
;
10735 cc
->gdb_write_register
= ppc_cpu_gdb_write_register
;
10736 #ifdef CONFIG_USER_ONLY
10737 cc
->handle_mmu_fault
= ppc_cpu_handle_mmu_fault
;
10739 cc
->get_phys_page_debug
= ppc_cpu_get_phys_page_debug
;
10740 cc
->vmsd
= &vmstate_ppc_cpu
;
10742 #if defined(CONFIG_SOFTMMU)
10743 cc
->write_elf64_note
= ppc64_cpu_write_elf64_note
;
10744 cc
->write_elf32_note
= ppc32_cpu_write_elf32_note
;
10747 cc
->gdb_num_core_regs
= 71;
10749 #ifdef USE_APPLE_GDB
10750 cc
->gdb_read_register
= ppc_cpu_gdb_read_register_apple
;
10751 cc
->gdb_write_register
= ppc_cpu_gdb_write_register_apple
;
10752 cc
->gdb_num_core_regs
= 71 + 32;
10755 cc
->gdb_arch_name
= ppc_gdb_arch_name
;
10756 #if defined(TARGET_PPC64)
10757 cc
->gdb_core_xml_file
= "power64-core.xml";
10759 cc
->gdb_core_xml_file
= "power-core.xml";
10761 #ifndef CONFIG_USER_ONLY
10762 cc
->virtio_is_big_endian
= ppc_cpu_is_big_endian
;
10765 dc
->fw_name
= "PowerPC,UNKNOWN";
10768 static const TypeInfo ppc_cpu_type_info
= {
10769 .name
= TYPE_POWERPC_CPU
,
10770 .parent
= TYPE_CPU
,
10771 .instance_size
= sizeof(PowerPCCPU
),
10772 .instance_init
= ppc_cpu_initfn
,
10774 .class_size
= sizeof(PowerPCCPUClass
),
10775 .class_init
= ppc_cpu_class_init
,
10778 static const TypeInfo ppc_vhyp_type_info
= {
10779 .name
= TYPE_PPC_VIRTUAL_HYPERVISOR
,
10780 .parent
= TYPE_INTERFACE
,
10781 .class_size
= sizeof(PPCVirtualHypervisorClass
),
10784 static void ppc_cpu_register_types(void)
10786 type_register_static(&ppc_cpu_type_info
);
10787 type_register_static(&ppc_vhyp_type_info
);
10790 type_init(ppc_cpu_register_types
)