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
,
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
,
1889 0x00000000); /* TOFIX */
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
);
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
{
4893 static void init_proc_e500(CPUPPCState
*env
, int version
)
4895 PowerPCCPU
*cpu
= ppc_env_get_cpu(env
);
4896 uint32_t tlbncfg
[2];
4898 uint64_t ivpr_mask
= 0xFFFF0000ULL
;
4899 uint32_t l1cfg0
= 0x3800 /* 8 ways */
4900 | 0x0020; /* 32 kb */
4901 uint32_t l1cfg1
= 0x3800 /* 8 ways */
4902 | 0x0020; /* 32 kb */
4903 #if !defined(CONFIG_USER_ONLY)
4910 * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't
4911 * complain when accessing them.
4912 * gen_spr_BookE(env, 0x0000000F0000FD7FULL);
4918 ivor_mask
= 0x0000000F0000FFFFULL
;
4922 ivor_mask
= 0x000003FE0000FFFFULL
;
4925 gen_spr_BookE(env
, ivor_mask
);
4926 gen_spr_usprg3(env
);
4927 /* Processor identification */
4928 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4929 SPR_NOACCESS
, SPR_NOACCESS
,
4930 &spr_read_generic
, &spr_write_pir
,
4932 /* XXX : not implemented */
4933 spr_register(env
, SPR_BOOKE_SPEFSCR
, "SPEFSCR",
4934 &spr_read_spefscr
, &spr_write_spefscr
,
4935 &spr_read_spefscr
, &spr_write_spefscr
,
4937 #if !defined(CONFIG_USER_ONLY)
4938 /* Memory management */
4944 tlbncfg
[0] = gen_tlbncfg(2, 1, 1, 0, 256);
4945 tlbncfg
[1] = gen_tlbncfg(16, 1, 9, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 16);
4948 tlbncfg
[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4949 tlbncfg
[1] = gen_tlbncfg(16, 1, 12, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 16);
4953 tlbncfg
[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4954 tlbncfg
[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 64);
4957 cpu_abort(CPU(cpu
), "Unknown CPU: " TARGET_FMT_lx
"\n", env
->spr
[SPR_PVR
]);
4964 env
->dcache_line_size
= 32;
4965 env
->icache_line_size
= 32;
4969 env
->dcache_line_size
= 64;
4970 env
->icache_line_size
= 64;
4971 l1cfg0
|= 0x1000000; /* 64 byte cache block size */
4972 l1cfg1
|= 0x1000000; /* 64 byte cache block size */
4975 cpu_abort(CPU(cpu
), "Unknown CPU: " TARGET_FMT_lx
"\n", env
->spr
[SPR_PVR
]);
4977 gen_spr_BookE206(env
, 0x000000DF, tlbncfg
);
4978 /* XXX : not implemented */
4979 spr_register(env
, SPR_HID0
, "HID0",
4980 SPR_NOACCESS
, SPR_NOACCESS
,
4981 &spr_read_generic
, &spr_write_generic
,
4983 /* XXX : not implemented */
4984 spr_register(env
, SPR_HID1
, "HID1",
4985 SPR_NOACCESS
, SPR_NOACCESS
,
4986 &spr_read_generic
, &spr_write_generic
,
4988 /* XXX : not implemented */
4989 spr_register(env
, SPR_Exxx_BBEAR
, "BBEAR",
4990 SPR_NOACCESS
, SPR_NOACCESS
,
4991 &spr_read_generic
, &spr_write_generic
,
4993 /* XXX : not implemented */
4994 spr_register(env
, SPR_Exxx_BBTAR
, "BBTAR",
4995 SPR_NOACCESS
, SPR_NOACCESS
,
4996 &spr_read_generic
, &spr_write_generic
,
4998 /* XXX : not implemented */
4999 spr_register(env
, SPR_Exxx_MCAR
, "MCAR",
5000 SPR_NOACCESS
, SPR_NOACCESS
,
5001 &spr_read_generic
, &spr_write_generic
,
5003 /* XXX : not implemented */
5004 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
5005 SPR_NOACCESS
, SPR_NOACCESS
,
5006 &spr_read_generic
, &spr_write_generic
,
5008 /* XXX : not implemented */
5009 spr_register(env
, SPR_Exxx_NPIDR
, "NPIDR",
5010 SPR_NOACCESS
, SPR_NOACCESS
,
5011 &spr_read_generic
, &spr_write_generic
,
5013 /* XXX : not implemented */
5014 spr_register(env
, SPR_Exxx_BUCSR
, "BUCSR",
5015 SPR_NOACCESS
, SPR_NOACCESS
,
5016 &spr_read_generic
, &spr_write_generic
,
5018 /* XXX : not implemented */
5019 spr_register(env
, SPR_Exxx_L1CFG0
, "L1CFG0",
5020 &spr_read_generic
, SPR_NOACCESS
,
5021 &spr_read_generic
, SPR_NOACCESS
,
5023 spr_register(env
, SPR_Exxx_L1CFG1
, "L1CFG1",
5024 &spr_read_generic
, SPR_NOACCESS
,
5025 &spr_read_generic
, SPR_NOACCESS
,
5027 spr_register(env
, SPR_Exxx_L1CSR0
, "L1CSR0",
5028 SPR_NOACCESS
, SPR_NOACCESS
,
5029 &spr_read_generic
, &spr_write_e500_l1csr0
,
5031 spr_register(env
, SPR_Exxx_L1CSR1
, "L1CSR1",
5032 SPR_NOACCESS
, SPR_NOACCESS
,
5033 &spr_read_generic
, &spr_write_e500_l1csr1
,
5035 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
5036 SPR_NOACCESS
, SPR_NOACCESS
,
5037 &spr_read_generic
, &spr_write_generic
,
5039 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
5040 SPR_NOACCESS
, SPR_NOACCESS
,
5041 &spr_read_generic
, &spr_write_generic
,
5043 spr_register(env
, SPR_MMUCSR0
, "MMUCSR0",
5044 SPR_NOACCESS
, SPR_NOACCESS
,
5045 &spr_read_generic
, &spr_write_booke206_mmucsr0
,
5047 spr_register(env
, SPR_BOOKE_EPR
, "EPR",
5048 SPR_NOACCESS
, SPR_NOACCESS
,
5049 &spr_read_generic
, SPR_NOACCESS
,
5051 /* XXX better abstract into Emb.xxx features */
5052 if (version
== fsl_e5500
) {
5053 spr_register(env
, SPR_BOOKE_EPCR
, "EPCR",
5054 SPR_NOACCESS
, SPR_NOACCESS
,
5055 &spr_read_generic
, &spr_write_generic
,
5057 spr_register(env
, SPR_BOOKE_MAS7_MAS3
, "MAS7_MAS3",
5058 SPR_NOACCESS
, SPR_NOACCESS
,
5059 &spr_read_mas73
, &spr_write_mas73
,
5061 ivpr_mask
= (target_ulong
)~0xFFFFULL
;
5064 #if !defined(CONFIG_USER_ONLY)
5066 env
->tlb_type
= TLB_MAS
;
5067 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
5068 env
->nb_tlb
+= booke206_tlb_size(env
, i
);
5072 init_excp_e200(env
, ivpr_mask
);
5073 /* Allocate hardware IRQ controller */
5074 ppce500_irq_init(ppc_env_get_cpu(env
));
5077 static void init_proc_e500v1(CPUPPCState
*env
)
5079 init_proc_e500(env
, fsl_e500v1
);
5082 POWERPC_FAMILY(e500v1
)(ObjectClass
*oc
, void *data
)
5084 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5085 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5087 dc
->desc
= "e500v1 core";
5088 pcc
->init_proc
= init_proc_e500v1
;
5089 pcc
->check_pow
= check_pow_hid0
;
5090 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
5091 PPC_SPE
| PPC_SPE_SINGLE
|
5092 PPC_WRTEE
| PPC_RFDI
|
5093 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5094 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5095 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5096 pcc
->insns_flags2
= PPC2_BOOKE206
;
5097 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
5111 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5112 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5113 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5114 pcc
->bfd_mach
= bfd_mach_ppc_860
;
5115 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
5116 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
5117 POWERPC_FLAG_BUS_CLK
;
5120 static void init_proc_e500v2(CPUPPCState
*env
)
5122 init_proc_e500(env
, fsl_e500v2
);
5125 POWERPC_FAMILY(e500v2
)(ObjectClass
*oc
, void *data
)
5127 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5128 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5130 dc
->desc
= "e500v2 core";
5131 pcc
->init_proc
= init_proc_e500v2
;
5132 pcc
->check_pow
= check_pow_hid0
;
5133 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
5134 PPC_SPE
| PPC_SPE_SINGLE
| PPC_SPE_DOUBLE
|
5135 PPC_WRTEE
| PPC_RFDI
|
5136 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5137 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5138 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5139 pcc
->insns_flags2
= PPC2_BOOKE206
;
5140 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
5154 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5155 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5156 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5157 pcc
->bfd_mach
= bfd_mach_ppc_860
;
5158 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
5159 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
5160 POWERPC_FLAG_BUS_CLK
;
5163 static void init_proc_e500mc(CPUPPCState
*env
)
5165 init_proc_e500(env
, fsl_e500mc
);
5168 POWERPC_FAMILY(e500mc
)(ObjectClass
*oc
, void *data
)
5170 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5171 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5173 dc
->desc
= "e500mc core";
5174 pcc
->init_proc
= init_proc_e500mc
;
5175 pcc
->check_pow
= check_pow_none
;
5176 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5177 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5178 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5179 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5180 PPC_FLOAT
| PPC_FLOAT_FRES
|
5181 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5182 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5183 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5184 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
;
5185 pcc
->msr_mask
= (1ull << MSR_GS
) |
5186 (1ull << MSR_UCLE
) |
5199 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5200 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5201 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5202 /* FIXME: figure out the correct flag for e500mc */
5203 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5204 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5205 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5209 static void init_proc_e5500(CPUPPCState
*env
)
5211 init_proc_e500(env
, fsl_e5500
);
5214 POWERPC_FAMILY(e5500
)(ObjectClass
*oc
, void *data
)
5216 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5217 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5219 dc
->desc
= "e5500 core";
5220 pcc
->init_proc
= init_proc_e5500
;
5221 pcc
->check_pow
= check_pow_none
;
5222 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5223 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5224 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5225 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5226 PPC_FLOAT
| PPC_FLOAT_FRES
|
5227 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5228 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5229 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
|
5230 PPC_64B
| PPC_POPCNTB
| PPC_POPCNTWD
;
5231 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
| PPC2_PERM_ISA206
| \
5233 pcc
->msr_mask
= (1ull << MSR_CM
) |
5235 (1ull << MSR_UCLE
) |
5248 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5249 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5250 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5251 /* FIXME: figure out the correct flag for e5500 */
5252 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5253 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5254 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5258 /* Non-embedded PowerPC */
5260 #define POWERPC_MSRR_601 (0x0000000000001040ULL)
5262 static void init_proc_601(CPUPPCState
*env
)
5264 gen_spr_ne_601(env
);
5267 /* Hardware implementation registers */
5268 /* XXX : not implemented */
5269 spr_register(env
, SPR_HID0
, "HID0",
5270 SPR_NOACCESS
, SPR_NOACCESS
,
5271 &spr_read_generic
, &spr_write_hid0_601
,
5273 /* XXX : not implemented */
5274 spr_register(env
, SPR_HID1
, "HID1",
5275 SPR_NOACCESS
, SPR_NOACCESS
,
5276 &spr_read_generic
, &spr_write_generic
,
5278 /* XXX : not implemented */
5279 spr_register(env
, SPR_601_HID2
, "HID2",
5280 SPR_NOACCESS
, SPR_NOACCESS
,
5281 &spr_read_generic
, &spr_write_generic
,
5283 /* XXX : not implemented */
5284 spr_register(env
, SPR_601_HID5
, "HID5",
5285 SPR_NOACCESS
, SPR_NOACCESS
,
5286 &spr_read_generic
, &spr_write_generic
,
5288 /* Memory management */
5290 /* XXX: beware that dcache line size is 64
5291 * but dcbz uses 32 bytes "sectors"
5292 * XXX: this breaks clcs instruction !
5294 env
->dcache_line_size
= 32;
5295 env
->icache_line_size
= 64;
5296 /* Allocate hardware IRQ controller */
5297 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5300 POWERPC_FAMILY(601)(ObjectClass
*oc
, void *data
)
5302 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5303 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5305 dc
->desc
= "PowerPC 601";
5306 pcc
->init_proc
= init_proc_601
;
5307 pcc
->check_pow
= check_pow_none
;
5308 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_POWER_BR
|
5310 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5311 PPC_MEM_SYNC
| PPC_MEM_EIEIO
| PPC_MEM_TLBIE
|
5312 PPC_SEGMENT
| PPC_EXTERN
;
5313 pcc
->msr_mask
= (1ull << MSR_EE
) |
5323 pcc
->mmu_model
= POWERPC_MMU_601
;
5324 #if defined(CONFIG_SOFTMMU)
5325 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5327 pcc
->excp_model
= POWERPC_EXCP_601
;
5328 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5329 pcc
->bfd_mach
= bfd_mach_ppc_601
;
5330 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_RTC_CLK
;
5333 #define POWERPC_MSRR_601v (0x0000000000001040ULL)
5335 static void init_proc_601v(CPUPPCState
*env
)
5338 /* XXX : not implemented */
5339 spr_register(env
, SPR_601_HID15
, "HID15",
5340 SPR_NOACCESS
, SPR_NOACCESS
,
5341 &spr_read_generic
, &spr_write_generic
,
5345 POWERPC_FAMILY(601v
)(ObjectClass
*oc
, void *data
)
5347 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5348 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5350 dc
->desc
= "PowerPC 601v";
5351 pcc
->init_proc
= init_proc_601v
;
5352 pcc
->check_pow
= check_pow_none
;
5353 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_POWER_BR
|
5355 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5356 PPC_MEM_SYNC
| PPC_MEM_EIEIO
| PPC_MEM_TLBIE
|
5357 PPC_SEGMENT
| PPC_EXTERN
;
5358 pcc
->msr_mask
= (1ull << MSR_EE
) |
5368 pcc
->mmu_model
= POWERPC_MMU_601
;
5369 #if defined(CONFIG_SOFTMMU)
5370 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5372 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5373 pcc
->bfd_mach
= bfd_mach_ppc_601
;
5374 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_RTC_CLK
;
5377 static void init_proc_602(CPUPPCState
*env
)
5379 gen_spr_ne_601(env
);
5384 /* hardware implementation registers */
5385 /* XXX : not implemented */
5386 spr_register(env
, SPR_HID0
, "HID0",
5387 SPR_NOACCESS
, SPR_NOACCESS
,
5388 &spr_read_generic
, &spr_write_generic
,
5390 /* XXX : not implemented */
5391 spr_register(env
, SPR_HID1
, "HID1",
5392 SPR_NOACCESS
, SPR_NOACCESS
,
5393 &spr_read_generic
, &spr_write_generic
,
5395 /* Memory management */
5397 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5399 env
->dcache_line_size
= 32;
5400 env
->icache_line_size
= 32;
5401 /* Allocate hardware IRQ controller */
5402 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5405 POWERPC_FAMILY(602)(ObjectClass
*oc
, void *data
)
5407 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5408 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5410 dc
->desc
= "PowerPC 602";
5411 pcc
->init_proc
= init_proc_602
;
5412 pcc
->check_pow
= check_pow_hid0
;
5413 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5414 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5415 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5416 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5417 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5418 PPC_MEM_TLBIE
| PPC_6xx_TLB
| PPC_MEM_TLBSYNC
|
5419 PPC_SEGMENT
| PPC_602_SPEC
;
5420 pcc
->msr_mask
= (1ull << MSR_VSX
) |
5423 (1ull << MSR_TGPR
) |
5438 /* XXX: 602 MMU is quite specific. Should add a special case */
5439 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5440 pcc
->excp_model
= POWERPC_EXCP_602
;
5441 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5442 pcc
->bfd_mach
= bfd_mach_ppc_602
;
5443 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5444 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5447 static void init_proc_603(CPUPPCState
*env
)
5449 gen_spr_ne_601(env
);
5454 /* hardware implementation registers */
5455 /* XXX : not implemented */
5456 spr_register(env
, SPR_HID0
, "HID0",
5457 SPR_NOACCESS
, SPR_NOACCESS
,
5458 &spr_read_generic
, &spr_write_generic
,
5460 /* XXX : not implemented */
5461 spr_register(env
, SPR_HID1
, "HID1",
5462 SPR_NOACCESS
, SPR_NOACCESS
,
5463 &spr_read_generic
, &spr_write_generic
,
5465 /* Memory management */
5467 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5469 env
->dcache_line_size
= 32;
5470 env
->icache_line_size
= 32;
5471 /* Allocate hardware IRQ controller */
5472 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5475 POWERPC_FAMILY(603)(ObjectClass
*oc
, void *data
)
5477 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5478 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5480 dc
->desc
= "PowerPC 603";
5481 pcc
->init_proc
= init_proc_603
;
5482 pcc
->check_pow
= check_pow_hid0
;
5483 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5484 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5485 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5486 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5487 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5488 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
5489 PPC_SEGMENT
| PPC_EXTERN
;
5490 pcc
->msr_mask
= (1ull << MSR_POW
) |
5491 (1ull << MSR_TGPR
) |
5506 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5507 pcc
->excp_model
= POWERPC_EXCP_603
;
5508 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5509 pcc
->bfd_mach
= bfd_mach_ppc_603
;
5510 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5511 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5514 static void init_proc_603E(CPUPPCState
*env
)
5516 gen_spr_ne_601(env
);
5521 /* hardware implementation registers */
5522 /* XXX : not implemented */
5523 spr_register(env
, SPR_HID0
, "HID0",
5524 SPR_NOACCESS
, SPR_NOACCESS
,
5525 &spr_read_generic
, &spr_write_generic
,
5527 /* XXX : not implemented */
5528 spr_register(env
, SPR_HID1
, "HID1",
5529 SPR_NOACCESS
, SPR_NOACCESS
,
5530 &spr_read_generic
, &spr_write_generic
,
5532 /* Memory management */
5534 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5536 env
->dcache_line_size
= 32;
5537 env
->icache_line_size
= 32;
5538 /* Allocate hardware IRQ controller */
5539 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5542 POWERPC_FAMILY(603E
)(ObjectClass
*oc
, void *data
)
5544 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5545 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5547 dc
->desc
= "PowerPC 603e";
5548 pcc
->init_proc
= init_proc_603E
;
5549 pcc
->check_pow
= check_pow_hid0
;
5550 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5551 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5552 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5553 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5554 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5555 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
5556 PPC_SEGMENT
| PPC_EXTERN
;
5557 pcc
->msr_mask
= (1ull << MSR_POW
) |
5558 (1ull << MSR_TGPR
) |
5573 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5574 pcc
->excp_model
= POWERPC_EXCP_603E
;
5575 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5576 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
5577 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5578 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5581 static void init_proc_604(CPUPPCState
*env
)
5583 gen_spr_ne_601(env
);
5588 /* Hardware implementation registers */
5589 /* XXX : not implemented */
5590 spr_register(env
, SPR_HID0
, "HID0",
5591 SPR_NOACCESS
, SPR_NOACCESS
,
5592 &spr_read_generic
, &spr_write_generic
,
5594 /* Memory management */
5597 env
->dcache_line_size
= 32;
5598 env
->icache_line_size
= 32;
5599 /* Allocate hardware IRQ controller */
5600 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5603 POWERPC_FAMILY(604)(ObjectClass
*oc
, void *data
)
5605 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5606 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5608 dc
->desc
= "PowerPC 604";
5609 pcc
->init_proc
= init_proc_604
;
5610 pcc
->check_pow
= check_pow_nocheck
;
5611 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5612 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5613 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5614 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5615 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5616 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5617 PPC_SEGMENT
| PPC_EXTERN
;
5618 pcc
->msr_mask
= (1ull << MSR_POW
) |
5634 pcc
->mmu_model
= POWERPC_MMU_32B
;
5635 #if defined(CONFIG_SOFTMMU)
5636 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5638 pcc
->excp_model
= POWERPC_EXCP_604
;
5639 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5640 pcc
->bfd_mach
= bfd_mach_ppc_604
;
5641 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5642 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5645 static void init_proc_604E(CPUPPCState
*env
)
5647 gen_spr_ne_601(env
);
5650 /* XXX : not implemented */
5651 spr_register(env
, SPR_7XX_MMCR1
, "MMCR1",
5652 SPR_NOACCESS
, SPR_NOACCESS
,
5653 &spr_read_generic
, &spr_write_generic
,
5655 /* XXX : not implemented */
5656 spr_register(env
, SPR_7XX_PMC3
, "PMC3",
5657 SPR_NOACCESS
, SPR_NOACCESS
,
5658 &spr_read_generic
, &spr_write_generic
,
5660 /* XXX : not implemented */
5661 spr_register(env
, SPR_7XX_PMC4
, "PMC4",
5662 SPR_NOACCESS
, SPR_NOACCESS
,
5663 &spr_read_generic
, &spr_write_generic
,
5667 /* Hardware implementation registers */
5668 /* XXX : not implemented */
5669 spr_register(env
, SPR_HID0
, "HID0",
5670 SPR_NOACCESS
, SPR_NOACCESS
,
5671 &spr_read_generic
, &spr_write_generic
,
5673 /* XXX : not implemented */
5674 spr_register(env
, SPR_HID1
, "HID1",
5675 SPR_NOACCESS
, SPR_NOACCESS
,
5676 &spr_read_generic
, &spr_write_generic
,
5678 /* Memory management */
5681 env
->dcache_line_size
= 32;
5682 env
->icache_line_size
= 32;
5683 /* Allocate hardware IRQ controller */
5684 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5687 POWERPC_FAMILY(604E
)(ObjectClass
*oc
, void *data
)
5689 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5690 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5692 dc
->desc
= "PowerPC 604E";
5693 pcc
->init_proc
= init_proc_604E
;
5694 pcc
->check_pow
= check_pow_nocheck
;
5695 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5696 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5697 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5698 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5699 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5700 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5701 PPC_SEGMENT
| PPC_EXTERN
;
5702 pcc
->msr_mask
= (1ull << MSR_POW
) |
5718 pcc
->mmu_model
= POWERPC_MMU_32B
;
5719 #if defined(CONFIG_SOFTMMU)
5720 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5722 pcc
->excp_model
= POWERPC_EXCP_604
;
5723 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5724 pcc
->bfd_mach
= bfd_mach_ppc_604
;
5725 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5726 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5729 static void init_proc_740(CPUPPCState
*env
)
5731 gen_spr_ne_601(env
);
5736 /* Thermal management */
5738 /* Hardware implementation registers */
5739 /* XXX : not implemented */
5740 spr_register(env
, SPR_HID0
, "HID0",
5741 SPR_NOACCESS
, SPR_NOACCESS
,
5742 &spr_read_generic
, &spr_write_generic
,
5744 /* XXX : not implemented */
5745 spr_register(env
, SPR_HID1
, "HID1",
5746 SPR_NOACCESS
, SPR_NOACCESS
,
5747 &spr_read_generic
, &spr_write_generic
,
5749 /* Memory management */
5752 env
->dcache_line_size
= 32;
5753 env
->icache_line_size
= 32;
5754 /* Allocate hardware IRQ controller */
5755 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5758 POWERPC_FAMILY(740)(ObjectClass
*oc
, void *data
)
5760 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5761 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5763 dc
->desc
= "PowerPC 740";
5764 pcc
->init_proc
= init_proc_740
;
5765 pcc
->check_pow
= check_pow_hid0
;
5766 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5767 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5768 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5769 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5770 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5771 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5772 PPC_SEGMENT
| PPC_EXTERN
;
5773 pcc
->msr_mask
= (1ull << MSR_POW
) |
5789 pcc
->mmu_model
= POWERPC_MMU_32B
;
5790 #if defined(CONFIG_SOFTMMU)
5791 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5793 pcc
->excp_model
= POWERPC_EXCP_7x0
;
5794 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5795 pcc
->bfd_mach
= bfd_mach_ppc_750
;
5796 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5797 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5800 static void init_proc_750(CPUPPCState
*env
)
5802 gen_spr_ne_601(env
);
5805 /* XXX : not implemented */
5806 spr_register(env
, SPR_L2CR
, "L2CR",
5807 SPR_NOACCESS
, SPR_NOACCESS
,
5808 &spr_read_generic
, spr_access_nop
,
5812 /* Thermal management */
5814 /* Hardware implementation registers */
5815 /* XXX : not implemented */
5816 spr_register(env
, SPR_HID0
, "HID0",
5817 SPR_NOACCESS
, SPR_NOACCESS
,
5818 &spr_read_generic
, &spr_write_generic
,
5820 /* XXX : not implemented */
5821 spr_register(env
, SPR_HID1
, "HID1",
5822 SPR_NOACCESS
, SPR_NOACCESS
,
5823 &spr_read_generic
, &spr_write_generic
,
5825 /* Memory management */
5827 /* XXX: high BATs are also present but are known to be bugged on
5831 env
->dcache_line_size
= 32;
5832 env
->icache_line_size
= 32;
5833 /* Allocate hardware IRQ controller */
5834 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5837 POWERPC_FAMILY(750)(ObjectClass
*oc
, void *data
)
5839 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5840 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5842 dc
->desc
= "PowerPC 750";
5843 pcc
->init_proc
= init_proc_750
;
5844 pcc
->check_pow
= check_pow_hid0
;
5845 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5846 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5847 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5848 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5849 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5850 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5851 PPC_SEGMENT
| PPC_EXTERN
;
5852 pcc
->msr_mask
= (1ull << MSR_POW
) |
5868 pcc
->mmu_model
= POWERPC_MMU_32B
;
5869 #if defined(CONFIG_SOFTMMU)
5870 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5872 pcc
->excp_model
= POWERPC_EXCP_7x0
;
5873 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5874 pcc
->bfd_mach
= bfd_mach_ppc_750
;
5875 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5876 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5879 static void init_proc_750cl(CPUPPCState
*env
)
5881 gen_spr_ne_601(env
);
5884 /* XXX : not implemented */
5885 spr_register(env
, SPR_L2CR
, "L2CR",
5886 SPR_NOACCESS
, SPR_NOACCESS
,
5887 &spr_read_generic
, spr_access_nop
,
5891 /* Thermal management */
5892 /* Those registers are fake on 750CL */
5893 spr_register(env
, SPR_THRM1
, "THRM1",
5894 SPR_NOACCESS
, SPR_NOACCESS
,
5895 &spr_read_generic
, &spr_write_generic
,
5897 spr_register(env
, SPR_THRM2
, "THRM2",
5898 SPR_NOACCESS
, SPR_NOACCESS
,
5899 &spr_read_generic
, &spr_write_generic
,
5901 spr_register(env
, SPR_THRM3
, "THRM3",
5902 SPR_NOACCESS
, SPR_NOACCESS
,
5903 &spr_read_generic
, &spr_write_generic
,
5905 /* XXX: not implemented */
5906 spr_register(env
, SPR_750_TDCL
, "TDCL",
5907 SPR_NOACCESS
, SPR_NOACCESS
,
5908 &spr_read_generic
, &spr_write_generic
,
5910 spr_register(env
, SPR_750_TDCH
, "TDCH",
5911 SPR_NOACCESS
, SPR_NOACCESS
,
5912 &spr_read_generic
, &spr_write_generic
,
5915 /* XXX : not implemented */
5916 spr_register(env
, SPR_750_WPAR
, "WPAR",
5917 SPR_NOACCESS
, SPR_NOACCESS
,
5918 &spr_read_generic
, &spr_write_generic
,
5920 spr_register(env
, SPR_750_DMAL
, "DMAL",
5921 SPR_NOACCESS
, SPR_NOACCESS
,
5922 &spr_read_generic
, &spr_write_generic
,
5924 spr_register(env
, SPR_750_DMAU
, "DMAU",
5925 SPR_NOACCESS
, SPR_NOACCESS
,
5926 &spr_read_generic
, &spr_write_generic
,
5928 /* Hardware implementation registers */
5929 /* XXX : not implemented */
5930 spr_register(env
, SPR_HID0
, "HID0",
5931 SPR_NOACCESS
, SPR_NOACCESS
,
5932 &spr_read_generic
, &spr_write_generic
,
5934 /* XXX : not implemented */
5935 spr_register(env
, SPR_HID1
, "HID1",
5936 SPR_NOACCESS
, SPR_NOACCESS
,
5937 &spr_read_generic
, &spr_write_generic
,
5939 /* XXX : not implemented */
5940 spr_register(env
, SPR_750CL_HID2
, "HID2",
5941 SPR_NOACCESS
, SPR_NOACCESS
,
5942 &spr_read_generic
, &spr_write_generic
,
5944 /* XXX : not implemented */
5945 spr_register(env
, SPR_750CL_HID4
, "HID4",
5946 SPR_NOACCESS
, SPR_NOACCESS
,
5947 &spr_read_generic
, &spr_write_generic
,
5949 /* Quantization registers */
5950 /* XXX : not implemented */
5951 spr_register(env
, SPR_750_GQR0
, "GQR0",
5952 SPR_NOACCESS
, SPR_NOACCESS
,
5953 &spr_read_generic
, &spr_write_generic
,
5955 /* XXX : not implemented */
5956 spr_register(env
, SPR_750_GQR1
, "GQR1",
5957 SPR_NOACCESS
, SPR_NOACCESS
,
5958 &spr_read_generic
, &spr_write_generic
,
5960 /* XXX : not implemented */
5961 spr_register(env
, SPR_750_GQR2
, "GQR2",
5962 SPR_NOACCESS
, SPR_NOACCESS
,
5963 &spr_read_generic
, &spr_write_generic
,
5965 /* XXX : not implemented */
5966 spr_register(env
, SPR_750_GQR3
, "GQR3",
5967 SPR_NOACCESS
, SPR_NOACCESS
,
5968 &spr_read_generic
, &spr_write_generic
,
5970 /* XXX : not implemented */
5971 spr_register(env
, SPR_750_GQR4
, "GQR4",
5972 SPR_NOACCESS
, SPR_NOACCESS
,
5973 &spr_read_generic
, &spr_write_generic
,
5975 /* XXX : not implemented */
5976 spr_register(env
, SPR_750_GQR5
, "GQR5",
5977 SPR_NOACCESS
, SPR_NOACCESS
,
5978 &spr_read_generic
, &spr_write_generic
,
5980 /* XXX : not implemented */
5981 spr_register(env
, SPR_750_GQR6
, "GQR6",
5982 SPR_NOACCESS
, SPR_NOACCESS
,
5983 &spr_read_generic
, &spr_write_generic
,
5985 /* XXX : not implemented */
5986 spr_register(env
, SPR_750_GQR7
, "GQR7",
5987 SPR_NOACCESS
, SPR_NOACCESS
,
5988 &spr_read_generic
, &spr_write_generic
,
5990 /* Memory management */
5992 /* PowerPC 750cl has 8 DBATs and 8 IBATs */
5994 init_excp_750cl(env
);
5995 env
->dcache_line_size
= 32;
5996 env
->icache_line_size
= 32;
5997 /* Allocate hardware IRQ controller */
5998 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6001 POWERPC_FAMILY(750cl
)(ObjectClass
*oc
, void *data
)
6003 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6004 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6006 dc
->desc
= "PowerPC 750 CL";
6007 pcc
->init_proc
= init_proc_750cl
;
6008 pcc
->check_pow
= check_pow_hid0
;
6009 /* XXX: not implemented:
6010 * cache lock instructions:
6012 * floating point paired instructions
6047 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6048 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6049 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6050 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6051 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6052 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6053 PPC_SEGMENT
| PPC_EXTERN
;
6054 pcc
->msr_mask
= (1ull << MSR_POW
) |
6070 pcc
->mmu_model
= POWERPC_MMU_32B
;
6071 #if defined(CONFIG_SOFTMMU)
6072 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6074 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6075 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6076 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6077 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6078 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6081 static void init_proc_750cx(CPUPPCState
*env
)
6083 gen_spr_ne_601(env
);
6086 /* XXX : not implemented */
6087 spr_register(env
, SPR_L2CR
, "L2CR",
6088 SPR_NOACCESS
, SPR_NOACCESS
,
6089 &spr_read_generic
, spr_access_nop
,
6093 /* Thermal management */
6095 /* This register is not implemented but is present for compatibility */
6096 spr_register(env
, SPR_SDA
, "SDA",
6097 SPR_NOACCESS
, SPR_NOACCESS
,
6098 &spr_read_generic
, &spr_write_generic
,
6100 /* Hardware implementation registers */
6101 /* XXX : not implemented */
6102 spr_register(env
, SPR_HID0
, "HID0",
6103 SPR_NOACCESS
, SPR_NOACCESS
,
6104 &spr_read_generic
, &spr_write_generic
,
6106 /* XXX : not implemented */
6107 spr_register(env
, SPR_HID1
, "HID1",
6108 SPR_NOACCESS
, SPR_NOACCESS
,
6109 &spr_read_generic
, &spr_write_generic
,
6111 /* Memory management */
6113 /* PowerPC 750cx has 8 DBATs and 8 IBATs */
6115 init_excp_750cx(env
);
6116 env
->dcache_line_size
= 32;
6117 env
->icache_line_size
= 32;
6118 /* Allocate hardware IRQ controller */
6119 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6122 POWERPC_FAMILY(750cx
)(ObjectClass
*oc
, void *data
)
6124 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6125 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6127 dc
->desc
= "PowerPC 750CX";
6128 pcc
->init_proc
= init_proc_750cx
;
6129 pcc
->check_pow
= check_pow_hid0
;
6130 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6131 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6132 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6133 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6134 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6135 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6136 PPC_SEGMENT
| PPC_EXTERN
;
6137 pcc
->msr_mask
= (1ull << MSR_POW
) |
6153 pcc
->mmu_model
= POWERPC_MMU_32B
;
6154 #if defined(CONFIG_SOFTMMU)
6155 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6157 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6158 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6159 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6160 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6161 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6164 static void init_proc_750fx(CPUPPCState
*env
)
6166 gen_spr_ne_601(env
);
6169 /* XXX : not implemented */
6170 spr_register(env
, SPR_L2CR
, "L2CR",
6171 SPR_NOACCESS
, SPR_NOACCESS
,
6172 &spr_read_generic
, spr_access_nop
,
6176 /* Thermal management */
6178 /* XXX : not implemented */
6179 spr_register(env
, SPR_750_THRM4
, "THRM4",
6180 SPR_NOACCESS
, SPR_NOACCESS
,
6181 &spr_read_generic
, &spr_write_generic
,
6183 /* Hardware implementation registers */
6184 /* XXX : not implemented */
6185 spr_register(env
, SPR_HID0
, "HID0",
6186 SPR_NOACCESS
, SPR_NOACCESS
,
6187 &spr_read_generic
, &spr_write_generic
,
6189 /* XXX : not implemented */
6190 spr_register(env
, SPR_HID1
, "HID1",
6191 SPR_NOACCESS
, SPR_NOACCESS
,
6192 &spr_read_generic
, &spr_write_generic
,
6194 /* XXX : not implemented */
6195 spr_register(env
, SPR_750FX_HID2
, "HID2",
6196 SPR_NOACCESS
, SPR_NOACCESS
,
6197 &spr_read_generic
, &spr_write_generic
,
6199 /* Memory management */
6201 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6204 env
->dcache_line_size
= 32;
6205 env
->icache_line_size
= 32;
6206 /* Allocate hardware IRQ controller */
6207 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6210 POWERPC_FAMILY(750fx
)(ObjectClass
*oc
, void *data
)
6212 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6213 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6215 dc
->desc
= "PowerPC 750FX";
6216 pcc
->init_proc
= init_proc_750fx
;
6217 pcc
->check_pow
= check_pow_hid0
;
6218 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6219 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6220 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6221 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6222 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6223 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6224 PPC_SEGMENT
| PPC_EXTERN
;
6225 pcc
->msr_mask
= (1ull << MSR_POW
) |
6241 pcc
->mmu_model
= POWERPC_MMU_32B
;
6242 #if defined(CONFIG_SOFTMMU)
6243 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6245 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6246 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6247 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6248 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6249 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6252 static void init_proc_750gx(CPUPPCState
*env
)
6254 gen_spr_ne_601(env
);
6257 /* XXX : not implemented (XXX: different from 750fx) */
6258 spr_register(env
, SPR_L2CR
, "L2CR",
6259 SPR_NOACCESS
, SPR_NOACCESS
,
6260 &spr_read_generic
, spr_access_nop
,
6264 /* Thermal management */
6266 /* XXX : not implemented */
6267 spr_register(env
, SPR_750_THRM4
, "THRM4",
6268 SPR_NOACCESS
, SPR_NOACCESS
,
6269 &spr_read_generic
, &spr_write_generic
,
6271 /* Hardware implementation registers */
6272 /* XXX : not implemented (XXX: different from 750fx) */
6273 spr_register(env
, SPR_HID0
, "HID0",
6274 SPR_NOACCESS
, SPR_NOACCESS
,
6275 &spr_read_generic
, &spr_write_generic
,
6277 /* XXX : not implemented */
6278 spr_register(env
, SPR_HID1
, "HID1",
6279 SPR_NOACCESS
, SPR_NOACCESS
,
6280 &spr_read_generic
, &spr_write_generic
,
6282 /* XXX : not implemented (XXX: different from 750fx) */
6283 spr_register(env
, SPR_750FX_HID2
, "HID2",
6284 SPR_NOACCESS
, SPR_NOACCESS
,
6285 &spr_read_generic
, &spr_write_generic
,
6287 /* Memory management */
6289 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6292 env
->dcache_line_size
= 32;
6293 env
->icache_line_size
= 32;
6294 /* Allocate hardware IRQ controller */
6295 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6298 POWERPC_FAMILY(750gx
)(ObjectClass
*oc
, void *data
)
6300 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6301 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6303 dc
->desc
= "PowerPC 750GX";
6304 pcc
->init_proc
= init_proc_750gx
;
6305 pcc
->check_pow
= check_pow_hid0
;
6306 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6307 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6308 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6309 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6310 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6311 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6312 PPC_SEGMENT
| PPC_EXTERN
;
6313 pcc
->msr_mask
= (1ull << MSR_POW
) |
6329 pcc
->mmu_model
= POWERPC_MMU_32B
;
6330 #if defined(CONFIG_SOFTMMU)
6331 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6333 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6334 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6335 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6336 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6337 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6340 static void init_proc_745(CPUPPCState
*env
)
6342 gen_spr_ne_601(env
);
6345 gen_spr_G2_755(env
);
6348 /* Thermal management */
6350 /* Hardware implementation registers */
6351 /* XXX : not implemented */
6352 spr_register(env
, SPR_HID0
, "HID0",
6353 SPR_NOACCESS
, SPR_NOACCESS
,
6354 &spr_read_generic
, &spr_write_generic
,
6356 /* XXX : not implemented */
6357 spr_register(env
, SPR_HID1
, "HID1",
6358 SPR_NOACCESS
, SPR_NOACCESS
,
6359 &spr_read_generic
, &spr_write_generic
,
6361 /* XXX : not implemented */
6362 spr_register(env
, SPR_HID2
, "HID2",
6363 SPR_NOACCESS
, SPR_NOACCESS
,
6364 &spr_read_generic
, &spr_write_generic
,
6366 /* Memory management */
6369 gen_6xx_7xx_soft_tlb(env
, 64, 2);
6371 env
->dcache_line_size
= 32;
6372 env
->icache_line_size
= 32;
6373 /* Allocate hardware IRQ controller */
6374 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6377 POWERPC_FAMILY(745)(ObjectClass
*oc
, void *data
)
6379 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6380 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6382 dc
->desc
= "PowerPC 745";
6383 pcc
->init_proc
= init_proc_745
;
6384 pcc
->check_pow
= check_pow_hid0
;
6385 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6386 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6387 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6388 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6389 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6390 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
6391 PPC_SEGMENT
| PPC_EXTERN
;
6392 pcc
->msr_mask
= (1ull << MSR_POW
) |
6408 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
6409 pcc
->excp_model
= POWERPC_EXCP_7x5
;
6410 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6411 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6412 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6413 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6416 static void init_proc_755(CPUPPCState
*env
)
6418 gen_spr_ne_601(env
);
6421 gen_spr_G2_755(env
);
6424 /* L2 cache control */
6425 /* XXX : not implemented */
6426 spr_register(env
, SPR_L2CR
, "L2CR",
6427 SPR_NOACCESS
, SPR_NOACCESS
,
6428 &spr_read_generic
, spr_access_nop
,
6430 /* XXX : not implemented */
6431 spr_register(env
, SPR_L2PMCR
, "L2PMCR",
6432 SPR_NOACCESS
, SPR_NOACCESS
,
6433 &spr_read_generic
, &spr_write_generic
,
6435 /* Thermal management */
6437 /* Hardware implementation registers */
6438 /* XXX : not implemented */
6439 spr_register(env
, SPR_HID0
, "HID0",
6440 SPR_NOACCESS
, SPR_NOACCESS
,
6441 &spr_read_generic
, &spr_write_generic
,
6443 /* XXX : not implemented */
6444 spr_register(env
, SPR_HID1
, "HID1",
6445 SPR_NOACCESS
, SPR_NOACCESS
,
6446 &spr_read_generic
, &spr_write_generic
,
6448 /* XXX : not implemented */
6449 spr_register(env
, SPR_HID2
, "HID2",
6450 SPR_NOACCESS
, SPR_NOACCESS
,
6451 &spr_read_generic
, &spr_write_generic
,
6453 /* Memory management */
6456 gen_6xx_7xx_soft_tlb(env
, 64, 2);
6458 env
->dcache_line_size
= 32;
6459 env
->icache_line_size
= 32;
6460 /* Allocate hardware IRQ controller */
6461 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6464 POWERPC_FAMILY(755)(ObjectClass
*oc
, void *data
)
6466 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6467 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6469 dc
->desc
= "PowerPC 755";
6470 pcc
->init_proc
= init_proc_755
;
6471 pcc
->check_pow
= check_pow_hid0
;
6472 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6473 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6474 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6475 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6476 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6477 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
6478 PPC_SEGMENT
| PPC_EXTERN
;
6479 pcc
->msr_mask
= (1ull << MSR_POW
) |
6495 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
6496 pcc
->excp_model
= POWERPC_EXCP_7x5
;
6497 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6498 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6499 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6500 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6503 static void init_proc_7400(CPUPPCState
*env
)
6505 gen_spr_ne_601(env
);
6510 /* 74xx specific SPR */
6512 /* XXX : not implemented */
6513 spr_register(env
, SPR_UBAMR
, "UBAMR",
6514 &spr_read_ureg
, SPR_NOACCESS
,
6515 &spr_read_ureg
, SPR_NOACCESS
,
6517 /* XXX: this seems not implemented on all revisions. */
6518 /* XXX : not implemented */
6519 spr_register(env
, SPR_MSSCR1
, "MSSCR1",
6520 SPR_NOACCESS
, SPR_NOACCESS
,
6521 &spr_read_generic
, &spr_write_generic
,
6523 /* Thermal management */
6525 /* Memory management */
6527 init_excp_7400(env
);
6528 env
->dcache_line_size
= 32;
6529 env
->icache_line_size
= 32;
6530 /* Allocate hardware IRQ controller */
6531 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6534 POWERPC_FAMILY(7400)(ObjectClass
*oc
, void *data
)
6536 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6537 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6539 dc
->desc
= "PowerPC 7400 (aka G4)";
6540 pcc
->init_proc
= init_proc_7400
;
6541 pcc
->check_pow
= check_pow_hid0
;
6542 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6543 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6544 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6546 PPC_CACHE
| PPC_CACHE_ICBI
|
6547 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6548 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6549 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6551 PPC_SEGMENT
| PPC_EXTERN
|
6553 pcc
->msr_mask
= (1ull << MSR_VR
) |
6570 pcc
->mmu_model
= POWERPC_MMU_32B
;
6571 #if defined(CONFIG_SOFTMMU)
6572 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6574 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6575 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6576 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6577 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6578 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6579 POWERPC_FLAG_BUS_CLK
;
6582 static void init_proc_7410(CPUPPCState
*env
)
6584 gen_spr_ne_601(env
);
6589 /* 74xx specific SPR */
6591 /* XXX : not implemented */
6592 spr_register(env
, SPR_UBAMR
, "UBAMR",
6593 &spr_read_ureg
, SPR_NOACCESS
,
6594 &spr_read_ureg
, SPR_NOACCESS
,
6596 /* Thermal management */
6599 /* XXX : not implemented */
6600 spr_register(env
, SPR_L2PMCR
, "L2PMCR",
6601 SPR_NOACCESS
, SPR_NOACCESS
,
6602 &spr_read_generic
, &spr_write_generic
,
6605 /* XXX : not implemented */
6606 spr_register(env
, SPR_LDSTDB
, "LDSTDB",
6607 SPR_NOACCESS
, SPR_NOACCESS
,
6608 &spr_read_generic
, &spr_write_generic
,
6610 /* Memory management */
6612 init_excp_7400(env
);
6613 env
->dcache_line_size
= 32;
6614 env
->icache_line_size
= 32;
6615 /* Allocate hardware IRQ controller */
6616 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6619 POWERPC_FAMILY(7410)(ObjectClass
*oc
, void *data
)
6621 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6622 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6624 dc
->desc
= "PowerPC 7410 (aka G4)";
6625 pcc
->init_proc
= init_proc_7410
;
6626 pcc
->check_pow
= check_pow_hid0
;
6627 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6628 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6629 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6631 PPC_CACHE
| PPC_CACHE_ICBI
|
6632 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6633 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6634 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6636 PPC_SEGMENT
| PPC_EXTERN
|
6638 pcc
->msr_mask
= (1ull << MSR_VR
) |
6655 pcc
->mmu_model
= POWERPC_MMU_32B
;
6656 #if defined(CONFIG_SOFTMMU)
6657 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6659 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6660 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6661 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6662 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6663 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6664 POWERPC_FLAG_BUS_CLK
;
6667 static void init_proc_7440(CPUPPCState
*env
)
6669 gen_spr_ne_601(env
);
6674 /* 74xx specific SPR */
6676 /* XXX : not implemented */
6677 spr_register(env
, SPR_UBAMR
, "UBAMR",
6678 &spr_read_ureg
, SPR_NOACCESS
,
6679 &spr_read_ureg
, SPR_NOACCESS
,
6682 /* XXX : not implemented */
6683 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6684 SPR_NOACCESS
, SPR_NOACCESS
,
6685 &spr_read_generic
, &spr_write_generic
,
6688 /* XXX : not implemented */
6689 spr_register(env
, SPR_ICTRL
, "ICTRL",
6690 SPR_NOACCESS
, SPR_NOACCESS
,
6691 &spr_read_generic
, &spr_write_generic
,
6694 /* XXX : not implemented */
6695 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6696 SPR_NOACCESS
, SPR_NOACCESS
,
6697 &spr_read_generic
, &spr_write_generic
,
6700 /* XXX : not implemented */
6701 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6702 SPR_NOACCESS
, SPR_NOACCESS
,
6703 &spr_read_generic
, &spr_write_generic
,
6705 /* XXX : not implemented */
6706 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6707 &spr_read_ureg
, SPR_NOACCESS
,
6708 &spr_read_ureg
, SPR_NOACCESS
,
6710 /* XXX : not implemented */
6711 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6712 SPR_NOACCESS
, SPR_NOACCESS
,
6713 &spr_read_generic
, &spr_write_generic
,
6715 /* XXX : not implemented */
6716 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6717 &spr_read_ureg
, SPR_NOACCESS
,
6718 &spr_read_ureg
, SPR_NOACCESS
,
6720 /* Memory management */
6722 gen_74xx_soft_tlb(env
, 128, 2);
6723 init_excp_7450(env
);
6724 env
->dcache_line_size
= 32;
6725 env
->icache_line_size
= 32;
6726 /* Allocate hardware IRQ controller */
6727 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6730 POWERPC_FAMILY(7440)(ObjectClass
*oc
, void *data
)
6732 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6733 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6735 dc
->desc
= "PowerPC 7440 (aka G4)";
6736 pcc
->init_proc
= init_proc_7440
;
6737 pcc
->check_pow
= check_pow_hid0_74xx
;
6738 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6739 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6740 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6742 PPC_CACHE
| PPC_CACHE_ICBI
|
6743 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6744 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6745 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6746 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6747 PPC_SEGMENT
| PPC_EXTERN
|
6749 pcc
->msr_mask
= (1ull << MSR_VR
) |
6766 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6767 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6768 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6769 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6770 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6771 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6772 POWERPC_FLAG_BUS_CLK
;
6775 static void init_proc_7450(CPUPPCState
*env
)
6777 gen_spr_ne_601(env
);
6782 /* 74xx specific SPR */
6784 /* Level 3 cache control */
6787 /* XXX : not implemented */
6788 spr_register(env
, SPR_L3ITCR1
, "L3ITCR1",
6789 SPR_NOACCESS
, SPR_NOACCESS
,
6790 &spr_read_generic
, &spr_write_generic
,
6793 /* XXX : not implemented */
6794 spr_register(env
, SPR_L3ITCR2
, "L3ITCR2",
6795 SPR_NOACCESS
, SPR_NOACCESS
,
6796 &spr_read_generic
, &spr_write_generic
,
6799 /* XXX : not implemented */
6800 spr_register(env
, SPR_L3ITCR3
, "L3ITCR3",
6801 SPR_NOACCESS
, SPR_NOACCESS
,
6802 &spr_read_generic
, &spr_write_generic
,
6805 /* XXX : not implemented */
6806 spr_register(env
, SPR_L3OHCR
, "L3OHCR",
6807 SPR_NOACCESS
, SPR_NOACCESS
,
6808 &spr_read_generic
, &spr_write_generic
,
6810 /* XXX : not implemented */
6811 spr_register(env
, SPR_UBAMR
, "UBAMR",
6812 &spr_read_ureg
, SPR_NOACCESS
,
6813 &spr_read_ureg
, SPR_NOACCESS
,
6816 /* XXX : not implemented */
6817 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6818 SPR_NOACCESS
, SPR_NOACCESS
,
6819 &spr_read_generic
, &spr_write_generic
,
6822 /* XXX : not implemented */
6823 spr_register(env
, SPR_ICTRL
, "ICTRL",
6824 SPR_NOACCESS
, SPR_NOACCESS
,
6825 &spr_read_generic
, &spr_write_generic
,
6828 /* XXX : not implemented */
6829 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6830 SPR_NOACCESS
, SPR_NOACCESS
,
6831 &spr_read_generic
, &spr_write_generic
,
6834 /* XXX : not implemented */
6835 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6836 SPR_NOACCESS
, SPR_NOACCESS
,
6837 &spr_read_generic
, &spr_write_generic
,
6839 /* XXX : not implemented */
6840 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6841 &spr_read_ureg
, SPR_NOACCESS
,
6842 &spr_read_ureg
, SPR_NOACCESS
,
6844 /* XXX : not implemented */
6845 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6846 SPR_NOACCESS
, SPR_NOACCESS
,
6847 &spr_read_generic
, &spr_write_generic
,
6849 /* XXX : not implemented */
6850 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6851 &spr_read_ureg
, SPR_NOACCESS
,
6852 &spr_read_ureg
, SPR_NOACCESS
,
6854 /* Memory management */
6856 gen_74xx_soft_tlb(env
, 128, 2);
6857 init_excp_7450(env
);
6858 env
->dcache_line_size
= 32;
6859 env
->icache_line_size
= 32;
6860 /* Allocate hardware IRQ controller */
6861 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6864 POWERPC_FAMILY(7450)(ObjectClass
*oc
, void *data
)
6866 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6867 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6869 dc
->desc
= "PowerPC 7450 (aka G4)";
6870 pcc
->init_proc
= init_proc_7450
;
6871 pcc
->check_pow
= check_pow_hid0_74xx
;
6872 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6873 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6874 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6876 PPC_CACHE
| PPC_CACHE_ICBI
|
6877 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6878 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6879 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6880 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6881 PPC_SEGMENT
| PPC_EXTERN
|
6883 pcc
->msr_mask
= (1ull << MSR_VR
) |
6900 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6901 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6902 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6903 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6904 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6905 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6906 POWERPC_FLAG_BUS_CLK
;
6909 static void init_proc_7445(CPUPPCState
*env
)
6911 gen_spr_ne_601(env
);
6916 /* 74xx specific SPR */
6919 /* XXX : not implemented */
6920 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6921 SPR_NOACCESS
, SPR_NOACCESS
,
6922 &spr_read_generic
, &spr_write_generic
,
6925 /* XXX : not implemented */
6926 spr_register(env
, SPR_ICTRL
, "ICTRL",
6927 SPR_NOACCESS
, SPR_NOACCESS
,
6928 &spr_read_generic
, &spr_write_generic
,
6931 /* XXX : not implemented */
6932 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6933 SPR_NOACCESS
, SPR_NOACCESS
,
6934 &spr_read_generic
, &spr_write_generic
,
6937 /* XXX : not implemented */
6938 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6939 SPR_NOACCESS
, SPR_NOACCESS
,
6940 &spr_read_generic
, &spr_write_generic
,
6942 /* XXX : not implemented */
6943 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6944 &spr_read_ureg
, SPR_NOACCESS
,
6945 &spr_read_ureg
, SPR_NOACCESS
,
6947 /* XXX : not implemented */
6948 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6949 SPR_NOACCESS
, SPR_NOACCESS
,
6950 &spr_read_generic
, &spr_write_generic
,
6952 /* XXX : not implemented */
6953 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6954 &spr_read_ureg
, SPR_NOACCESS
,
6955 &spr_read_ureg
, SPR_NOACCESS
,
6958 spr_register(env
, SPR_SPRG4
, "SPRG4",
6959 SPR_NOACCESS
, SPR_NOACCESS
,
6960 &spr_read_generic
, &spr_write_generic
,
6962 spr_register(env
, SPR_USPRG4
, "USPRG4",
6963 &spr_read_ureg
, SPR_NOACCESS
,
6964 &spr_read_ureg
, SPR_NOACCESS
,
6966 spr_register(env
, SPR_SPRG5
, "SPRG5",
6967 SPR_NOACCESS
, SPR_NOACCESS
,
6968 &spr_read_generic
, &spr_write_generic
,
6970 spr_register(env
, SPR_USPRG5
, "USPRG5",
6971 &spr_read_ureg
, SPR_NOACCESS
,
6972 &spr_read_ureg
, SPR_NOACCESS
,
6974 spr_register(env
, SPR_SPRG6
, "SPRG6",
6975 SPR_NOACCESS
, SPR_NOACCESS
,
6976 &spr_read_generic
, &spr_write_generic
,
6978 spr_register(env
, SPR_USPRG6
, "USPRG6",
6979 &spr_read_ureg
, SPR_NOACCESS
,
6980 &spr_read_ureg
, SPR_NOACCESS
,
6982 spr_register(env
, SPR_SPRG7
, "SPRG7",
6983 SPR_NOACCESS
, SPR_NOACCESS
,
6984 &spr_read_generic
, &spr_write_generic
,
6986 spr_register(env
, SPR_USPRG7
, "USPRG7",
6987 &spr_read_ureg
, SPR_NOACCESS
,
6988 &spr_read_ureg
, SPR_NOACCESS
,
6990 /* Memory management */
6993 gen_74xx_soft_tlb(env
, 128, 2);
6994 init_excp_7450(env
);
6995 env
->dcache_line_size
= 32;
6996 env
->icache_line_size
= 32;
6997 /* Allocate hardware IRQ controller */
6998 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7001 POWERPC_FAMILY(7445)(ObjectClass
*oc
, void *data
)
7003 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7004 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7006 dc
->desc
= "PowerPC 7445 (aka G4)";
7007 pcc
->init_proc
= init_proc_7445
;
7008 pcc
->check_pow
= check_pow_hid0_74xx
;
7009 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7010 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7011 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7013 PPC_CACHE
| PPC_CACHE_ICBI
|
7014 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7015 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7016 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7017 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7018 PPC_SEGMENT
| PPC_EXTERN
|
7020 pcc
->msr_mask
= (1ull << MSR_VR
) |
7037 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7038 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7039 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7040 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7041 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7042 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7043 POWERPC_FLAG_BUS_CLK
;
7046 static void init_proc_7455(CPUPPCState
*env
)
7048 gen_spr_ne_601(env
);
7053 /* 74xx specific SPR */
7055 /* Level 3 cache control */
7058 /* XXX : not implemented */
7059 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7060 SPR_NOACCESS
, SPR_NOACCESS
,
7061 &spr_read_generic
, &spr_write_generic
,
7064 /* XXX : not implemented */
7065 spr_register(env
, SPR_ICTRL
, "ICTRL",
7066 SPR_NOACCESS
, SPR_NOACCESS
,
7067 &spr_read_generic
, &spr_write_generic
,
7070 /* XXX : not implemented */
7071 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7072 SPR_NOACCESS
, SPR_NOACCESS
,
7073 &spr_read_generic
, &spr_write_generic
,
7076 /* XXX : not implemented */
7077 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7078 SPR_NOACCESS
, SPR_NOACCESS
,
7079 &spr_read_generic
, &spr_write_generic
,
7081 /* XXX : not implemented */
7082 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7083 &spr_read_ureg
, SPR_NOACCESS
,
7084 &spr_read_ureg
, SPR_NOACCESS
,
7086 /* XXX : not implemented */
7087 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7088 SPR_NOACCESS
, SPR_NOACCESS
,
7089 &spr_read_generic
, &spr_write_generic
,
7091 /* XXX : not implemented */
7092 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7093 &spr_read_ureg
, SPR_NOACCESS
,
7094 &spr_read_ureg
, SPR_NOACCESS
,
7097 spr_register(env
, SPR_SPRG4
, "SPRG4",
7098 SPR_NOACCESS
, SPR_NOACCESS
,
7099 &spr_read_generic
, &spr_write_generic
,
7101 spr_register(env
, SPR_USPRG4
, "USPRG4",
7102 &spr_read_ureg
, SPR_NOACCESS
,
7103 &spr_read_ureg
, SPR_NOACCESS
,
7105 spr_register(env
, SPR_SPRG5
, "SPRG5",
7106 SPR_NOACCESS
, SPR_NOACCESS
,
7107 &spr_read_generic
, &spr_write_generic
,
7109 spr_register(env
, SPR_USPRG5
, "USPRG5",
7110 &spr_read_ureg
, SPR_NOACCESS
,
7111 &spr_read_ureg
, SPR_NOACCESS
,
7113 spr_register(env
, SPR_SPRG6
, "SPRG6",
7114 SPR_NOACCESS
, SPR_NOACCESS
,
7115 &spr_read_generic
, &spr_write_generic
,
7117 spr_register(env
, SPR_USPRG6
, "USPRG6",
7118 &spr_read_ureg
, SPR_NOACCESS
,
7119 &spr_read_ureg
, SPR_NOACCESS
,
7121 spr_register(env
, SPR_SPRG7
, "SPRG7",
7122 SPR_NOACCESS
, SPR_NOACCESS
,
7123 &spr_read_generic
, &spr_write_generic
,
7125 spr_register(env
, SPR_USPRG7
, "USPRG7",
7126 &spr_read_ureg
, SPR_NOACCESS
,
7127 &spr_read_ureg
, SPR_NOACCESS
,
7129 /* Memory management */
7132 gen_74xx_soft_tlb(env
, 128, 2);
7133 init_excp_7450(env
);
7134 env
->dcache_line_size
= 32;
7135 env
->icache_line_size
= 32;
7136 /* Allocate hardware IRQ controller */
7137 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7140 POWERPC_FAMILY(7455)(ObjectClass
*oc
, void *data
)
7142 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7143 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7145 dc
->desc
= "PowerPC 7455 (aka G4)";
7146 pcc
->init_proc
= init_proc_7455
;
7147 pcc
->check_pow
= check_pow_hid0_74xx
;
7148 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7149 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7150 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7152 PPC_CACHE
| PPC_CACHE_ICBI
|
7153 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7154 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7155 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7156 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7157 PPC_SEGMENT
| PPC_EXTERN
|
7159 pcc
->msr_mask
= (1ull << MSR_VR
) |
7176 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7177 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7178 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7179 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7180 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7181 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7182 POWERPC_FLAG_BUS_CLK
;
7185 static void init_proc_7457(CPUPPCState
*env
)
7187 gen_spr_ne_601(env
);
7192 /* 74xx specific SPR */
7194 /* Level 3 cache control */
7197 /* XXX : not implemented */
7198 spr_register(env
, SPR_L3ITCR1
, "L3ITCR1",
7199 SPR_NOACCESS
, SPR_NOACCESS
,
7200 &spr_read_generic
, &spr_write_generic
,
7203 /* XXX : not implemented */
7204 spr_register(env
, SPR_L3ITCR2
, "L3ITCR2",
7205 SPR_NOACCESS
, SPR_NOACCESS
,
7206 &spr_read_generic
, &spr_write_generic
,
7209 /* XXX : not implemented */
7210 spr_register(env
, SPR_L3ITCR3
, "L3ITCR3",
7211 SPR_NOACCESS
, SPR_NOACCESS
,
7212 &spr_read_generic
, &spr_write_generic
,
7215 /* XXX : not implemented */
7216 spr_register(env
, SPR_L3OHCR
, "L3OHCR",
7217 SPR_NOACCESS
, SPR_NOACCESS
,
7218 &spr_read_generic
, &spr_write_generic
,
7221 /* XXX : not implemented */
7222 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7223 SPR_NOACCESS
, SPR_NOACCESS
,
7224 &spr_read_generic
, &spr_write_generic
,
7227 /* XXX : not implemented */
7228 spr_register(env
, SPR_ICTRL
, "ICTRL",
7229 SPR_NOACCESS
, SPR_NOACCESS
,
7230 &spr_read_generic
, &spr_write_generic
,
7233 /* XXX : not implemented */
7234 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7235 SPR_NOACCESS
, SPR_NOACCESS
,
7236 &spr_read_generic
, &spr_write_generic
,
7239 /* XXX : not implemented */
7240 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7241 SPR_NOACCESS
, SPR_NOACCESS
,
7242 &spr_read_generic
, &spr_write_generic
,
7244 /* XXX : not implemented */
7245 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7246 &spr_read_ureg
, SPR_NOACCESS
,
7247 &spr_read_ureg
, SPR_NOACCESS
,
7249 /* XXX : not implemented */
7250 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7251 SPR_NOACCESS
, SPR_NOACCESS
,
7252 &spr_read_generic
, &spr_write_generic
,
7254 /* XXX : not implemented */
7255 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7256 &spr_read_ureg
, SPR_NOACCESS
,
7257 &spr_read_ureg
, SPR_NOACCESS
,
7260 spr_register(env
, SPR_SPRG4
, "SPRG4",
7261 SPR_NOACCESS
, SPR_NOACCESS
,
7262 &spr_read_generic
, &spr_write_generic
,
7264 spr_register(env
, SPR_USPRG4
, "USPRG4",
7265 &spr_read_ureg
, SPR_NOACCESS
,
7266 &spr_read_ureg
, SPR_NOACCESS
,
7268 spr_register(env
, SPR_SPRG5
, "SPRG5",
7269 SPR_NOACCESS
, SPR_NOACCESS
,
7270 &spr_read_generic
, &spr_write_generic
,
7272 spr_register(env
, SPR_USPRG5
, "USPRG5",
7273 &spr_read_ureg
, SPR_NOACCESS
,
7274 &spr_read_ureg
, SPR_NOACCESS
,
7276 spr_register(env
, SPR_SPRG6
, "SPRG6",
7277 SPR_NOACCESS
, SPR_NOACCESS
,
7278 &spr_read_generic
, &spr_write_generic
,
7280 spr_register(env
, SPR_USPRG6
, "USPRG6",
7281 &spr_read_ureg
, SPR_NOACCESS
,
7282 &spr_read_ureg
, SPR_NOACCESS
,
7284 spr_register(env
, SPR_SPRG7
, "SPRG7",
7285 SPR_NOACCESS
, SPR_NOACCESS
,
7286 &spr_read_generic
, &spr_write_generic
,
7288 spr_register(env
, SPR_USPRG7
, "USPRG7",
7289 &spr_read_ureg
, SPR_NOACCESS
,
7290 &spr_read_ureg
, SPR_NOACCESS
,
7292 /* Memory management */
7295 gen_74xx_soft_tlb(env
, 128, 2);
7296 init_excp_7450(env
);
7297 env
->dcache_line_size
= 32;
7298 env
->icache_line_size
= 32;
7299 /* Allocate hardware IRQ controller */
7300 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7303 POWERPC_FAMILY(7457)(ObjectClass
*oc
, void *data
)
7305 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7306 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7308 dc
->desc
= "PowerPC 7457 (aka G4)";
7309 pcc
->init_proc
= init_proc_7457
;
7310 pcc
->check_pow
= check_pow_hid0_74xx
;
7311 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7312 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7313 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7315 PPC_CACHE
| PPC_CACHE_ICBI
|
7316 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7317 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7318 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7319 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7320 PPC_SEGMENT
| PPC_EXTERN
|
7322 pcc
->msr_mask
= (1ull << MSR_VR
) |
7339 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7340 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7341 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7342 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7343 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7344 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7345 POWERPC_FLAG_BUS_CLK
;
7348 static void init_proc_e600(CPUPPCState
*env
)
7350 gen_spr_ne_601(env
);
7355 /* 74xx specific SPR */
7357 /* XXX : not implemented */
7358 spr_register(env
, SPR_UBAMR
, "UBAMR",
7359 &spr_read_ureg
, SPR_NOACCESS
,
7360 &spr_read_ureg
, SPR_NOACCESS
,
7362 /* XXX : not implemented */
7363 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7364 SPR_NOACCESS
, SPR_NOACCESS
,
7365 &spr_read_generic
, &spr_write_generic
,
7367 /* XXX : not implemented */
7368 spr_register(env
, SPR_ICTRL
, "ICTRL",
7369 SPR_NOACCESS
, SPR_NOACCESS
,
7370 &spr_read_generic
, &spr_write_generic
,
7372 /* XXX : not implemented */
7373 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7374 SPR_NOACCESS
, SPR_NOACCESS
,
7375 &spr_read_generic
, &spr_write_generic
,
7377 /* XXX : not implemented */
7378 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7379 SPR_NOACCESS
, SPR_NOACCESS
,
7380 &spr_read_generic
, &spr_write_generic
,
7382 /* XXX : not implemented */
7383 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7384 &spr_read_ureg
, SPR_NOACCESS
,
7385 &spr_read_ureg
, SPR_NOACCESS
,
7387 /* XXX : not implemented */
7388 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7389 SPR_NOACCESS
, SPR_NOACCESS
,
7390 &spr_read_generic
, &spr_write_generic
,
7392 /* XXX : not implemented */
7393 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7394 &spr_read_ureg
, SPR_NOACCESS
,
7395 &spr_read_ureg
, SPR_NOACCESS
,
7398 spr_register(env
, SPR_SPRG4
, "SPRG4",
7399 SPR_NOACCESS
, SPR_NOACCESS
,
7400 &spr_read_generic
, &spr_write_generic
,
7402 spr_register(env
, SPR_USPRG4
, "USPRG4",
7403 &spr_read_ureg
, SPR_NOACCESS
,
7404 &spr_read_ureg
, SPR_NOACCESS
,
7406 spr_register(env
, SPR_SPRG5
, "SPRG5",
7407 SPR_NOACCESS
, SPR_NOACCESS
,
7408 &spr_read_generic
, &spr_write_generic
,
7410 spr_register(env
, SPR_USPRG5
, "USPRG5",
7411 &spr_read_ureg
, SPR_NOACCESS
,
7412 &spr_read_ureg
, SPR_NOACCESS
,
7414 spr_register(env
, SPR_SPRG6
, "SPRG6",
7415 SPR_NOACCESS
, SPR_NOACCESS
,
7416 &spr_read_generic
, &spr_write_generic
,
7418 spr_register(env
, SPR_USPRG6
, "USPRG6",
7419 &spr_read_ureg
, SPR_NOACCESS
,
7420 &spr_read_ureg
, SPR_NOACCESS
,
7422 spr_register(env
, SPR_SPRG7
, "SPRG7",
7423 SPR_NOACCESS
, SPR_NOACCESS
,
7424 &spr_read_generic
, &spr_write_generic
,
7426 spr_register(env
, SPR_USPRG7
, "USPRG7",
7427 &spr_read_ureg
, SPR_NOACCESS
,
7428 &spr_read_ureg
, SPR_NOACCESS
,
7430 /* Memory management */
7433 gen_74xx_soft_tlb(env
, 128, 2);
7434 init_excp_7450(env
);
7435 env
->dcache_line_size
= 32;
7436 env
->icache_line_size
= 32;
7437 /* Allocate hardware IRQ controller */
7438 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7441 POWERPC_FAMILY(e600
)(ObjectClass
*oc
, void *data
)
7443 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7444 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7446 dc
->desc
= "PowerPC e600";
7447 pcc
->init_proc
= init_proc_e600
;
7448 pcc
->check_pow
= check_pow_hid0_74xx
;
7449 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7450 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7451 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7453 PPC_CACHE
| PPC_CACHE_ICBI
|
7454 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7455 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7456 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7457 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7458 PPC_SEGMENT
| PPC_EXTERN
|
7460 pcc
->insns_flags2
= PPC_NONE
;
7461 pcc
->msr_mask
= (1ull << MSR_VR
) |
7478 pcc
->mmu_model
= POWERPC_MMU_32B
;
7479 #if defined(CONFIG_SOFTMMU)
7480 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
7482 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7483 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7484 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7485 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7486 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7487 POWERPC_FLAG_BUS_CLK
;
7490 #if defined(TARGET_PPC64)
7491 #if defined(CONFIG_USER_ONLY)
7492 #define POWERPC970_HID5_INIT 0x00000080
7494 #define POWERPC970_HID5_INIT 0x00000000
7497 static void gen_fscr_facility_check(DisasContext
*ctx
, int facility_sprn
,
7498 int bit
, int sprn
, int cause
)
7500 TCGv_i32 t1
= tcg_const_i32(bit
);
7501 TCGv_i32 t2
= tcg_const_i32(sprn
);
7502 TCGv_i32 t3
= tcg_const_i32(cause
);
7504 gen_helper_fscr_facility_check(cpu_env
, t1
, t2
, t3
);
7506 tcg_temp_free_i32(t3
);
7507 tcg_temp_free_i32(t2
);
7508 tcg_temp_free_i32(t1
);
7511 static void gen_msr_facility_check(DisasContext
*ctx
, int facility_sprn
,
7512 int bit
, int sprn
, int cause
)
7514 TCGv_i32 t1
= tcg_const_i32(bit
);
7515 TCGv_i32 t2
= tcg_const_i32(sprn
);
7516 TCGv_i32 t3
= tcg_const_i32(cause
);
7518 gen_helper_msr_facility_check(cpu_env
, t1
, t2
, t3
);
7520 tcg_temp_free_i32(t3
);
7521 tcg_temp_free_i32(t2
);
7522 tcg_temp_free_i32(t1
);
7525 static void spr_read_prev_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
7527 TCGv spr_up
= tcg_temp_new();
7528 TCGv spr
= tcg_temp_new();
7530 gen_load_spr(spr
, sprn
- 1);
7531 tcg_gen_shri_tl(spr_up
, spr
, 32);
7532 tcg_gen_ext32u_tl(cpu_gpr
[gprn
], spr_up
);
7535 tcg_temp_free(spr_up
);
7538 static void spr_write_prev_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
7540 TCGv spr
= tcg_temp_new();
7542 gen_load_spr(spr
, sprn
- 1);
7543 tcg_gen_deposit_tl(spr
, spr
, cpu_gpr
[gprn
], 32, 32);
7544 gen_store_spr(sprn
- 1, spr
);
7549 static int check_pow_970(CPUPPCState
*env
)
7551 if (env
->spr
[SPR_HID0
] & (HID0_DEEPNAP
| HID0_DOZE
| HID0_NAP
)) {
7558 static void gen_spr_970_hid(CPUPPCState
*env
)
7560 /* Hardware implementation registers */
7561 /* XXX : not implemented */
7562 spr_register(env
, SPR_HID0
, "HID0",
7563 SPR_NOACCESS
, SPR_NOACCESS
,
7564 &spr_read_generic
, &spr_write_clear
,
7566 spr_register(env
, SPR_HID1
, "HID1",
7567 SPR_NOACCESS
, SPR_NOACCESS
,
7568 &spr_read_generic
, &spr_write_generic
,
7570 spr_register(env
, SPR_970_HID5
, "HID5",
7571 SPR_NOACCESS
, SPR_NOACCESS
,
7572 &spr_read_generic
, &spr_write_generic
,
7573 POWERPC970_HID5_INIT
);
7576 static void gen_spr_970_hior(CPUPPCState
*env
)
7578 spr_register(env
, SPR_HIOR
, "SPR_HIOR",
7579 SPR_NOACCESS
, SPR_NOACCESS
,
7580 &spr_read_hior
, &spr_write_hior
,
7584 static void gen_spr_book3s_ctrl(CPUPPCState
*env
)
7586 spr_register(env
, SPR_CTRL
, "SPR_CTRL",
7587 SPR_NOACCESS
, SPR_NOACCESS
,
7588 SPR_NOACCESS
, &spr_write_generic
,
7590 spr_register(env
, SPR_UCTRL
, "SPR_UCTRL",
7591 &spr_read_ureg
, SPR_NOACCESS
,
7592 &spr_read_ureg
, SPR_NOACCESS
,
7596 static void gen_spr_book3s_altivec(CPUPPCState
*env
)
7598 if (!(env
->insns_flags
& PPC_ALTIVEC
)) {
7602 spr_register_kvm(env
, SPR_VRSAVE
, "VRSAVE",
7603 &spr_read_generic
, &spr_write_generic
,
7604 &spr_read_generic
, &spr_write_generic
,
7605 KVM_REG_PPC_VRSAVE
, 0x00000000);
7607 /* Can't find information on what this should be on reset. This
7608 * value is the one used by 74xx processors. */
7609 vscr_init(env
, 0x00010000);
7612 static void gen_spr_book3s_dbg(CPUPPCState
*env
)
7615 * TODO: different specs define different scopes for these,
7616 * will have to address this:
7617 * 970: super/write and super/read
7618 * powerisa 2.03..2.04: hypv/write and super/read.
7619 * powerisa 2.05 and newer: hypv/write and hypv/read.
7621 spr_register_kvm(env
, SPR_DABR
, "DABR",
7622 SPR_NOACCESS
, SPR_NOACCESS
,
7623 &spr_read_generic
, &spr_write_generic
,
7624 KVM_REG_PPC_DABR
, 0x00000000);
7625 spr_register_kvm(env
, SPR_DABRX
, "DABRX",
7626 SPR_NOACCESS
, SPR_NOACCESS
,
7627 &spr_read_generic
, &spr_write_generic
,
7628 KVM_REG_PPC_DABRX
, 0x00000000);
7631 static void gen_spr_book3s_207_dbg(CPUPPCState
*env
)
7633 spr_register_kvm_hv(env
, SPR_DAWR
, "DAWR",
7634 SPR_NOACCESS
, SPR_NOACCESS
,
7635 SPR_NOACCESS
, SPR_NOACCESS
,
7636 &spr_read_generic
, &spr_write_generic
,
7637 KVM_REG_PPC_DAWR
, 0x00000000);
7638 spr_register_kvm_hv(env
, SPR_DAWRX
, "DAWRX",
7639 SPR_NOACCESS
, SPR_NOACCESS
,
7640 SPR_NOACCESS
, SPR_NOACCESS
,
7641 &spr_read_generic
, &spr_write_generic
,
7642 KVM_REG_PPC_DAWRX
, 0x00000000);
7643 spr_register_kvm_hv(env
, SPR_CIABR
, "CIABR",
7644 SPR_NOACCESS
, SPR_NOACCESS
,
7645 SPR_NOACCESS
, SPR_NOACCESS
,
7646 &spr_read_generic
, &spr_write_generic
,
7647 KVM_REG_PPC_CIABR
, 0x00000000);
7650 static void gen_spr_970_dbg(CPUPPCState
*env
)
7653 spr_register(env
, SPR_IABR
, "IABR",
7654 SPR_NOACCESS
, SPR_NOACCESS
,
7655 &spr_read_generic
, &spr_write_generic
,
7659 static void gen_spr_book3s_pmu_sup(CPUPPCState
*env
)
7661 spr_register_kvm(env
, SPR_POWER_MMCR0
, "MMCR0",
7662 SPR_NOACCESS
, SPR_NOACCESS
,
7663 &spr_read_generic
, &spr_write_generic
,
7664 KVM_REG_PPC_MMCR0
, 0x00000000);
7665 spr_register_kvm(env
, SPR_POWER_MMCR1
, "MMCR1",
7666 SPR_NOACCESS
, SPR_NOACCESS
,
7667 &spr_read_generic
, &spr_write_generic
,
7668 KVM_REG_PPC_MMCR1
, 0x00000000);
7669 spr_register_kvm(env
, SPR_POWER_MMCRA
, "MMCRA",
7670 SPR_NOACCESS
, SPR_NOACCESS
,
7671 &spr_read_generic
, &spr_write_generic
,
7672 KVM_REG_PPC_MMCRA
, 0x00000000);
7673 spr_register_kvm(env
, SPR_POWER_PMC1
, "PMC1",
7674 SPR_NOACCESS
, SPR_NOACCESS
,
7675 &spr_read_generic
, &spr_write_generic
,
7676 KVM_REG_PPC_PMC1
, 0x00000000);
7677 spr_register_kvm(env
, SPR_POWER_PMC2
, "PMC2",
7678 SPR_NOACCESS
, SPR_NOACCESS
,
7679 &spr_read_generic
, &spr_write_generic
,
7680 KVM_REG_PPC_PMC2
, 0x00000000);
7681 spr_register_kvm(env
, SPR_POWER_PMC3
, "PMC3",
7682 SPR_NOACCESS
, SPR_NOACCESS
,
7683 &spr_read_generic
, &spr_write_generic
,
7684 KVM_REG_PPC_PMC3
, 0x00000000);
7685 spr_register_kvm(env
, SPR_POWER_PMC4
, "PMC4",
7686 SPR_NOACCESS
, SPR_NOACCESS
,
7687 &spr_read_generic
, &spr_write_generic
,
7688 KVM_REG_PPC_PMC4
, 0x00000000);
7689 spr_register_kvm(env
, SPR_POWER_PMC5
, "PMC5",
7690 SPR_NOACCESS
, SPR_NOACCESS
,
7691 &spr_read_generic
, &spr_write_generic
,
7692 KVM_REG_PPC_PMC5
, 0x00000000);
7693 spr_register_kvm(env
, SPR_POWER_PMC6
, "PMC6",
7694 SPR_NOACCESS
, SPR_NOACCESS
,
7695 &spr_read_generic
, &spr_write_generic
,
7696 KVM_REG_PPC_PMC6
, 0x00000000);
7697 spr_register_kvm(env
, SPR_POWER_SIAR
, "SIAR",
7698 SPR_NOACCESS
, SPR_NOACCESS
,
7699 &spr_read_generic
, &spr_write_generic
,
7700 KVM_REG_PPC_SIAR
, 0x00000000);
7701 spr_register_kvm(env
, SPR_POWER_SDAR
, "SDAR",
7702 SPR_NOACCESS
, SPR_NOACCESS
,
7703 &spr_read_generic
, &spr_write_generic
,
7704 KVM_REG_PPC_SDAR
, 0x00000000);
7707 static void gen_spr_book3s_pmu_user(CPUPPCState
*env
)
7709 spr_register(env
, SPR_POWER_UMMCR0
, "UMMCR0",
7710 &spr_read_ureg
, SPR_NOACCESS
,
7711 &spr_read_ureg
, &spr_write_ureg
,
7713 spr_register(env
, SPR_POWER_UMMCR1
, "UMMCR1",
7714 &spr_read_ureg
, SPR_NOACCESS
,
7715 &spr_read_ureg
, &spr_write_ureg
,
7717 spr_register(env
, SPR_POWER_UMMCRA
, "UMMCRA",
7718 &spr_read_ureg
, SPR_NOACCESS
,
7719 &spr_read_ureg
, &spr_write_ureg
,
7721 spr_register(env
, SPR_POWER_UPMC1
, "UPMC1",
7722 &spr_read_ureg
, SPR_NOACCESS
,
7723 &spr_read_ureg
, &spr_write_ureg
,
7725 spr_register(env
, SPR_POWER_UPMC2
, "UPMC2",
7726 &spr_read_ureg
, SPR_NOACCESS
,
7727 &spr_read_ureg
, &spr_write_ureg
,
7729 spr_register(env
, SPR_POWER_UPMC3
, "UPMC3",
7730 &spr_read_ureg
, SPR_NOACCESS
,
7731 &spr_read_ureg
, &spr_write_ureg
,
7733 spr_register(env
, SPR_POWER_UPMC4
, "UPMC4",
7734 &spr_read_ureg
, SPR_NOACCESS
,
7735 &spr_read_ureg
, &spr_write_ureg
,
7737 spr_register(env
, SPR_POWER_UPMC5
, "UPMC5",
7738 &spr_read_ureg
, SPR_NOACCESS
,
7739 &spr_read_ureg
, &spr_write_ureg
,
7741 spr_register(env
, SPR_POWER_UPMC6
, "UPMC6",
7742 &spr_read_ureg
, SPR_NOACCESS
,
7743 &spr_read_ureg
, &spr_write_ureg
,
7745 spr_register(env
, SPR_POWER_USIAR
, "USIAR",
7746 &spr_read_ureg
, SPR_NOACCESS
,
7747 &spr_read_ureg
, &spr_write_ureg
,
7749 spr_register(env
, SPR_POWER_USDAR
, "USDAR",
7750 &spr_read_ureg
, SPR_NOACCESS
,
7751 &spr_read_ureg
, &spr_write_ureg
,
7755 static void gen_spr_970_pmu_sup(CPUPPCState
*env
)
7757 spr_register_kvm(env
, SPR_970_PMC7
, "PMC7",
7758 SPR_NOACCESS
, SPR_NOACCESS
,
7759 &spr_read_generic
, &spr_write_generic
,
7760 KVM_REG_PPC_PMC7
, 0x00000000);
7761 spr_register_kvm(env
, SPR_970_PMC8
, "PMC8",
7762 SPR_NOACCESS
, SPR_NOACCESS
,
7763 &spr_read_generic
, &spr_write_generic
,
7764 KVM_REG_PPC_PMC8
, 0x00000000);
7767 static void gen_spr_970_pmu_user(CPUPPCState
*env
)
7769 spr_register(env
, SPR_970_UPMC7
, "UPMC7",
7770 &spr_read_ureg
, SPR_NOACCESS
,
7771 &spr_read_ureg
, &spr_write_ureg
,
7773 spr_register(env
, SPR_970_UPMC8
, "UPMC8",
7774 &spr_read_ureg
, SPR_NOACCESS
,
7775 &spr_read_ureg
, &spr_write_ureg
,
7779 static void gen_spr_power8_pmu_sup(CPUPPCState
*env
)
7781 spr_register_kvm(env
, SPR_POWER_MMCR2
, "MMCR2",
7782 SPR_NOACCESS
, SPR_NOACCESS
,
7783 &spr_read_generic
, &spr_write_generic
,
7784 KVM_REG_PPC_MMCR2
, 0x00000000);
7785 spr_register_kvm(env
, SPR_POWER_MMCRS
, "MMCRS",
7786 SPR_NOACCESS
, SPR_NOACCESS
,
7787 &spr_read_generic
, &spr_write_generic
,
7788 KVM_REG_PPC_MMCRS
, 0x00000000);
7789 spr_register_kvm(env
, SPR_POWER_SIER
, "SIER",
7790 SPR_NOACCESS
, SPR_NOACCESS
,
7791 &spr_read_generic
, &spr_write_generic
,
7792 KVM_REG_PPC_SIER
, 0x00000000);
7793 spr_register_kvm(env
, SPR_POWER_SPMC1
, "SPMC1",
7794 SPR_NOACCESS
, SPR_NOACCESS
,
7795 &spr_read_generic
, &spr_write_generic
,
7796 KVM_REG_PPC_SPMC1
, 0x00000000);
7797 spr_register_kvm(env
, SPR_POWER_SPMC2
, "SPMC2",
7798 SPR_NOACCESS
, SPR_NOACCESS
,
7799 &spr_read_generic
, &spr_write_generic
,
7800 KVM_REG_PPC_SPMC2
, 0x00000000);
7801 spr_register_kvm(env
, SPR_TACR
, "TACR",
7802 SPR_NOACCESS
, SPR_NOACCESS
,
7803 &spr_read_generic
, &spr_write_generic
,
7804 KVM_REG_PPC_TACR
, 0x00000000);
7805 spr_register_kvm(env
, SPR_TCSCR
, "TCSCR",
7806 SPR_NOACCESS
, SPR_NOACCESS
,
7807 &spr_read_generic
, &spr_write_generic
,
7808 KVM_REG_PPC_TCSCR
, 0x00000000);
7809 spr_register_kvm(env
, SPR_CSIGR
, "CSIGR",
7810 SPR_NOACCESS
, SPR_NOACCESS
,
7811 &spr_read_generic
, &spr_write_generic
,
7812 KVM_REG_PPC_CSIGR
, 0x00000000);
7815 static void gen_spr_power8_pmu_user(CPUPPCState
*env
)
7817 spr_register(env
, SPR_POWER_UMMCR2
, "UMMCR2",
7818 &spr_read_ureg
, SPR_NOACCESS
,
7819 &spr_read_ureg
, &spr_write_ureg
,
7821 spr_register(env
, SPR_POWER_USIER
, "USIER",
7822 &spr_read_generic
, SPR_NOACCESS
,
7823 &spr_read_generic
, &spr_write_generic
,
7827 static void gen_spr_power5p_ear(CPUPPCState
*env
)
7829 /* External access control */
7830 spr_register(env
, SPR_EAR
, "EAR",
7831 SPR_NOACCESS
, SPR_NOACCESS
,
7832 &spr_read_generic
, &spr_write_generic
,
7836 #if !defined(CONFIG_USER_ONLY)
7837 static void spr_write_hmer(DisasContext
*ctx
, int sprn
, int gprn
)
7839 TCGv hmer
= tcg_temp_new();
7841 gen_load_spr(hmer
, sprn
);
7842 tcg_gen_and_tl(hmer
, cpu_gpr
[gprn
], hmer
);
7843 gen_store_spr(sprn
, hmer
);
7844 spr_store_dump_spr(sprn
);
7845 tcg_temp_free(hmer
);
7848 static void spr_write_lpcr(DisasContext
*ctx
, int sprn
, int gprn
)
7850 gen_helper_store_lpcr(cpu_env
, cpu_gpr
[gprn
]);
7853 static void spr_write_970_hid4(DisasContext
*ctx
, int sprn
, int gprn
)
7855 #if defined(TARGET_PPC64)
7856 spr_write_generic(ctx
, sprn
, gprn
);
7857 gen_helper_store_lpcr(cpu_env
, cpu_gpr
[gprn
]);
7861 #endif /* !defined(CONFIG_USER_ONLY) */
7863 static void gen_spr_970_lpar(CPUPPCState
*env
)
7865 #if !defined(CONFIG_USER_ONLY)
7866 /* Logical partitionning */
7867 /* PPC970: HID4 is effectively the LPCR */
7868 spr_register(env
, SPR_970_HID4
, "HID4",
7869 SPR_NOACCESS
, SPR_NOACCESS
,
7870 &spr_read_generic
, &spr_write_970_hid4
,
7875 static void gen_spr_power5p_lpar(CPUPPCState
*env
)
7877 #if !defined(CONFIG_USER_ONLY)
7878 /* Logical partitionning */
7879 spr_register_kvm_hv(env
, SPR_LPCR
, "LPCR",
7880 SPR_NOACCESS
, SPR_NOACCESS
,
7881 SPR_NOACCESS
, SPR_NOACCESS
,
7882 &spr_read_generic
, &spr_write_lpcr
,
7883 KVM_REG_PPC_LPCR
, LPCR_LPES0
| LPCR_LPES1
);
7884 spr_register_hv(env
, SPR_HDEC
, "HDEC",
7885 SPR_NOACCESS
, SPR_NOACCESS
,
7886 SPR_NOACCESS
, SPR_NOACCESS
,
7887 &spr_read_hdecr
, &spr_write_hdecr
, 0);
7891 static void gen_spr_book3s_ids(CPUPPCState
*env
)
7893 /* FIXME: Will need to deal with thread vs core only SPRs */
7895 /* Processor identification */
7896 spr_register_hv(env
, SPR_PIR
, "PIR",
7897 SPR_NOACCESS
, SPR_NOACCESS
,
7898 SPR_NOACCESS
, SPR_NOACCESS
,
7899 &spr_read_generic
, NULL
,
7901 spr_register_hv(env
, SPR_HID0
, "HID0",
7902 SPR_NOACCESS
, SPR_NOACCESS
,
7903 SPR_NOACCESS
, SPR_NOACCESS
,
7904 &spr_read_generic
, &spr_write_generic
,
7906 spr_register_hv(env
, SPR_TSCR
, "TSCR",
7907 SPR_NOACCESS
, SPR_NOACCESS
,
7908 SPR_NOACCESS
, SPR_NOACCESS
,
7909 &spr_read_generic
, &spr_write_generic
,
7911 spr_register_hv(env
, SPR_HMER
, "HMER",
7912 SPR_NOACCESS
, SPR_NOACCESS
,
7913 SPR_NOACCESS
, SPR_NOACCESS
,
7914 &spr_read_generic
, &spr_write_hmer
,
7916 spr_register_hv(env
, SPR_HMEER
, "HMEER",
7917 SPR_NOACCESS
, SPR_NOACCESS
,
7918 SPR_NOACCESS
, SPR_NOACCESS
,
7919 &spr_read_generic
, &spr_write_generic
,
7921 spr_register_hv(env
, SPR_TFMR
, "TFMR",
7922 SPR_NOACCESS
, SPR_NOACCESS
,
7923 SPR_NOACCESS
, SPR_NOACCESS
,
7924 &spr_read_generic
, &spr_write_generic
,
7926 spr_register_hv(env
, SPR_LPIDR
, "LPIDR",
7927 SPR_NOACCESS
, SPR_NOACCESS
,
7928 SPR_NOACCESS
, SPR_NOACCESS
,
7929 &spr_read_generic
, &spr_write_generic
,
7931 spr_register_hv(env
, SPR_HFSCR
, "HFSCR",
7932 SPR_NOACCESS
, SPR_NOACCESS
,
7933 SPR_NOACCESS
, SPR_NOACCESS
,
7934 &spr_read_generic
, &spr_write_generic
,
7936 spr_register_hv(env
, SPR_MMCRC
, "MMCRC",
7937 SPR_NOACCESS
, SPR_NOACCESS
,
7938 SPR_NOACCESS
, SPR_NOACCESS
,
7939 &spr_read_generic
, &spr_write_generic
,
7941 spr_register_hv(env
, SPR_MMCRH
, "MMCRH",
7942 SPR_NOACCESS
, SPR_NOACCESS
,
7943 SPR_NOACCESS
, SPR_NOACCESS
,
7944 &spr_read_generic
, &spr_write_generic
,
7946 spr_register_hv(env
, SPR_HSPRG0
, "HSPRG0",
7947 SPR_NOACCESS
, SPR_NOACCESS
,
7948 SPR_NOACCESS
, SPR_NOACCESS
,
7949 &spr_read_generic
, &spr_write_generic
,
7951 spr_register_hv(env
, SPR_HSPRG1
, "HSPRG1",
7952 SPR_NOACCESS
, SPR_NOACCESS
,
7953 SPR_NOACCESS
, SPR_NOACCESS
,
7954 &spr_read_generic
, &spr_write_generic
,
7956 spr_register_hv(env
, SPR_HSRR0
, "HSRR0",
7957 SPR_NOACCESS
, SPR_NOACCESS
,
7958 SPR_NOACCESS
, SPR_NOACCESS
,
7959 &spr_read_generic
, &spr_write_generic
,
7961 spr_register_hv(env
, SPR_HSRR1
, "HSRR1",
7962 SPR_NOACCESS
, SPR_NOACCESS
,
7963 SPR_NOACCESS
, SPR_NOACCESS
,
7964 &spr_read_generic
, &spr_write_generic
,
7966 spr_register_hv(env
, SPR_HDAR
, "HDAR",
7967 SPR_NOACCESS
, SPR_NOACCESS
,
7968 SPR_NOACCESS
, SPR_NOACCESS
,
7969 &spr_read_generic
, &spr_write_generic
,
7971 spr_register_hv(env
, SPR_HDSISR
, "HDSISR",
7972 SPR_NOACCESS
, SPR_NOACCESS
,
7973 SPR_NOACCESS
, SPR_NOACCESS
,
7974 &spr_read_generic
, &spr_write_generic
,
7976 spr_register_hv(env
, SPR_RMOR
, "RMOR",
7977 SPR_NOACCESS
, SPR_NOACCESS
,
7978 SPR_NOACCESS
, SPR_NOACCESS
,
7979 &spr_read_generic
, &spr_write_generic
,
7981 spr_register_hv(env
, SPR_HRMOR
, "HRMOR",
7982 SPR_NOACCESS
, SPR_NOACCESS
,
7983 SPR_NOACCESS
, SPR_NOACCESS
,
7984 &spr_read_generic
, &spr_write_generic
,
7988 static void gen_spr_power8_ids(CPUPPCState
*env
)
7990 /* Thread identification */
7991 spr_register(env
, SPR_TIR
, "TIR",
7992 SPR_NOACCESS
, SPR_NOACCESS
,
7993 &spr_read_generic
, SPR_NOACCESS
,
7997 static void gen_spr_book3s_purr(CPUPPCState
*env
)
7999 #if !defined(CONFIG_USER_ONLY)
8000 /* PURR & SPURR: Hack - treat these as aliases for the TB for now */
8001 spr_register_kvm(env
, SPR_PURR
, "PURR",
8002 &spr_read_purr
, SPR_NOACCESS
,
8003 &spr_read_purr
, SPR_NOACCESS
,
8004 KVM_REG_PPC_PURR
, 0x00000000);
8005 spr_register_kvm(env
, SPR_SPURR
, "SPURR",
8006 &spr_read_purr
, SPR_NOACCESS
,
8007 &spr_read_purr
, SPR_NOACCESS
,
8008 KVM_REG_PPC_SPURR
, 0x00000000);
8012 static void gen_spr_power6_dbg(CPUPPCState
*env
)
8014 #if !defined(CONFIG_USER_ONLY)
8015 spr_register(env
, SPR_CFAR
, "SPR_CFAR",
8016 SPR_NOACCESS
, SPR_NOACCESS
,
8017 &spr_read_cfar
, &spr_write_cfar
,
8022 static void gen_spr_power5p_common(CPUPPCState
*env
)
8024 spr_register_kvm(env
, SPR_PPR
, "PPR",
8025 &spr_read_generic
, &spr_write_generic
,
8026 &spr_read_generic
, &spr_write_generic
,
8027 KVM_REG_PPC_PPR
, 0x00000000);
8030 static void gen_spr_power6_common(CPUPPCState
*env
)
8032 #if !defined(CONFIG_USER_ONLY)
8033 spr_register_kvm(env
, SPR_DSCR
, "SPR_DSCR",
8034 SPR_NOACCESS
, SPR_NOACCESS
,
8035 &spr_read_generic
, &spr_write_generic
,
8036 KVM_REG_PPC_DSCR
, 0x00000000);
8039 * Register PCR to report POWERPC_EXCP_PRIV_REG instead of
8040 * POWERPC_EXCP_INVAL_SPR.
8042 spr_register(env
, SPR_PCR
, "PCR",
8043 SPR_NOACCESS
, SPR_NOACCESS
,
8044 SPR_NOACCESS
, SPR_NOACCESS
,
8048 static void spr_read_tar(DisasContext
*ctx
, int gprn
, int sprn
)
8050 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_TAR
, sprn
, FSCR_IC_TAR
);
8051 spr_read_generic(ctx
, gprn
, sprn
);
8054 static void spr_write_tar(DisasContext
*ctx
, int sprn
, int gprn
)
8056 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_TAR
, sprn
, FSCR_IC_TAR
);
8057 spr_write_generic(ctx
, sprn
, gprn
);
8060 static void gen_spr_power8_tce_address_control(CPUPPCState
*env
)
8062 spr_register_kvm(env
, SPR_TAR
, "TAR",
8063 &spr_read_tar
, &spr_write_tar
,
8064 &spr_read_generic
, &spr_write_generic
,
8065 KVM_REG_PPC_TAR
, 0x00000000);
8068 static void spr_read_tm(DisasContext
*ctx
, int gprn
, int sprn
)
8070 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8071 spr_read_generic(ctx
, gprn
, sprn
);
8074 static void spr_write_tm(DisasContext
*ctx
, int sprn
, int gprn
)
8076 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8077 spr_write_generic(ctx
, sprn
, gprn
);
8080 static void spr_read_tm_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
8082 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8083 spr_read_prev_upper32(ctx
, gprn
, sprn
);
8086 static void spr_write_tm_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
8088 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8089 spr_write_prev_upper32(ctx
, sprn
, gprn
);
8092 static void gen_spr_power8_tm(CPUPPCState
*env
)
8094 spr_register_kvm(env
, SPR_TFHAR
, "TFHAR",
8095 &spr_read_tm
, &spr_write_tm
,
8096 &spr_read_tm
, &spr_write_tm
,
8097 KVM_REG_PPC_TFHAR
, 0x00000000);
8098 spr_register_kvm(env
, SPR_TFIAR
, "TFIAR",
8099 &spr_read_tm
, &spr_write_tm
,
8100 &spr_read_tm
, &spr_write_tm
,
8101 KVM_REG_PPC_TFIAR
, 0x00000000);
8102 spr_register_kvm(env
, SPR_TEXASR
, "TEXASR",
8103 &spr_read_tm
, &spr_write_tm
,
8104 &spr_read_tm
, &spr_write_tm
,
8105 KVM_REG_PPC_TEXASR
, 0x00000000);
8106 spr_register(env
, SPR_TEXASRU
, "TEXASRU",
8107 &spr_read_tm_upper32
, &spr_write_tm_upper32
,
8108 &spr_read_tm_upper32
, &spr_write_tm_upper32
,
8112 static void spr_read_ebb(DisasContext
*ctx
, int gprn
, int sprn
)
8114 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8115 spr_read_generic(ctx
, gprn
, sprn
);
8118 static void spr_write_ebb(DisasContext
*ctx
, int sprn
, int gprn
)
8120 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8121 spr_write_generic(ctx
, sprn
, gprn
);
8124 static void spr_read_ebb_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
8126 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8127 spr_read_prev_upper32(ctx
, gprn
, sprn
);
8130 static void spr_write_ebb_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
8132 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8133 spr_write_prev_upper32(ctx
, sprn
, gprn
);
8136 static void gen_spr_power8_ebb(CPUPPCState
*env
)
8138 spr_register(env
, SPR_BESCRS
, "BESCRS",
8139 &spr_read_ebb
, &spr_write_ebb
,
8140 &spr_read_generic
, &spr_write_generic
,
8142 spr_register(env
, SPR_BESCRSU
, "BESCRSU",
8143 &spr_read_ebb_upper32
, &spr_write_ebb_upper32
,
8144 &spr_read_prev_upper32
, &spr_write_prev_upper32
,
8146 spr_register(env
, SPR_BESCRR
, "BESCRR",
8147 &spr_read_ebb
, &spr_write_ebb
,
8148 &spr_read_generic
, &spr_write_generic
,
8150 spr_register(env
, SPR_BESCRRU
, "BESCRRU",
8151 &spr_read_ebb_upper32
, &spr_write_ebb_upper32
,
8152 &spr_read_prev_upper32
, &spr_write_prev_upper32
,
8154 spr_register_kvm(env
, SPR_EBBHR
, "EBBHR",
8155 &spr_read_ebb
, &spr_write_ebb
,
8156 &spr_read_generic
, &spr_write_generic
,
8157 KVM_REG_PPC_EBBHR
, 0x00000000);
8158 spr_register_kvm(env
, SPR_EBBRR
, "EBBRR",
8159 &spr_read_ebb
, &spr_write_ebb
,
8160 &spr_read_generic
, &spr_write_generic
,
8161 KVM_REG_PPC_EBBRR
, 0x00000000);
8162 spr_register_kvm(env
, SPR_BESCR
, "BESCR",
8163 &spr_read_ebb
, &spr_write_ebb
,
8164 &spr_read_generic
, &spr_write_generic
,
8165 KVM_REG_PPC_BESCR
, 0x00000000);
8168 /* Virtual Time Base */
8169 static void gen_spr_vtb(CPUPPCState
*env
)
8171 spr_register(env
, SPR_VTB
, "VTB",
8172 SPR_NOACCESS
, SPR_NOACCESS
,
8173 &spr_read_tbl
, SPR_NOACCESS
,
8177 static void gen_spr_power8_fscr(CPUPPCState
*env
)
8179 #if defined(CONFIG_USER_ONLY)
8180 target_ulong initval
= 1ULL << FSCR_TAR
;
8182 target_ulong initval
= 0;
8184 spr_register_kvm(env
, SPR_FSCR
, "FSCR",
8185 SPR_NOACCESS
, SPR_NOACCESS
,
8186 &spr_read_generic
, &spr_write_generic
,
8187 KVM_REG_PPC_FSCR
, initval
);
8190 static void gen_spr_power8_pspb(CPUPPCState
*env
)
8192 spr_register_kvm(env
, SPR_PSPB
, "PSPB",
8193 SPR_NOACCESS
, SPR_NOACCESS
,
8194 &spr_read_generic
, &spr_write_generic32
,
8195 KVM_REG_PPC_PSPB
, 0);
8198 static void gen_spr_power8_ic(CPUPPCState
*env
)
8200 #if !defined(CONFIG_USER_ONLY)
8201 spr_register_hv(env
, SPR_IC
, "IC",
8202 SPR_NOACCESS
, SPR_NOACCESS
,
8203 &spr_read_generic
, SPR_NOACCESS
,
8204 &spr_read_generic
, &spr_write_generic
,
8209 static void gen_spr_power8_book4(CPUPPCState
*env
)
8211 /* Add a number of P8 book4 registers */
8212 #if !defined(CONFIG_USER_ONLY)
8213 spr_register_kvm(env
, SPR_ACOP
, "ACOP",
8214 SPR_NOACCESS
, SPR_NOACCESS
,
8215 &spr_read_generic
, &spr_write_generic
,
8216 KVM_REG_PPC_ACOP
, 0);
8217 spr_register_kvm(env
, SPR_BOOKS_PID
, "PID",
8218 SPR_NOACCESS
, SPR_NOACCESS
,
8219 &spr_read_generic
, &spr_write_pidr
,
8220 KVM_REG_PPC_PID
, 0);
8221 spr_register_kvm(env
, SPR_WORT
, "WORT",
8222 SPR_NOACCESS
, SPR_NOACCESS
,
8223 &spr_read_generic
, &spr_write_generic
,
8224 KVM_REG_PPC_WORT
, 0);
8228 static void gen_spr_power7_book4(CPUPPCState
*env
)
8230 /* Add a number of P7 book4 registers */
8231 #if !defined(CONFIG_USER_ONLY)
8232 spr_register_kvm(env
, SPR_ACOP
, "ACOP",
8233 SPR_NOACCESS
, SPR_NOACCESS
,
8234 &spr_read_generic
, &spr_write_generic
,
8235 KVM_REG_PPC_ACOP
, 0);
8236 spr_register_kvm(env
, SPR_BOOKS_PID
, "PID",
8237 SPR_NOACCESS
, SPR_NOACCESS
,
8238 &spr_read_generic
, &spr_write_generic
,
8239 KVM_REG_PPC_PID
, 0);
8243 static void gen_spr_power8_rpr(CPUPPCState
*env
)
8245 #if !defined(CONFIG_USER_ONLY)
8246 spr_register_hv(env
, SPR_RPR
, "RPR",
8247 SPR_NOACCESS
, SPR_NOACCESS
,
8248 SPR_NOACCESS
, SPR_NOACCESS
,
8249 &spr_read_generic
, &spr_write_generic
,
8250 0x00000103070F1F3F);
8254 static void init_proc_book3s_common(CPUPPCState
*env
)
8256 gen_spr_ne_601(env
);
8258 gen_spr_usprg3(env
);
8259 gen_spr_book3s_altivec(env
);
8260 gen_spr_book3s_pmu_sup(env
);
8261 gen_spr_book3s_pmu_user(env
);
8262 gen_spr_book3s_ctrl(env
);
8265 static void init_proc_970(CPUPPCState
*env
)
8267 /* Common Registers */
8268 init_proc_book3s_common(env
);
8270 gen_spr_book3s_dbg(env
);
8272 /* 970 Specific Registers */
8273 gen_spr_970_hid(env
);
8274 gen_spr_970_hior(env
);
8276 gen_spr_970_pmu_sup(env
);
8277 gen_spr_970_pmu_user(env
);
8278 gen_spr_970_lpar(env
);
8279 gen_spr_970_dbg(env
);
8282 #if !defined(CONFIG_USER_ONLY)
8285 env
->dcache_line_size
= 128;
8286 env
->icache_line_size
= 128;
8288 /* Allocate hardware IRQ controller */
8290 ppc970_irq_init(ppc_env_get_cpu(env
));
8293 POWERPC_FAMILY(970)(ObjectClass
*oc
, void *data
)
8295 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8296 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8298 dc
->desc
= "PowerPC 970";
8299 pcc
->init_proc
= init_proc_970
;
8300 pcc
->check_pow
= check_pow_970
;
8301 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
8302 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8303 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8305 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8306 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8307 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8308 PPC_64B
| PPC_ALTIVEC
|
8309 PPC_SEGMENT_64B
| PPC_SLBI
;
8310 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
8311 pcc
->msr_mask
= (1ull << MSR_SF
) |
8326 pcc
->mmu_model
= POWERPC_MMU_64B
;
8327 #if defined(CONFIG_SOFTMMU)
8328 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8330 pcc
->excp_model
= POWERPC_EXCP_970
;
8331 pcc
->bus_model
= PPC_FLAGS_INPUT_970
;
8332 pcc
->bfd_mach
= bfd_mach_ppc64
;
8333 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8334 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8335 POWERPC_FLAG_BUS_CLK
;
8336 pcc
->l1_dcache_size
= 0x8000;
8337 pcc
->l1_icache_size
= 0x10000;
8340 static void init_proc_power5plus(CPUPPCState
*env
)
8342 /* Common Registers */
8343 init_proc_book3s_common(env
);
8345 gen_spr_book3s_dbg(env
);
8347 /* POWER5+ Specific Registers */
8348 gen_spr_970_hid(env
);
8349 gen_spr_970_hior(env
);
8351 gen_spr_970_pmu_sup(env
);
8352 gen_spr_970_pmu_user(env
);
8353 gen_spr_power5p_common(env
);
8354 gen_spr_power5p_lpar(env
);
8355 gen_spr_power5p_ear(env
);
8358 #if !defined(CONFIG_USER_ONLY)
8361 env
->dcache_line_size
= 128;
8362 env
->icache_line_size
= 128;
8364 /* Allocate hardware IRQ controller */
8366 ppc970_irq_init(ppc_env_get_cpu(env
));
8369 POWERPC_FAMILY(POWER5P
)(ObjectClass
*oc
, void *data
)
8371 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8372 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8374 dc
->fw_name
= "PowerPC,POWER5";
8375 dc
->desc
= "POWER5+";
8376 pcc
->init_proc
= init_proc_power5plus
;
8377 pcc
->check_pow
= check_pow_970
;
8378 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
8379 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8380 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8382 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8383 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8384 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8386 PPC_SEGMENT_64B
| PPC_SLBI
;
8387 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
8388 pcc
->msr_mask
= (1ull << MSR_SF
) |
8403 pcc
->mmu_model
= POWERPC_MMU_2_03
;
8404 #if defined(CONFIG_SOFTMMU)
8405 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8407 pcc
->excp_model
= POWERPC_EXCP_970
;
8408 pcc
->bus_model
= PPC_FLAGS_INPUT_970
;
8409 pcc
->bfd_mach
= bfd_mach_ppc64
;
8410 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8411 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8412 POWERPC_FLAG_BUS_CLK
;
8413 pcc
->l1_dcache_size
= 0x8000;
8414 pcc
->l1_icache_size
= 0x10000;
8418 * The CPU used to have a "compat" property which set the
8419 * compatibility mode PVR. However, this was conceptually broken - it
8420 * only makes sense on the pseries machine type (otherwise the guest
8421 * owns the PCR and can control the compatibility mode itself). It's
8422 * been replaced with the 'max-cpu-compat' property on the pseries
8423 * machine type. For backwards compatibility, pseries specially
8424 * parses the -cpu parameter and converts old compat= parameters into
8425 * the appropriate machine parameters. This stub implementation of
8426 * the parameter catches any uses on explicitly created CPUs.
8428 static void getset_compat_deprecated(Object
*obj
, Visitor
*v
, const char *name
,
8429 void *opaque
, Error
**errp
)
8431 if (!qtest_enabled()) {
8432 error_report("CPU 'compat' property is deprecated and has no effect; "
8433 "use max-cpu-compat machine property instead");
8435 visit_type_null(v
, name
, NULL
);
8438 static PropertyInfo ppc_compat_deprecated_propinfo
= {
8440 .description
= "compatibility mode (deprecated)",
8441 .get
= getset_compat_deprecated
,
8442 .set
= getset_compat_deprecated
,
8444 static Property powerpc_servercpu_properties
[] = {
8447 .info
= &ppc_compat_deprecated_propinfo
,
8449 DEFINE_PROP_END_OF_LIST(),
8452 #ifdef CONFIG_SOFTMMU
8453 static const struct ppc_segment_page_sizes POWER7_POWER8_sps
= {
8456 .page_shift
= 12, /* 4K */
8458 .enc
= { { .page_shift
= 12, .pte_enc
= 0 },
8459 { .page_shift
= 16, .pte_enc
= 0x7 },
8460 { .page_shift
= 24, .pte_enc
= 0x38 }, },
8463 .page_shift
= 16, /* 64K */
8464 .slb_enc
= SLB_VSID_64K
,
8465 .enc
= { { .page_shift
= 16, .pte_enc
= 0x1 },
8466 { .page_shift
= 24, .pte_enc
= 0x8 }, },
8469 .page_shift
= 24, /* 16M */
8470 .slb_enc
= SLB_VSID_16M
,
8471 .enc
= { { .page_shift
= 24, .pte_enc
= 0 }, },
8474 .page_shift
= 34, /* 16G */
8475 .slb_enc
= SLB_VSID_16G
,
8476 .enc
= { { .page_shift
= 34, .pte_enc
= 0x3 }, },
8480 #endif /* CONFIG_SOFTMMU */
8482 static void init_proc_POWER7(CPUPPCState
*env
)
8484 /* Common Registers */
8485 init_proc_book3s_common(env
);
8487 gen_spr_book3s_dbg(env
);
8489 /* POWER7 Specific Registers */
8490 gen_spr_book3s_ids(env
);
8492 gen_spr_book3s_purr(env
);
8493 gen_spr_power5p_common(env
);
8494 gen_spr_power5p_lpar(env
);
8495 gen_spr_power5p_ear(env
);
8496 gen_spr_power6_common(env
);
8497 gen_spr_power6_dbg(env
);
8498 gen_spr_power7_book4(env
);
8501 #if !defined(CONFIG_USER_ONLY)
8504 env
->ci_large_pages
= true;
8505 env
->dcache_line_size
= 128;
8506 env
->icache_line_size
= 128;
8508 /* Allocate hardware IRQ controller */
8509 init_excp_POWER7(env
);
8510 ppcPOWER7_irq_init(ppc_env_get_cpu(env
));
8513 static bool ppc_pvr_match_power7(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8515 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER7P_BASE
) {
8518 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER7_BASE
) {
8524 static bool cpu_has_work_POWER7(CPUState
*cs
)
8526 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8527 CPUPPCState
*env
= &cpu
->env
;
8530 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8533 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8534 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE0
)) {
8537 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8538 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE1
)) {
8541 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
)) &&
8542 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE2
)) {
8545 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HMI
)) &&
8546 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE2
)) {
8549 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8554 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8558 POWERPC_FAMILY(POWER7
)(ObjectClass
*oc
, void *data
)
8560 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8561 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8562 CPUClass
*cc
= CPU_CLASS(oc
);
8564 dc
->fw_name
= "PowerPC,POWER7";
8565 dc
->desc
= "POWER7";
8566 dc
->props
= powerpc_servercpu_properties
;
8567 pcc
->pvr_match
= ppc_pvr_match_power7
;
8568 pcc
->pcr_mask
= PCR_VEC_DIS
| PCR_VSX_DIS
| PCR_COMPAT_2_05
;
8569 pcc
->pcr_supported
= PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8570 pcc
->init_proc
= init_proc_POWER7
;
8571 pcc
->check_pow
= check_pow_nocheck
;
8572 cc
->has_work
= cpu_has_work_POWER7
;
8573 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8574 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8575 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8576 PPC_FLOAT_FRSQRTES
|
8579 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8580 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8581 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8582 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
8583 PPC_SEGMENT_64B
| PPC_SLBI
|
8584 PPC_POPCNTB
| PPC_POPCNTWD
|
8586 pcc
->insns_flags2
= PPC2_VSX
| PPC2_DFP
| PPC2_DBRX
| PPC2_ISA205
|
8587 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8588 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8589 PPC2_FP_TST_ISA206
| PPC2_FP_CVT_S64
|
8591 pcc
->msr_mask
= (1ull << MSR_SF
) |
8607 pcc
->mmu_model
= POWERPC_MMU_2_06
;
8608 #if defined(CONFIG_SOFTMMU)
8609 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8610 pcc
->sps
= &POWER7_POWER8_sps
;
8612 pcc
->excp_model
= POWERPC_EXCP_POWER7
;
8613 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8614 pcc
->bfd_mach
= bfd_mach_ppc64
;
8615 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8616 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8617 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8619 pcc
->l1_dcache_size
= 0x8000;
8620 pcc
->l1_icache_size
= 0x8000;
8621 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8624 static void init_proc_POWER8(CPUPPCState
*env
)
8626 /* Common Registers */
8627 init_proc_book3s_common(env
);
8629 gen_spr_book3s_207_dbg(env
);
8631 /* POWER8 Specific Registers */
8632 gen_spr_book3s_ids(env
);
8635 gen_spr_book3s_purr(env
);
8636 gen_spr_power5p_common(env
);
8637 gen_spr_power5p_lpar(env
);
8638 gen_spr_power5p_ear(env
);
8639 gen_spr_power6_common(env
);
8640 gen_spr_power6_dbg(env
);
8641 gen_spr_power8_tce_address_control(env
);
8642 gen_spr_power8_ids(env
);
8643 gen_spr_power8_ebb(env
);
8644 gen_spr_power8_fscr(env
);
8645 gen_spr_power8_pmu_sup(env
);
8646 gen_spr_power8_pmu_user(env
);
8647 gen_spr_power8_tm(env
);
8648 gen_spr_power8_pspb(env
);
8650 gen_spr_power8_ic(env
);
8651 gen_spr_power8_book4(env
);
8652 gen_spr_power8_rpr(env
);
8655 #if !defined(CONFIG_USER_ONLY)
8658 env
->ci_large_pages
= true;
8659 env
->dcache_line_size
= 128;
8660 env
->icache_line_size
= 128;
8662 /* Allocate hardware IRQ controller */
8663 init_excp_POWER8(env
);
8664 ppcPOWER7_irq_init(ppc_env_get_cpu(env
));
8667 static bool ppc_pvr_match_power8(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8669 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8NVL_BASE
) {
8672 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8E_BASE
) {
8675 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8_BASE
) {
8681 static bool cpu_has_work_POWER8(CPUState
*cs
)
8683 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8684 CPUPPCState
*env
= &cpu
->env
;
8687 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8690 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8691 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE2
)) {
8694 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8695 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE3
)) {
8698 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
)) &&
8699 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE4
)) {
8702 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HMI
)) &&
8703 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE4
)) {
8706 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DOORBELL
)) &&
8707 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE0
)) {
8710 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HDOORBELL
)) &&
8711 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE1
)) {
8714 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8719 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8723 POWERPC_FAMILY(POWER8
)(ObjectClass
*oc
, void *data
)
8725 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8726 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8727 CPUClass
*cc
= CPU_CLASS(oc
);
8729 dc
->fw_name
= "PowerPC,POWER8";
8730 dc
->desc
= "POWER8";
8731 dc
->props
= powerpc_servercpu_properties
;
8732 pcc
->pvr_match
= ppc_pvr_match_power8
;
8733 pcc
->pcr_mask
= PCR_TM_DIS
| PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8734 pcc
->pcr_supported
= PCR_COMPAT_2_07
| PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8735 pcc
->init_proc
= init_proc_POWER8
;
8736 pcc
->check_pow
= check_pow_nocheck
;
8737 cc
->has_work
= cpu_has_work_POWER8
;
8738 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8739 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8740 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8741 PPC_FLOAT_FRSQRTES
|
8744 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8745 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8746 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8747 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
8748 PPC_SEGMENT_64B
| PPC_SLBI
|
8749 PPC_POPCNTB
| PPC_POPCNTWD
|
8751 pcc
->insns_flags2
= PPC2_VSX
| PPC2_VSX207
| PPC2_DFP
| PPC2_DBRX
|
8752 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8753 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8754 PPC2_FP_TST_ISA206
| PPC2_BCTAR_ISA207
|
8755 PPC2_LSQ_ISA207
| PPC2_ALTIVEC_207
|
8756 PPC2_ISA205
| PPC2_ISA207S
| PPC2_FP_CVT_S64
|
8757 PPC2_TM
| PPC2_PM_ISA206
;
8758 pcc
->msr_mask
= (1ull << MSR_SF
) |
8776 pcc
->mmu_model
= POWERPC_MMU_2_07
;
8777 #if defined(CONFIG_SOFTMMU)
8778 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8779 pcc
->sps
= &POWER7_POWER8_sps
;
8781 pcc
->excp_model
= POWERPC_EXCP_POWER8
;
8782 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8783 pcc
->bfd_mach
= bfd_mach_ppc64
;
8784 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8785 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8786 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8787 POWERPC_FLAG_VSX
| POWERPC_FLAG_TM
;
8788 pcc
->l1_dcache_size
= 0x8000;
8789 pcc
->l1_icache_size
= 0x8000;
8790 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8793 #ifdef CONFIG_SOFTMMU
8795 * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
8796 * Encoded as array of int_32s in the form:
8797 * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
8799 * y -> radix mode supported page size (encoded as a shift)
8801 static struct ppc_radix_page_info POWER9_radix_page_info
= {
8804 0x0000000c, /* 4K - enc: 0x0 */
8805 0xa0000010, /* 64K - enc: 0x5 */
8806 0x20000015, /* 2M - enc: 0x1 */
8807 0x4000001e /* 1G - enc: 0x2 */
8810 #endif /* CONFIG_SOFTMMU */
8812 static void init_proc_POWER9(CPUPPCState
*env
)
8814 /* Common Registers */
8815 init_proc_book3s_common(env
);
8816 gen_spr_book3s_207_dbg(env
);
8818 /* POWER8 Specific Registers */
8819 gen_spr_book3s_ids(env
);
8822 gen_spr_book3s_purr(env
);
8823 gen_spr_power5p_common(env
);
8824 gen_spr_power5p_lpar(env
);
8825 gen_spr_power5p_ear(env
);
8826 gen_spr_power6_common(env
);
8827 gen_spr_power6_dbg(env
);
8828 gen_spr_power8_tce_address_control(env
);
8829 gen_spr_power8_ids(env
);
8830 gen_spr_power8_ebb(env
);
8831 gen_spr_power8_fscr(env
);
8832 gen_spr_power8_pmu_sup(env
);
8833 gen_spr_power8_pmu_user(env
);
8834 gen_spr_power8_tm(env
);
8835 gen_spr_power8_pspb(env
);
8837 gen_spr_power8_ic(env
);
8838 gen_spr_power8_book4(env
);
8839 gen_spr_power8_rpr(env
);
8842 #if !defined(CONFIG_USER_ONLY)
8845 env
->ci_large_pages
= true;
8846 env
->dcache_line_size
= 128;
8847 env
->icache_line_size
= 128;
8849 /* Allocate hardware IRQ controller */
8850 init_excp_POWER8(env
);
8851 ppcPOWER7_irq_init(ppc_env_get_cpu(env
));
8854 static bool ppc_pvr_match_power9(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8856 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER9_BASE
) {
8862 static bool cpu_has_work_POWER9(CPUState
*cs
)
8864 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8865 CPUPPCState
*env
= &cpu
->env
;
8868 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8871 /* External Exception */
8872 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8873 (env
->spr
[SPR_LPCR
] & LPCR_EEE
)) {
8876 /* Decrementer Exception */
8877 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8878 (env
->spr
[SPR_LPCR
] & LPCR_DEE
)) {
8881 /* Machine Check or Hypervisor Maintenance Exception */
8882 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
|
8883 1u << PPC_INTERRUPT_HMI
)) && (env
->spr
[SPR_LPCR
] & LPCR_OEE
)) {
8886 /* Privileged Doorbell Exception */
8887 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DOORBELL
)) &&
8888 (env
->spr
[SPR_LPCR
] & LPCR_PDEE
)) {
8891 /* Hypervisor Doorbell Exception */
8892 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HDOORBELL
)) &&
8893 (env
->spr
[SPR_LPCR
] & LPCR_HDEE
)) {
8896 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8901 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8905 POWERPC_FAMILY(POWER9
)(ObjectClass
*oc
, void *data
)
8907 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8908 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8909 CPUClass
*cc
= CPU_CLASS(oc
);
8911 dc
->fw_name
= "PowerPC,POWER9";
8912 dc
->desc
= "POWER9";
8913 dc
->props
= powerpc_servercpu_properties
;
8914 pcc
->pvr_match
= ppc_pvr_match_power9
;
8915 pcc
->pcr_mask
= PCR_COMPAT_2_05
| PCR_COMPAT_2_06
| PCR_COMPAT_2_07
;
8916 pcc
->pcr_supported
= PCR_COMPAT_3_00
| PCR_COMPAT_2_07
| PCR_COMPAT_2_06
|
8918 pcc
->init_proc
= init_proc_POWER9
;
8919 pcc
->check_pow
= check_pow_nocheck
;
8920 cc
->has_work
= cpu_has_work_POWER9
;
8921 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8922 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8923 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8924 PPC_FLOAT_FRSQRTES
|
8927 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8928 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8930 PPC_64B
| PPC_64BX
| PPC_ALTIVEC
|
8931 PPC_SEGMENT_64B
| PPC_SLBI
|
8932 PPC_POPCNTB
| PPC_POPCNTWD
|
8934 pcc
->insns_flags2
= PPC2_VSX
| PPC2_VSX207
| PPC2_DFP
| PPC2_DBRX
|
8935 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8936 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8937 PPC2_FP_TST_ISA206
| PPC2_BCTAR_ISA207
|
8938 PPC2_LSQ_ISA207
| PPC2_ALTIVEC_207
|
8939 PPC2_ISA205
| PPC2_ISA207S
| PPC2_FP_CVT_S64
|
8940 PPC2_TM
| PPC2_PM_ISA206
| PPC2_ISA300
;
8941 pcc
->msr_mask
= (1ull << MSR_SF
) |
8958 pcc
->mmu_model
= POWERPC_MMU_3_00
;
8959 #if defined(CONFIG_SOFTMMU)
8960 pcc
->handle_mmu_fault
= ppc64_v3_handle_mmu_fault
;
8961 /* segment page size remain the same */
8962 pcc
->sps
= &POWER7_POWER8_sps
;
8963 pcc
->radix_page_info
= &POWER9_radix_page_info
;
8965 pcc
->excp_model
= POWERPC_EXCP_POWER8
;
8966 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8967 pcc
->bfd_mach
= bfd_mach_ppc64
;
8968 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8969 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8970 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8971 POWERPC_FLAG_VSX
| POWERPC_FLAG_TM
;
8972 pcc
->l1_dcache_size
= 0x8000;
8973 pcc
->l1_icache_size
= 0x8000;
8974 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8977 #if !defined(CONFIG_USER_ONLY)
8978 void cpu_ppc_set_papr(PowerPCCPU
*cpu
, PPCVirtualHypervisor
*vhyp
)
8980 CPUPPCState
*env
= &cpu
->env
;
8981 ppc_spr_t
*lpcr
= &env
->spr_cb
[SPR_LPCR
];
8982 ppc_spr_t
*amor
= &env
->spr_cb
[SPR_AMOR
];
8986 /* PAPR always has exception vectors in RAM not ROM. To ensure this,
8987 * MSR[IP] should never be set.
8989 * We also disallow setting of MSR_HV
8991 env
->msr_mask
&= ~((1ull << MSR_EP
) | MSR_HVB
);
8993 /* Set emulated LPCR to not send interrupts to hypervisor. Note that
8994 * under KVM, the actual HW LPCR will be set differently by KVM itself,
8995 * the settings below ensure proper operations with TCG in absence of
8996 * a real hypervisor.
8998 * Clearing VPM0 will also cause us to use RMOR in mmu-hash64.c for
8999 * real mode accesses, which thankfully defaults to 0 and isn't
9000 * accessible in guest mode.
9002 lpcr
->default_value
&= ~(LPCR_VPM0
| LPCR_VPM1
| LPCR_ISL
| LPCR_KBV
);
9003 lpcr
->default_value
|= LPCR_LPES0
| LPCR_LPES1
;
9005 /* Set RMLS to the max (ie, 16G) */
9006 lpcr
->default_value
&= ~LPCR_RMLS
;
9007 lpcr
->default_value
|= 1ull << LPCR_RMLS_SHIFT
;
9009 switch (env
->mmu_model
) {
9010 case POWERPC_MMU_3_00
:
9011 /* By default we choose legacy mode and switch to new hash or radix
9012 * when a register process table hcall is made. So disable process
9013 * tables and guest translation shootdown by default
9015 lpcr
->default_value
&= ~(LPCR_UPRT
| LPCR_GTSE
);
9016 lpcr
->default_value
|= LPCR_PDEE
| LPCR_HDEE
| LPCR_EEE
| LPCR_DEE
|
9020 /* P7 and P8 has slightly different PECE bits, mostly because P8 adds
9021 * bit 47 and 48 which are reserved on P7. Here we set them all, which
9022 * will work as expected for both implementations
9024 lpcr
->default_value
|= LPCR_P8_PECE0
| LPCR_P8_PECE1
| LPCR_P8_PECE2
|
9025 LPCR_P8_PECE3
| LPCR_P8_PECE4
;
9028 /* We should be followed by a CPU reset but update the active value
9031 env
->spr
[SPR_LPCR
] = lpcr
->default_value
;
9033 /* Set a full AMOR so guest can use the AMR as it sees fit */
9034 env
->spr
[SPR_AMOR
] = amor
->default_value
= 0xffffffffffffffffull
;
9036 /* Update some env bits based on new LPCR value */
9037 ppc_hash64_update_rmls(env
);
9038 ppc_hash64_update_vrma(env
);
9040 /* Tell KVM that we're in PAPR mode */
9041 if (kvm_enabled()) {
9042 kvmppc_set_papr(cpu
);
9046 #endif /* !defined(CONFIG_USER_ONLY) */
9048 #endif /* defined(TARGET_PPC64) */
9050 /*****************************************************************************/
9051 /* Generic CPU instantiation routine */
9052 static void init_ppc_proc(PowerPCCPU
*cpu
)
9054 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9055 CPUPPCState
*env
= &cpu
->env
;
9056 #if !defined(CONFIG_USER_ONLY)
9059 env
->irq_inputs
= NULL
;
9060 /* Set all exception vectors to an invalid address */
9061 for (i
= 0; i
< POWERPC_EXCP_NB
; i
++)
9062 env
->excp_vectors
[i
] = (target_ulong
)(-1ULL);
9063 env
->ivor_mask
= 0x00000000;
9064 env
->ivpr_mask
= 0x00000000;
9065 /* Default MMU definitions */
9069 env
->tlb_type
= TLB_NONE
;
9071 /* Register SPR common to all PowerPC implementations */
9072 gen_spr_generic(env
);
9073 spr_register(env
, SPR_PVR
, "PVR",
9074 /* Linux permits userspace to read PVR */
9075 #if defined(CONFIG_LINUX_USER)
9081 &spr_read_generic
, SPR_NOACCESS
,
9083 /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
9084 if (pcc
->svr
!= POWERPC_SVR_NONE
) {
9085 if (pcc
->svr
& POWERPC_SVR_E500
) {
9086 spr_register(env
, SPR_E500_SVR
, "SVR",
9087 SPR_NOACCESS
, SPR_NOACCESS
,
9088 &spr_read_generic
, SPR_NOACCESS
,
9089 pcc
->svr
& ~POWERPC_SVR_E500
);
9091 spr_register(env
, SPR_SVR
, "SVR",
9092 SPR_NOACCESS
, SPR_NOACCESS
,
9093 &spr_read_generic
, SPR_NOACCESS
,
9097 /* PowerPC implementation specific initialisations (SPRs, timers, ...) */
9098 (*pcc
->init_proc
)(env
);
9100 /* MSR bits & flags consistency checks */
9101 if (env
->msr_mask
& (1 << 25)) {
9102 switch (env
->flags
& (POWERPC_FLAG_SPE
| POWERPC_FLAG_VRE
)) {
9103 case POWERPC_FLAG_SPE
:
9104 case POWERPC_FLAG_VRE
:
9107 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9108 "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n");
9111 } else if (env
->flags
& (POWERPC_FLAG_SPE
| POWERPC_FLAG_VRE
)) {
9112 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9113 "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n");
9116 if (env
->msr_mask
& (1 << 17)) {
9117 switch (env
->flags
& (POWERPC_FLAG_TGPR
| POWERPC_FLAG_CE
)) {
9118 case POWERPC_FLAG_TGPR
:
9119 case POWERPC_FLAG_CE
:
9122 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9123 "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n");
9126 } else if (env
->flags
& (POWERPC_FLAG_TGPR
| POWERPC_FLAG_CE
)) {
9127 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9128 "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n");
9131 if (env
->msr_mask
& (1 << 10)) {
9132 switch (env
->flags
& (POWERPC_FLAG_SE
| POWERPC_FLAG_DWE
|
9133 POWERPC_FLAG_UBLE
)) {
9134 case POWERPC_FLAG_SE
:
9135 case POWERPC_FLAG_DWE
:
9136 case POWERPC_FLAG_UBLE
:
9139 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9140 "Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE or "
9141 "POWERPC_FLAG_UBLE\n");
9144 } else if (env
->flags
& (POWERPC_FLAG_SE
| POWERPC_FLAG_DWE
|
9145 POWERPC_FLAG_UBLE
)) {
9146 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9147 "Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE nor "
9148 "POWERPC_FLAG_UBLE\n");
9151 if (env
->msr_mask
& (1 << 9)) {
9152 switch (env
->flags
& (POWERPC_FLAG_BE
| POWERPC_FLAG_DE
)) {
9153 case POWERPC_FLAG_BE
:
9154 case POWERPC_FLAG_DE
:
9157 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9158 "Should define POWERPC_FLAG_BE or POWERPC_FLAG_DE\n");
9161 } else if (env
->flags
& (POWERPC_FLAG_BE
| POWERPC_FLAG_DE
)) {
9162 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9163 "Should not define POWERPC_FLAG_BE nor POWERPC_FLAG_DE\n");
9166 if (env
->msr_mask
& (1 << 2)) {
9167 switch (env
->flags
& (POWERPC_FLAG_PX
| POWERPC_FLAG_PMM
)) {
9168 case POWERPC_FLAG_PX
:
9169 case POWERPC_FLAG_PMM
:
9172 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9173 "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n");
9176 } else if (env
->flags
& (POWERPC_FLAG_PX
| POWERPC_FLAG_PMM
)) {
9177 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9178 "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
9181 if ((env
->flags
& (POWERPC_FLAG_RTC_CLK
| POWERPC_FLAG_BUS_CLK
)) == 0) {
9182 fprintf(stderr
, "PowerPC flags inconsistency\n"
9183 "Should define the time-base and decrementer clock source\n");
9186 /* Allocate TLBs buffer when needed */
9187 #if !defined(CONFIG_USER_ONLY)
9188 if (env
->nb_tlb
!= 0) {
9189 int nb_tlb
= env
->nb_tlb
;
9190 if (env
->id_tlbs
!= 0)
9192 switch (env
->tlb_type
) {
9194 env
->tlb
.tlb6
= g_malloc0(nb_tlb
* sizeof(ppc6xx_tlb_t
));
9197 env
->tlb
.tlbe
= g_malloc0(nb_tlb
* sizeof(ppcemb_tlb_t
));
9200 env
->tlb
.tlbm
= g_malloc0(nb_tlb
* sizeof(ppcmas_tlb_t
));
9203 /* Pre-compute some useful values */
9204 env
->tlb_per_way
= env
->nb_tlb
/ env
->nb_ways
;
9206 if (env
->irq_inputs
== NULL
) {
9207 fprintf(stderr
, "WARNING: no internal IRQ controller registered.\n"
9208 " Attempt QEMU to crash very soon !\n");
9211 if (env
->check_pow
== NULL
) {
9212 fprintf(stderr
, "WARNING: no power management check handler "
9214 " Attempt QEMU to crash very soon !\n");
9218 #if defined(PPC_DUMP_CPU)
9219 static void dump_ppc_sprs(CPUPPCState
*env
)
9222 #if !defined(CONFIG_USER_ONLY)
9228 printf("Special purpose registers:\n");
9229 for (i
= 0; i
< 32; i
++) {
9230 for (j
= 0; j
< 32; j
++) {
9232 spr
= &env
->spr_cb
[n
];
9233 uw
= spr
->uea_write
!= NULL
&& spr
->uea_write
!= SPR_NOACCESS
;
9234 ur
= spr
->uea_read
!= NULL
&& spr
->uea_read
!= SPR_NOACCESS
;
9235 #if !defined(CONFIG_USER_ONLY)
9236 sw
= spr
->oea_write
!= NULL
&& spr
->oea_write
!= SPR_NOACCESS
;
9237 sr
= spr
->oea_read
!= NULL
&& spr
->oea_read
!= SPR_NOACCESS
;
9238 if (sw
|| sr
|| uw
|| ur
) {
9239 printf("SPR: %4d (%03x) %-8s s%c%c u%c%c\n",
9240 (i
<< 5) | j
, (i
<< 5) | j
, spr
->name
,
9241 sw
? 'w' : '-', sr
? 'r' : '-',
9242 uw
? 'w' : '-', ur
? 'r' : '-');
9246 printf("SPR: %4d (%03x) %-8s u%c%c\n",
9247 (i
<< 5) | j
, (i
<< 5) | j
, spr
->name
,
9248 uw
? 'w' : '-', ur
? 'r' : '-');
9258 /*****************************************************************************/
9262 PPC_DIRECT
= 0, /* Opcode routine */
9263 PPC_INDIRECT
= 1, /* Indirect opcode table */
9266 #define PPC_OPCODE_MASK 0x3
9268 static inline int is_indirect_opcode(void *handler
)
9270 return ((uintptr_t)handler
& PPC_OPCODE_MASK
) == PPC_INDIRECT
;
9273 static inline opc_handler_t
**ind_table(void *handler
)
9275 return (opc_handler_t
**)((uintptr_t)handler
& ~PPC_OPCODE_MASK
);
9278 /* Instruction table creation */
9279 /* Opcodes tables creation */
9280 static void fill_new_table(opc_handler_t
**table
, int len
)
9284 for (i
= 0; i
< len
; i
++)
9285 table
[i
] = &invalid_handler
;
9288 static int create_new_table(opc_handler_t
**table
, unsigned char idx
)
9290 opc_handler_t
**tmp
;
9292 tmp
= g_new(opc_handler_t
*, PPC_CPU_INDIRECT_OPCODES_LEN
);
9293 fill_new_table(tmp
, PPC_CPU_INDIRECT_OPCODES_LEN
);
9294 table
[idx
] = (opc_handler_t
*)((uintptr_t)tmp
| PPC_INDIRECT
);
9299 static int insert_in_table(opc_handler_t
**table
, unsigned char idx
,
9300 opc_handler_t
*handler
)
9302 if (table
[idx
] != &invalid_handler
)
9304 table
[idx
] = handler
;
9309 static int register_direct_insn(opc_handler_t
**ppc_opcodes
,
9310 unsigned char idx
, opc_handler_t
*handler
)
9312 if (insert_in_table(ppc_opcodes
, idx
, handler
) < 0) {
9313 printf("*** ERROR: opcode %02x already assigned in main "
9314 "opcode table\n", idx
);
9315 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9316 printf(" Registered handler '%s' - new handler '%s'\n",
9317 ppc_opcodes
[idx
]->oname
, handler
->oname
);
9325 static int register_ind_in_table(opc_handler_t
**table
,
9326 unsigned char idx1
, unsigned char idx2
,
9327 opc_handler_t
*handler
)
9329 if (table
[idx1
] == &invalid_handler
) {
9330 if (create_new_table(table
, idx1
) < 0) {
9331 printf("*** ERROR: unable to create indirect table "
9332 "idx=%02x\n", idx1
);
9336 if (!is_indirect_opcode(table
[idx1
])) {
9337 printf("*** ERROR: idx %02x already assigned to a direct "
9339 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9340 printf(" Registered handler '%s' - new handler '%s'\n",
9341 ind_table(table
[idx1
])[idx2
]->oname
, handler
->oname
);
9346 if (handler
!= NULL
&&
9347 insert_in_table(ind_table(table
[idx1
]), idx2
, handler
) < 0) {
9348 printf("*** ERROR: opcode %02x already assigned in "
9349 "opcode table %02x\n", idx2
, idx1
);
9350 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9351 printf(" Registered handler '%s' - new handler '%s'\n",
9352 ind_table(table
[idx1
])[idx2
]->oname
, handler
->oname
);
9360 static int register_ind_insn(opc_handler_t
**ppc_opcodes
,
9361 unsigned char idx1
, unsigned char idx2
,
9362 opc_handler_t
*handler
)
9364 return register_ind_in_table(ppc_opcodes
, idx1
, idx2
, handler
);
9367 static int register_dblind_insn(opc_handler_t
**ppc_opcodes
,
9368 unsigned char idx1
, unsigned char idx2
,
9369 unsigned char idx3
, opc_handler_t
*handler
)
9371 if (register_ind_in_table(ppc_opcodes
, idx1
, idx2
, NULL
) < 0) {
9372 printf("*** ERROR: unable to join indirect table idx "
9373 "[%02x-%02x]\n", idx1
, idx2
);
9376 if (register_ind_in_table(ind_table(ppc_opcodes
[idx1
]), idx2
, idx3
,
9378 printf("*** ERROR: unable to insert opcode "
9379 "[%02x-%02x-%02x]\n", idx1
, idx2
, idx3
);
9386 static int register_trplind_insn(opc_handler_t
**ppc_opcodes
,
9387 unsigned char idx1
, unsigned char idx2
,
9388 unsigned char idx3
, unsigned char idx4
,
9389 opc_handler_t
*handler
)
9391 opc_handler_t
**table
;
9393 if (register_ind_in_table(ppc_opcodes
, idx1
, idx2
, NULL
) < 0) {
9394 printf("*** ERROR: unable to join indirect table idx "
9395 "[%02x-%02x]\n", idx1
, idx2
);
9398 table
= ind_table(ppc_opcodes
[idx1
]);
9399 if (register_ind_in_table(table
, idx2
, idx3
, NULL
) < 0) {
9400 printf("*** ERROR: unable to join 2nd-level indirect table idx "
9401 "[%02x-%02x-%02x]\n", idx1
, idx2
, idx3
);
9404 table
= ind_table(table
[idx2
]);
9405 if (register_ind_in_table(table
, idx3
, idx4
, handler
) < 0) {
9406 printf("*** ERROR: unable to insert opcode "
9407 "[%02x-%02x-%02x-%02x]\n", idx1
, idx2
, idx3
, idx4
);
9412 static int register_insn(opc_handler_t
**ppc_opcodes
, opcode_t
*insn
)
9414 if (insn
->opc2
!= 0xFF) {
9415 if (insn
->opc3
!= 0xFF) {
9416 if (insn
->opc4
!= 0xFF) {
9417 if (register_trplind_insn(ppc_opcodes
, insn
->opc1
, insn
->opc2
,
9418 insn
->opc3
, insn
->opc4
,
9419 &insn
->handler
) < 0) {
9423 if (register_dblind_insn(ppc_opcodes
, insn
->opc1
, insn
->opc2
,
9424 insn
->opc3
, &insn
->handler
) < 0)
9428 if (register_ind_insn(ppc_opcodes
, insn
->opc1
,
9429 insn
->opc2
, &insn
->handler
) < 0)
9433 if (register_direct_insn(ppc_opcodes
, insn
->opc1
, &insn
->handler
) < 0)
9440 static int test_opcode_table(opc_handler_t
**table
, int len
)
9444 for (i
= 0, count
= 0; i
< len
; i
++) {
9445 /* Consistency fixup */
9446 if (table
[i
] == NULL
)
9447 table
[i
] = &invalid_handler
;
9448 if (table
[i
] != &invalid_handler
) {
9449 if (is_indirect_opcode(table
[i
])) {
9450 tmp
= test_opcode_table(ind_table(table
[i
]),
9451 PPC_CPU_INDIRECT_OPCODES_LEN
);
9454 table
[i
] = &invalid_handler
;
9467 static void fix_opcode_tables(opc_handler_t
**ppc_opcodes
)
9469 if (test_opcode_table(ppc_opcodes
, PPC_CPU_OPCODES_LEN
) == 0)
9470 printf("*** WARNING: no opcode defined !\n");
9473 /*****************************************************************************/
9474 static void create_ppc_opcodes(PowerPCCPU
*cpu
, Error
**errp
)
9476 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9477 CPUPPCState
*env
= &cpu
->env
;
9480 fill_new_table(env
->opcodes
, PPC_CPU_OPCODES_LEN
);
9481 for (opc
= opcodes
; opc
< &opcodes
[ARRAY_SIZE(opcodes
)]; opc
++) {
9482 if (((opc
->handler
.type
& pcc
->insns_flags
) != 0) ||
9483 ((opc
->handler
.type2
& pcc
->insns_flags2
) != 0)) {
9484 if (register_insn(env
->opcodes
, opc
) < 0) {
9485 error_setg(errp
, "ERROR initializing PowerPC instruction "
9486 "0x%02x 0x%02x 0x%02x", opc
->opc1
, opc
->opc2
,
9492 fix_opcode_tables(env
->opcodes
);
9497 #if defined(PPC_DUMP_CPU)
9498 static void dump_ppc_insns(CPUPPCState
*env
)
9500 opc_handler_t
**table
, *handler
;
9502 uint8_t opc1
, opc2
, opc3
, opc4
;
9504 printf("Instructions set:\n");
9505 /* opc1 is 6 bits long */
9506 for (opc1
= 0x00; opc1
< PPC_CPU_OPCODES_LEN
; opc1
++) {
9507 table
= env
->opcodes
;
9508 handler
= table
[opc1
];
9509 if (is_indirect_opcode(handler
)) {
9510 /* opc2 is 5 bits long */
9511 for (opc2
= 0; opc2
< PPC_CPU_INDIRECT_OPCODES_LEN
; opc2
++) {
9512 table
= env
->opcodes
;
9513 handler
= env
->opcodes
[opc1
];
9514 table
= ind_table(handler
);
9515 handler
= table
[opc2
];
9516 if (is_indirect_opcode(handler
)) {
9517 table
= ind_table(handler
);
9518 /* opc3 is 5 bits long */
9519 for (opc3
= 0; opc3
< PPC_CPU_INDIRECT_OPCODES_LEN
;
9521 handler
= table
[opc3
];
9522 if (is_indirect_opcode(handler
)) {
9523 table
= ind_table(handler
);
9524 /* opc4 is 5 bits long */
9525 for (opc4
= 0; opc4
< PPC_CPU_INDIRECT_OPCODES_LEN
;
9527 handler
= table
[opc4
];
9528 if (handler
->handler
!= &gen_invalid
) {
9529 printf("INSN: %02x %02x %02x %02x -- "
9530 "(%02d %04d %02d) : %s\n",
9531 opc1
, opc2
, opc3
, opc4
,
9532 opc1
, (opc3
<< 5) | opc2
, opc4
,
9537 if (handler
->handler
!= &gen_invalid
) {
9538 /* Special hack to properly dump SPE insns */
9539 p
= strchr(handler
->oname
, '_');
9541 printf("INSN: %02x %02x %02x (%02d %04d) : "
9543 opc1
, opc2
, opc3
, opc1
,
9548 if ((p
- handler
->oname
) != strlen(q
)
9549 || (memcmp(handler
->oname
, q
, strlen(q
))
9551 /* First instruction */
9552 printf("INSN: %02x %02x %02x"
9553 "(%02d %04d) : %.*s\n",
9554 opc1
, opc2
<< 1, opc3
, opc1
,
9555 (opc3
<< 6) | (opc2
<< 1),
9556 (int)(p
- handler
->oname
),
9559 if (strcmp(p
+ 1, q
) != 0) {
9560 /* Second instruction */
9561 printf("INSN: %02x %02x %02x "
9562 "(%02d %04d) : %s\n", opc1
,
9563 (opc2
<< 1) | 1, opc3
, opc1
,
9564 (opc3
<< 6) | (opc2
<< 1) | 1,
9572 if (handler
->handler
!= &gen_invalid
) {
9573 printf("INSN: %02x %02x -- (%02d %04d) : %s\n",
9574 opc1
, opc2
, opc1
, opc2
, handler
->oname
);
9579 if (handler
->handler
!= &gen_invalid
) {
9580 printf("INSN: %02x -- -- (%02d ----) : %s\n",
9581 opc1
, opc1
, handler
->oname
);
9588 static bool avr_need_swap(CPUPPCState
*env
)
9590 #ifdef HOST_WORDS_BIGENDIAN
9597 static int gdb_get_float_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9600 stfq_p(mem_buf
, env
->fpr
[n
]);
9601 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9605 stl_p(mem_buf
, env
->fpscr
);
9606 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9612 static int gdb_set_float_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9615 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9616 env
->fpr
[n
] = ldfq_p(mem_buf
);
9620 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9621 helper_store_fpscr(env
, ldl_p(mem_buf
), 0xffffffff);
9627 static int gdb_get_avr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9630 if (!avr_need_swap(env
)) {
9631 stq_p(mem_buf
, env
->avr
[n
].u64
[0]);
9632 stq_p(mem_buf
+8, env
->avr
[n
].u64
[1]);
9634 stq_p(mem_buf
, env
->avr
[n
].u64
[1]);
9635 stq_p(mem_buf
+8, env
->avr
[n
].u64
[0]);
9637 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9638 ppc_maybe_bswap_register(env
, mem_buf
+ 8, 8);
9642 stl_p(mem_buf
, env
->vscr
);
9643 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9647 stl_p(mem_buf
, (uint32_t)env
->spr
[SPR_VRSAVE
]);
9648 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9654 static int gdb_set_avr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9657 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9658 ppc_maybe_bswap_register(env
, mem_buf
+ 8, 8);
9659 if (!avr_need_swap(env
)) {
9660 env
->avr
[n
].u64
[0] = ldq_p(mem_buf
);
9661 env
->avr
[n
].u64
[1] = ldq_p(mem_buf
+8);
9663 env
->avr
[n
].u64
[1] = ldq_p(mem_buf
);
9664 env
->avr
[n
].u64
[0] = ldq_p(mem_buf
+8);
9669 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9670 env
->vscr
= ldl_p(mem_buf
);
9674 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9675 env
->spr
[SPR_VRSAVE
] = (target_ulong
)ldl_p(mem_buf
);
9681 static int gdb_get_spe_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9684 #if defined(TARGET_PPC64)
9685 stl_p(mem_buf
, env
->gpr
[n
] >> 32);
9686 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9688 stl_p(mem_buf
, env
->gprh
[n
]);
9693 stq_p(mem_buf
, env
->spe_acc
);
9694 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9698 stl_p(mem_buf
, env
->spe_fscr
);
9699 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9705 static int gdb_set_spe_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9708 #if defined(TARGET_PPC64)
9709 target_ulong lo
= (uint32_t)env
->gpr
[n
];
9712 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9714 hi
= (target_ulong
)ldl_p(mem_buf
) << 32;
9715 env
->gpr
[n
] = lo
| hi
;
9717 env
->gprh
[n
] = ldl_p(mem_buf
);
9722 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9723 env
->spe_acc
= ldq_p(mem_buf
);
9727 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9728 env
->spe_fscr
= ldl_p(mem_buf
);
9734 static int gdb_get_vsx_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9737 stq_p(mem_buf
, env
->vsr
[n
]);
9738 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9744 static int gdb_set_vsx_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9747 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9748 env
->vsr
[n
] = ldq_p(mem_buf
);
9754 static int ppc_fixup_cpu(PowerPCCPU
*cpu
)
9756 CPUPPCState
*env
= &cpu
->env
;
9758 /* TCG doesn't (yet) emulate some groups of instructions that
9759 * are implemented on some otherwise supported CPUs (e.g. VSX
9760 * and decimal floating point instructions on POWER7). We
9761 * remove unsupported instruction groups from the cpu state's
9762 * instruction masks and hope the guest can cope. For at
9763 * least the pseries machine, the unavailability of these
9764 * instructions can be advertised to the guest via the device
9766 if ((env
->insns_flags
& ~PPC_TCG_INSNS
)
9767 || (env
->insns_flags2
& ~PPC_TCG_INSNS2
)) {
9768 fprintf(stderr
, "Warning: Disabling some instructions which are not "
9769 "emulated by TCG (0x%" PRIx64
", 0x%" PRIx64
")\n",
9770 env
->insns_flags
& ~PPC_TCG_INSNS
,
9771 env
->insns_flags2
& ~PPC_TCG_INSNS2
);
9773 env
->insns_flags
&= PPC_TCG_INSNS
;
9774 env
->insns_flags2
&= PPC_TCG_INSNS2
;
9778 static inline bool ppc_cpu_is_valid(PowerPCCPUClass
*pcc
)
9780 #ifdef TARGET_PPCEMB
9781 return pcc
->mmu_model
== POWERPC_MMU_BOOKE
||
9782 pcc
->mmu_model
== POWERPC_MMU_SOFT_4xx
||
9783 pcc
->mmu_model
== POWERPC_MMU_SOFT_4xx_Z
;
9789 static void ppc_cpu_realizefn(DeviceState
*dev
, Error
**errp
)
9791 CPUState
*cs
= CPU(dev
);
9792 PowerPCCPU
*cpu
= POWERPC_CPU(dev
);
9793 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9794 Error
*local_err
= NULL
;
9795 #if !defined(CONFIG_USER_ONLY)
9796 int max_smt
= kvmppc_smt_threads();
9799 #if !defined(CONFIG_USER_ONLY)
9800 if (smp_threads
> max_smt
) {
9801 error_setg(errp
, "Cannot support more than %d threads on PPC with %s",
9802 max_smt
, kvm_enabled() ? "KVM" : "TCG");
9805 if (!is_power_of_2(smp_threads
)) {
9806 error_setg(errp
, "Cannot support %d threads on PPC with %s, "
9807 "threads count must be a power of 2.",
9808 smp_threads
, kvm_enabled() ? "KVM" : "TCG");
9813 cpu_exec_realizefn(cs
, &local_err
);
9814 if (local_err
!= NULL
) {
9815 error_propagate(errp
, local_err
);
9819 #if !defined(CONFIG_USER_ONLY)
9820 cpu
->cpu_dt_id
= (cs
->cpu_index
/ smp_threads
) * max_smt
9821 + (cs
->cpu_index
% smp_threads
);
9823 if (kvm_enabled() && !kvm_vcpu_id_is_valid(cpu
->cpu_dt_id
)) {
9824 error_setg(errp
, "Can't create CPU with id %d in KVM", cpu
->cpu_dt_id
);
9825 error_append_hint(errp
, "Adjust the number of cpus to %d "
9826 "or try to raise the number of threads per core\n",
9827 cpu
->cpu_dt_id
* smp_threads
/ max_smt
);
9832 if (tcg_enabled()) {
9833 if (ppc_fixup_cpu(cpu
) != 0) {
9834 error_setg(errp
, "Unable to emulate selected CPU with TCG");
9839 #if defined(TARGET_PPCEMB)
9840 if (!ppc_cpu_is_valid(pcc
)) {
9841 error_setg(errp
, "CPU does not possess a BookE or 4xx MMU. "
9842 "Please use qemu-system-ppc or qemu-system-ppc64 instead "
9843 "or choose another CPU model.");
9848 create_ppc_opcodes(cpu
, &local_err
);
9849 if (local_err
!= NULL
) {
9850 error_propagate(errp
, local_err
);
9855 if (pcc
->insns_flags
& PPC_FLOAT
) {
9856 gdb_register_coprocessor(cs
, gdb_get_float_reg
, gdb_set_float_reg
,
9857 33, "power-fpu.xml", 0);
9859 if (pcc
->insns_flags
& PPC_ALTIVEC
) {
9860 gdb_register_coprocessor(cs
, gdb_get_avr_reg
, gdb_set_avr_reg
,
9861 34, "power-altivec.xml", 0);
9863 if (pcc
->insns_flags
& PPC_SPE
) {
9864 gdb_register_coprocessor(cs
, gdb_get_spe_reg
, gdb_set_spe_reg
,
9865 34, "power-spe.xml", 0);
9867 if (pcc
->insns_flags2
& PPC2_VSX
) {
9868 gdb_register_coprocessor(cs
, gdb_get_vsx_reg
, gdb_set_vsx_reg
,
9869 32, "power-vsx.xml", 0);
9874 pcc
->parent_realize(dev
, errp
);
9876 #if defined(PPC_DUMP_CPU)
9878 CPUPPCState
*env
= &cpu
->env
;
9879 const char *mmu_model
, *excp_model
, *bus_model
;
9880 switch (env
->mmu_model
) {
9881 case POWERPC_MMU_32B
:
9882 mmu_model
= "PowerPC 32";
9884 case POWERPC_MMU_SOFT_6xx
:
9885 mmu_model
= "PowerPC 6xx/7xx with software driven TLBs";
9887 case POWERPC_MMU_SOFT_74xx
:
9888 mmu_model
= "PowerPC 74xx with software driven TLBs";
9890 case POWERPC_MMU_SOFT_4xx
:
9891 mmu_model
= "PowerPC 4xx with software driven TLBs";
9893 case POWERPC_MMU_SOFT_4xx_Z
:
9894 mmu_model
= "PowerPC 4xx with software driven TLBs "
9895 "and zones protections";
9897 case POWERPC_MMU_REAL
:
9898 mmu_model
= "PowerPC real mode only";
9900 case POWERPC_MMU_MPC8xx
:
9901 mmu_model
= "PowerPC MPC8xx";
9903 case POWERPC_MMU_BOOKE
:
9904 mmu_model
= "PowerPC BookE";
9906 case POWERPC_MMU_BOOKE206
:
9907 mmu_model
= "PowerPC BookE 2.06";
9909 case POWERPC_MMU_601
:
9910 mmu_model
= "PowerPC 601";
9912 #if defined(TARGET_PPC64)
9913 case POWERPC_MMU_64B
:
9914 mmu_model
= "PowerPC 64";
9918 mmu_model
= "Unknown or invalid";
9921 switch (env
->excp_model
) {
9922 case POWERPC_EXCP_STD
:
9923 excp_model
= "PowerPC";
9925 case POWERPC_EXCP_40x
:
9926 excp_model
= "PowerPC 40x";
9928 case POWERPC_EXCP_601
:
9929 excp_model
= "PowerPC 601";
9931 case POWERPC_EXCP_602
:
9932 excp_model
= "PowerPC 602";
9934 case POWERPC_EXCP_603
:
9935 excp_model
= "PowerPC 603";
9937 case POWERPC_EXCP_603E
:
9938 excp_model
= "PowerPC 603e";
9940 case POWERPC_EXCP_604
:
9941 excp_model
= "PowerPC 604";
9943 case POWERPC_EXCP_7x0
:
9944 excp_model
= "PowerPC 740/750";
9946 case POWERPC_EXCP_7x5
:
9947 excp_model
= "PowerPC 745/755";
9949 case POWERPC_EXCP_74xx
:
9950 excp_model
= "PowerPC 74xx";
9952 case POWERPC_EXCP_BOOKE
:
9953 excp_model
= "PowerPC BookE";
9955 #if defined(TARGET_PPC64)
9956 case POWERPC_EXCP_970
:
9957 excp_model
= "PowerPC 970";
9961 excp_model
= "Unknown or invalid";
9964 switch (env
->bus_model
) {
9965 case PPC_FLAGS_INPUT_6xx
:
9966 bus_model
= "PowerPC 6xx";
9968 case PPC_FLAGS_INPUT_BookE
:
9969 bus_model
= "PowerPC BookE";
9971 case PPC_FLAGS_INPUT_405
:
9972 bus_model
= "PowerPC 405";
9974 case PPC_FLAGS_INPUT_401
:
9975 bus_model
= "PowerPC 401/403";
9977 case PPC_FLAGS_INPUT_RCPU
:
9978 bus_model
= "RCPU / MPC8xx";
9980 #if defined(TARGET_PPC64)
9981 case PPC_FLAGS_INPUT_970
:
9982 bus_model
= "PowerPC 970";
9986 bus_model
= "Unknown or invalid";
9989 printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64
"\n"
9990 " MMU model : %s\n",
9991 object_class_get_name(OBJECT_CLASS(pcc
)),
9992 pcc
->pvr
, pcc
->msr_mask
, mmu_model
);
9993 #if !defined(CONFIG_USER_ONLY)
9994 if (env
->tlb
.tlb6
) {
9995 printf(" %d %s TLB in %d ways\n",
9996 env
->nb_tlb
, env
->id_tlbs
? "splitted" : "merged",
10000 printf(" Exceptions model : %s\n"
10001 " Bus model : %s\n",
10002 excp_model
, bus_model
);
10003 printf(" MSR features :\n");
10004 if (env
->flags
& POWERPC_FLAG_SPE
)
10005 printf(" signal processing engine enable"
10007 else if (env
->flags
& POWERPC_FLAG_VRE
)
10008 printf(" vector processor enable\n");
10009 if (env
->flags
& POWERPC_FLAG_TGPR
)
10010 printf(" temporary GPRs\n");
10011 else if (env
->flags
& POWERPC_FLAG_CE
)
10012 printf(" critical input enable\n");
10013 if (env
->flags
& POWERPC_FLAG_SE
)
10014 printf(" single-step trace mode\n");
10015 else if (env
->flags
& POWERPC_FLAG_DWE
)
10016 printf(" debug wait enable\n");
10017 else if (env
->flags
& POWERPC_FLAG_UBLE
)
10018 printf(" user BTB lock enable\n");
10019 if (env
->flags
& POWERPC_FLAG_BE
)
10020 printf(" branch-step trace mode\n");
10021 else if (env
->flags
& POWERPC_FLAG_DE
)
10022 printf(" debug interrupt enable\n");
10023 if (env
->flags
& POWERPC_FLAG_PX
)
10024 printf(" inclusive protection\n");
10025 else if (env
->flags
& POWERPC_FLAG_PMM
)
10026 printf(" performance monitor mark\n");
10027 if (env
->flags
== POWERPC_FLAG_NONE
)
10029 printf(" Time-base/decrementer clock source: %s\n",
10030 env
->flags
& POWERPC_FLAG_RTC_CLK
? "RTC clock" : "bus clock");
10031 dump_ppc_insns(env
);
10032 dump_ppc_sprs(env
);
10039 cpu_exec_unrealizefn(cs
);
10042 static void ppc_cpu_unrealizefn(DeviceState
*dev
, Error
**errp
)
10044 PowerPCCPU
*cpu
= POWERPC_CPU(dev
);
10045 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10046 CPUPPCState
*env
= &cpu
->env
;
10047 Error
*local_err
= NULL
;
10048 opc_handler_t
**table
, **table_2
;
10051 pcc
->parent_unrealize(dev
, &local_err
);
10052 if (local_err
!= NULL
) {
10053 error_propagate(errp
, local_err
);
10057 for (i
= 0; i
< PPC_CPU_OPCODES_LEN
; i
++) {
10058 if (env
->opcodes
[i
] == &invalid_handler
) {
10061 if (is_indirect_opcode(env
->opcodes
[i
])) {
10062 table
= ind_table(env
->opcodes
[i
]);
10063 for (j
= 0; j
< PPC_CPU_INDIRECT_OPCODES_LEN
; j
++) {
10064 if (table
[j
] == &invalid_handler
) {
10067 if (is_indirect_opcode(table
[j
])) {
10068 table_2
= ind_table(table
[j
]);
10069 for (k
= 0; k
< PPC_CPU_INDIRECT_OPCODES_LEN
; k
++) {
10070 if (table_2
[k
] != &invalid_handler
&&
10071 is_indirect_opcode(table_2
[k
])) {
10072 g_free((opc_handler_t
*)((uintptr_t)table_2
[k
] &
10076 g_free((opc_handler_t
*)((uintptr_t)table
[j
] &
10080 g_free((opc_handler_t
*)((uintptr_t)env
->opcodes
[i
] &
10086 static gint
ppc_cpu_compare_class_pvr(gconstpointer a
, gconstpointer b
)
10088 ObjectClass
*oc
= (ObjectClass
*)a
;
10089 uint32_t pvr
= *(uint32_t *)b
;
10090 PowerPCCPUClass
*pcc
= (PowerPCCPUClass
*)a
;
10092 /* -cpu host does a PVR lookup during construction */
10093 if (unlikely(strcmp(object_class_get_name(oc
),
10094 TYPE_HOST_POWERPC_CPU
) == 0)) {
10098 if (!ppc_cpu_is_valid(pcc
)) {
10102 return pcc
->pvr
== pvr
? 0 : -1;
10105 PowerPCCPUClass
*ppc_cpu_class_by_pvr(uint32_t pvr
)
10107 GSList
*list
, *item
;
10108 PowerPCCPUClass
*pcc
= NULL
;
10110 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10111 item
= g_slist_find_custom(list
, &pvr
, ppc_cpu_compare_class_pvr
);
10112 if (item
!= NULL
) {
10113 pcc
= POWERPC_CPU_CLASS(item
->data
);
10115 g_slist_free(list
);
10120 static gint
ppc_cpu_compare_class_pvr_mask(gconstpointer a
, gconstpointer b
)
10122 ObjectClass
*oc
= (ObjectClass
*)a
;
10123 uint32_t pvr
= *(uint32_t *)b
;
10124 PowerPCCPUClass
*pcc
= (PowerPCCPUClass
*)a
;
10126 /* -cpu host does a PVR lookup during construction */
10127 if (unlikely(strcmp(object_class_get_name(oc
),
10128 TYPE_HOST_POWERPC_CPU
) == 0)) {
10132 if (!ppc_cpu_is_valid(pcc
)) {
10136 if (pcc
->pvr_match(pcc
, pvr
)) {
10143 PowerPCCPUClass
*ppc_cpu_class_by_pvr_mask(uint32_t pvr
)
10145 GSList
*list
, *item
;
10146 PowerPCCPUClass
*pcc
= NULL
;
10148 list
= object_class_get_list(TYPE_POWERPC_CPU
, true);
10149 item
= g_slist_find_custom(list
, &pvr
, ppc_cpu_compare_class_pvr_mask
);
10150 if (item
!= NULL
) {
10151 pcc
= POWERPC_CPU_CLASS(item
->data
);
10153 g_slist_free(list
);
10158 static gint
ppc_cpu_compare_class_name(gconstpointer a
, gconstpointer b
)
10160 ObjectClass
*oc
= (ObjectClass
*)a
;
10161 const char *name
= b
;
10162 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10164 if (strncasecmp(name
, object_class_get_name(oc
), strlen(name
)) == 0 &&
10165 ppc_cpu_is_valid(pcc
) &&
10166 strcmp(object_class_get_name(oc
) + strlen(name
),
10167 "-" TYPE_POWERPC_CPU
) == 0) {
10174 static ObjectClass
*ppc_cpu_class_by_name(const char *name
);
10176 static ObjectClass
*ppc_cpu_class_by_alias(PowerPCCPUAlias
*alias
)
10178 ObjectClass
*invalid_class
= (void*)ppc_cpu_class_by_alias
;
10180 /* Cache target class lookups in the alias table */
10182 alias
->oc
= ppc_cpu_class_by_name(alias
->model
);
10184 /* Fast check for non-existing aliases */
10185 alias
->oc
= invalid_class
;
10189 if (alias
->oc
== invalid_class
) {
10196 static ObjectClass
*ppc_cpu_class_by_name(const char *name
)
10198 GSList
*list
, *item
;
10199 ObjectClass
*ret
= NULL
;
10203 /* Check if the given name is a PVR */
10204 len
= strlen(name
);
10205 if (len
== 10 && name
[0] == '0' && name
[1] == 'x') {
10208 } else if (len
== 8) {
10211 for (i
= 0; i
< 8; i
++) {
10212 if (!qemu_isxdigit(*p
++))
10216 return OBJECT_CLASS(ppc_cpu_class_by_pvr(strtoul(name
, NULL
, 16)));
10220 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10221 item
= g_slist_find_custom(list
, name
, ppc_cpu_compare_class_name
);
10222 if (item
!= NULL
) {
10223 ret
= OBJECT_CLASS(item
->data
);
10225 g_slist_free(list
);
10231 for (i
= 0; ppc_cpu_aliases
[i
].alias
!= NULL
; i
++) {
10232 if (strcmp(ppc_cpu_aliases
[i
].alias
, name
) == 0) {
10233 return ppc_cpu_class_by_alias(&ppc_cpu_aliases
[i
]);
10240 const char *ppc_cpu_lookup_alias(const char *alias
)
10244 for (ai
= 0; ppc_cpu_aliases
[ai
].alias
!= NULL
; ai
++) {
10245 if (strcmp(ppc_cpu_aliases
[ai
].alias
, alias
) == 0) {
10246 return ppc_cpu_aliases
[ai
].model
;
10253 PowerPCCPU
*cpu_ppc_init(const char *cpu_model
)
10255 return POWERPC_CPU(cpu_generic_init(TYPE_POWERPC_CPU
, cpu_model
));
10258 PowerPCCPUClass
*ppc_cpu_get_family_class(PowerPCCPUClass
*pcc
)
10260 ObjectClass
*oc
= OBJECT_CLASS(pcc
);
10262 while (oc
&& !object_class_is_abstract(oc
)) {
10263 oc
= object_class_get_parent(oc
);
10267 return POWERPC_CPU_CLASS(oc
);
10270 /* Sort by PVR, ordering special case "host" last. */
10271 static gint
ppc_cpu_list_compare(gconstpointer a
, gconstpointer b
)
10273 ObjectClass
*oc_a
= (ObjectClass
*)a
;
10274 ObjectClass
*oc_b
= (ObjectClass
*)b
;
10275 PowerPCCPUClass
*pcc_a
= POWERPC_CPU_CLASS(oc_a
);
10276 PowerPCCPUClass
*pcc_b
= POWERPC_CPU_CLASS(oc_b
);
10277 const char *name_a
= object_class_get_name(oc_a
);
10278 const char *name_b
= object_class_get_name(oc_b
);
10280 if (strcmp(name_a
, TYPE_HOST_POWERPC_CPU
) == 0) {
10282 } else if (strcmp(name_b
, TYPE_HOST_POWERPC_CPU
) == 0) {
10285 /* Avoid an integer overflow during subtraction */
10286 if (pcc_a
->pvr
< pcc_b
->pvr
) {
10288 } else if (pcc_a
->pvr
> pcc_b
->pvr
) {
10296 static void ppc_cpu_list_entry(gpointer data
, gpointer user_data
)
10298 ObjectClass
*oc
= data
;
10299 CPUListState
*s
= user_data
;
10300 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10301 DeviceClass
*family
= DEVICE_CLASS(ppc_cpu_get_family_class(pcc
));
10302 const char *typename
= object_class_get_name(oc
);
10306 if (!ppc_cpu_is_valid(pcc
)) {
10309 if (unlikely(strcmp(typename
, TYPE_HOST_POWERPC_CPU
) == 0)) {
10313 name
= g_strndup(typename
,
10314 strlen(typename
) - strlen("-" TYPE_POWERPC_CPU
));
10315 (*s
->cpu_fprintf
)(s
->file
, "PowerPC %-16s PVR %08x\n",
10317 for (i
= 0; ppc_cpu_aliases
[i
].alias
!= NULL
; i
++) {
10318 PowerPCCPUAlias
*alias
= &ppc_cpu_aliases
[i
];
10319 ObjectClass
*alias_oc
= ppc_cpu_class_by_alias(alias
);
10321 if (alias_oc
!= oc
) {
10325 * If running with KVM, we might update the family alias later, so
10326 * avoid printing the wrong alias here and use "preferred" instead
10328 if (strcmp(alias
->alias
, family
->desc
) == 0) {
10329 (*s
->cpu_fprintf
)(s
->file
,
10330 "PowerPC %-16s (alias for preferred %s CPU)\n",
10331 alias
->alias
, family
->desc
);
10333 (*s
->cpu_fprintf
)(s
->file
, "PowerPC %-16s (alias for %s)\n",
10334 alias
->alias
, name
);
10340 void ppc_cpu_list(FILE *f
, fprintf_function cpu_fprintf
)
10344 .cpu_fprintf
= cpu_fprintf
,
10348 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10349 list
= g_slist_sort(list
, ppc_cpu_list_compare
);
10350 g_slist_foreach(list
, ppc_cpu_list_entry
, &s
);
10351 g_slist_free(list
);
10354 cpu_fprintf(f
, "\n");
10355 cpu_fprintf(f
, "PowerPC %-16s\n", "host");
10359 static void ppc_cpu_defs_entry(gpointer data
, gpointer user_data
)
10361 ObjectClass
*oc
= data
;
10362 CpuDefinitionInfoList
**first
= user_data
;
10363 const char *typename
;
10364 CpuDefinitionInfoList
*entry
;
10365 CpuDefinitionInfo
*info
;
10366 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10368 if (!ppc_cpu_is_valid(pcc
)) {
10372 typename
= object_class_get_name(oc
);
10373 info
= g_malloc0(sizeof(*info
));
10374 info
->name
= g_strndup(typename
,
10375 strlen(typename
) - strlen("-" TYPE_POWERPC_CPU
));
10377 entry
= g_malloc0(sizeof(*entry
));
10378 entry
->value
= info
;
10379 entry
->next
= *first
;
10383 CpuDefinitionInfoList
*arch_query_cpu_definitions(Error
**errp
)
10385 CpuDefinitionInfoList
*cpu_list
= NULL
;
10389 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10390 g_slist_foreach(list
, ppc_cpu_defs_entry
, &cpu_list
);
10391 g_slist_free(list
);
10393 for (i
= 0; ppc_cpu_aliases
[i
].alias
!= NULL
; i
++) {
10394 PowerPCCPUAlias
*alias
= &ppc_cpu_aliases
[i
];
10396 CpuDefinitionInfoList
*entry
;
10397 CpuDefinitionInfo
*info
;
10399 oc
= ppc_cpu_class_by_alias(alias
);
10404 info
= g_malloc0(sizeof(*info
));
10405 info
->name
= g_strdup(alias
->alias
);
10406 info
->q_typename
= g_strdup(object_class_get_name(oc
));
10408 entry
= g_malloc0(sizeof(*entry
));
10409 entry
->value
= info
;
10410 entry
->next
= cpu_list
;
10417 static void ppc_cpu_set_pc(CPUState
*cs
, vaddr value
)
10419 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10421 cpu
->env
.nip
= value
;
10424 static bool ppc_cpu_has_work(CPUState
*cs
)
10426 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10427 CPUPPCState
*env
= &cpu
->env
;
10429 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
10432 /* CPUClass::reset() */
10433 static void ppc_cpu_reset(CPUState
*s
)
10435 PowerPCCPU
*cpu
= POWERPC_CPU(s
);
10436 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10437 CPUPPCState
*env
= &cpu
->env
;
10441 pcc
->parent_reset(s
);
10443 msr
= (target_ulong
)0;
10444 msr
|= (target_ulong
)MSR_HVB
;
10445 msr
|= (target_ulong
)0 << MSR_AP
; /* TO BE CHECKED */
10446 msr
|= (target_ulong
)0 << MSR_SA
; /* TO BE CHECKED */
10447 msr
|= (target_ulong
)1 << MSR_EP
;
10448 #if defined(DO_SINGLE_STEP) && 0
10449 /* Single step trace mode */
10450 msr
|= (target_ulong
)1 << MSR_SE
;
10451 msr
|= (target_ulong
)1 << MSR_BE
;
10453 #if defined(CONFIG_USER_ONLY)
10454 msr
|= (target_ulong
)1 << MSR_FP
; /* Allow floating point usage */
10455 msr
|= (target_ulong
)1 << MSR_VR
; /* Allow altivec usage */
10456 msr
|= (target_ulong
)1 << MSR_VSX
; /* Allow VSX usage */
10457 msr
|= (target_ulong
)1 << MSR_SPE
; /* Allow SPE usage */
10458 msr
|= (target_ulong
)1 << MSR_PR
;
10459 #if defined(TARGET_PPC64)
10460 msr
|= (target_ulong
)1 << MSR_TM
; /* Transactional memory */
10462 #if !defined(TARGET_WORDS_BIGENDIAN)
10463 msr
|= (target_ulong
)1 << MSR_LE
; /* Little-endian user mode */
10464 if (!((env
->msr_mask
>> MSR_LE
) & 1)) {
10465 fprintf(stderr
, "Selected CPU does not support little-endian.\n");
10471 #if defined(TARGET_PPC64)
10472 if (env
->mmu_model
& POWERPC_MMU_64
) {
10473 msr
|= (1ULL << MSR_SF
);
10477 hreg_store_msr(env
, msr
, 1);
10479 #if !defined(CONFIG_USER_ONLY)
10480 env
->nip
= env
->hreset_vector
| env
->excp_prefix
;
10481 if (env
->mmu_model
!= POWERPC_MMU_REAL
) {
10482 ppc_tlb_invalidate_all(env
);
10486 hreg_compute_hflags(env
);
10487 env
->reserve_addr
= (target_ulong
)-1ULL;
10488 /* Be sure no exception or interrupt is pending */
10489 env
->pending_interrupts
= 0;
10490 s
->exception_index
= POWERPC_EXCP_NONE
;
10491 env
->error_code
= 0;
10493 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
10495 env
->slb_shadow_addr
= 0;
10496 env
->slb_shadow_size
= 0;
10499 #endif /* TARGET_PPC64 */
10501 for (i
= 0; i
< ARRAY_SIZE(env
->spr_cb
); i
++) {
10502 ppc_spr_t
*spr
= &env
->spr_cb
[i
];
10507 env
->spr
[i
] = spr
->default_value
;
10511 #ifndef CONFIG_USER_ONLY
10512 static bool ppc_cpu_is_big_endian(CPUState
*cs
)
10514 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10515 CPUPPCState
*env
= &cpu
->env
;
10517 cpu_synchronize_state(cs
);
10523 static void ppc_cpu_initfn(Object
*obj
)
10525 CPUState
*cs
= CPU(obj
);
10526 PowerPCCPU
*cpu
= POWERPC_CPU(obj
);
10527 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10528 CPUPPCState
*env
= &cpu
->env
;
10532 env
->msr_mask
= pcc
->msr_mask
;
10533 env
->mmu_model
= pcc
->mmu_model
;
10534 env
->excp_model
= pcc
->excp_model
;
10535 env
->bus_model
= pcc
->bus_model
;
10536 env
->insns_flags
= pcc
->insns_flags
;
10537 env
->insns_flags2
= pcc
->insns_flags2
;
10538 env
->flags
= pcc
->flags
;
10539 env
->bfd_mach
= pcc
->bfd_mach
;
10540 env
->check_pow
= pcc
->check_pow
;
10542 /* Mark HV mode as supported if the CPU has an MSR_HV bit
10543 * in the msr_mask. The mask can later be cleared by PAPR
10544 * mode but the hv mode support will remain, thus enforcing
10545 * that we cannot use priv. instructions in guest in PAPR
10546 * mode. For 970 we currently simply don't set HV in msr_mask
10547 * thus simulating an "Apple mode" 970. If we ever want to
10548 * support 970 HV mode, we'll have to add a processor attribute
10551 #if !defined(CONFIG_USER_ONLY)
10552 env
->has_hv_mode
= !!(env
->msr_mask
& MSR_HVB
);
10555 #if defined(TARGET_PPC64)
10557 env
->sps
= *pcc
->sps
;
10558 } else if (env
->mmu_model
& POWERPC_MMU_64
) {
10559 /* Use default sets of page sizes. We don't support MPSS */
10560 static const struct ppc_segment_page_sizes defsps_4k
= {
10562 { .page_shift
= 12, /* 4K */
10564 .enc
= { { .page_shift
= 12, .pte_enc
= 0 } }
10566 { .page_shift
= 24, /* 16M */
10568 .enc
= { { .page_shift
= 24, .pte_enc
= 0 } }
10572 static const struct ppc_segment_page_sizes defsps_64k
= {
10574 { .page_shift
= 12, /* 4K */
10576 .enc
= { { .page_shift
= 12, .pte_enc
= 0 } }
10578 { .page_shift
= 16, /* 64K */
10580 .enc
= { { .page_shift
= 16, .pte_enc
= 1 } }
10582 { .page_shift
= 24, /* 16M */
10584 .enc
= { { .page_shift
= 24, .pte_enc
= 0 } }
10588 env
->sps
= (env
->mmu_model
& POWERPC_MMU_64K
) ? defsps_64k
: defsps_4k
;
10590 #endif /* defined(TARGET_PPC64) */
10592 if (tcg_enabled()) {
10593 ppc_translate_init();
10597 static bool ppc_pvr_match_default(PowerPCCPUClass
*pcc
, uint32_t pvr
)
10599 return pcc
->pvr
== pvr
;
10602 static gchar
*ppc_gdb_arch_name(CPUState
*cs
)
10604 #if defined(TARGET_PPC64)
10605 return g_strdup("powerpc:common64");
10607 return g_strdup("powerpc:common");
10611 static Property ppc_cpu_properties
[] = {
10612 DEFINE_PROP_BOOL("pre-2.8-migration", PowerPCCPU
, pre_2_8_migration
, false),
10613 DEFINE_PROP_BOOL("pre-2.10-migration", PowerPCCPU
, pre_2_10_migration
,
10615 DEFINE_PROP_END_OF_LIST(),
10618 static void ppc_cpu_class_init(ObjectClass
*oc
, void *data
)
10620 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10621 CPUClass
*cc
= CPU_CLASS(oc
);
10622 DeviceClass
*dc
= DEVICE_CLASS(oc
);
10624 pcc
->parent_realize
= dc
->realize
;
10625 pcc
->parent_unrealize
= dc
->unrealize
;
10626 pcc
->pvr_match
= ppc_pvr_match_default
;
10627 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_always
;
10628 dc
->realize
= ppc_cpu_realizefn
;
10629 dc
->unrealize
= ppc_cpu_unrealizefn
;
10630 dc
->props
= ppc_cpu_properties
;
10632 pcc
->parent_reset
= cc
->reset
;
10633 cc
->reset
= ppc_cpu_reset
;
10635 cc
->class_by_name
= ppc_cpu_class_by_name
;
10636 cc
->has_work
= ppc_cpu_has_work
;
10637 cc
->do_interrupt
= ppc_cpu_do_interrupt
;
10638 cc
->cpu_exec_interrupt
= ppc_cpu_exec_interrupt
;
10639 cc
->dump_state
= ppc_cpu_dump_state
;
10640 cc
->dump_statistics
= ppc_cpu_dump_statistics
;
10641 cc
->set_pc
= ppc_cpu_set_pc
;
10642 cc
->gdb_read_register
= ppc_cpu_gdb_read_register
;
10643 cc
->gdb_write_register
= ppc_cpu_gdb_write_register
;
10644 #ifdef CONFIG_USER_ONLY
10645 cc
->handle_mmu_fault
= ppc_cpu_handle_mmu_fault
;
10647 cc
->get_phys_page_debug
= ppc_cpu_get_phys_page_debug
;
10648 cc
->vmsd
= &vmstate_ppc_cpu
;
10650 #if defined(CONFIG_SOFTMMU)
10651 cc
->write_elf64_note
= ppc64_cpu_write_elf64_note
;
10652 cc
->write_elf32_note
= ppc32_cpu_write_elf32_note
;
10655 cc
->gdb_num_core_regs
= 71;
10657 #ifdef USE_APPLE_GDB
10658 cc
->gdb_read_register
= ppc_cpu_gdb_read_register_apple
;
10659 cc
->gdb_write_register
= ppc_cpu_gdb_write_register_apple
;
10660 cc
->gdb_num_core_regs
= 71 + 32;
10663 cc
->gdb_arch_name
= ppc_gdb_arch_name
;
10664 #if defined(TARGET_PPC64)
10665 cc
->gdb_core_xml_file
= "power64-core.xml";
10667 cc
->gdb_core_xml_file
= "power-core.xml";
10669 #ifndef CONFIG_USER_ONLY
10670 cc
->virtio_is_big_endian
= ppc_cpu_is_big_endian
;
10673 dc
->fw_name
= "PowerPC,UNKNOWN";
10676 static const TypeInfo ppc_cpu_type_info
= {
10677 .name
= TYPE_POWERPC_CPU
,
10678 .parent
= TYPE_CPU
,
10679 .instance_size
= sizeof(PowerPCCPU
),
10680 .instance_init
= ppc_cpu_initfn
,
10682 .class_size
= sizeof(PowerPCCPUClass
),
10683 .class_init
= ppc_cpu_class_init
,
10686 static const TypeInfo ppc_vhyp_type_info
= {
10687 .name
= TYPE_PPC_VIRTUAL_HYPERVISOR
,
10688 .parent
= TYPE_INTERFACE
,
10689 .class_size
= sizeof(PPCVirtualHypervisorClass
),
10692 static void ppc_cpu_register_types(void)
10694 type_register_static(&ppc_cpu_type_info
);
10695 type_register_static(&ppc_vhyp_type_info
);
10698 type_init(ppc_cpu_register_types
)